Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.5217
diff -u -p -r1.5217 ChangeLog
--- ChangeLog	11 Mar 2004 21:38:06 -0000	1.5217
+++ ChangeLog	11 Mar 2004 22:41:42 -0000
@@ -1,3 +1,11 @@
+Thu Mar 11 17:33:26 2004  Owen Taylor  <otaylor@redhat.com>
+
+	* gtk/gtkwindow.c (gtk_window_activate_key_after): As
+	a last stage in GtkWindow key press handing, try adding
+	window->mnemonic_modifier to event->state and see if it
+	matches a mnemonic. (#53709, based on a patch by
+	Pasupathi Duraisamy)
+
 Thu Mar 11 16:28:15 2004  Owen Taylor  <otaylor@redhat.com>
 
 	* gtk/gtkmenu.c (gtk_menu_get_toplevel): Fix attach/attach->parent
Index: gtk/gtkwindow.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkwindow.c,v
retrieving revision 1.262
diff -u -p -r1.262 gtkwindow.c
--- gtk/gtkwindow.c	6 Mar 2004 03:38:37 -0000	1.262
+++ gtk/gtkwindow.c	11 Mar 2004 22:41:42 -0000
@@ -266,6 +266,9 @@ static void        gtk_window_notify_key
 static GtkKeyHash *gtk_window_get_key_hash        (GtkWindow   *window);
 static void        gtk_window_free_key_hash       (GtkWindow   *window);
 
+static gboolean    gtk_window_activate_key_after (GtkWindow    *window,
+						  GdkEventKey  *event);
+
 static GSList      *toplevel_list = NULL;
 static GHashTable  *mnemonic_hash_table = NULL;
 static GtkBinClass *parent_class = NULL;
@@ -4256,6 +4259,10 @@ gtk_window_key_press_event (GtkWidget   
   if (!handled)
     handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
 
+  /* Fallback mnemonic handling if nothing else took the key */
+  if (!handled)
+    handled = gtk_window_activate_key_after (window, event);
+  
   return handled;
 }
 
@@ -7086,6 +7093,21 @@ gtk_window_free_key_hash (GtkWindow *win
     }
 }
 
+static GtkWindowKeyEntry *
+find_mnemonic_entry (GSList *entries)
+{
+  GSList *tmp_list;
+  
+  for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
+    {
+      GtkWindowKeyEntry *entry = tmp_list->data;
+      if (entry->is_mnemonic)
+	return entry;
+    }
+
+  return NULL;
+}
+
 /**
  * gtk_window_activate_key:
  * @window:  a #GtkWindow
@@ -7102,39 +7124,20 @@ gboolean
 gtk_window_activate_key (GtkWindow   *window,
 			 GdkEventKey *event)
 {
-  GtkKeyHash *key_hash = g_object_get_data (G_OBJECT (window), "gtk-window-key-hash");
+  GtkKeyHash *key_hash = gtk_window_get_key_hash (window);
   GtkWindowKeyEntry *found_entry = NULL;
 
-  if (!key_hash)
-    {
-      gtk_window_keys_changed (window);
-      key_hash = g_object_get_data (G_OBJECT (window), "gtk-window-key-hash");
-    }
+  GSList *entries = _gtk_key_hash_lookup (key_hash,
+					  event->hardware_keycode,
+					  event->state,
+					  gtk_accelerator_get_default_mod_mask (),
+					  event->group);
+
+  found_entry = find_mnemonic_entry (entries);
+  if (!found_entry && entries)
+    found_entry = entries->data;
   
-  if (key_hash)
-    {
-      GSList *entries = _gtk_key_hash_lookup (key_hash,
-					      event->hardware_keycode,
-					      event->state,
-					      gtk_accelerator_get_default_mod_mask (),
-					      event->group);
-      GSList *tmp_list;
-
-      for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
-	{
-	  GtkWindowKeyEntry *entry = tmp_list->data;
-	  if (entry->is_mnemonic)
-	    {
-	      found_entry = entry;
-	      break;
-	    }
-	}
-      
-      if (!found_entry && entries)
-	found_entry = entries->data;
-
-      g_slist_free (entries);
-    }
+  g_slist_free (entries);
 
   if (found_entry)
     {
@@ -7147,6 +7150,51 @@ gtk_window_activate_key (GtkWindow   *wi
     return FALSE;
 }
 
+/**
+ * gtk_window_activate_key_after:
+ * @window:  a #GtkWindow
+ * @event:   a #GdkEventKey
+ *
+ * Activates fallback mnemonic and accelerator handling for this
+ * #GtkWindow. This is normally called by the default
+ * ::key_press_event handler for toplevel windows after all other key
+ * press handling for the widget does not handle the key, however in some
+ * cases it may be useful to call this directly when overriding the
+ * standard key handling for a toplevel window. Currently, what
+ * this function does is check for the user pressing a mnemonic key
+ * unmodified; if that key is not consumed previously, then it will
+ * activate the mnemonic.
+ * 
+ * Return value: %TRUE if a mnemonic or accelerator was found and activated.
+ **/
+static gboolean
+gtk_window_activate_key_after (GtkWindow   *window,
+			       GdkEventKey *event)
+{
+  GtkKeyHash *key_hash = gtk_window_get_key_hash (window);
+  GtkWindowKeyEntry *found_entry = NULL;
+  GSList *entries;
+  
+  if (window->mnemonic_modifier == 0 ||
+      (gtk_accelerator_get_default_mod_mask () & event->state != 0))
+    return FALSE;
+
+  entries = _gtk_key_hash_lookup (key_hash,
+				  event->hardware_keycode,
+				  event->state | window->mnemonic_modifier,
+				  gtk_accelerator_get_default_mod_mask (),
+				  event->group);
+
+  found_entry = find_mnemonic_entry (entries);
+  
+  g_slist_free (entries);
+  
+  if (found_entry)
+    return gtk_window_mnemonic_activate (window, found_entry->keyval, found_entry->modifiers);
+  else
+    return FALSE;
+}
+
 static void
 window_update_has_focus (GtkWindow *window)
 {
