cgtk

Get the visible state of a GtkWidget that may be in GtkStack, GtkNotebook or GtkBox


I am trying to check the visible state of a Gtk widget in C. I have a GList * of widgets, and I don't know at runtime whether they are inserted into a GtkBox, a GtkNotebook or a GtkStack.

gtk_widget_is_visible(widget) works as expected in a GtkBox, but will also return TRUE when the widget belongs to an hidden page of GtkStack or GtkNotebook.

gtk_widget_get_realized(widget) works only after initialization time: children of hidden pages return FALSE until the page is shown. After that, they get realized.

My ultimate goal is simply to assign the focus on those widgets upon key accelerator (shortcut). Alternatively, showing the parent page would be an acceptable solution, but given that parents are of different types, I don't know of any unified method to do so.


Solution

  • I resorted to that for the time being…

    static gboolean is_visible_widget(GtkWidget *widget)
    {
      // The parent will always be a GtkBox
      GtkWidget *parent = gtk_widget_get_parent(widget);
      GtkWidget *grandparent = gtk_widget_get_parent(parent);
      GType type = G_OBJECT_TYPE(grandparent);
    
      gboolean visible_parent = TRUE;
    
      if(type == GTK_TYPE_NOTEBOOK)
      {
        // Find the page in which the current widget is and try to show it
        gint page_num = gtk_notebook_page_num(GTK_NOTEBOOK(grandparent), parent);
        if(page_num > -1)
          gtk_notebook_set_current_page(GTK_NOTEBOOK(grandparent), page_num);
        else
          visible_parent = FALSE;
      }
      else if(type == GTK_TYPE_STACK)
      {
        // Stack pages are enabled based on user parameteters,
        // so if not visible, then do nothing.
        GtkWidget *visible_child = gtk_stack_get_visible_child(GTK_STACK(grandparent));
        if(visible_child != parent) visible_parent = FALSE;
      }
    
      return gtk_widget_is_visible(widget) && gtk_widget_is_sensitive(widget) && gtk_widget_get_realized(widget) && visible_parent;
    }