]> Pileus Git - ~andy/gtk/commitdiff
allow accel activation depending on sensitivity and the attach widget.
authorTim Janik <timj@gtk.org>
Thu, 27 Nov 2003 15:51:32 +0000 (15:51 +0000)
committerTim Janik <timj@src.gnome.org>
Thu, 27 Nov 2003 15:51:32 +0000 (15:51 +0000)
Thu Nov 27 16:19:03 2003  Tim Janik  <timj@gtk.org>

        * gtk/gtkmenu.c: allow accel activation depending on sensitivity
        and the attach widget.

        * gtk/gtkmenuitem.c: allow accel activation depending on visibility,
        sensitivity and the parent menu.

        * gtk/gtkwidget.[hc]: introduced ::can-activate-accel signal which
        checks whether accelerators may activate a widget. the default handler
        demands the widget be sensitive and visible+viewable.

        * gtk/gtkaccelgroup.[hc]: export gtk_accel_group_activate().

12 files changed:
ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkaccelgroup.c
gtk/gtkaccelgroup.h
gtk/gtkmarshalers.list
gtk/gtkmenu.c
gtk/gtkmenuitem.c
gtk/gtkwidget.c
gtk/gtkwidget.h

index 68f37b89e94b5ef7fed830291f6b98f7e85fcb28..f9fd26b23ff236c57901919d6e581733972210dc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+Thu Nov 27 16:19:03 2003  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkmenu.c: allow accel activation depending on sensitivity
+       and the attach widget.
+
+       * gtk/gtkmenuitem.c: allow accel activation depending on visibility,
+       sensitivity and the parent menu.
+
+       * gtk/gtkwidget.[hc]: introduced ::can-activate-accel signal which
+       checks whether accelerators may activate a widget. the default handler
+       demands the widget be sensitive and visible+viewable.
+
+       * gtk/gtkaccelgroup.[hc]: export gtk_accel_group_activate().
+
 Tue Nov 25 00:10:05 2003  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtkuimanager.c (update_node): Don't show accelerators in
index 68f37b89e94b5ef7fed830291f6b98f7e85fcb28..f9fd26b23ff236c57901919d6e581733972210dc 100644 (file)
@@ -1,3 +1,17 @@
+Thu Nov 27 16:19:03 2003  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkmenu.c: allow accel activation depending on sensitivity
+       and the attach widget.
+
+       * gtk/gtkmenuitem.c: allow accel activation depending on visibility,
+       sensitivity and the parent menu.
+
+       * gtk/gtkwidget.[hc]: introduced ::can-activate-accel signal which
+       checks whether accelerators may activate a widget. the default handler
+       demands the widget be sensitive and visible+viewable.
+
+       * gtk/gtkaccelgroup.[hc]: export gtk_accel_group_activate().
+
 Tue Nov 25 00:10:05 2003  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtkuimanager.c (update_node): Don't show accelerators in
index 68f37b89e94b5ef7fed830291f6b98f7e85fcb28..f9fd26b23ff236c57901919d6e581733972210dc 100644 (file)
@@ -1,3 +1,17 @@
+Thu Nov 27 16:19:03 2003  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkmenu.c: allow accel activation depending on sensitivity
+       and the attach widget.
+
+       * gtk/gtkmenuitem.c: allow accel activation depending on visibility,
+       sensitivity and the parent menu.
+
+       * gtk/gtkwidget.[hc]: introduced ::can-activate-accel signal which
+       checks whether accelerators may activate a widget. the default handler
+       demands the widget be sensitive and visible+viewable.
+
+       * gtk/gtkaccelgroup.[hc]: export gtk_accel_group_activate().
+
 Tue Nov 25 00:10:05 2003  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtkuimanager.c (update_node): Don't show accelerators in
index 68f37b89e94b5ef7fed830291f6b98f7e85fcb28..f9fd26b23ff236c57901919d6e581733972210dc 100644 (file)
@@ -1,3 +1,17 @@
+Thu Nov 27 16:19:03 2003  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkmenu.c: allow accel activation depending on sensitivity
+       and the attach widget.
+
+       * gtk/gtkmenuitem.c: allow accel activation depending on visibility,
+       sensitivity and the parent menu.
+
+       * gtk/gtkwidget.[hc]: introduced ::can-activate-accel signal which
+       checks whether accelerators may activate a widget. the default handler
+       demands the widget be sensitive and visible+viewable.
+
+       * gtk/gtkaccelgroup.[hc]: export gtk_accel_group_activate().
+
 Tue Nov 25 00:10:05 2003  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtkuimanager.c (update_node): Don't show accelerators in
