Exemple #1
0
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)));
}