]> Pileus Git - ~andy/gtk/commitdiff
Implement accelerator propagation using a custom XEMBED_GTK_KEY_GRAB
authorOwen Taylor <otaylor@redhat.com>
Sun, 24 Feb 2002 01:52:14 +0000 (01:52 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Sun, 24 Feb 2002 01:52:14 +0000 (01:52 +0000)
Sat Feb 23 20:33:29 2002  Owen Taylor  <otaylor@redhat.com>

        * gtk/gtkplug.[ch] gtk/gtksocket.[ch] gtk/xembed.h: Implement
        accelerator propagation using a custom XEMBED_GTK_KEY_GRAB
        XEMBED_GTK_KEY_UNGRAB pair of messages.

        * gtk/gtkwindow.[ch]: private export _gtk_window_keys_foreach().

        * gtk/gtkplug.c (gtk_plug_set_is_child): Clear focus and default
        widgets.

14 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkplug.c
gtk/gtkplug.h
gtk/gtksocket.c
gtk/gtksocket.h
gtk/gtkwindow.c
gtk/gtkwindow.h
gtk/xembed.h

index dc6b004ee437705e7533ae4e2f268dc1bf8e9f3e..aba8ba2e359f8d191393de1cb80d04294386c4f7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Sat Feb 23 20:33:29 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.[ch] gtk/xembed.h: Implement 
+       accelerator propagation using a custom XEMBED_GTK_KEY_GRAB
+       XEMBED_GTK_KEY_UNGRAB pair of messages.
+
+       * gtk/gtkwindow.[ch]: private export _gtk_window_keys_foreach().
+
+       * gtk/gtkplug.c (gtk_plug_set_is_child): Clear focus and default
+       widgets.
+
 2002-02-23  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktextbuffer.c (save_range): change gravity of start/end
index dc6b004ee437705e7533ae4e2f268dc1bf8e9f3e..aba8ba2e359f8d191393de1cb80d04294386c4f7 100644 (file)
@@ -1,3 +1,14 @@
+Sat Feb 23 20:33:29 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.[ch] gtk/xembed.h: Implement 
+       accelerator propagation using a custom XEMBED_GTK_KEY_GRAB
+       XEMBED_GTK_KEY_UNGRAB pair of messages.
+
+       * gtk/gtkwindow.[ch]: private export _gtk_window_keys_foreach().
+
+       * gtk/gtkplug.c (gtk_plug_set_is_child): Clear focus and default
+       widgets.
+
 2002-02-23  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktextbuffer.c (save_range): change gravity of start/end
index dc6b004ee437705e7533ae4e2f268dc1bf8e9f3e..aba8ba2e359f8d191393de1cb80d04294386c4f7 100644 (file)
@@ -1,3 +1,14 @@
+Sat Feb 23 20:33:29 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.[ch] gtk/xembed.h: Implement 
+       accelerator propagation using a custom XEMBED_GTK_KEY_GRAB
+       XEMBED_GTK_KEY_UNGRAB pair of messages.
+
+       * gtk/gtkwindow.[ch]: private export _gtk_window_keys_foreach().
+
+       * gtk/gtkplug.c (gtk_plug_set_is_child): Clear focus and default
+       widgets.
+
 2002-02-23  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktextbuffer.c (save_range): change gravity of start/end
index dc6b004ee437705e7533ae4e2f268dc1bf8e9f3e..aba8ba2e359f8d191393de1cb80d04294386c4f7 100644 (file)
@@ -1,3 +1,14 @@
+Sat Feb 23 20:33:29 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.[ch] gtk/xembed.h: Implement 
+       accelerator propagation using a custom XEMBED_GTK_KEY_GRAB
+       XEMBED_GTK_KEY_UNGRAB pair of messages.
+
+       * gtk/gtkwindow.[ch]: private export _gtk_window_keys_foreach().
+
+       * gtk/gtkplug.c (gtk_plug_set_is_child): Clear focus and default
+       widgets.
+
 2002-02-23  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktextbuffer.c (save_range): change gravity of start/end
index dc6b004ee437705e7533ae4e2f268dc1bf8e9f3e..aba8ba2e359f8d191393de1cb80d04294386c4f7 100644 (file)
@@ -1,3 +1,14 @@
+Sat Feb 23 20:33:29 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.[ch] gtk/xembed.h: Implement 
+       accelerator propagation using a custom XEMBED_GTK_KEY_GRAB
+       XEMBED_GTK_KEY_UNGRAB pair of messages.
+
+       * gtk/gtkwindow.[ch]: private export _gtk_window_keys_foreach().
+
+       * gtk/gtkplug.c (gtk_plug_set_is_child): Clear focus and default
+       widgets.
+
 2002-02-23  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktextbuffer.c (save_range): change gravity of start/end
index dc6b004ee437705e7533ae4e2f268dc1bf8e9f3e..aba8ba2e359f8d191393de1cb80d04294386c4f7 100644 (file)
@@ -1,3 +1,14 @@
+Sat Feb 23 20:33:29 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.[ch] gtk/xembed.h: Implement 
+       accelerator propagation using a custom XEMBED_GTK_KEY_GRAB
+       XEMBED_GTK_KEY_UNGRAB pair of messages.
+
+       * gtk/gtkwindow.[ch]: private export _gtk_window_keys_foreach().
+
+       * gtk/gtkplug.c (gtk_plug_set_is_child): Clear focus and default
+       widgets.
+
 2002-02-23  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktextbuffer.c (save_range): change gravity of start/end
index dc6b004ee437705e7533ae4e2f268dc1bf8e9f3e..aba8ba2e359f8d191393de1cb80d04294386c4f7 100644 (file)
@@ -1,3 +1,14 @@
+Sat Feb 23 20:33:29 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkplug.[ch] gtk/gtksocket.[ch] gtk/xembed.h: Implement 
+       accelerator propagation using a custom XEMBED_GTK_KEY_GRAB
+       XEMBED_GTK_KEY_UNGRAB pair of messages.
+
+       * gtk/gtkwindow.[ch]: private export _gtk_window_keys_foreach().
+
+       * gtk/gtkplug.c (gtk_plug_set_is_child): Clear focus and default
+       widgets.
+
 2002-02-23  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktextbuffer.c (save_range): change gravity of start/end
index eb4f10c228ae35adedce92a04a1fd21cf082f016..b179fe865f02f5b6bbd0c9ab470229518c7dab85 100644 (file)
@@ -37,6 +37,7 @@
 
 static void            gtk_plug_class_init            (GtkPlugClass     *klass);
 static void            gtk_plug_init                  (GtkPlug          *plug);
+static void            gtk_plug_finalize              (GObject          *object);
 static void            gtk_plug_realize               (GtkWidget        *widget);
 static void            gtk_plug_unrealize             (GtkWidget        *widget);
 static void            gtk_plug_show                  (GtkWidget        *widget);
@@ -47,23 +48,16 @@ static void            gtk_plug_size_allocate         (GtkWidget        *widget,
                                                       GtkAllocation    *allocation);
 static gboolean        gtk_plug_key_press_event       (GtkWidget        *widget,
                                                       GdkEventKey      *event);
-static void            gtk_plug_forward_key_press     (GtkPlug          *plug,
-                                                      GdkEventKey      *event);
 static void            gtk_plug_set_focus             (GtkWindow        *window,
                                                       GtkWidget        *focus);
 static gboolean        gtk_plug_focus                 (GtkWidget        *widget,
                                                       GtkDirectionType  direction);
 static void            gtk_plug_check_resize          (GtkContainer     *container);
-#if 0
-static void            gtk_plug_accel_entries_changed (GtkWindow        *window);
-#endif
+static void            gtk_plug_keys_changed          (GtkWindow        *window);
 static GdkFilterReturn gtk_plug_filter_func           (GdkXEvent        *gdk_xevent,
                                                       GdkEvent         *event,
                                                       gpointer          data);
 
-#if 0
-static void gtk_plug_free_grabbed_keys (GHashTable    *key_table);
-#endif
 static void handle_modality_off        (GtkPlug       *plug);
 static void send_xembed_message        (GtkPlug       *plug,
                                        glong          message,
@@ -116,6 +110,7 @@ gtk_plug_get_type ()
 static void
 gtk_plug_class_init (GtkPlugClass *class)
 {
+  GObjectClass *gobject_class = (GObjectClass *)class;
   GtkWidgetClass *widget_class = (GtkWidgetClass *)class;
   GtkWindowClass *window_class = (GtkWindowClass *)class;
   GtkContainerClass *container_class = (GtkContainerClass *)class;
@@ -123,6 +118,8 @@ gtk_plug_class_init (GtkPlugClass *class)
   parent_class = gtk_type_class (GTK_TYPE_WINDOW);
   bin_class = gtk_type_class (GTK_TYPE_BIN);
 
+  gobject_class->finalize = gtk_plug_finalize;
+  
   widget_class->realize = gtk_plug_realize;
   widget_class->unrealize = gtk_plug_unrealize;
   widget_class->key_press_event = gtk_plug_key_press_event;
@@ -138,9 +135,7 @@ gtk_plug_class_init (GtkPlugClass *class)
   container_class->check_resize = gtk_plug_check_resize;
 
   window_class->set_focus = gtk_plug_set_focus;
-#if 0  
-  window_class->accel_entries_changed = gtk_plug_accel_entries_changed;
-#endif
+  window_class->keys_changed = gtk_plug_keys_changed;
 
   plug_signals[EMBEDDED] =
     g_signal_new ("embedded",
@@ -195,6 +190,11 @@ gtk_plug_set_is_child (GtkPlug  *plug,
     }
   else
     {
+      if (GTK_WINDOW (plug)->focus_widget)
+       gtk_window_set_focus (GTK_WINDOW (plug), NULL);
+      if (GTK_WINDOW (plug)->default_widget)
+       gtk_window_set_default (GTK_WINDOW (plug), NULL);
+         
       plug->modality_group = gtk_window_group_new ();
       gtk_window_group_add_window (plug->modality_group, GTK_WINDOW (plug));
       
@@ -364,6 +364,20 @@ gtk_plug_get_id (GtkPlug *plug)
   return GDK_WINDOW_XWINDOW (GTK_WIDGET (plug)->window);
 }
 
+static void
+gtk_plug_finalize (GObject *object)
+{
+  GtkPlug *plug = GTK_PLUG (object);
+
+  if (plug->grabbed_keys)
+    {
+      g_hash_table_destroy (plug->grabbed_keys);
+      plug->grabbed_keys = NULL;
+    }
+  
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
 static void
 gtk_plug_unrealize (GtkWidget *widget)
 {
@@ -568,48 +582,11 @@ gtk_plug_key_press_event (GtkWidget   *widget,
                          GdkEventKey *event)
 {
   if (GTK_WIDGET_TOPLEVEL (widget))
-    {
-      if (!GTK_WINDOW (widget)->has_focus)
-       {
-         gtk_plug_forward_key_press (GTK_PLUG (widget), event);
-         return TRUE;
-       }
-      else
-       return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
-    }
+    return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
   else
     return FALSE;
 }
 
-static void
-gtk_plug_forward_key_press (GtkPlug *plug, GdkEventKey *event)
-{
-  XEvent xevent;
-  
-  xevent.xkey.type = KeyPress;
-  xevent.xkey.display = GDK_WINDOW_XDISPLAY (GTK_WIDGET(plug)->window);
-  xevent.xkey.window = GDK_WINDOW_XWINDOW (plug->socket_window);
-  xevent.xkey.root = GDK_ROOT_WINDOW (); /* FIXME */
-  xevent.xkey.time = event->time;
-  /* FIXME, the following might cause big problems for
-   * non-GTK apps */
-  xevent.xkey.x = 0;
-  xevent.xkey.y = 0;
-  xevent.xkey.x_root = 0;
-  xevent.xkey.y_root = 0;
-  xevent.xkey.state = event->state;
-  xevent.xkey.keycode =  XKeysymToKeycode(GDK_DISPLAY(), 
-                                         event->keyval);
-  xevent.xkey.same_screen = TRUE; /* FIXME ? */
-
-  gdk_error_trap_push ();
-  XSendEvent (GDK_DISPLAY (),
-             GDK_WINDOW_XWINDOW (plug->socket_window),
-             False, NoEventMask, &xevent);
-  gdk_flush ();
-  gdk_error_trap_pop ();
-}
-
 static void
 gtk_plug_set_focus (GtkWindow *window,
                    GtkWidget *focus)
@@ -645,8 +622,6 @@ gtk_plug_set_focus (GtkWindow *window,
     }
 }
 
-#if 0
-
 typedef struct
 {
   guint                         accelerator_key;
@@ -677,7 +652,7 @@ grabbed_key_equal (gconstpointer a, gconstpointer b)
 }
 
 static void
-add_grabbed_keys (gpointer key, gpointer val, gpointer data)
+add_grabbed_key (gpointer key, gpointer val, gpointer data)
 {
   GrabbedKey *grabbed_key = key;
   GtkPlug *plug = data;
@@ -685,14 +660,25 @@ add_grabbed_keys (gpointer key, gpointer val, gpointer data)
   if (!plug->grabbed_keys ||
       !g_hash_table_lookup (plug->grabbed_keys, grabbed_key))
     {
-      send_xembed_message (plug, XEMBED_GRAB_KEY, 0, 
+      send_xembed_message (plug, XEMBED_GTK_GRAB_KEY, 0, 
                           grabbed_key->accelerator_key, grabbed_key->accelerator_mods,
                           gtk_get_current_event_time ());
     }
 }
 
 static void
-remove_grabbed_keys (gpointer key, gpointer val, gpointer data)
+add_grabbed_key_always (gpointer key, gpointer val, gpointer data)
+{
+  GrabbedKey *grabbed_key = key;
+  GtkPlug *plug = data;
+
+  send_xembed_message (plug, XEMBED_GTK_GRAB_KEY, 0, 
+                      grabbed_key->accelerator_key, grabbed_key->accelerator_mods,
+                      gtk_get_current_event_time ());
+}
+
+static void
+remove_grabbed_key (gpointer key, gpointer val, gpointer data)
 {
   GrabbedKey *grabbed_key = key;
   GtkPlug *plug = data;
@@ -700,74 +686,50 @@ remove_grabbed_keys (gpointer key, gpointer val, gpointer data)
   if (!plug->grabbed_keys ||
       !g_hash_table_lookup (plug->grabbed_keys, grabbed_key))
     {
-      send_xembed_message (plug, XEMBED_UNGRAB_KEY, 0, 
+      send_xembed_message (plug, XEMBED_GTK_UNGRAB_KEY, 0, 
                           grabbed_key->accelerator_key, grabbed_key->accelerator_mods,
                           gtk_get_current_event_time ());
     }
 }
 
 static void
-gtk_plug_free_grabbed_keys (GHashTable *key_table)
+keys_foreach (GtkWindow      *window,
+             guint           keyval,
+             GdkModifierType modifiers,
+             gboolean        is_mnemonic,
+             gpointer        data)
 {
-  g_hash_table_foreach (key_table, (GHFunc)g_free, NULL);
-  g_hash_table_destroy (key_table);
+  GHashTable *new_grabbed_keys = data;
+  GrabbedKey *key = g_new (GrabbedKey, 1);
+
+  key->accelerator_key = keyval;
+  key->accelerator_mods = modifiers;
+  
+  g_hash_table_replace (new_grabbed_keys, key, key);
 }
 
 static void
-gtk_plug_accel_entries_changed (GtkWindow *window)
+gtk_plug_keys_changed (GtkWindow *window)
 {
   GHashTable *new_grabbed_keys, *old_grabbed_keys;
-  GSList *accel_groups, *tmp_list;
   GtkPlug *plug = GTK_PLUG (window);
 
-  new_grabbed_keys = g_hash_table_new (grabbed_key_hash, grabbed_key_equal);
-
-  accel_groups = gtk_accel_groups_from_object (G_OBJECT (window));
-  
-  tmp_list = accel_groups;
+  new_grabbed_keys = g_hash_table_new_full (grabbed_key_hash, grabbed_key_equal, (GDestroyNotify)g_free, NULL);
+  _gtk_window_keys_foreach (window, keys_foreach, new_grabbed_keys);
 
-  while (tmp_list)
-    {
-      GtkAccelGroup *accel_group = tmp_list->data;
-      gint i, n_entries;
-      GtkAccelEntry *entries;
-
-      gtk_accel_group_get_entries (accel_group, &entries, &n_entries);
-
-      for (i = 0; i < n_entries; i++)
-       {
-         GdkKeymapKey *keys;
-         gint n_keys;
-         
-         if (gdk_keymap_get_entries_for_keyval (NULL, entries[i].accelerator_key, &keys, &n_keys))
-           {
-             GrabbedKey *key = g_new (GrabbedKey, 1);
-             
-             key->accelerator_key = keys[0].keycode;
-             key->accelerator_mods = entries[i].accelerator_mods;
-             
-             g_hash_table_insert (new_grabbed_keys, key, key);
-
-             g_free (keys);
-           }
-       }
-      
-      tmp_list = tmp_list->next;
-    }
-
-  g_hash_table_foreach (new_grabbed_keys, add_grabbed_keys, plug);
+  if (plug->socket_window)
+    g_hash_table_foreach (new_grabbed_keys, add_grabbed_key, plug);
 
   old_grabbed_keys = plug->grabbed_keys;
   plug->grabbed_keys = new_grabbed_keys;
 
   if (old_grabbed_keys)
     {
-      g_hash_table_foreach (old_grabbed_keys, remove_grabbed_keys, plug);
-      gtk_plug_free_grabbed_keys (old_grabbed_keys);
+      if (plug->socket_window)
+       g_hash_table_foreach (old_grabbed_keys, remove_grabbed_key, plug);
+      g_hash_table_destroy (old_grabbed_keys);
     }
-
 }
-#endif
 
 static gboolean
 gtk_plug_focus (GtkWidget        *widget,
@@ -1009,11 +971,13 @@ handle_xembed_message (GtkPlug   *plug,
        break;
       }
       
+    case XEMBED_GRAB_KEY:
+    case XEMBED_UNGRAB_KEY:
+    case XEMBED_GTK_GRAB_KEY:
+    case XEMBED_GTK_UNGRAB_KEY:
     case XEMBED_REQUEST_FOCUS:
     case XEMBED_FOCUS_NEXT:
     case XEMBED_FOCUS_PREV:
-    case XEMBED_GRAB_KEY:
-    case XEMBED_UNGRAB_KEY:
       g_warning ("GtkPlug: Invalid _XEMBED message of type %ld received", message);
       break;
       
@@ -1137,7 +1101,8 @@ gtk_plug_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
                  break;
              }
 
-           /* FIXME: Add grabbed keys here */
+           if (plug->grabbed_keys)
+             g_hash_table_foreach (plug->grabbed_keys, add_grabbed_key_always, plug);
 
            if (!was_embedded)
              g_signal_emit (G_OBJECT (plug), plug_signals[EMBEDDED], 0);
index b711c021e852a6905adb01566bedc0234a5164d3..17e4261698b1e731c4fb503f920a4b7f0e9e2ee6 100644 (file)
@@ -56,6 +56,8 @@ struct _GtkPlug
   GdkWindow *socket_window;
   GtkWidget *modality_window;
   GtkWindowGroup *modality_group;
+  GHashTable *grabbed_keys;
+
   guint same_app : 1;
 };
 
index 6a65e199b0f6bb8b9b05d030f6d0076ffb379434..8546b959628b0b2460f4e42c67784ada23660285 100644 (file)
@@ -43,6 +43,7 @@
 
 static void     gtk_socket_class_init           (GtkSocketClass   *klass);
 static void     gtk_socket_init                 (GtkSocket        *socket);
+static void     gtk_socket_finalize             (GObject          *object);
 static void     gtk_socket_realize              (GtkWidget        *widget);
 static void     gtk_socket_unrealize            (GtkWidget        *widget);
 static void     gtk_socket_size_request         (GtkWidget        *widget,
@@ -129,17 +130,32 @@ gtk_socket_get_type (void)
   return socket_type;
 }
 
+static void
+gtk_socket_finalize (GObject *object)
+{
+  GtkSocket *socket = GTK_SOCKET (object);
+  
+  g_object_unref (socket->accel_group);
+  socket->accel_group = NULL;
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
 static void
 gtk_socket_class_init (GtkSocketClass *class)
 {
   GtkWidgetClass *widget_class;
   GtkContainerClass *container_class;
+  GObjectClass *gobject_class;
 
+  gobject_class = (GObjectClass *) class;
   widget_class = (GtkWidgetClass*) class;
   container_class = (GtkContainerClass*) class;
 
   parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
 
+  gobject_class->finalize = gtk_socket_finalize;
+
   widget_class->realize = gtk_socket_realize;
   widget_class->unrealize = gtk_socket_unrealize;
   widget_class->size_request = gtk_socket_size_request;
@@ -185,6 +201,9 @@ gtk_socket_init (GtkSocket *socket)
   socket->focus_in = FALSE;
   socket->have_size = FALSE;
   socket->need_map = FALSE;
+
+  socket->accel_group = gtk_accel_group_new ();
+  g_object_set_data (G_OBJECT (socket->accel_group), "gtk-socket", socket);
 }
 
 /**
@@ -336,6 +355,27 @@ gtk_socket_realize (GtkWidget *widget)
   gdk_flush();
 }
 
+static void
+gtk_socket_end_embedding (GtkSocket *socket)
+{
+  GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
+  gint i;
+  
+  if (toplevel && GTK_IS_WINDOW (toplevel))
+    gtk_window_remove_embedded_xid (GTK_WINDOW (toplevel), 
+                                   GDK_WINDOW_XWINDOW (socket->plug_window));
+
+  g_object_unref (socket->plug_window);
+  socket->plug_window = NULL;
+
+  /* Remove from end to avoid indexes shiting. This is evil */
+  for (i = socket->accel_group->n_accels; i >= 0; i--)
+    {
+      GtkAccelGroupEntry *accel_entry = &socket->accel_group->priv_accels[i];
+      gtk_accel_group_disconnect (socket->accel_group, accel_entry->closure);
+    }
+}
+
 static void
 gtk_socket_unrealize (GtkWidget *widget)
 {
@@ -349,24 +389,9 @@ gtk_socket_unrealize (GtkWidget *widget)
     }
   else if (socket->plug_window)
     {
-      GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
-      if (toplevel && GTK_IS_WINDOW (toplevel))
-       gtk_window_remove_embedded_xid (GTK_WINDOW (toplevel), 
-                                       GDK_WINDOW_XWINDOW (socket->plug_window));
-
-      g_object_unref (socket->plug_window);
-      socket->plug_window = NULL;
+      gtk_socket_end_embedding (socket);
     }
 
-#if 0  
-  if (socket->grabbed_keys)
-    {
-      g_hash_table_foreach (socket->grabbed_keys, (GHFunc)g_free, NULL);
-      g_hash_table_destroy (socket->grabbed_keys);
-      socket->grabbed_keys = NULL;
-    }
-#endif
-  
   if (GTK_WIDGET_CLASS (parent_class)->unrealize)
     (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
 }
@@ -496,122 +521,112 @@ gtk_socket_size_allocate (GtkWidget     *widget,
     }
 }
 
-#if 0
-
 typedef struct
 {
-  guint                         accelerator_key;
-  GdkModifierType       accelerator_mods;
+  guint                         accel_key;
+  GdkModifierType       accel_mods;
 } GrabbedKey;
 
-static guint
-grabbed_key_hash (gconstpointer a)
+static void
+activate_key (GtkAccelGroup *accel_group,
+             GrabbedKey    *grabbed_key)
 {
-  const GrabbedKey *key = a;
-  guint h;
+  XEvent xevent;
+  GdkEvent *gdk_event = gtk_get_current_event ();
   
-  h = key->accelerator_key << 16;
-  h ^= key->accelerator_key >> 16;
-  h ^= key->accelerator_mods;
+  GtkSocket *socket = g_object_get_data (G_OBJECT (accel_group), "gtk-socket");
 
-  return h;
+  if (gdk_event && gdk_event->type == GDK_KEY_PRESS && socket->plug_window)
+    {
+      xevent.xkey.type = KeyPress;
+      xevent.xkey.window = GDK_WINDOW_XWINDOW (socket->plug_window);
+      xevent.xkey.root = GDK_ROOT_WINDOW ();
+      xevent.xkey.subwindow = None;
+      xevent.xkey.time = gdk_event->key.time;
+      xevent.xkey.x = 0;
+      xevent.xkey.y = 0;
+      xevent.xkey.x_root = 0;
+      xevent.xkey.y_root = 0;
+      xevent.xkey.state = gdk_event->key.state;
+      xevent.xkey.keycode = gdk_event->key.hardware_keycode;
+      xevent.xkey.same_screen = True;
+
+      gdk_error_trap_push ();
+      XSendEvent (GDK_DISPLAY (),
+                 GDK_WINDOW_XWINDOW (socket->plug_window),
+                 False, KeyPressMask, &xevent);
+      gdk_flush ();
+      gdk_error_trap_pop ();
+    }
+
+  if (gdk_event)
+    gdk_event_free (gdk_event);
 }
 
 static gboolean
-grabbed_key_equal (gconstpointer a, gconstpointer b)
+find_accel_key (GtkAccelKey *key,
+               GClosure    *closure,
+               gpointer     data)
 {
-  const GrabbedKey *keya = a;
-  const GrabbedKey *keyb = b;
-
-  return (keya->accelerator_key == keyb->accelerator_key &&
-         keya->accelerator_mods == keyb->accelerator_mods);
+  GrabbedKey *grabbed_key = data;
+  
+  return (key->accel_key == grabbed_key->accel_key &&
+         key->accel_mods == grabbed_key->accel_mods);
 }
 
 static void
-add_grabbed_key (GtkSocket      *socket,
-                guint           hardware_keycode,
-                GdkModifierType mods)
+add_grabbed_key (GtkSocket       *socket,
+                guint            keyval,
+                GdkModifierType  modifiers)
 {
-  GrabbedKey key;
-  GrabbedKey *new_key;
-  GrabbedKey *found_key;
+  GClosure *closure;
+  GrabbedKey *grabbed_key;
 
-  if (socket->grabbed_keys)
-    {
-      key.accelerator_key = hardware_keycode;
-      key.accelerator_mods = mods;
-
-      found_key = g_hash_table_lookup (socket->grabbed_keys, &key);
+  grabbed_key = g_new (GrabbedKey, 1);
+  
+  grabbed_key->accel_key = keyval;
+  grabbed_key->accel_mods = modifiers;
 
-      if (found_key)
-       {
-         g_warning ("GtkSocket: request to add already present grabbed key %u,%#x\n",
-                    hardware_keycode, mods);
-         return;
-       }
+  if (gtk_accel_group_find (socket->accel_group,
+                           find_accel_key,
+                           &grabbed_key))
+    {
+      g_warning ("GtkSocket: request to add already present grabbed key %u,%#x\n",
+                keyval, modifiers);
+      g_free (grabbed_key);
+      return;
     }
-  
-  if (!socket->grabbed_keys)
-    socket->grabbed_keys = g_hash_table_new (grabbed_key_hash, grabbed_key_equal);
 
-  new_key = g_new (GrabbedKey, 1);
-  
-  new_key->accelerator_key = hardware_keycode;
-  new_key->accelerator_mods = mods;
+  closure = g_cclosure_new (G_CALLBACK (activate_key), grabbed_key, (GClosureNotify)g_free);
 
-  g_hash_table_insert (socket->grabbed_keys, new_key, new_key);
+  gtk_accel_group_connect (socket->accel_group, keyval, modifiers, GTK_ACCEL_LOCKED,
+                          closure);
 }
 
 static void
 remove_grabbed_key (GtkSocket      *socket,
-                   guint           hardware_keycode,
-                   GdkModifierType mods)
+                   guint           keyval,
+                   GdkModifierType modifiers)
 {
-  GrabbedKey key;
-  GrabbedKey *found_key = NULL;
+  gint i;
 
-  if (socket->grabbed_keys)
+  for (i = 0; i < socket->accel_group->n_accels; i++)
     {
-      key.accelerator_key = hardware_keycode;
-      key.accelerator_mods = mods;
-
-      found_key = g_hash_table_lookup (socket->grabbed_keys, &key);
+      GtkAccelGroupEntry *accel_entry = &socket->accel_group->priv_accels[i];
+      if (accel_entry->key.accel_key == keyval &&
+         accel_entry->key.accel_mods == modifiers)
+       {
+         gtk_accel_group_disconnect (socket->accel_group,
+                                     accel_entry->closure);
+         return;
+       }
+       
     }
 
-  if (found_key)
-    {
-      g_hash_table_remove (socket->grabbed_keys, &key);
-      g_free (found_key);
-    }
-  else
-    g_warning ("GtkSocket: request to remove non-present grabbed key %u,%#x\n",
-              hardware_keycode, mods);
+  g_warning ("GtkSocket: request to remove non-present grabbed key %u,%#x\n",
+            keyval, modifiers);
 }
 
-static gboolean
-toplevel_key_press_handler (GtkWidget   *toplevel,
-                           GdkEventKey *event,
-                           GtkSocket   *socket)
-{
-  GrabbedKey search_key;
-
-  search_key.accelerator_key = event->hardware_keycode;
-  search_key.accelerator_mods = event->state;
-
-  if (socket->grabbed_keys &&
-      g_hash_table_lookup (socket->grabbed_keys, &search_key))
-    {
-      gtk_socket_key_press_event (GTK_WIDGET (socket), event);
-      gtk_signal_emit_stop_by_name (GTK_OBJECT (toplevel), "key_press_event");
-
-      return TRUE;
-    }
-  else
-    return FALSE;
-}
-
-#endif
-
 static gboolean
 toplevel_focus_in_handler (GtkWidget     *toplevel,
                           GdkEventFocus *event,
@@ -654,9 +669,7 @@ gtk_socket_hierarchy_changed (GtkWidget *widget,
     {
       if (socket->toplevel)
        {
-#if 0
-         gtk_signal_disconnect_by_func (GTK_OBJECT (socket->toplevel), GTK_SIGNAL_FUNC (toplevel_key_press_handler), socket);
-#endif   
+         gtk_window_remove_accel_group (GTK_WINDOW (socket->toplevel), socket->accel_group);
          gtk_signal_disconnect_by_func (GTK_OBJECT (socket->toplevel), GTK_SIGNAL_FUNC (toplevel_focus_in_handler), socket);
          gtk_signal_disconnect_by_func (GTK_OBJECT (socket->toplevel), GTK_SIGNAL_FUNC (toplevel_focus_out_handler), socket);
        }
@@ -665,10 +678,7 @@ gtk_socket_hierarchy_changed (GtkWidget *widget,
 
       if (toplevel)
        {
-#if 0
-         gtk_signal_connect (GTK_OBJECT (socket->toplevel), "key_press_event",
-                             GTK_SIGNAL_FUNC (toplevel_key_press_handler), socket);
-#endif
+         gtk_window_add_accel_group (GTK_WINDOW (socket->toplevel), socket->accel_group);
          gtk_signal_connect (GTK_OBJECT (socket->toplevel), "focus_in_event",
                              GTK_SIGNAL_FUNC (toplevel_focus_in_handler), socket);
          gtk_signal_connect (GTK_OBJECT (socket->toplevel), "focus_out_event",
@@ -1184,15 +1194,15 @@ handle_xembed_message (GtkSocket *socket,
        break;
       }
       
-    case XEMBED_GRAB_KEY:
-#if 0
+    case XEMBED_GTK_GRAB_KEY:
       add_grabbed_key (socket, data1, data2);
-#endif
       break; 
-    case XEMBED_UNGRAB_KEY:
-#if 0      
+    case XEMBED_GTK_UNGRAB_KEY:
       remove_grabbed_key (socket, data1, data2);
-#endif
+      break;
+
+    case XEMBED_GRAB_KEY:
+    case XEMBED_UNGRAB_KEY:
       break;
       
     default:
@@ -1327,19 +1337,13 @@ gtk_socket_filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
         */
        if (socket->plug_window && (xdwe->window == GDK_WINDOW_XWINDOW (socket->plug_window)))
          {
-           GtkWidget *toplevel;
            gboolean result;
            
            GTK_NOTE(PLUGSOCKET,
                     g_message ("GtkSocket - destroy notify"));
            
-           toplevel = gtk_widget_get_toplevel (GTK_WIDGET (socket));
-           if (toplevel && GTK_IS_WINDOW (toplevel))
-             gtk_window_remove_embedded_xid (GTK_WINDOW (toplevel), xdwe->window);
-           
            gdk_window_destroy_notify (socket->plug_window);
-           g_object_unref (socket->plug_window);
-           socket->plug_window = NULL;
+           gtk_socket_end_embedding (socket);
 
            g_object_ref (widget);
            g_signal_emit (G_OBJECT (widget), socket_signals[PLUG_REMOVED], 0, &result);
index 814bb335d76be32bb8f92fcc18f48395ef0abbc8..b6859cc8a9067c888b6a4e486acaf2d2c6ea99a3 100644 (file)
@@ -63,7 +63,7 @@ struct _GtkSocket
   guint need_map : 1;
   guint is_mapped : 1;
 
-  GHashTable *grabbed_keys;
+  GtkAccelGroup *accel_group;
   GtkWidget *toplevel;
 };
 
index 45267e189313ea8624f5c9bc828c85ab32701458..7f860fc5875463cb56c93344131105e3629554a1 100644 (file)
@@ -5675,12 +5675,6 @@ gtk_window_parse_geometry (GtkWindow   *window,
   return result != 0;
 }
 
-typedef void (*GtkWindowKeysForeach) (GtkWindow      *window,
-                                     guint           keyval,
-                                     GdkModifierType modifiers,
-                                     gboolean        is_mnemonic,
-                                     gpointer        data);
-
 static void
 gtk_window_mnemonic_hash_foreach (gpointer key,
                                  gpointer value,
@@ -5688,7 +5682,7 @@ gtk_window_mnemonic_hash_foreach (gpointer key,
 {
   struct {
     GtkWindow *window;
-    GtkWindowKeysForeach func;
+    GtkWindowKeysForeachFunc func;
     gpointer func_data;
   } *info = data;
 
@@ -5698,16 +5692,16 @@ gtk_window_mnemonic_hash_foreach (gpointer key,
     (*info->func) (info->window, mnemonic->keyval, info->window->mnemonic_modifier, TRUE, info->func_data);
 }
 
-static void
-gtk_window_keys_foreach (GtkWindow           *window,
-                        GtkWindowKeysForeach func,
-                        gpointer             func_data)
+void
+_gtk_window_keys_foreach (GtkWindow                *window,
+                         GtkWindowKeysForeachFunc func,
+                         gpointer                 func_data)
 {
   GSList *groups;
 
   struct {
     GtkWindow *window;
-    GtkWindowKeysForeach func;
+    GtkWindowKeysForeachFunc func;
     gpointer func_data;
   } info;
 
@@ -5790,7 +5784,7 @@ gtk_window_get_key_hash (GtkWindow *window)
     return key_hash;
   
   key_hash = _gtk_key_hash_new (gdk_keymap_get_default(), (GDestroyNotify)g_free);
-  gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
+  _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
   g_object_set_data (G_OBJECT (window), "gtk-window-key-hash", key_hash);
 
   return key_hash;
index 2aaa13eb97018b8ed598e89b3ca091dfdbf59177..c8e79474b4af618d73d288a297f27687069b40f1 100644 (file)
@@ -340,6 +340,16 @@ GtkWindowGroup *_gtk_window_get_group          (GtkWindow *window);
 gboolean        _gtk_window_activate_key       (GtkWindow   *window,
                                                GdkEventKey *event);
 
+typedef void (*GtkWindowKeysForeachFunc) (GtkWindow      *window,
+                                         guint           keyval,
+                                         GdkModifierType modifiers,
+                                         gboolean        is_mnemonic,
+                                         gpointer        data);
+
+void _gtk_window_keys_foreach (GtkWindow               *window,
+                              GtkWindowKeysForeachFunc func,
+                              gpointer                 func_data);
+
 /* --- internal (GtkAcceleratable) --- */
 gboolean       _gtk_window_query_nonaccels     (GtkWindow      *window,
                                                 guint           accel_key,
index d6de700f2a566c26415ea162f8ad77ee58ced536..14d55e604d02e7e689f5c3144d61386efcc909a8 100644 (file)
 #define XEMBED_MODALITY_ON              10
 #define XEMBED_MODALITY_OFF             11
 
+/* Non standard messages*/
+#define XEMBED_GTK_GRAB_KEY             108 
+#define XEMBED_GTK_UNGRAB_KEY           109
+
 /* Details for  XEMBED_FOCUS_IN: */
 #define XEMBED_FOCUS_CURRENT            0
 #define XEMBED_FOCUS_FIRST              1