index 68f37b89e94b5ef7fed830291f6b98f7e85fcb28..f9fd26b23ff236c57901919d6e581733972210dc 100644 (file)
@@ -1,3 +1,17 @@
+Thu Nov 27 16:19:03 2003  Tim Janik  <timj@gtk.org>
+
+       * gtk/gtkmenu.c: allow accel activation depending on sensitivity
+       and the attach widget.
+
+       * gtk/gtkmenuitem.c: allow accel activation depending on visibility,
+       sensitivity and the parent menu.
+
+       * gtk/gtkwidget.[hc]: introduced ::can-activate-accel signal which
+       checks whether accelerators may activate a widget. the default handler
+       demands the widget be sensitive and visible+viewable.
+
+       * gtk/gtkaccelgroup.[hc]: export gtk_accel_group_activate().
+
 Tue Nov 25 00:10:05 2003  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtkuimanager.c (update_node): Don't show accelerators in
index 3a6020c85716353eafacc082c11afd7b9863eb36..a327fd26045e95631aa50d05ccd2883f3196f852 100644 (file)
@@ -718,16 +718,17 @@ gtk_accel_group_from_accel_closure (GClosure *closure)
 }
 
 gboolean
-_gtk_accel_group_activate (GtkAccelGroup  *accel_group,
-                          GQuark          accel_quark,
-                          GObject        *acceleratable,
-                          guint           accel_key,
-                          GdkModifierType accel_mods)
+gtk_accel_group_activate (GtkAccelGroup   *accel_group,
+                          GQuark          accel_quark,
+                          GObject        *acceleratable,
+                          guint                   accel_key,
+                          GdkModifierType  accel_mods)
 {
   gboolean was_handled;
 
   g_return_val_if_fail (GTK_IS_ACCEL_GROUP (accel_group), FALSE);
-
+  g_return_val_if_fail (G_IS_OBJECT (acceleratable), FALSE);
+  
   was_handled = FALSE;
   g_signal_emit (accel_group, signal_accel_activate, accel_quark,
                 acceleratable, accel_key, accel_mods, &was_handled);
@@ -767,7 +768,7 @@ gtk_accel_groups_activate (GObject    *object,
       g_free (accel_name);
       
       for (slist = gtk_accel_groups_from_object (object); slist; slist = slist->next)
-       if (_gtk_accel_group_activate (slist->data, accel_quark, object, accel_key, accel_mods))
+       if (gtk_accel_group_activate (slist->data, accel_quark, object, accel_key, accel_mods))
          return TRUE;
     }
   
index a3a53d48586ca241517238616822471251e62e5b..b4f1b032e766fad68110deb0c127967ad5190e87 100644 (file)
@@ -118,6 +118,11 @@ gboolean       gtk_accel_group_disconnect    (GtkAccelGroup  *accel_group,
 gboolean       gtk_accel_group_disconnect_key    (GtkAccelGroup  *accel_group,
                                                   guint           accel_key,
                                                   GdkModifierType accel_mods);
+gboolean       gtk_accel_group_activate           (GtkAccelGroup   *accel_group,
+                                                   GQuark         accel_quark,
+                                                   GObject       *acceleratable,
+                                                   guint          accel_key,
+                                                   GdkModifierType accel_mods);
 
 
 /* --- GtkActivatable glue --- */
index 601139e4471fc150adb18f6a26cf13357397d948..f897caef29e1687143140cc646974837922e9e1a 100644 (file)
@@ -33,6 +33,7 @@ BOOLEAN:OBJECT,BOXED,BOXED
 BOOLEAN:OBJECT,STRING,STRING
 BOOLEAN:INT,INT
 BOOLEAN:INT,INT,INT
+BOOLEAN:UINT
 BOOLEAN:VOID
 BOOLEAN:BOOLEAN
 BOOLEAN:NONE
index db002aa4cf5e6b553bb411075a6a0760f810b362..3999ee545ff188da2bbc9bad3d9cf5c936fe8513 100644 (file)
@@ -215,6 +215,8 @@ static void gtk_menu_update_title   (GtkMenu           *menu);
 static void       menu_grab_transfer_window_destroy (GtkMenu *menu);
 static GdkWindow *menu_grab_transfer_window_get     (GtkMenu *menu);
 
+static gboolean gtk_menu_real_can_activate_accel (GtkWidget *widget,
+                                                  guint      signal_id);
 static void _gtk_menu_refresh_accel_paths (GtkMenu *menu,
                                           gboolean group_changed);
 
@@ -318,6 +320,7 @@ gtk_menu_class_init (GtkMenuClass *class)
   widget_class->motion_notify_event = gtk_menu_motion_notify;
   widget_class->style_set = gtk_menu_style_set;
   widget_class->focus = gtk_menu_focus;
+  widget_class->can_activate_accel = gtk_menu_real_can_activate_accel;
 
   container_class->remove = gtk_menu_remove;
   container_class->get_child_property = gtk_menu_get_child_property;
@@ -1416,6 +1419,19 @@ gtk_menu_get_accel_group (GtkMenu *menu)
   return menu->accel_group;
 }
 
+static gboolean
+gtk_menu_real_can_activate_accel (GtkWidget *widget,
+                                  guint      signal_id)
+{
+  /* menu items chain here to figure whether they can activate their accelerators.
+   * despite ordinary widgets, menus allow accel activation even if invisible
+   * since that's the usual case for submenus/popup-menus. however, the state
+   * of the attch widget affects "activeness" of the menu.
+   */
+  GtkWidget *awidget = gtk_menu_get_attach_widget (GTK_MENU (widget));
+  return awidget ? gtk_widget_can_activate_accel (awidget, signal_id) : GTK_WIDGET_IS_SENSITIVE (widget);
+}
+
 /**
  * gtk_menu_set_accel_path
  * @menu:       a valid #GtkMenu
index 3058706b9787e9e62c71bf93acd363287e07b9e0..ac594005d16e60acec190d526bc441a4cf4bb7eb 100644 (file)
@@ -89,6 +89,8 @@ static void gtk_menu_item_forall         (GtkContainer    *container,
                                          gboolean         include_internals,
                                          GtkCallback      callback,
                                          gpointer         callback_data);
+static gboolean gtk_menu_item_real_can_activate_accel (GtkWidget *widget,
+                                                       guint      signal_id);
 
 
 static GtkItemClass *parent_class;
@@ -147,6 +149,7 @@ gtk_menu_item_class_init (GtkMenuItemClass *klass)
   widget_class->hide_all = gtk_menu_item_hide_all;
   widget_class->mnemonic_activate = gtk_menu_item_mnemonic_activate;
   widget_class->parent_set = gtk_menu_item_parent_set;
+  widget_class->can_activate_accel = gtk_menu_item_real_can_activate_accel;
   
   container_class->forall = gtk_menu_item_forall;
 
@@ -1214,6 +1217,15 @@ gtk_menu_item_hide_all (GtkWidget *widget)
     gtk_widget_hide_all (menu_item->submenu);
 }
 
+static gboolean
+gtk_menu_item_real_can_activate_accel (GtkWidget *widget,
+                                       guint      signal_id)
+{
+  /* defer to parent menu to allow accel activation */
+  return (GTK_WIDGET_IS_SENSITIVE (widget) && GTK_WIDGET_VISIBLE (widget) &&
+          widget->parent && gtk_widget_can_activate_accel (widget->parent, signal_id));
+}
+
 static void
 gtk_menu_item_accel_name_foreach (GtkWidget *widget,
                                  gpointer data)
