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.
This commit is contained in:
Owen Taylor 2002-02-24 01:52:14 +00:00 committed by Owen Taylor
parent f97ae50153
commit 6a802b24b3
14 changed files with 293 additions and 237 deletions

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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);
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);
accel_groups = gtk_accel_groups_from_object (G_OBJECT (window));
tmp_list = accel_groups;
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);

View File

@ -56,6 +56,8 @@ struct _GtkPlug
GdkWindow *socket_window;
GtkWidget *modality_window;
GtkWindowGroup *modality_group;
GHashTable *grabbed_keys;
guint same_app : 1;
};

View 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)
grabbed_key = g_new (GrabbedKey, 1);
grabbed_key->accel_key = keyval;
grabbed_key->accel_mods = modifiers;
if (gtk_accel_group_find (socket->accel_group,
find_accel_key,
&grabbed_key))
{
key.accelerator_key = hardware_keycode;
key.accelerator_mods = mods;
found_key = g_hash_table_lookup (socket->grabbed_keys, &key);
if (found_key)
{
g_warning ("GtkSocket: request to add already present grabbed key %u,%#x\n",
hardware_keycode, mods);
return;
}
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);

View File

@ -63,7 +63,7 @@ struct _GtkSocket
guint need_map : 1;
guint is_mapped : 1;
GHashTable *grabbed_keys;
GtkAccelGroup *accel_group;
GtkWidget *toplevel;
};

View 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;

View 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,

View File

@ -12,6 +12,10 @@
#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