F10 for menus



Hi,

Patch making a global GtkSetting for the "open the menubar" key.
The patch is mildly hacky, but the only good way to add this we could
come up with for now.

Also, killed gtk_menu_bar_set_shadow_type() and replaced it with a
style property.

Havoc

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.1907
diff -u -u -r1.1907 ChangeLog
--- ChangeLog	2001/04/18 22:21:42	1.1907
+++ ChangeLog	2001/04/19 21:20:33
@@ -1,3 +1,23 @@
+2001-04-19  Havoc Pennington  <hp redhat com>
+
+	* gtk/gtkmenu.c (gtk_menu_key_press): handle menu bar accel to pop 
+	it back down
+
+	* gtk/gtkoptionmenu.c (gtk_option_menu_get_props): free boxed
+	types from gtk_widget_style_get
+
+	* gtk/gtkmenubar.c (gtk_menu_bar_set_shadow_type): Remove, replace
+	with a style property.
+
+	* gdk/x11/gdkevents-x11.c: namespace the settings
+
+	* gtk/gtkmenubar.c: Add F10 accelerator to move between menubars.
+
+	* gtk/gtksettings.c (gtk_settings_class_init): remove code with
+	side effects from inside g_assert(), so that G_DISABLE_ASSERT can
+	be used. Also, translate doc strings for settings. Also, namespace
+	the double-click-time property
+
 2001-04-18  Havoc Pennington  <hp redhat com>
 
 	* gtk/gtkwindow.c (gtk_window_class_init): add signals and binding
Index: docs/reference/gtk/tmpl/gtk-unused.sgml
===================================================================
RCS file: /cvs/gnome/gtk+/docs/reference/gtk/tmpl/gtk-unused.sgml,v
retrieving revision 1.35
diff -u -u -r1.35 gtk-unused.sgml
--- docs/reference/gtk/tmpl/gtk-unused.sgml	2001/04/18 18:09:16	1.35
+++ docs/reference/gtk/tmpl/gtk-unused.sgml	2001/04/19 21:20:34
@@ -557,6 +557,12 @@
 </para>
 
 
+<!-- ##### ARG GtkMenuBar:shadow ##### -->
+<para>
+Used by #GtkMenuBar to determine the shadow type.
+</para>
+
+
 <!-- ##### ARG GtkObject:object-signal ##### -->
 <para>
 Setting this with a GtkType of GTK_TYPE_SIGNAL connects
@@ -953,6 +959,15 @@
 @iter: 
 @column: 
 @value: 
+
+<!-- ##### FUNCTION gtk_menu_bar_set_shadow_type ##### -->
+<para>
+Sets the shadow type to use on the GtkMenuBar. The shadow types to use are:
+GTK_SHADOW_NONE, GTK_SHADOW_IN, GTK_SHADOW_OUT, GTK_SHADOW_ETCHED_IN, and GTK_SHADOW_ETCHED_OUT
+</para>
+
+ menu_bar: a #GtkMenuBar
+ type: the GtkShadowtype
 
 <!-- ##### FUNCTION gtk_menu_ensure_uline_accel_group ##### -->
 <para>
Index: docs/reference/gtk/tmpl/gtkmenubar.sgml
===================================================================
RCS file: /cvs/gnome/gtk+/docs/reference/gtk/tmpl/gtkmenubar.sgml,v
retrieving revision 1.5
diff -u -u -r1.5 gtkmenubar.sgml
--- docs/reference/gtk/tmpl/gtkmenubar.sgml	1999/11/16 00:33:10	1.5
+++ docs/reference/gtk/tmpl/gtkmenubar.sgml	2001/04/19 21:20:34
@@ -56,18 +56,3 @@
 @position: the position in the item list where the @child is added.
 
 
-<!-- ##### FUNCTION gtk_menu_bar_set_shadow_type ##### -->
-<para>
-Sets the shadow type to use on the GtkMenuBar. The shadow types to use are:
-GTK_SHADOW_NONE, GTK_SHADOW_IN, GTK_SHADOW_OUT, GTK_SHADOW_ETCHED_IN, and GTK_SHADOW_ETCHED_OUT
-</para>
-
- menu_bar: a #GtkMenuBar
- type: the GtkShadowtype
-
-
-<!-- ##### ARG GtkMenuBar:shadow ##### -->
-<para>
-Used by #GtkMenuBar to determine the shadow type.
-</para>
-
Index: gdk/x11/gdkevents-x11.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/x11/gdkevents-x11.c,v
retrieving revision 1.46
diff -u -u -r1.46 gdkevents-x11.c
--- gdk/x11/gdkevents-x11.c	2001/04/18 17:57:36	1.46
+++ gdk/x11/gdkevents-x11.c	2001/04/19 21:20:34
@@ -1901,8 +1901,8 @@
   const char *xsettings_name;
   const char *gdk_name;
 } settings_map[] = {
-  { "Net/DoubleClickTime", "double-click-timeout" },
-  { "Net/DragThreshold", "drag-threshold" }
+  { "Net/DoubleClickTime", "gtk-double-click-timeout" },
+  { "Net/DragThreshold", "gtk-drag-threshold" }
 };
 
 static void