index 98b7c5c48a402875bf19257b686b9af56d63ae3d..f7dc67ae8028cc9d5dbc63b0dc6f4ff611caa2aa 100644 (file)
@@ -117,6 +117,7 @@ enum {
   SHOW_HELP,
   ACCEL_CLOSURES_CHANGED,
   SCREEN_CHANGED,
+  CAN_ACTIVATE_ACCEL,
   LAST_SIGNAL
 };
 
@@ -218,7 +219,9 @@ static void             gtk_widget_invalidate_widget_windows    (GtkWidget
                                                                 GdkRegion        *region);
 static GdkScreen *      gtk_widget_get_screen_unchecked         (GtkWidget        *widget);
 static void            gtk_widget_queue_shallow_draw           (GtkWidget        *widget);
-
+static gboolean         gtk_widget_real_can_activate_accel      (GtkWidget *widget,
+                                                                 guint      signal_id);
+     
 static void gtk_widget_set_usize_internal (GtkWidget *widget,
                                           gint       width,
                                           gint       height);
@@ -388,6 +391,7 @@ gtk_widget_class_init (GtkWidgetClass *klass)
   klass->drag_drop = NULL;
   klass->drag_data_received = NULL;
   klass->screen_changed = NULL;
+  klass->can_activate_accel = gtk_widget_real_can_activate_accel;
 
   klass->show_help = gtk_widget_real_show_help;
   
