static void ViewAutoDrawerUpdate(ViewAutoDrawer *that, // IN gboolean immediate) // IN { ViewAutoDrawerPrivate *priv = that->priv; GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(that)); GtkWindow *window; GtkAllocation allocation; if (!toplevel || !gtk_widget_is_toplevel(toplevel)) { // The autoDrawer cannot function properly without a toplevel. return; } window = GTK_WINDOW(toplevel); /* * We decide to open the drawer by OR'ing several conditions. Evaluating a * condition can have the side-effect of setting 'immediate' to TRUE, so we * cannot stop evaluating the conditions after we have found one to be TRUE. */ priv->opened = FALSE; /* Is the AutoDrawer pinned? */ if (priv->pinned) { immediate = TRUE; priv->opened = TRUE; } /* Is the mouse cursor inside the event box? */ { int x; int y; gtk_widget_get_pointer(priv->evBox, &x, &y); gtk_widget_get_allocation(priv->evBox, &allocation); g_assert(gtk_container_get_border_width( GTK_CONTAINER(priv->evBox)) == 0); if ( (guint)x < (guint)allocation.width && (guint)y < (guint)allocation.height) { priv->opened = TRUE; } } /* If there is a focused widget, is it inside the event box? */ { GtkWidget *focus; focus = gtk_window_get_focus(window); if (focus && gtk_widget_is_ancestor(focus, priv->evBox)) { /* * Override the default 'immediate' to make sure the 'over' widget * immediately appears along with the widget the focused widget. */ immediate = TRUE; priv->opened = TRUE; } } /* If input is grabbed, is it on behalf of a widget inside the event box? */ if (!priv->inputUngrabbed) { GtkWidget *grabbed = NULL; if (gtk_window_has_group (window)) { GtkWindowGroup *group = gtk_window_get_group (window); grabbed = gtk_window_group_get_current_grab (group); } if (!grabbed) { grabbed = gtk_grab_get_current(); } if (grabbed && GTK_IS_MENU(grabbed)) { /* * With cascading menus, the deepest menu owns the grab. Traverse the * menu hierarchy up until we reach the attach widget for the whole * hierarchy. */ for (;;) { GtkWidget *menuAttach; GtkWidget *menuItemParent; menuAttach = gtk_menu_get_attach_widget(GTK_MENU(grabbed)); if (!menuAttach) { /* * It is unfortunately not mandatory for a menu to have a proper * attach widget set. */ break; } grabbed = menuAttach; if (!GTK_IS_MENU_ITEM(grabbed)) { break; } menuItemParent = gtk_widget_get_parent(grabbed); g_return_if_fail(menuItemParent); if (!GTK_IS_MENU(menuItemParent)) { break; } grabbed = menuItemParent; } } if (grabbed && gtk_widget_is_ancestor(grabbed, priv->evBox)) { /* * Override the default 'immediate' to make sure the 'over' widget * immediately appears along with the widget the grab happens on * behalf of. */ immediate = TRUE; priv->opened = TRUE; } } if (priv->delayConnection) { g_source_remove(priv->delayConnection); } if (priv->forceClosing) { ViewAutoDrawerEnforce(that, TRUE); } else if (immediate) { ViewAutoDrawerEnforce(that, FALSE); } else { priv->delayConnection = g_timeout_add(priv->delayValue, (GSourceFunc)ViewAutoDrawerOnEnforceDelay, that); } }
static VALUE rg_current_grab(VALUE self) { return GOBJ2RVAL(gtk_window_group_get_current_grab(_SELF(self))); }