summaryrefslogtreecommitdiff
path: root/gtk/gtkplug.c
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2002-02-24 01:52:14 +0000
committerOwen Taylor <otaylor@src.gnome.org>2002-02-24 01:52:14 +0000
commit6a802b24b3308daac4533c5bb19dc8660c4b3ab8 (patch)
tree91ddc37b158ba5d6ba430e4016e8d4b42d81c981 /gtk/gtkplug.c
parentf97ae50153c212d18b03c198046fcd54d6562c97 (diff)
downloadgtk+-6a802b24b3308daac4533c5bb19dc8660c4b3ab8.tar.gz
Implement accelerator propagation using a custom XEMBED_GTK_KEY_GRAB
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.
Diffstat (limited to 'gtk/gtkplug.c')
-rw-r--r--gtk/gtkplug.c169
1 files changed, 67 insertions, 102 deletions
diff --git a/gtk/gtkplug.c b/gtk/gtkplug.c
index eb4f10c228..b179fe865f 100644
--- a/gtk/gtkplug.c
+++ b/gtk/gtkplug.c
@@ -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));
@@ -365,6 +365,20 @@ gtk_plug_get_id (GtkPlug *plug)
}
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)
{
GtkPlug *plug;
@@ -568,49 +582,12 @@ 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);