diff options
author | Tim Janik <timj@gtk.org> | 2001-11-13 00:53:47 +0000 |
---|---|---|
committer | Tim Janik <timj@src.gnome.org> | 2001-11-13 00:53:47 +0000 |
commit | d07573c090f8ca8c3fdb8f4d3f63b32be96ea7d6 (patch) | |
tree | ea660dfa3bec08f14714db1b2e9699bf5f126394 /gtk/gtkwindow.c | |
parent | aebe24f2bba1a41b23ab62b7adfc867e28adb3fc (diff) | |
download | gdk-pixbuf-d07573c090f8ca8c3fdb8f4d3f63b32be96ea7d6.tar.gz |
added gtkaccelmap.sgml. other updates.
Mon Nov 12 23:06:38 2001 Tim Janik <timj@gtk.org>
* added gtkaccelmap.sgml. other updates.
Mon Nov 12 23:08:37 2001 Tim Janik <timj@gtk.org>
* gtk/maketypes.awk: fix type utils generation on unix.
* gtk/gtkaccelmap.[hc]: new files, implementing a global accelerator
registry.
* gtk/gtkaccelgroup.[hc]: major API/implementation revamp:
removed GTK_ACCEL_SIGNAL_VISIBLE, gtk_accel_group_get_default,
gtk_accel_group_get_entry, gtk_accel_group_(un)lock_entry,
gtk_accel_group_add/remove, gtk_accel_group_handle_add/remove,
gtk_accel_group_create_add/remove, gtk_accel_group_entries_from_object.
introduced ::accel_changed signal for change notification, and
gtk_accel_group_connect/disconnect to connect closures to accel groups.
made gtk_accel_group_attach/detach and gtk_accel_group_activate private
functions.
deprecated gtk_accel_group_ref/unref.
* gtk/gtkaccellabel.[hc]: changes to make accellabels pay attention
to accel group changed notification and basically operate on closures.
removed gtk_accel_label_get_accel_object and
gtk_accel_label_set_accel_object.
introduced gtk_accel_label_set_accel_closure, and for convenience,
gtk_accel_label_set_accel_widget.
* gtk/gtkitemfactory.[hc]: removed accelerator propagation code
which mostly moved into gtkaccelmap.[hc].
removed gtk_item_factory_parse_rc*, gtk_item_factory_dump_*
and gtk_item_factory_print_func.
* gtk/gtkmain.c: call _gtk_accel_map_init().
* gtk/gtkmenuitem.[hc]: introduced gtk_menu_item_set_accel_path(),
that associates an accelerator path with menu items, through which
persistent accelerator settings on menu items are enabled.
* gtk/gtkmenu.[hc]: added gtk_menu_set_accel_path() so accelerator
paths of menu item can be default constructed to allow installation
of accelerators on menu items that don't come with an accelerator
binding by default.
* gtk/gtksettings.c: fix STRING type rc settings by special casing
them appropriately in the parser.
* gtk/gtksignal.[hc]: allow a class function offset of 0 for
gtk_signal_newv().
* gtk/gtkwidget.[hc]: accelerator API revamp.
removed ::accelerator_add/remove signals, gtk_widget_accelerator_signal,
gtk_widget_accelerators_locked, gtk_widget_remove_accelerators and
gtk_widget_(un)lock_accelerators.
accelerators maintained through gtk_widget_add/remove_accelerator()
are not runtime changable now, the correct sequence to setup a
widget for runtime changable accelerators is now:
gtk_accel_map_add_entry(accel_path, key, mods);
_gtk_widget_set_accel_path(widget, accel_path, accel_group);
* gtk/gtkwindow.[hc]: accelerator changes, proxy and coalesce accel
group changes (as well as mnemonic changes) through the new signal
::accels_changed.
Sat Nov 10 12:08:56 2001 Tim Janik <timj@gtk.org>
* gtk/gtksettings.c (_gtk_settings_parse_convert): properly handle
GString->string conversions.
Diffstat (limited to 'gtk/gtkwindow.c')
-rw-r--r-- | gtk/gtkwindow.c | 164 |
1 files changed, 134 insertions, 30 deletions
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 5641caaea..d5b68cb0f 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -45,6 +45,7 @@ enum { ACTIVATE_FOCUS, ACTIVATE_DEFAULT, MOVE_FOCUS, + ACCELS_CHANGED, LAST_SIGNAL }; @@ -220,6 +221,7 @@ static void gtk_window_set_default_size_internal (GtkWindow *window, static void gtk_window_realize_icon (GtkWindow *window); static void gtk_window_unrealize_icon (GtkWindow *window); +static void gtk_window_notify_accels_changed (GtkWindow *window); static GSList *toplevel_list = NULL; static GHashTable *mnemonic_hash_table = NULL; @@ -309,6 +311,8 @@ gtk_window_class_init (GtkWindowClass *klass) parent_class = gtk_type_class (gtk_bin_get_type ()); + mnemonic_hash_table = g_hash_table_new (mnemonic_hash, mnemonic_equal); + gobject_class->dispose = gtk_window_dispose; gobject_class->finalize = gtk_window_finalize; @@ -345,6 +349,7 @@ gtk_window_class_init (GtkWindowClass *klass) klass->activate_default = gtk_window_real_activate_default; klass->activate_focus = gtk_window_real_activate_focus; klass->move_focus = gtk_window_move_focus; + klass->accels_changed = NULL; /* Construct */ g_object_class_install_property (gobject_class, @@ -493,10 +498,16 @@ gtk_window_class_init (GtkWindowClass *klass) G_TYPE_NONE, 1, GTK_TYPE_DIRECTION_TYPE); - - if (!mnemonic_hash_table) - mnemonic_hash_table = g_hash_table_new (mnemonic_hash, - mnemonic_equal); + + window_signals[ACCELS_CHANGED] = + g_signal_new ("accels_changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + GTK_SIGNAL_OFFSET (GtkWindowClass, accels_changed), + NULL, NULL, + gtk_marshal_VOID__VOID, + G_TYPE_NONE, + 0); /* * Key bindings @@ -1001,6 +1012,38 @@ gtk_window_set_policy (GtkWindow *window, gtk_widget_queue_resize (GTK_WIDGET (window)); } +static gboolean +handle_accels_changed (gpointer data) +{ + GtkWindow *window = GTK_WINDOW (data); + + if (window->accels_changed_handler) + { + gtk_idle_remove (window->accels_changed_handler); + window->accels_changed_handler = 0; + } + + g_signal_emit (window, window_signals[ACCELS_CHANGED], 0); + + return FALSE; +} + +static void +gtk_window_notify_accels_changed (GtkWindow *window) +{ + if (!window->accels_changed_handler) + window->accels_changed_handler = gtk_idle_add (handle_accels_changed, window); +} + +/** + * gtk_window_add_accel_group: + * @window: window to attach accelerator group to + * @accel_group: a #GtkAccelGroup + * + * Associate @accel_group with @window, such that calling + * gtk_accel_groups_activate() on @window will activate accelerators + * in @accel_group. + **/ void gtk_window_add_accel_group (GtkWindow *window, GtkAccelGroup *accel_group) @@ -1008,9 +1051,19 @@ gtk_window_add_accel_group (GtkWindow *window, g_return_if_fail (GTK_IS_WINDOW (window)); g_return_if_fail (accel_group != NULL); - gtk_accel_group_attach (accel_group, G_OBJECT (window)); + _gtk_accel_group_attach (accel_group, G_OBJECT (window)); + g_signal_connect_object (accel_group, "accel_changed", + G_CALLBACK (gtk_window_notify_accels_changed), + window, G_CONNECT_SWAPPED); } +/** + * gtk_accel_group_detach: + * @accel_group: a #GtkAccelGroup + * @object: a #GObject + * + * Reverses the effects of gtk_window_add_accel_group(). + **/ void gtk_window_remove_accel_group (GtkWindow *window, GtkAccelGroup *accel_group) @@ -1018,7 +1071,10 @@ gtk_window_remove_accel_group (GtkWindow *window, g_return_if_fail (GTK_IS_WINDOW (window)); g_return_if_fail (accel_group != NULL); - gtk_accel_group_detach (accel_group, G_OBJECT (window)); + g_signal_handlers_disconnect_by_func (accel_group, + G_CALLBACK (gtk_window_notify_accels_changed), + window); + _gtk_accel_group_detach (accel_group, G_OBJECT (window)); } void @@ -1048,6 +1104,7 @@ gtk_window_add_mnemonic (GtkWindow *window, mnemonic->targets = g_slist_prepend (NULL, target); g_hash_table_insert (mnemonic_hash_table, mnemonic, mnemonic); } + gtk_window_notify_accels_changed (window); } void @@ -1073,6 +1130,7 @@ gtk_window_remove_mnemonic (GtkWindow *window, g_hash_table_remove (mnemonic_hash_table, mnemonic); g_free (mnemonic); } + gtk_window_notify_accels_changed (window); } gboolean @@ -1140,6 +1198,7 @@ gtk_window_set_mnemonic_modifier (GtkWindow *window, g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0); window->mnemonic_modifier = modifier; + gtk_window_notify_accels_changed (window); } /** @@ -2836,7 +2895,13 @@ gtk_window_finalize (GObject *object) &window->geometry_info->widget); g_free (window->geometry_info); } - + + if (window->accels_changed_handler) + { + gtk_idle_remove (window->accels_changed_handler); + window->accels_changed_handler = 0; + } + G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -3371,6 +3436,46 @@ gtk_window_configure_event (GtkWidget *widget, return TRUE; } +/* the accel_key and accel_mods fields of the key have to be setup + * upon calling this function. it'll then return whether that key + * is at all used as accelerator, and if so will OR in the + * accel_flags member of the key. + */ +gboolean +_gtk_window_query_nonaccels (GtkWindow *window, + guint accel_key, + GdkModifierType accel_mods) +{ + g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE); + + /* movement keys are considered locked accels */ + if (!accel_mods) + { + static const guint bindings[] = { + GDK_space, GDK_KP_Space, GDK_Return, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down, + GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab, + }; + guint i; + + for (i = 0; i < G_N_ELEMENTS (bindings); i++) + if (bindings[i] == accel_key) + return TRUE; + } + + /* mnemonics are considered locked accels */ + if (accel_mods == window->mnemonic_modifier) + { + GtkWindowMnemonic mkey; + + mkey.window = window; + mkey.keyval = accel_key; + if (g_hash_table_lookup (mnemonic_hash_table, &mkey)) + return TRUE; + } + + return FALSE; +} + static gint gtk_window_key_press_event (GtkWidget *widget, GdkEventKey *event) @@ -3404,29 +3509,6 @@ gtk_window_key_press_event (GtkWidget *widget, return handled; } - -static void -gtk_window_real_activate_default (GtkWindow *window) -{ - gtk_window_activate_default (window); -} - -static void -gtk_window_real_activate_focus (GtkWindow *window) -{ - gtk_window_activate_focus (window); -} - -static void -gtk_window_move_focus (GtkWindow *window, - GtkDirectionType dir) -{ - gtk_widget_child_focus (GTK_WIDGET (window), dir); - - if (!GTK_CONTAINER (window)->focus_child) - gtk_window_set_focus (window, NULL); -} - static gint gtk_window_key_release_event (GtkWidget *widget, GdkEventKey *event) @@ -3452,6 +3534,28 @@ gtk_window_key_release_event (GtkWidget *widget, return handled; } +static void +gtk_window_real_activate_default (GtkWindow *window) +{ + gtk_window_activate_default (window); +} + +static void +gtk_window_real_activate_focus (GtkWindow *window) +{ + gtk_window_activate_focus (window); +} + +static void +gtk_window_move_focus (GtkWindow *window, + GtkDirectionType dir) +{ + gtk_widget_child_focus (GTK_WIDGET (window), dir); + + if (!GTK_CONTAINER (window)->focus_child) + gtk_window_set_focus (window, NULL); +} + static gint gtk_window_enter_notify_event (GtkWidget *widget, GdkEventCrossing *event) |