Index: gtk/gtkmenu.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenu.c,v
retrieving revision 1.61
diff -u -u -r1.61 gtkmenu.c
--- gtk/gtkmenu.c	2001/03/29 00:24:57	1.61
+++ gtk/gtkmenu.c	2001/04/19 21:20:34
@@ -36,6 +36,8 @@
 #include "gtkwindow.h"
 #include "gtkhbox.h"
 #include "gtkvscrollbar.h"
+#include "gtkmenubar.h"
+#include "gtksettings.h"
 
 
 #define MENU_ITEM_CLASS(w)   GTK_MENU_ITEM_GET_CLASS (w)
@@ -1372,19 +1374,55 @@
 		    GdkEventKey *event)
 {
   GtkMenuShell *menu_shell;
+  GtkMenu *menu;
   gboolean delete = FALSE;
-
+  gchar *accel = NULL;
+  
   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_MENU (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
       
   menu_shell = GTK_MENU_SHELL (widget);
-
+  menu = GTK_MENU (widget);
+  
   gtk_menu_stop_navigating_submenu (GTK_MENU (widget));
 
   if (GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event))
     return TRUE;
+    
+  g_object_get (G_OBJECT (gtk_settings_get_global ()),
+                "gtk-menu-bar-accel",
+                &accel,
+                NULL);
+
+  if (accel)
+    {
+      guint keyval = 0;
+      GdkModifierType mods = 0;
+      gboolean handled = FALSE;
+      
+      gtk_accelerator_parse (accel, &keyval, &mods);
 
+      if (keyval == 0)
+        g_warning ("Failed to parse menu bar accelerator '%s'\n", accel);
+
+      /* FIXME this is wrong, needs to be in the global accel resolution
+       * thing, to properly consider i18n etc., but that probably requires
+       * AccelGroup changes etc.
+       */
+      if (event->keyval == keyval &&
+          (mods & event->state) == mods)
+        {
+          gtk_signal_emit_by_name (GTK_OBJECT (menu),
+                                   "cancel");
+        }
+
+      g_free (accel);
+
+      if (handled)
+        return TRUE;
+    }
+  
   switch (event->keyval)
     {
     case GDK_Delete:
Index: gtk/gtkmenubar.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenubar.c,v
retrieving revision 1.23
diff -u -u -r1.23 gtkmenubar.c
--- gtk/gtkmenubar.c	2001/03/09 13:28:25	1.23
+++ gtk/gtkmenubar.c	2001/04/19 21:20:34
@@ -29,6 +29,10 @@
 #include "gtkmain.h"
 #include "gtkmenubar.h"
 #include "gtkmenuitem.h"
+#include "gtksettings.h"
+#include "gtkintl.h"
+#include "gtkwindow.h"
+#include "gtksignal.h"
 
 enum {
   ARG_0,
@@ -42,12 +46,6 @@
 
 static void gtk_menu_bar_class_init    (GtkMenuBarClass *klass);
 static void gtk_menu_bar_init          (GtkMenuBar      *menu_bar);
-static void gtk_menu_bar_set_arg       (GtkObject      *object,
-					GtkArg         *arg,
-					guint           arg_id);
-static void gtk_menu_bar_get_arg       (GtkObject      *object,
-					GtkArg         *arg,
-					guint           arg_id);
 static void gtk_menu_bar_size_request  (GtkWidget       *widget,
 					GtkRequisition  *requisition);
 static void gtk_menu_bar_size_allocate (GtkWidget       *widget,
@@ -56,8 +54,9 @@
 					GdkRectangle    *area);
 static gint gtk_menu_bar_expose        (GtkWidget       *widget,
 					GdkEventExpose  *event);
+static void gtk_menu_bar_hierarchy_changed (GtkWidget   *widget);                                            
+static GtkShadowType get_shadow_type   (GtkMenuBar      *menubar);
 
-
 static GtkMenuShellClass *parent_class = NULL;
 
 GtkType
@@ -100,15 +99,11 @@
   widget_class = (GtkWidgetClass*) class;
   menu_shell_class = (GtkMenuShellClass*) class;
 
-  gtk_object_add_arg_type ("GtkMenuBar::shadow", GTK_TYPE_SHADOW_TYPE, GTK_ARG_READWRITE, ARG_SHADOW);
-
-  object_class->set_arg = gtk_menu_bar_set_arg;
-  object_class->get_arg = gtk_menu_bar_get_arg;
-  
   widget_class->size_request = gtk_menu_bar_size_request;
   widget_class->size_allocate = gtk_menu_bar_size_allocate;
   widget_class->expose_event = gtk_menu_bar_expose;
-
+  widget_class->hierarchy_changed = gtk_menu_bar_hierarchy_changed;
+  
   menu_shell_class->submenu_placement = GTK_TOP_BOTTOM;
 
   binding_set = gtk_binding_set_by_class (class);
@@ -132,51 +127,27 @@
 				"move_current", 1,
 				GTK_TYPE_MENU_DIRECTION_TYPE,
 				GTK_MENU_DIR_CHILD);
-}
-
-static void
-gtk_menu_bar_init (GtkMenuBar *menu_bar)
-{
-  menu_bar->shadow_type = GTK_SHADOW_OUT;
-}
 
-static void
-gtk_menu_bar_set_arg (GtkObject      *object,
-		      GtkArg         *arg,
-		      guint           arg_id)
-{
-  GtkMenuBar *menu_bar;
-
-  menu_bar = GTK_MENU_BAR (object);
-
-  switch (arg_id)
-    {
-    case ARG_SHADOW:
-      gtk_menu_bar_set_shadow_type (menu_bar, GTK_VALUE_ENUM (*arg));
-      break;
-    default:
-      break;
-    }
+  gtk_settings_install_property (gtk_settings_get_global (),
+                                 g_param_spec_string ("gtk-menu-bar-accel",
+                                                      _("Menu bar accelerator"),
+                                                      _("Keybinding to activate the menu bar"),
+                                                      "F10",
+                                                      G_PARAM_READWRITE));
+
+  gtk_widget_class_install_style_property (widget_class,
+					   g_param_spec_enum ("shadow_type",
+                                                              _("Shadow type"),
+                                                              _("Style of bevel around the menubar"),
+                                                              GTK_TYPE_SHADOW_TYPE,
+                                                              GTK_SHADOW_OUT,
+                                                              G_PARAM_READABLE));
 }
 
 static void
-gtk_menu_bar_get_arg (GtkObject      *object,
-		      GtkArg         *arg,
-		      guint           arg_id)
+gtk_menu_bar_init (GtkMenuBar *menu_bar)
 {
-  GtkMenuBar *menu_bar;
 
-  menu_bar = GTK_MENU_BAR (object);
-
-  switch (arg_id)
-    {
-    case ARG_SHADOW:
-      GTK_VALUE_ENUM (*arg) = menu_bar->shadow_type;
-      break;
-    default:
-      arg->type = GTK_TYPE_INVALID;
-      break;
-    }
 }
  
 GtkWidget*
@@ -347,25 +318,6 @@
     }
 }
 