@@ -1309,7 +1313,15 @@ gtk_widget_class_init (GtkWidgetClass *klass)
                  _gtk_marshal_VOID__OBJECT,
                  G_TYPE_NONE, 1,
                  GDK_TYPE_SCREEN);
-  
+  widget_signals[CAN_ACTIVATE_ACCEL] =
+    g_signal_new ("can_activate_accel",
+                 G_TYPE_FROM_CLASS (gobject_class),
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET (GtkWidgetClass, can_activate_accel),
+                  _gtk_boolean_handled_accumulator, NULL,
+                 _gtk_marshal_BOOLEAN__UINT,
+                  G_TYPE_BOOLEAN, 1, G_TYPE_UINT);
+
   binding_set = gtk_binding_set_by_class (klass);
   gtk_binding_entry_add_signal (binding_set, GDK_F10, GDK_SHIFT_MASK,
                                 "popup_menu", 0);
@@ -2884,6 +2896,24 @@ gtk_widget_real_size_allocate (GtkWidget     *widget,
      }
 }
 
+static gboolean
+gtk_widget_real_can_activate_accel (GtkWidget *widget,
+                                    guint      signal_id)
+{
+  /* widgets must be onscreen for accels to take effect */
+  return GTK_WIDGET_IS_SENSITIVE (widget) && GTK_WIDGET_DRAWABLE (widget) && gdk_window_is_viewable (widget->window);
+}
+
+gboolean
+gtk_widget_can_activate_accel (GtkWidget *widget,
+                               guint      signal_id)
+{
+  gboolean can_activate = FALSE;
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
+  g_signal_emit (widget, widget_signals[CAN_ACTIVATE_ACCEL], 0, signal_id, &can_activate);
+  return can_activate;
+}
+
 typedef struct {
   GClosure   closure;
   guint      signal_id;
@@ -2898,12 +2928,13 @@ closure_accel_activate (GClosure     *closure,
                        gpointer      marshal_data)
 {
   AccelClosure *aclosure = (AccelClosure*) closure;
+  gboolean can_activate = gtk_widget_can_activate_accel (closure->data, aclosure->signal_id);
 
-  if (GTK_WIDGET_IS_SENSITIVE (closure->data))
+  if (can_activate)
     g_signal_emit (closure->data, aclosure->signal_id, 0);
 
-  /* we handled the accelerator */
-  g_value_set_boolean (return_value, TRUE);
+  /* wether accelerator was handled */
+  g_value_set_boolean (return_value, can_activate);
 }
 
 static void
index 7aaba52179b92f300c909a959bcdd66c138e0004..f4bd4d125fd0f1ee278b455257043ea64d78844a 100644 (file)
@@ -399,12 +399,14 @@ struct _GtkWidgetClass
   
   /* accessibility support 
    */
-  AtkObject*   (* get_accessible)  (GtkWidget          *widget);
+  AtkObject*   (*get_accessible)     (GtkWidget *widget);
+
+  void         (*screen_changed)     (GtkWidget *widget,
+                                      GdkScreen *previous_screen);
+  gboolean     (*can_activate_accel) (GtkWidget *widget,
+                                      guint      signal_id);
 
-  void (* screen_changed) (GtkWidget *widget,
-                          GdkScreen *previous_screen);
   /* Padding for future expansion */
-  void (*_gtk_reserved1) (void);
   void (*_gtk_reserved2) (void);
   void (*_gtk_reserved3) (void);
   void (*_gtk_reserved4) (void);
@@ -503,6 +505,8 @@ void       gtk_widget_set_accel_path      (GtkWidget           *widget,
 const gchar* _gtk_widget_get_accel_path   (GtkWidget           *widget,
                                           gboolean            *locked);
 GList*     gtk_widget_list_accel_closures (GtkWidget          *widget);
+gboolean   gtk_widget_can_activate_accel  (GtkWidget           *widget,
+                                           guint                signal_id);
 gboolean   gtk_widget_mnemonic_activate   (GtkWidget           *widget,
                                           gboolean             group_cycling);
 gboolean   gtk_widget_event              (GtkWidget           *widget,