-void
-gtk_menu_bar_set_shadow_type (GtkMenuBar    *menu_bar,
-			      GtkShadowType  type)
-{
-  g_return_if_fail (menu_bar != NULL);
-  g_return_if_fail (GTK_IS_MENU_BAR (menu_bar));
-
-  if ((GtkShadowType) menu_bar->shadow_type != type)
-    {
-      menu_bar->shadow_type = type;
-
-      if (GTK_WIDGET_DRAWABLE (menu_bar))
-        {
-          gtk_widget_queue_clear (GTK_WIDGET (menu_bar));
-        }
-      gtk_widget_queue_resize (GTK_WIDGET (menu_bar));
-    }
-}
-
 static void
 gtk_menu_bar_paint (GtkWidget *widget, GdkRectangle *area)
 {
@@ -377,7 +329,7 @@
       gtk_paint_box (widget->style,
 		     widget->window,
 		     GTK_STATE_NORMAL,
-		     GTK_MENU_BAR (widget)->shadow_type,
+                     get_shadow_type (GTK_MENU_BAR (widget)),
 		     area, widget, "menubar",
 		     0, 0,
 		     -1,-1);
@@ -400,4 +352,151 @@
     }
 
   return FALSE;
+}
+
+static gboolean
+window_key_press_handler (GtkWidget   *widget,
+                          GdkEventKey *event,
+                          gpointer     data)
+{
+  gchar *accel = NULL;
+  gboolean retval = FALSE;
+  
+  g_object_get (G_OBJECT (gtk_settings_get_global ()),
+                "gtk-menu-bar-accel",
+                &accel,
+                NULL);
+
+  if (accel)
+    {
+      guint keyval = 0;
+      GdkModifierType mods = 0;
+
+      gtk_accelerator_parse (accel, &keyval, &mods);
+
+      if (keyval == 0)
+        g_warning ("Failed to parse menu bar accelerator '%s'\n", accel);
+
+      /* FIXME this is wrong, needs to be in the global accel resolution
+       * thing, to properly consider i18n etc., but that probably requires
+       * AccelGroup changes etc.
+       */
+      if (event->keyval == keyval &&
+          (mods & event->state) == mods)
+        {
+          GtkMenuBar *menubar;
+          GtkMenuShell *menushell;
+          
+          menubar = GTK_MENU_BAR (data);
+          menushell = GTK_MENU_SHELL (menubar);
+
+          if (menushell->children)
+            {
+              gtk_signal_emit_by_name (GTK_OBJECT (menushell->children->data),
+                                       "activate_item");
+              
+              retval = TRUE;
+            }
+        }
+
+      g_free (accel);
+    }
+
+  return retval;
+}
+
+static void
+menubar_dnotify (gpointer data)
+{
+  GtkMenuBar *menubar;
+
+  menubar = GTK_MENU_BAR (data);
+
+  menubar->toplevel = NULL;
+}
+
+static void
+add_to_window (GtkWindow  *window,
+               GtkMenuBar *menubar)
+{
+  GtkMenuBar *old_menubar;
+
+  old_menubar = g_object_get_data (G_OBJECT (window),
+                                   "gtk-menu-bar");
+  
+  if (old_menubar)
+    return; /* ignore this case; app programmer on crack, but
+             * shouldn't spew stuff, just don't support the accel
+             * for menubar #2
+             */
+
+  g_object_set_data_full (G_OBJECT (window),
+                          "gtk-menu-bar",
+                          menubar,
+                          menubar_dnotify);
+
+  g_signal_connect_data (G_OBJECT (window),
+                         "key_press_event",
+                         G_CALLBACK (window_key_press_handler),
+                         menubar,
+                         NULL, FALSE, FALSE);
+
+  menubar->toplevel = GTK_WIDGET (window);
+}
+
+/* Hack-around */
+#define g_signal_handlers_disconnect_by_func(obj, func, data) g_signal_handlers_disconnect_matched (obj, G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, 0, 0, NULL, func, data)
+
+static void
+remove_from_window (GtkWindow  *window,
+                    GtkMenuBar *menubar)
+{
+  g_return_if_fail (menubar->toplevel == GTK_WIDGET (window));
+
+  g_signal_handlers_disconnect_by_func (G_OBJECT (window),
+                                        G_CALLBACK (window_key_press_handler),
+                                        menubar);
+
+  /* dnotify zeroes menubar->toplevel */
+  g_object_set_data (G_OBJECT (window),
+                     "gtk-menu-bar",
+                     NULL);
+}
+
+static void
+gtk_menu_bar_hierarchy_changed (GtkWidget *widget)
+{
+  GtkWidget *toplevel;  
+  GtkMenuBar *menubar;
+
+  menubar = GTK_MENU_BAR (widget);
+
+  toplevel = gtk_widget_get_toplevel (widget);
+
+  if (menubar->toplevel &&
+      toplevel != menubar->toplevel)
+    {
+      remove_from_window (GTK_WINDOW (menubar->toplevel),
+                          menubar);
+    }
+  
+  if (toplevel &&
+      GTK_IS_WINDOW (toplevel))
+    {
+      add_to_window (GTK_WINDOW (toplevel),
+                     menubar);
+    }
+}
+
+static GtkShadowType
+get_shadow_type (GtkMenuBar *menubar)
+{
+  GtkShadowType shadow_type = GTK_SHADOW_OUT;
+  
+  gtk_widget_style_get (GTK_WIDGET (menubar),
+			"shadow_type", &shadow_type,
+			NULL);
+
+
+  return shadow_type;
 }
Index: gtk/gtkmenubar.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenubar.h,v
retrieving revision 1.9
diff -u -u -r1.9 gtkmenubar.h
--- gtk/gtkmenubar.h	2000/08/30 00:33:37	1.9
+++ gtk/gtkmenubar.h	2001/04/19 21:20:34
@@ -52,7 +52,7 @@
 {
   GtkMenuShell menu_shell;
 
-  GtkShadowType shadow_type;
+  GtkWidget *toplevel;
 };
 
 struct _GtkMenuBarClass
@@ -70,9 +70,6 @@
 void       gtk_menu_bar_insert          (GtkMenuBar    *menu_bar,
 					 GtkWidget     *child,
 					 gint           position);
-void       gtk_menu_bar_set_shadow_type (GtkMenuBar    *menu_bar,
-					 GtkShadowType  type);
-
 
 #ifdef __cplusplus
 }
Index: gtk/gtkoptionmenu.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkoptionmenu.c,v
retrieving revision 1.42
diff -u -u -r1.42 gtkoptionmenu.c
--- gtk/gtkoptionmenu.c	2001/04/02 19:09:52	1.42
+++ gtk/gtkoptionmenu.c	2001/04/19 21:20:34
@@ -347,6 +347,9 @@
     props->indicator_spacing = *indicator_spacing;
   else
     props->indicator_spacing = default_props.indicator_spacing;
+
+  g_free (indicator_size);
+  g_free (indicator_spacing);
 }
 
 static void
Index: gtk/gtksettings.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtksettings.c,v
retrieving revision 1.7
diff -u -u -r1.7 gtksettings.c
--- gtk/gtksettings.c	2001/04/03 13:18:00	1.7
+++ gtk/gtksettings.c	2001/04/19 21:20:34
@@ -15,10 +15,10 @@
  * License along with this library; if not, write to the Free
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-#include	"gtksettings.h"
 
+#include "gtksettings.h"
+#include "gtkintl.h"
 
-
 enum {
   PROP_0,
   PROP_DOUBLE_CLICK_TIMEOUT,
@@ -114,6 +114,7 @@
 gtk_settings_class_init (GtkSettingsClass *class)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+  guint result;
   
   parent_class = g_type_class_peek_parent (class);
 
@@ -127,30 +128,40 @@
   quark_property_id = g_quark_try_string ("GObject-property-id");
   g_assert (quark_property_id != 0);	/* special quarks from GObjectClass */
 
-  g_assert (PROP_DOUBLE_CLICK_TIMEOUT ==
-	    settings_install_property_parser (class,
-					      g_param_spec_int ("double-click-timeout", "Double Click Timeout", NULL,
-								0, G_MAXINT, 1000,
-								G_PARAM_READWRITE),
-					      NULL));
-  g_assert (PROP_BELL_PITCH ==
-	    settings_install_property_parser (class,
-					      g_param_spec_int ("bell-pitch", "Bell Pitch", NULL,
-								0, G_MAXINT, 440,
-								G_PARAM_READWRITE),
-					      NULL));
-  g_assert (PROP_BELL_DURATION ==
-	    settings_install_property_parser (class,
-					      g_param_spec_int ("bell_duration", "Bell Duration", NULL,
-								1, G_MAXINT, 250,
-								G_PARAM_READWRITE),
-					      NULL));
-  g_assert (PROP_BELL_PERCENT ==
-	    settings_install_property_parser (class,
-					      g_param_spec_float ("bell_percent", "Bell Percent", NULL,
-								  0, 100, 80,
-								  G_PARAM_READWRITE),
-					      NULL));
+  result = settings_install_property_parser (class,
+                                             g_param_spec_int ("gtk-double-click-timeout",
+                                                               _("Double Click Timeout"),
+                                                               _("Maximum time allowed between two clicks for them to be considered a double click"),
+                                                               0, G_MAXINT, 1000,
+                                                               G_PARAM_READWRITE),
+                                             NULL);
+  g_assert (result == PROP_DOUBLE_CLICK_TIMEOUT);
+
+  /* FIXME all this bell stuff should come out eventually, it's just for testing. */
+  result = settings_install_property_parser (class,
+                                             g_param_spec_int ("bell-pitch",
+                                                               _("Bell Pitch"), NULL,
+                                                               0, G_MAXINT, 440,
+                                                               G_PARAM_READWRITE),
+                                             NULL);
+  g_assert (result == PROP_BELL_PITCH);
+
+  result = settings_install_property_parser (class,
+                                             g_param_spec_int ("bell_duration",
+                                                               _("Bell Duration"), NULL,
+                                                               1, G_MAXINT, 250,
+                                                               G_PARAM_READWRITE),
+                                             NULL);  
+  g_assert (result == PROP_BELL_DURATION);
+
+  result = settings_install_property_parser (class,
+                                             g_param_spec_float ("bell_percent",
+                                                                 _("Bell Percent"),
+                                                                 NULL,
+                                                                 0, 100, 80,
+                                                                 G_PARAM_READWRITE),
+                                             NULL);    
+  g_assert (result == PROP_BELL_PERCENT);
 }
 
 static void




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]