summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog51
-rw-r--r--ChangeLog.pre-2-051
-rw-r--r--ChangeLog.pre-2-1051
-rw-r--r--ChangeLog.pre-2-251
-rw-r--r--ChangeLog.pre-2-451
-rw-r--r--ChangeLog.pre-2-651
-rw-r--r--ChangeLog.pre-2-851
-rw-r--r--docs/reference/gtk/gtk-sections.txt27
-rw-r--r--docs/reference/gtk/tmpl/gtk-unused.sgml39
-rw-r--r--docs/reference/gtk/tmpl/gtkaccelgroup.sgml48
-rw-r--r--docs/reference/gtk/tmpl/gtkaccellabel.sgml9
-rw-r--r--docs/reference/gtk/tmpl/gtkwidget.sgml9
-rw-r--r--docs/reference/gtk/tmpl/gtkwindow.sgml12
-rw-r--r--gtk/gtkaccelgroup.c356
-rw-r--r--gtk/gtkaccelgroup.h35
-rw-r--r--gtk/gtkaccellabel.c22
-rw-r--r--gtk/gtkaccelmap.c321
-rw-r--r--gtk/gtkaccelmap.h24
-rw-r--r--gtk/gtkitemfactory.c2
-rw-r--r--gtk/gtkmenu.c13
-rw-r--r--gtk/gtkmenu.h2
-rw-r--r--gtk/gtkwidget.c122
-rw-r--r--gtk/gtkwidget.h2
-rw-r--r--gtk/gtkwindow.c54
-rw-r--r--gtk/gtkwindow.h4
25 files changed, 933 insertions, 525 deletions
diff --git a/ChangeLog b/ChangeLog
index 9915522ca4..fb08736ec1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,54 @@
+Tue Nov 20 21:25:08 2001 Tim Janik <timj@gtk.org>
+
+ * applied patch from owen to get rid of accel map notifiers.
+ changed things to fix reentrancy and API as discussed on gtk-devel.
+
+ * gtk/gtkaccelgroup.[hc]:
+ (gtk_accel_group_finalize): unregister this accel group from all
+ accel map paths.
+ (accel_closure_invalidate): handle invalidation of closures by
+ disconnecting their accelerators.
+ (quick_accel_add): move closure connection and changed notification
+ into this function to reduce code duplication. don't emit change
+ notification on closurers without accelerators.
+ (quick_accel_remove): rewrite, do the exact opposite of quick_accel_add
+ for a GtkAccelGroupEntry.
+ (gtk_accel_group_connect): get rid of the accel_path_quark argument.
+ (gtk_accel_group_connect_by_path): new function to add accelerators
+ with an accel path.
+ (gtk_accel_group_disconnect_closure): new function, disconnect a
+ closure from of an accel group.
+ (gtk_accel_group_disconnect): loop over all closure for a accel_ley,
+ accel_mods pair and remove them.
+ (_gtk_accel_group_reconnect): new function that basically does
+ gtk_accel_group_disconnect_closure() and
+ gtk_accel_group_connect_by_path() once an accel path changed.
+ (gtk_accel_groups_disconnect_closure): remove this, there's
+ gtk_accel_group_disconnect_closure().
+
+ * gtk/gtkaccelmap.[hc]: keep list of accel groups per entry now,
+ nuke notifiers.
+ (_gtk_accel_path_is_valid): make this non-static for
+ gtkwidget.c and gtkaccelgroup.c assertions.
+ (gtk_accel_map_add_notifer): removed this function.
+ (gtk_accel_map_remove_notifer): same.
+ (_gtk_accel_map_add_group):
+ (_gtk_accel_map_remove_group): (un-)register accel groups, with
+ accel paths for correct propagation.
+ (gtk_accel_map_add_entry): return void.
+ (gtk_accel_map_lookup): return gboolean instead of GQuark.
+
+ * gtk/gtkitemfactory.c (gtk_item_factory_add_foreign): always
+ set accel_path on widgets.
+
+ * gtk/gtkwidget.[hc]:
+ (accel_path_changed): got rid of this, changes are handled by
+ accel maps internally now.
+ (_gtk_widget_set_accel_path): get things to work without notifiers.
+ (gtk_widget_list_accel_closures): list accel closures of a widget.
+
+ * gtk/gtkwindow.[hc]: rename ::accels_changed, to ::keys_changed.
+
2001-11-20 Matthias Clasen <matthiasc@poet.de>
* gtk/gtkcontainer.c (gtk_container_propagate_expose): Typo fix.
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
index 9915522ca4..fb08736ec1 100644
--- a/ChangeLog.pre-2-0
+++ b/ChangeLog.pre-2-0
@@ -1,3 +1,54 @@
+Tue Nov 20 21:25:08 2001 Tim Janik <timj@gtk.org>
+
+ * applied patch from owen to get rid of accel map notifiers.
+ changed things to fix reentrancy and API as discussed on gtk-devel.
+
+ * gtk/gtkaccelgroup.[hc]:
+ (gtk_accel_group_finalize): unregister this accel group from all
+ accel map paths.
+ (accel_closure_invalidate): handle invalidation of closures by
+ disconnecting their accelerators.
+ (quick_accel_add): move closure connection and changed notification
+ into this function to reduce code duplication. don't emit change
+ notification on closurers without accelerators.
+ (quick_accel_remove): rewrite, do the exact opposite of quick_accel_add
+ for a GtkAccelGroupEntry.
+ (gtk_accel_group_connect): get rid of the accel_path_quark argument.
+ (gtk_accel_group_connect_by_path): new function to add accelerators
+ with an accel path.
+ (gtk_accel_group_disconnect_closure): new function, disconnect a
+ closure from of an accel group.
+ (gtk_accel_group_disconnect): loop over all closure for a accel_ley,
+ accel_mods pair and remove them.
+ (_gtk_accel_group_reconnect): new function that basically does
+ gtk_accel_group_disconnect_closure() and
+ gtk_accel_group_connect_by_path() once an accel path changed.
+ (gtk_accel_groups_disconnect_closure): remove this, there's
+ gtk_accel_group_disconnect_closure().
+
+ * gtk/gtkaccelmap.[hc]: keep list of accel groups per entry now,
+ nuke notifiers.
+ (_gtk_accel_path_is_valid): make this non-static for
+ gtkwidget.c and gtkaccelgroup.c assertions.
+ (gtk_accel_map_add_notifer): removed this function.
+ (gtk_accel_map_remove_notifer): same.
+ (_gtk_accel_map_add_group):
+ (_gtk_accel_map_remove_group): (un-)register accel groups, with
+ accel paths for correct propagation.
+ (gtk_accel_map_add_entry): return void.
+ (gtk_accel_map_lookup): return gboolean instead of GQuark.
+
+ * gtk/gtkitemfactory.c (gtk_item_factory_add_foreign): always
+ set accel_path on widgets.
+
+ * gtk/gtkwidget.[hc]:
+ (accel_path_changed): got rid of this, changes are handled by
+ accel maps internally now.
+ (_gtk_widget_set_accel_path): get things to work without notifiers.
+ (gtk_widget_list_accel_closures): list accel closures of a widget.
+
+ * gtk/gtkwindow.[hc]: rename ::accels_changed, to ::keys_changed.
+
2001-11-20 Matthias Clasen <matthiasc@poet.de>
* gtk/gtkcontainer.c (gtk_container_propagate_expose): Typo fix.
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index 9915522ca4..fb08736ec1 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,54 @@
+Tue Nov 20 21:25:08 2001 Tim Janik <timj@gtk.org>
+
+ * applied patch from owen to get rid of accel map notifiers.
+ changed things to fix reentrancy and API as discussed on gtk-devel.
+
+ * gtk/gtkaccelgroup.[hc]:
+ (gtk_accel_group_finalize): unregister this accel group from all
+ accel map paths.
+ (accel_closure_invalidate): handle invalidation of closures by
+ disconnecting their accelerators.
+ (quick_accel_add): move closure connection and changed notification
+ into this function to reduce code duplication. don't emit change
+ notification on closurers without accelerators.
+ (quick_accel_remove): rewrite, do the exact opposite of quick_accel_add
+ for a GtkAccelGroupEntry.
+ (gtk_accel_group_connect): get rid of the accel_path_quark argument.
+ (gtk_accel_group_connect_by_path): new function to add accelerators
+ with an accel path.
+ (gtk_accel_group_disconnect_closure): new function, disconnect a
+ closure from of an accel group.
+ (gtk_accel_group_disconnect): loop over all closure for a accel_ley,
+ accel_mods pair and remove them.
+ (_gtk_accel_group_reconnect): new function that basically does
+ gtk_accel_group_disconnect_closure() and
+ gtk_accel_group_connect_by_path() once an accel path changed.
+ (gtk_accel_groups_disconnect_closure): remove this, there's
+ gtk_accel_group_disconnect_closure().
+
+ * gtk/gtkaccelmap.[hc]: keep list of accel groups per entry now,
+ nuke notifiers.
+ (_gtk_accel_path_is_valid): make this non-static for
+ gtkwidget.c and gtkaccelgroup.c assertions.
+ (gtk_accel_map_add_notifer): removed this function.
+ (gtk_accel_map_remove_notifer): same.
+ (_gtk_accel_map_add_group):
+ (_gtk_accel_map_remove_group): (un-)register accel groups, with
+ accel paths for correct propagation.
+ (gtk_accel_map_add_entry): return void.
+ (gtk_accel_map_lookup): return gboolean instead of GQuark.
+
+ * gtk/gtkitemfactory.c (gtk_item_factory_add_foreign): always
+ set accel_path on widgets.
+
+ * gtk/gtkwidget.[hc]:
+ (accel_path_changed): got rid of this, changes are handled by
+ accel maps internally now.
+ (_gtk_widget_set_accel_path): get things to work without notifiers.
+ (gtk_widget_list_accel_closures): list accel closures of a widget.
+
+ * gtk/gtkwindow.[hc]: rename ::accels_changed, to ::keys_changed.
+
2001-11-20 Matthias Clasen <matthiasc@poet.de>
* gtk/gtkcontainer.c (gtk_container_propagate_expose): Typo fix.
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
index 9915522ca4..fb08736ec1 100644
--- a/ChangeLog.pre-2-2
+++ b/ChangeLog.pre-2-2
@@ -1,3 +1,54 @@
+Tue Nov 20 21:25:08 2001 Tim Janik <timj@gtk.org>
+
+ * applied patch from owen to get rid of accel map notifiers.
+ changed things to fix reentrancy and API as discussed on gtk-devel.
+
+ * gtk/gtkaccelgroup.[hc]:
+ (gtk_accel_group_finalize): unregister this accel group from all
+ accel map paths.
+ (accel_closure_invalidate): handle invalidation of closures by
+ disconnecting their accelerators.
+ (quick_accel_add): move closure connection and changed notification
+ into this function to reduce code duplication. don't emit change
+ notification on closurers without accelerators.
+ (quick_accel_remove): rewrite, do the exact opposite of quick_accel_add
+ for a GtkAccelGroupEntry.
+ (gtk_accel_group_connect): get rid of the accel_path_quark argument.
+ (gtk_accel_group_connect_by_path): new function to add accelerators
+ with an accel path.
+ (gtk_accel_group_disconnect_closure): new function, disconnect a
+ closure from of an accel group.
+ (gtk_accel_group_disconnect): loop over all closure for a accel_ley,
+ accel_mods pair and remove them.
+ (_gtk_accel_group_reconnect): new function that basically does
+ gtk_accel_group_disconnect_closure() and
+ gtk_accel_group_connect_by_path() once an accel path changed.
+ (gtk_accel_groups_disconnect_closure): remove this, there's
+ gtk_accel_group_disconnect_closure().
+
+ * gtk/gtkaccelmap.[hc]: keep list of accel groups per entry now,
+ nuke notifiers.
+ (_gtk_accel_path_is_valid): make this non-static for
+ gtkwidget.c and gtkaccelgroup.c assertions.
+ (gtk_accel_map_add_notifer): removed this function.
+ (gtk_accel_map_remove_notifer): same.
+ (_gtk_accel_map_add_group):
+ (_gtk_accel_map_remove_group): (un-)register accel groups, with
+ accel paths for correct propagation.
+ (gtk_accel_map_add_entry): return void.
+ (gtk_accel_map_lookup): return gboolean instead of GQuark.
+
+ * gtk/gtkitemfactory.c (gtk_item_factory_add_foreign): always
+ set accel_path on widgets.
+
+ * gtk/gtkwidget.[hc]:
+ (accel_path_changed): got rid of this, changes are handled by
+ accel maps internally now.
+ (_gtk_widget_set_accel_path): get things to work without notifiers.
+ (gtk_widget_list_accel_closures): list accel closures of a widget.
+
+ * gtk/gtkwindow.[hc]: rename ::accels_changed, to ::keys_changed.
+
2001-11-20 Matthias Clasen <matthiasc@poet.de>
* gtk/gtkcontainer.c (gtk_container_propagate_expose): Typo fix.
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index 9915522ca4..fb08736ec1 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,54 @@
+Tue Nov 20 21:25:08 2001 Tim Janik <timj@gtk.org>
+
+ * applied patch from owen to get rid of accel map notifiers.
+ changed things to fix reentrancy and API as discussed on gtk-devel.
+
+ * gtk/gtkaccelgroup.[hc]:
+ (gtk_accel_group_finalize): unregister this accel group from all
+ accel map paths.
+ (accel_closure_invalidate): handle invalidation of closures by
+ disconnecting their accelerators.
+ (quick_accel_add): move closure connection and changed notification
+ into this function to reduce code duplication. don't emit change
+ notification on closurers without accelerators.
+ (quick_accel_remove): rewrite, do the exact opposite of quick_accel_add
+ for a GtkAccelGroupEntry.
+ (gtk_accel_group_connect): get rid of the accel_path_quark argument.
+ (gtk_accel_group_connect_by_path): new function to add accelerators
+ with an accel path.
+ (gtk_accel_group_disconnect_closure): new function, disconnect a
+ closure from of an accel group.
+ (gtk_accel_group_disconnect): loop over all closure for a accel_ley,
+ accel_mods pair and remove them.
+ (_gtk_accel_group_reconnect): new function that basically does
+ gtk_accel_group_disconnect_closure() and
+ gtk_accel_group_connect_by_path() once an accel path changed.
+ (gtk_accel_groups_disconnect_closure): remove this, there's
+ gtk_accel_group_disconnect_closure().
+
+ * gtk/gtkaccelmap.[hc]: keep list of accel groups per entry now,
+ nuke notifiers.
+ (_gtk_accel_path_is_valid): make this non-static for
+ gtkwidget.c and gtkaccelgroup.c assertions.
+ (gtk_accel_map_add_notifer): removed this function.
+ (gtk_accel_map_remove_notifer): same.
+ (_gtk_accel_map_add_group):
+ (_gtk_accel_map_remove_group): (un-)register accel groups, with
+ accel paths for correct propagation.
+ (gtk_accel_map_add_entry): return void.
+ (gtk_accel_map_lookup): return gboolean instead of GQuark.
+
+ * gtk/gtkitemfactory.c (gtk_item_factory_add_foreign): always
+ set accel_path on widgets.
+
+ * gtk/gtkwidget.[hc]:
+ (accel_path_changed): got rid of this, changes are handled by
+ accel maps internally now.
+ (_gtk_widget_set_accel_path): get things to work without notifiers.
+ (gtk_widget_list_accel_closures): list accel closures of a widget.
+
+ * gtk/gtkwindow.[hc]: rename ::accels_changed, to ::keys_changed.
+
2001-11-20 Matthias Clasen <matthiasc@poet.de>
* gtk/gtkcontainer.c (gtk_container_propagate_expose): Typo fix.
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index 9915522ca4..fb08736ec1 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,54 @@
+Tue Nov 20 21:25:08 2001 Tim Janik <timj@gtk.org>
+
+ * applied patch from owen to get rid of accel map notifiers.
+ changed things to fix reentrancy and API as discussed on gtk-devel.
+
+ * gtk/gtkaccelgroup.[hc]:
+ (gtk_accel_group_finalize): unregister this accel group from all
+ accel map paths.
+ (accel_closure_invalidate): handle invalidation of closures by
+ disconnecting their accelerators.
+ (quick_accel_add): move closure connection and changed notification
+ into this function to reduce code duplication. don't emit change
+ notification on closurers without accelerators.
+ (quick_accel_remove): rewrite, do the exact opposite of quick_accel_add
+ for a GtkAccelGroupEntry.
+ (gtk_accel_group_connect): get rid of the accel_path_quark argument.
+ (gtk_accel_group_connect_by_path): new function to add accelerators
+ with an accel path.
+ (gtk_accel_group_disconnect_closure): new function, disconnect a
+ closure from of an accel group.
+ (gtk_accel_group_disconnect): loop over all closure for a accel_ley,
+ accel_mods pair and remove them.
+ (_gtk_accel_group_reconnect): new function that basically does
+ gtk_accel_group_disconnect_closure() and
+ gtk_accel_group_connect_by_path() once an accel path changed.
+ (gtk_accel_groups_disconnect_closure): remove this, there's
+ gtk_accel_group_disconnect_closure().
+
+ * gtk/gtkaccelmap.[hc]: keep list of accel groups per entry now,
+ nuke notifiers.
+ (_gtk_accel_path_is_valid): make this non-static for
+ gtkwidget.c and gtkaccelgroup.c assertions.
+ (gtk_accel_map_add_notifer): removed this function.
+ (gtk_accel_map_remove_notifer): same.
+ (_gtk_accel_map_add_group):
+ (_gtk_accel_map_remove_group): (un-)register accel groups, with
+ accel paths for correct propagation.
+ (gtk_accel_map_add_entry): return void.
+ (gtk_accel_map_lookup): return gboolean instead of GQuark.
+
+ * gtk/gtkitemfactory.c (gtk_item_factory_add_foreign): always
+ set accel_path on widgets.
+
+ * gtk/gtkwidget.[hc]:
+ (accel_path_changed): got rid of this, changes are handled by
+ accel maps internally now.
+ (_gtk_widget_set_accel_path): get things to work without notifiers.
+ (gtk_widget_list_accel_closures): list accel closures of a widget.
+
+ * gtk/gtkwindow.[hc]: rename ::accels_changed, to ::keys_changed.
+
2001-11-20 Matthias Clasen <matthiasc@poet.de>
* gtk/gtkcontainer.c (gtk_container_propagate_expose): Typo fix.
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index 9915522ca4..fb08736ec1 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,54 @@
+Tue Nov 20 21:25:08 2001 Tim Janik <timj@gtk.org>
+
+ * applied patch from owen to get rid of accel map notifiers.
+ changed things to fix reentrancy and API as discussed on gtk-devel.
+
+ * gtk/gtkaccelgroup.[hc]:
+ (gtk_accel_group_finalize): unregister this accel group from all
+ accel map paths.
+ (accel_closure_invalidate): handle invalidation of closures by
+ disconnecting their accelerators.
+ (quick_accel_add): move closure connection and changed notification
+ into this function to reduce code duplication. don't emit change
+ notification on closurers without accelerators.
+ (quick_accel_remove): rewrite, do the exact opposite of quick_accel_add
+ for a GtkAccelGroupEntry.
+ (gtk_accel_group_connect): get rid of the accel_path_quark argument.
+ (gtk_accel_group_connect_by_path): new function to add accelerators
+ with an accel path.
+ (gtk_accel_group_disconnect_closure): new function, disconnect a
+ closure from of an accel group.
+ (gtk_accel_group_disconnect): loop over all closure for a accel_ley,
+ accel_mods pair and remove them.
+ (_gtk_accel_group_reconnect): new function that basically does
+ gtk_accel_group_disconnect_closure() and
+ gtk_accel_group_connect_by_path() once an accel path changed.
+ (gtk_accel_groups_disconnect_closure): remove this, there's
+ gtk_accel_group_disconnect_closure().
+
+ * gtk/gtkaccelmap.[hc]: keep list of accel groups per entry now,
+ nuke notifiers.
+ (_gtk_accel_path_is_valid): make this non-static for
+ gtkwidget.c and gtkaccelgroup.c assertions.
+ (gtk_accel_map_add_notifer): removed this function.
+ (gtk_accel_map_remove_notifer): same.
+ (_gtk_accel_map_add_group):
+ (_gtk_accel_map_remove_group): (un-)register accel groups, with
+ accel paths for correct propagation.
+ (gtk_accel_map_add_entry): return void.
+ (gtk_accel_map_lookup): return gboolean instead of GQuark.
+
+ * gtk/gtkitemfactory.c (gtk_item_factory_add_foreign): always
+ set accel_path on widgets.
+
+ * gtk/gtkwidget.[hc]:
+ (accel_path_changed): got rid of this, changes are handled by
+ accel maps internally now.
+ (_gtk_widget_set_accel_path): get things to work without notifiers.
+ (gtk_widget_list_accel_closures): list accel closures of a widget.
+
+ * gtk/gtkwindow.[hc]: rename ::accels_changed, to ::keys_changed.
+
2001-11-20 Matthias Clasen <matthiasc@poet.de>
* gtk/gtkcontainer.c (gtk_container_propagate_expose): Typo fix.
diff --git a/docs/reference/gtk/gtk-sections.txt b/docs/reference/gtk/gtk-sections.txt
index fc97655694..40ea35c2f1 100644
--- a/docs/reference/gtk/gtk-sections.txt
+++ b/docs/reference/gtk/gtk-sections.txt
@@ -8,12 +8,14 @@ GtkAccelGroup
gtk_accel_group_get_type
gtk_accel_group_new
gtk_accel_group_connect
+gtk_accel_group_connect_by_path
gtk_accel_group_disconnect
+gtk_accel_group_disconnect_key
gtk_accel_group_query
-gtk_accel_group_activate
-gtk_accel_groups_activate
gtk_accel_group_lock
gtk_accel_group_unlock
+gtk_accel_group_from_accel_closure
+gtk_accel_groups_activate
gtk_accelerator_valid
gtk_accelerator_parse
gtk_accelerator_name
@@ -33,18 +35,16 @@ GTK_ACCEL_GROUP_GET_CLASS
<SECTION>
<FILE>gtkaccelmap</FILE>
<TITLE>Accelerator Maps</TITLE>
-GtkAccelMapNotify
GtkAccelMapForeach
gtk_accel_map_add_entry
gtk_accel_map_lookup_entry
gtk_accel_map_change_entry
-gtk_accel_map_add_notifer
-gtk_accel_map_remove_notifer
gtk_accel_map_load
gtk_accel_map_save
gtk_accel_map_foreach
gtk_accel_map_load_fd
gtk_accel_map_save_fd
+gtk_accel_map_load_scanner
</SECTION>
<SECTION>
@@ -52,8 +52,8 @@ gtk_accel_map_save_fd
<TITLE>GtkAccelLabel</TITLE>
GtkAccelLabel
gtk_accel_label_new
-gtk_accel_label_get_accel_object
-gtk_accel_label_set_accel_object
+gtk_accel_label_get_accel_closure
+gtk_accel_label_set_accel_closure
gtk_accel_label_get_accel_widget
gtk_accel_label_set_accel_widget
gtk_accel_label_get_accel_width
@@ -1290,9 +1290,6 @@ GtkItemFactoryEntry
GtkItemFactoryItem
gtk_item_factory_new
gtk_item_factory_construct
-gtk_item_factory_parse_rc
-gtk_item_factory_parse_rc_string
-gtk_item_factory_parse_rc_scanner
gtk_item_factory_add_foreign
gtk_item_factory_from_widget
gtk_item_factory_path_from_widget
@@ -1300,9 +1297,6 @@ gtk_item_factory_get_item
gtk_item_factory_get_widget
gtk_item_factory_get_widget_by_action
gtk_item_factory_get_item_by_action
-gtk_item_factory_dump_items
-gtk_item_factory_dump_rc
-gtk_item_factory_print_func
gtk_item_factory_create_item
gtk_item_factory_create_items
gtk_item_factory_create_items_ac
@@ -1674,7 +1668,6 @@ GTK_OBJECT_TYPE
GTK_OBJECT_TYPE_NAME
GtkObjectFlags
GTK_OBJECT_FLAGS
-GTK_OBJECT_DESTROYED
GTK_OBJECT_FLOATING
GTK_OBJECT_CONNECTED
GTK_OBJECT_SET_FLAGS
@@ -3467,8 +3460,7 @@ gtk_widget_get_child_requisition
gtk_widget_size_allocate
gtk_widget_add_accelerator
gtk_widget_remove_accelerator
-gtk_widget_remove_accelerators
-gtk_widget_accelerator_signal
+gtk_widget_list_accel_closures
gtk_widget_event
gtk_widget_activate
gtk_widget_reparent
@@ -3519,7 +3511,6 @@ gtk_widget_shape_combine_mask
gtk_widget_path
gtk_widget_class_path
gtk_widget_get_composite_name
-gtk_widget_lock_accelerators
gtk_widget_modify_style
gtk_widget_get_modifier_style
gtk_widget_modify_fg
@@ -3541,8 +3532,6 @@ gtk_widget_set_app_paintable
gtk_widget_set_double_buffered
gtk_widget_set_composite_name
gtk_widget_set_scroll_adjustments
-gtk_widget_unlock_accelerators
-gtk_widget_accelerators_locked
gtk_widget_mnemonic_activate
gtk_widget_class_install_style_property
gtk_widget_class_install_style_property_parser
diff --git a/docs/reference/gtk/tmpl/gtk-unused.sgml b/docs/reference/gtk/tmpl/gtk-unused.sgml
index 3bb9d320f3..6f3500c43b 100644
--- a/docs/reference/gtk/tmpl/gtk-unused.sgml
+++ b/docs/reference/gtk/tmpl/gtk-unused.sgml
@@ -514,6 +514,19 @@ This is a private struct used by GTK+ internally, don't worry about it.
</para>
+<!-- ##### USER_FUNCTION GtkAccelMapNotify ##### -->
+<para>
+
+</para>
+
+@data:
+@accel_path_quark:
+@accel_key:
+@accel_mods:
+@accel_group:
+@old_accel_key:
+@old_accel_mods:
+
<!-- ##### ENUM GtkAnchorType ##### -->
<para>
@@ -1299,6 +1312,13 @@ the #GtkAdjustment which sets the range of the scale.
</para>
+<!-- ##### SIGNAL GtkWindow::accels-changed ##### -->
+<para>
+
+</para>
+
+@window: the object which received the signal.
+
<!-- ##### ARG GtkWindow:auto-shrink ##### -->
<para>
If the window shrinks automatically when widgets within it shrink.
@@ -1484,6 +1504,25 @@ If the window shrinks automatically when widgets within it shrink.
@accel_label:
@accel_object:
+<!-- ##### FUNCTION gtk_accel_map_add_notifer ##### -->
+<para>
+
+</para>
+
+@accel_path:
+@notify_data:
+@notify_func:
+@accel_group:
+
+<!-- ##### FUNCTION gtk_accel_map_remove_notifer ##### -->
+<para>
+
+</para>
+
+@accel_path:
+@notify_data:
+@notify_func:
+
<!-- ##### FUNCTION gtk_arg_copy ##### -->
<para>
It will either copy data into an existing argument or allocate a new argument
diff --git a/docs/reference/gtk/tmpl/gtkaccelgroup.sgml b/docs/reference/gtk/tmpl/gtkaccelgroup.sgml
index b069f7e738..f397377766 100644
--- a/docs/reference/gtk/tmpl/gtkaccelgroup.sgml
+++ b/docs/reference/gtk/tmpl/gtkaccelgroup.sgml
@@ -64,23 +64,35 @@ An object representing and maintaining a group of accelerators.
@accel_mods:
@accel_flags:
@closure:
-@accel_path_quark:
<!-- # Unused Parameters # -->
+@accel_path_quark:
@path_quark:
+<!-- ##### FUNCTION gtk_accel_group_connect_by_path ##### -->
+<para>
+
+</para>
+
+@accel_group:
+@accel_path:
+@closure:
+
+
<!-- ##### FUNCTION gtk_accel_group_disconnect ##### -->
<para>
</para>
@accel_group:
+@closure:
+@Returns:
+<!-- # Unused Parameters # -->
@accel_key:
@accel_mods:
-@Returns:
-<!-- ##### FUNCTION gtk_accel_group_query ##### -->
+<!-- ##### FUNCTION gtk_accel_group_disconnect_key ##### -->
<para>
</para>
@@ -88,21 +100,19 @@ An object representing and maintaining a group of accelerators.
@accel_group:
@accel_key:
@accel_mods:
-@n_entries:
@Returns:
-<!-- ##### FUNCTION gtk_accel_groups_activate ##### -->
+<!-- ##### FUNCTION gtk_accel_group_query ##### -->
<para>
</para>
-@acceleratable:
+@accel_group:
@accel_key:
@accel_mods:
+@n_entries:
@Returns:
-<!-- # Unused Parameters # -->
-@object:
<!-- ##### FUNCTION gtk_accel_group_lock ##### -->
@@ -121,6 +131,28 @@ An object representing and maintaining a group of accelerators.
@accel_group:
+<!-- ##### FUNCTION gtk_accel_group_from_accel_closure ##### -->
+<para>
+
+</para>
+
+@closure:
+@Returns:
+
+
+<!-- ##### FUNCTION gtk_accel_groups_activate ##### -->
+<para>
+
+</para>
+
+@acceleratable:
+@accel_key:
+@accel_mods:
+@Returns:
+<!-- # Unused Parameters # -->
+@object:
+
+
<!-- ##### FUNCTION gtk_accelerator_valid ##### -->
<para>
diff --git a/docs/reference/gtk/tmpl/gtkaccellabel.sgml b/docs/reference/gtk/tmpl/gtkaccellabel.sgml
index 4587cf7515..dac75d7438 100644
--- a/docs/reference/gtk/tmpl/gtkaccellabel.sgml
+++ b/docs/reference/gtk/tmpl/gtkaccellabel.sgml
@@ -94,6 +94,15 @@ Creates a new #GtkAccelLabel.
@Returns: a new #GtkAccelLabel.
+<!-- ##### FUNCTION gtk_accel_label_set_accel_closure ##### -->
+<para>
+
+</para>
+
+@accel_label:
+@closure:
+
+
<!-- ##### FUNCTION gtk_accel_label_get_accel_widget ##### -->
<para>
diff --git a/docs/reference/gtk/tmpl/gtkwidget.sgml b/docs/reference/gtk/tmpl/gtkwidget.sgml
index 76769b73b5..dbe5a82a33 100644
--- a/docs/reference/gtk/tmpl/gtkwidget.sgml
+++ b/docs/reference/gtk/tmpl/gtkwidget.sgml
@@ -530,6 +530,15 @@ GtkWidget
@Returns:
+<!-- ##### FUNCTION gtk_widget_list_accel_closures ##### -->
+<para>
+
+</para>
+
+@widget:
+@Returns:
+
+
<!-- ##### FUNCTION gtk_widget_event ##### -->
<para>
diff --git a/docs/reference/gtk/tmpl/gtkwindow.sgml b/docs/reference/gtk/tmpl/gtkwindow.sgml
index b8111b4362..d5a4f46478 100644
--- a/docs/reference/gtk/tmpl/gtkwindow.sgml
+++ b/docs/reference/gtk/tmpl/gtkwindow.sgml
@@ -694,35 +694,35 @@ it's larger
@height:
-<!-- ##### SIGNAL GtkWindow::accels-changed ##### -->
+<!-- ##### SIGNAL GtkWindow::activate-default ##### -->
<para>
</para>
@window: the object which received the signal.
-<!-- ##### SIGNAL GtkWindow::activate-default ##### -->
+<!-- ##### SIGNAL GtkWindow::activate-focus ##### -->
<para>
</para>
@window: the object which received the signal.
-<!-- ##### SIGNAL GtkWindow::activate-focus ##### -->
+<!-- ##### SIGNAL GtkWindow::frame-event ##### -->
<para>
</para>
@window: the object which received the signal.
+@event:
+@Returns:
-<!-- ##### SIGNAL GtkWindow::frame-event ##### -->
+<!-- ##### SIGNAL GtkWindow::keys-changed ##### -->
<para>
</para>
@window: the object which received the signal.
-@event:
-@Returns:
<!-- ##### SIGNAL GtkWindow::move-focus ##### -->
<para>
diff --git a/gtk/gtkaccelgroup.c b/gtk/gtkaccelgroup.c
index 7d5ec04b8f..8106f813e1 100644
--- a/gtk/gtkaccelgroup.c
+++ b/gtk/gtkaccelgroup.c
@@ -52,7 +52,7 @@ static guint default_accel_mod_mask = (GDK_SHIFT_MASK |
/* --- functions --- */
/**
- * gtk_accel_map_change_entry
+ * gtk_accel_group_get_type
* @returns: the type ID for accelerator groups
*/
GType
@@ -135,6 +135,19 @@ static void
gtk_accel_group_finalize (GObject *object)
{
GtkAccelGroup *accel_group = GTK_ACCEL_GROUP (object);
+ guint i;
+
+ for (i = 0; i < accel_group->n_accels; i++)
+ {
+ GtkAccelGroupEntry *entry = &accel_group->priv_accels[i];
+
+ if (entry->accel_path_quark)
+ {
+ const gchar *accel_path = g_quark_to_string (entry[i].accel_path_quark);
+
+ _gtk_accel_map_remove_group (accel_path, accel_group);
+ }
+ }
g_free (accel_group->priv_accels);
@@ -300,10 +313,12 @@ gtk_accel_group_unlock (GtkAccelGroup *accel_group)
}
static void
-accel_tag_func (gpointer data,
- GClosure *closure)
+accel_closure_invalidate (gpointer data,
+ GClosure *closure)
{
- /* GtkAccelGroup *accel_group = data; */
+ GtkAccelGroup *accel_group = GTK_ACCEL_GROUP (data);
+
+ gtk_accel_group_disconnect (accel_group, closure);
}
static int
@@ -330,11 +345,14 @@ quick_accel_add (GtkAccelGroup *accel_group,
guint pos, i = accel_group->n_accels++;
GtkAccelGroupEntry key;
+ /* find position */
key.key.accel_key = accel_key;
key.key.accel_mods = accel_mods;
for (pos = 0; pos < i; pos++)
if (bsearch_compare_accels (&key, accel_group->priv_accels + pos) < 0)
break;
+
+ /* insert at position, ref closure */
accel_group->priv_accels = g_renew (GtkAccelGroupEntry, accel_group->priv_accels, accel_group->n_accels);
g_memmove (accel_group->priv_accels + pos + 1, accel_group->priv_accels + pos,
(i - pos) * sizeof (accel_group->priv_accels[0]));
@@ -344,9 +362,71 @@ quick_accel_add (GtkAccelGroup *accel_group,
accel_group->priv_accels[pos].closure = g_closure_ref (closure);
accel_group->priv_accels[pos].accel_path_quark = path_quark;
g_closure_sink (closure);
+
+ /* handle closure invalidation and reverse lookups */
+ g_closure_add_invalidate_notifier (closure, accel_group, accel_closure_invalidate);
+
+ /* get accel path notification */
+ if (path_quark)
+ _gtk_accel_map_add_group (g_quark_to_string (path_quark), accel_group);
+
+ /* connect and notify changed */
+ if (accel_key)
+ {
+ gchar *accel_name = gtk_accelerator_name (accel_key, accel_mods);
+ GQuark accel_quark = g_quark_from_string (accel_name);
- /* tag closure for backwards lookup */
- g_closure_add_invalidate_notifier (closure, accel_group, accel_tag_func);
+ g_free (accel_name);
+
+ /* setup handler */
+ g_signal_connect_closure_by_id (accel_group, signal_accel_activate, accel_quark, closure, FALSE);
+
+ /* and notify */
+ g_signal_emit (accel_group, signal_accel_changed, accel_quark, accel_key, accel_mods, closure);
+ }
+}
+
+static void
+quick_accel_remove (GtkAccelGroup *accel_group,
+ GtkAccelGroupEntry *entry)
+{
+ guint pos = entry - accel_group->priv_accels;
+ GQuark accel_quark = 0;
+ guint accel_key = entry->key.accel_key;
+ GdkModifierType accel_mods = entry->key.accel_mods;
+ GClosure *closure = entry->closure;
+
+ /* quark for notification */
+ if (accel_key)
+ {
+ gchar *accel_name = gtk_accelerator_name (accel_key, accel_mods);
+
+ accel_quark = g_quark_from_string (accel_name);
+ g_free (accel_name);
+ }
+
+ /* clean up closure invalidate notification and disconnect */
+ g_closure_remove_invalidate_notifier (entry->closure, accel_group, accel_closure_invalidate);
+ if (accel_quark)
+ g_signal_handlers_disconnect_matched (accel_group,
+ G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL | G_SIGNAL_MATCH_CLOSURE,
+ signal_accel_activate, accel_quark,
+ closure, NULL, NULL);
+ /* clean up accel path notification */
+ if (entry->accel_path_quark)
+ _gtk_accel_map_remove_group (g_quark_to_string (entry->accel_path_quark), accel_group);
+
+ /* physically remove */
+ accel_group->n_accels -= 1;
+ g_memmove (entry, entry + 1,
+ (accel_group->n_accels - pos) * sizeof (accel_group->priv_accels[0]));
+
+ /* and notify */
+ if (accel_quark)
+ g_signal_emit (accel_group, signal_accel_changed, accel_quark, accel_key, accel_mods, closure);
+
+ /* remove quick_accel_add() refcount */
+ g_closure_unref (closure);
}
static GtkAccelGroupEntry*
@@ -382,31 +462,6 @@ quick_accel_find (GtkAccelGroup *accel_group,
return entry;
}
-static GSList*
-quick_accel_remove (GtkAccelGroup *accel_group,
- guint accel_key,
- GdkModifierType accel_mods)
-{
- guint i, n;
- GtkAccelGroupEntry *entry = quick_accel_find (accel_group, accel_key, accel_mods, &n);
- guint pos = entry - accel_group->priv_accels;
- GSList *clist = NULL;
-
- if (!entry)
- return NULL;
- for (i = 0; i < n; i++)
- {
- g_closure_remove_invalidate_notifier (entry[i].closure, accel_group, accel_tag_func);
- clist = g_slist_prepend (clist, entry[i].closure);
- }
-
- accel_group->n_accels -= n;
- g_memmove (entry, entry + n,
- (accel_group->n_accels - pos) * sizeof (accel_group->priv_accels[0]));
-
- return clist;
-}
-
/**
* gtk_accel_group_connect
* @accel_group: the ccelerator group to install an accelerator in
@@ -414,90 +469,107 @@ quick_accel_remove (GtkAccelGroup *accel_group,
* @accel_mods: modifier combination of the accelerator
* @accel_flags: a flag mask to configure this accelerator
* @closure: closure to be executed upon accelerator activation
- * @accel_path_quark: accelerator path quark from GtkAccelMapNotify
*
* Install an accelerator in this group. When @accel_group is being activated
* in response to a call to gtk_accel_groups_activate(), @closure will be
* invoked if the @accel_key and @accel_mods from gtk_accel_groups_activate()
* match those of this connection.
* The signature used for the @closure is that of #GtkAccelGroupActivate.
- * If this connection is made in response to an accelerator path change (see
- * gtk_accel_map_change_entry()) from a #GtkAccelMapNotify notifier,
- * @accel_path_quark must be passed on from the notifier into this function,
- * it should be 0 otherwise.
+ * Note that, due to implementation details, a single closure can only be
+ * connected to one accelerator group.
*/
void
gtk_accel_group_connect (GtkAccelGroup *accel_group,
guint accel_key,
GdkModifierType accel_mods,
GtkAccelFlags accel_flags,
- GClosure *closure,
- GQuark accel_path_quark)
+ GClosure *closure)
{
- gchar *accel_name;
- GQuark accel_quark;
-
g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
g_return_if_fail (closure != NULL);
g_return_if_fail (accel_key > 0);
+ g_return_if_fail (gtk_accel_group_from_accel_closure (closure) == NULL);
- accel_name = gtk_accelerator_name (accel_key, accel_mods);
- accel_quark = g_quark_from_string (accel_name);
- g_free (accel_name);
-
- quick_accel_add (accel_group, accel_key, accel_mods, accel_flags, closure, accel_path_quark);
-
- /* setup handler */
- g_signal_connect_closure_by_id (accel_group, signal_accel_activate, accel_quark, closure, FALSE);
-
- /* and notify */
- g_signal_emit (accel_group, signal_accel_changed, accel_quark, accel_key, accel_mods, closure);
+ g_object_ref (accel_group);
+ if (!closure->is_invalid)
+ quick_accel_add (accel_group, accel_key, accel_mods, accel_flags, closure, 0);
+ g_object_unref (accel_group);
}
-static gboolean
-accel_group_disconnect_closure (GtkAccelGroup *accel_group,
- guint accel_key,
- GdkModifierType accel_mods,
- GClosure *closure)
+/**
+ * gtk_accel_group_connect_by_path
+ * @accel_group: the ccelerator group to install an accelerator in
+ * @accel_path: path used for determining key and modifiers.
+ * @closure: closure to be executed upon accelerator activation
+ *
+ * Install an accelerator in this group, using a accelerator path to look
+ * up the appropriate key and modifiers. (See gtk_accel_map_add_entry())
+ * When @accel_group is being activated in response to a call to
+ * gtk_accel_groups_activate(), @closure will be invoked if the @accel_key and
+ * @accel_mods from gtk_accel_groups_activate() match the key and modifiers
+ * for the path.
+ * The signature used for the @closure is that of #GtkAccelGroupActivate.
+ */
+void
+gtk_accel_group_connect_by_path (GtkAccelGroup *accel_group,
+ const gchar *accel_path,
+ GClosure *closure)
{
- gchar *accel_name;
- GQuark accel_quark;
- GSList *clist , *slist;
- gboolean removed_some = FALSE;
+ guint accel_key = 0;
+ GdkModifierType accel_mods = 0;
+ GtkAccelKey key;
- accel_name = gtk_accelerator_name (accel_key, accel_mods);
- accel_quark = g_quark_from_string (accel_name);
- g_free (accel_name);
+ g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
+ g_return_if_fail (closure != NULL);
+ g_return_if_fail (_gtk_accel_path_is_valid (accel_path));
- clist = quick_accel_remove (accel_group, accel_key, accel_mods);
- if (!clist)
- return FALSE;
+ if (closure->is_invalid)
+ return;
g_object_ref (accel_group);
- for (slist = clist; slist; slist = slist->next)
- if (!closure || slist->data == (gpointer) closure)
- {
- g_signal_handlers_disconnect_matched (accel_group, G_SIGNAL_MATCH_CLOSURE | G_SIGNAL_MATCH_ID,
- signal_accel_activate, 0,
- slist->data, NULL, NULL);
- /* and notify */
- g_signal_emit (accel_group, signal_accel_changed, accel_quark, accel_key, accel_mods, slist->data);
-
- /* remove quick_accel_add() ref_count */
- g_closure_unref (slist->data);
-
- removed_some = TRUE;
- }
- g_slist_free (clist);
+ if (gtk_accel_map_lookup_entry (accel_path, &key))
+ {
+ accel_key = key.accel_key;
+ accel_mods = key.accel_mods;
+ }
+
+ quick_accel_add (accel_group, accel_key, accel_mods, GTK_ACCEL_VISIBLE, closure,
+ g_quark_from_string (accel_path));
g_object_unref (accel_group);
-
- return removed_some;
}
/**
* gtk_accel_group_disconnect
+ * @accel_group: the accelerator group to remove an accelerator from
+ * @closure: the closure to remove from this accelerator group
+ * @returns: %TRUE if the closure was found and got disconnected
+ *
+ * Remove an accelerator previously installed through
+ * gtk_accel_group_connect().
+ */
+gboolean
+gtk_accel_group_disconnect (GtkAccelGroup *accel_group,
+ GClosure *closure)
+{
+ guint i;
+
+ g_return_val_if_fail (GTK_IS_ACCEL_GROUP (accel_group), FALSE);
+
+ for (i = 0; i < accel_group->n_accels; i++)
+ if (accel_group->priv_accels[i].closure == closure)
+ {
+ g_object_ref (accel_group);
+ quick_accel_remove (accel_group, accel_group->priv_accels + i);
+ g_object_unref (accel_group);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * gtk_accel_group_disconnect_key
* @accel_group: the ccelerator group to install an accelerator in
* @accel_key: key value of the accelerator
* @accel_mods: modifier combination of the accelerator
@@ -507,13 +579,71 @@ accel_group_disconnect_closure (GtkAccelGroup *accel_group,
* gtk_accel_group_connect().
*/
gboolean
-gtk_accel_group_disconnect (GtkAccelGroup *accel_group,
- guint accel_key,
- GdkModifierType accel_mods)
+gtk_accel_group_disconnect_key (GtkAccelGroup *accel_group,
+ guint accel_key,
+ GdkModifierType accel_mods)
{
+ GtkAccelGroupEntry *entries;
+ GSList *slist, *clist = NULL;
+ gboolean removed_one = FALSE;
+ guint n;
+
g_return_val_if_fail (GTK_IS_ACCEL_GROUP (accel_group), FALSE);
- return accel_group_disconnect_closure (accel_group, accel_key, accel_mods, NULL);
+ g_object_ref (accel_group);
+
+ entries = quick_accel_find (accel_group, accel_key, accel_mods, &n);
+ while (n--)
+ {
+ GClosure *closure = g_closure_ref (entries[n].closure);
+
+ clist = g_slist_prepend (clist, closure);
+ }
+
+ for (slist = clist; slist; slist = slist->next)
+ {
+ GClosure *closure = slist->data;
+
+ removed_one |= gtk_accel_group_disconnect (accel_group, closure);
+ g_closure_unref (closure);
+ }
+ g_slist_free (clist);
+
+ g_object_unref (accel_group);
+
+ return removed_one;
+}
+
+void
+_gtk_accel_group_reconnect (GtkAccelGroup *accel_group,
+ GQuark accel_path_quark)
+{
+ GSList *slist, *clist = NULL;
+ guint i;
+
+ g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
+
+ g_object_ref (accel_group);
+
+ for (i = 0; i < accel_group->n_accels; i++)
+ if (accel_group->priv_accels[i].accel_path_quark == accel_path_quark)
+ {
+ GClosure *closure = g_closure_ref (accel_group->priv_accels[i].closure);
+
+ clist = g_slist_prepend (clist, closure);
+ }
+
+ for (slist = clist; slist; slist = slist->next)
+ {
+ GClosure *closure = slist->data;
+
+ gtk_accel_group_disconnect (accel_group, closure);
+ gtk_accel_group_connect_by_path (accel_group, g_quark_to_string (accel_path_quark), closure);
+ g_closure_unref (closure);
+ }
+ g_slist_free (clist);
+
+ g_object_unref (accel_group);
}
GtkAccelGroupEntry*
@@ -535,38 +665,6 @@ gtk_accel_group_query (GtkAccelGroup *accel_group,
return entries;
}
-static gboolean
-find_accel_closure (GtkAccelKey *key,
- GClosure *closure,
- gpointer data)
-{
- return data == (gpointer) closure;
-}
-
-gboolean
-gtk_accel_groups_disconnect_closure (GClosure *closure)
-{
- GtkAccelGroup *group;
-
- g_return_val_if_fail (closure != NULL, FALSE);
-
- group = gtk_accel_group_from_accel_closure (closure);
- if (group)
- {
- GtkAccelKey *key = gtk_accel_group_find (group, find_accel_closure, closure);
-
- /* sigh, not finding the key can unexpectedly happen if someone disposes
- * accel groups. that's highly recommended to _not_ do though.
- */
- if (key)
- {
- accel_group_disconnect_closure (group, key->accel_key, key->accel_mods, closure);
- return TRUE;
- }
- }
- return FALSE;
-}
-
GtkAccelGroup*
gtk_accel_group_from_accel_closure (GClosure *closure)
{
@@ -574,15 +672,15 @@ gtk_accel_group_from_accel_closure (GClosure *closure)
g_return_val_if_fail (closure != NULL, NULL);
- /* a few remarks on wat we do here. in general, we need a way to back-lookup
+ /* a few remarks on wat we do here. in general, we need a way to reverse lookup
* accel_groups from closures that are being used in accel groups. this could
* be done e.g via a hashtable. it is however cheaper (memory wise) to just
- * store a NOP notifier on the closure itself that contains the accel group
- * as data which, besides needing to peek a bit at closure internals, works
- * just as good.
+ * use the invalidation notifier on the closure itself (which we need to install
+ * anyway), that contains the accel group as data which, besides needing to peek
+ * a bit at closure internals, works just as good.
*/
for (i = 0; i < G_CLOSURE_N_NOTIFIERS (closure); i++)
- if (closure->notifiers[i].notify == accel_tag_func)
+ if (closure->notifiers[i].notify == accel_closure_invalidate)
return closure->notifiers[i].data;
return NULL;
@@ -791,10 +889,10 @@ is_release (const gchar *string)
* @accelerator_mods: return location for accelerator modifier mask
*
* Parses a string representing an accelerator. The
- * format looks like "<Control>a" or "<Shift><Alt>F1" or
- * "<Release>z" (the last one is for key release).
+ * format looks like "&lt;Control&gt;a" or "&lt;Shift&gt;&lt;Alt&gt;F1" or
+ * "&lt;Release&gt;z" (the last one is for key release).
* The parser is fairly liberal and allows lower or upper case,
- * and also abbreviations such as "<Ctl>" and "<Ctrl>".
+ * and also abbreviations such as "&lt;Ctl&gt;" and "&lt;Ctrl&gt;".
*
* If the parse fails, @accelerator_key and @accelerator_mods will
* be set to 0 (zero).
@@ -911,7 +1009,7 @@ gtk_accelerator_parse (const gchar *accelerator,
* Converts an accelerator keyval and modifier mask
* into a string parseable by gtk_accelerator_parse().
* For example, if you pass in GDK_q and GDK_CONTROL_MASK,
- * this function returns "<Control>q".
+ * this function returns "&lt;Control&gt;q".
*
* The caller of this function must free the returned string.
*/
diff --git a/gtk/gtkaccelgroup.h b/gtk/gtkaccelgroup.h
index 5fca1a33b3..cfb207f8a7 100644
--- a/gtk/gtkaccelgroup.h
+++ b/gtk/gtkaccelgroup.h
@@ -88,20 +88,23 @@ struct _GtkAccelKey
/* -- Accelerator Groups --- */
-GType gtk_accel_group_get_type (void);
-GtkAccelGroup* gtk_accel_group_new (void);
-void gtk_accel_group_lock (GtkAccelGroup *accel_group);
-void gtk_accel_group_unlock (GtkAccelGroup *accel_group);
-void gtk_accel_group_connect (GtkAccelGroup *accel_group,
- guint accel_key,
- GdkModifierType accel_mods,
- GtkAccelFlags accel_flags,
- GClosure *closure,
- GQuark accel_path_quark);
-gboolean gtk_accel_group_disconnect (GtkAccelGroup *accel_group,
- guint accel_key,
- GdkModifierType accel_mods);
-gboolean gtk_accel_groups_disconnect_closure (GClosure *closure);
+GType gtk_accel_group_get_type (void);
+GtkAccelGroup* gtk_accel_group_new (void);
+void gtk_accel_group_lock (GtkAccelGroup *accel_group);
+void gtk_accel_group_unlock (GtkAccelGroup *accel_group);
+void gtk_accel_group_connect (GtkAccelGroup *accel_group,
+ guint accel_key,
+ GdkModifierType accel_mods,
+ GtkAccelFlags accel_flags,
+ GClosure *closure);
+void gtk_accel_group_connect_by_path (GtkAccelGroup *accel_group,
+ const gchar *accel_path,
+ GClosure *closure);
+gboolean gtk_accel_group_disconnect (GtkAccelGroup *accel_group,
+ GClosure *closure);
+gboolean gtk_accel_group_disconnect_key (GtkAccelGroup *accel_group,
+ guint accel_key,
+ GdkModifierType accel_mods);
/* --- GtkActivatable glue --- */
@@ -138,6 +141,10 @@ GtkAccelGroupEntry* gtk_accel_group_query (GtkAccelGroup *accel_group,
guint accel_key,
GdkModifierType accel_mods,
guint *n_entries);
+
+void _gtk_accel_group_reconnect (GtkAccelGroup *accel_group,
+ GQuark accel_path_quark);
+
struct _GtkAccelGroupEntry
{
GtkAccelKey key;
diff --git a/gtk/gtkaccellabel.c b/gtk/gtkaccellabel.c
index efa096fd35..b3721e1c4c 100644
--- a/gtk/gtkaccellabel.c
+++ b/gtk/gtkaccellabel.c
@@ -351,19 +351,21 @@ gtk_accel_label_expose_event (GtkWidget *widget,
static void
refetch_widget_accel_closure (GtkAccelLabel *accel_label)
{
- GSList *slist;
-
+ GClosure *closure = NULL;
+ GList *clist, *list;
+
g_return_if_fail (GTK_IS_ACCEL_LABEL (accel_label));
g_return_if_fail (GTK_IS_WIDGET (accel_label->accel_widget));
- for (slist = _gtk_widget_get_accel_closures (accel_label->accel_widget); slist; slist = slist->next)
- if (gtk_accel_group_from_accel_closure (slist->data))
- {
- /* we just take the first correctly used closure */
- gtk_accel_label_set_accel_closure (accel_label, slist->data);
- return;
- }
- gtk_accel_label_set_accel_closure (accel_label, NULL);
+ clist = gtk_widget_list_accel_closures (accel_label->accel_widget);
+ for (list = clist; list; list = list->next)
+ {
+ /* we just take the first closure used */
+ closure = list->data;
+ break;
+ }
+ g_list_free (clist);
+ gtk_accel_label_set_accel_closure (accel_label, closure);
}
void
diff --git a/gtk/gtkaccelmap.c b/gtk/gtkaccelmap.c
index d99e01aacb..7fe375c606 100644
--- a/gtk/gtkaccelmap.c
+++ b/gtk/gtkaccelmap.c
@@ -42,7 +42,7 @@ typedef struct {
guint std_accel_key;
guint std_accel_mods;
guint changed : 1;
- GHookList *hooks;
+ GSList *groups;
} AccelEntry;
@@ -89,8 +89,8 @@ _gtk_accel_map_init (void)
accel_entry_ht = g_hash_table_new (accel_entry_hash, accel_entry_equal);
}
-static gboolean
-gtk_accel_path_is_valid (const gchar *accel_path)
+gboolean
+_gtk_accel_path_is_valid (const gchar *accel_path)
{
gchar *p;
@@ -108,14 +108,13 @@ gtk_accel_path_is_valid (const gchar *accel_path)
* @accel_path: valid accelerator path
* @accel_key: the accelerator key
* @accel_mods: the accelerator modifiers
- * @returns: the GQuark for the @accel_path (to ease local storage)
*
* Register a new accelerator with the global accelerator map.
* This function should only be called once per @accel_path
* with the canonical @accel_key and @accel_mods for this path.
* To change the accelerator during runtime programatically, use
* gtk_accel_map_change_entry().
- * The accelerator path must consist of "<WINDOWTYPE>/Category1/Category2/.../Action",
+ * The accelerator path must consist of "&lt;WINDOWTYPE&gt;/Category1/Category2/.../Action",
* where WINDOWTYPE should be a unique application specifc identifier, that
* corresponds to the kind of window the accelerator is being used in, e.g. "Gimp-Image",
* "Abiword-Document" or "Gnumeric-Settings".
@@ -123,18 +122,21 @@ gtk_accel_path_is_valid (const gchar *accel_path)
* accelerator triggers, i.e. for accelerators on menu items, choose the item's menu path,
* e.g. "File/Save As", "Image/View/Zoom" or "Edit/Select All".
* So a full valid accelerator path may look like:
- * "<Gimp-Toolbox>/File/Dialogs/Tool Options...".
+ * "&lt;Gimp-Toolbox&gt;/File/Dialogs/Tool Options...".
*/
-GQuark
+void
gtk_accel_map_add_entry (const gchar *accel_path,
guint accel_key,
guint accel_mods)
{
AccelEntry *entry;
- g_return_val_if_fail (gtk_accel_path_is_valid (accel_path), 0);
+ g_return_if_fail (_gtk_accel_path_is_valid (accel_path));
- accel_mods &= gtk_accelerator_get_default_mod_mask ();
+ if (!accel_key)
+ accel_mods = 0;
+ else
+ accel_mods &= gtk_accelerator_get_default_mod_mask ();
entry = accel_path_lookup (accel_path);
if (entry)
@@ -159,154 +161,35 @@ gtk_accel_map_add_entry (const gchar *accel_path,
entry->changed = FALSE;
g_hash_table_insert (accel_entry_ht, entry, entry);
}
- return g_quark_try_string (entry->accel_path);
-}
-
-typedef struct {
- GHook hook;
- GtkAccelGroup *accel_group;
-} AccelHook;
-
-static void
-accel_hook_finalize (GHookList *hook_list,
- GHook *hook)
-{
- GDestroyNotify destroy = hook->destroy;
- AccelHook *ahook = (AccelHook*) hook;
-
- if (ahook->accel_group)
- g_object_unref (ahook->accel_group);
-
- if (destroy)
- {
- hook->destroy = NULL;
- destroy (hook->data);
- }
-}
-
-/**
- * GtkAccelMapNotify
- * @data: notifier user data
- * @accel_path_quark: accelerator path (as #GQuark) which has just changed
- * @accel_key: new accelerator key
- * @accel_mods: new accelerator modifiers
- * @accel_group: accelerator group of this notifier
- * @old_accel_key: former accelerator key
- * @old_accel_mods): former accelerator modifiers
- *
- * #GtkAccelMapNotify is the signature of user callbacks, installed via
- * gtk_accel_map_add_notifier(). Once the accel path of the notifier changes,
- * the notifier is invoked with this signature, where @accel_path_quark
- * indicates the accel path that changed, and @data and @accel_group are
- * the notifier's arguments as passed into gtk_accel_map_add_notifier().
- */
-
-/**
- * gtk_accel_map_add_notifer
- * @accel_path: valid accelerator path
- * @notify_data: data argument to the notifier
- * @notify_func: the notifier function
- * @accel_group: accelerator group used by the notifier function
- *
- * Install a notifier function to be called if an accelerator
- * map entry changes. @accel_group has to be the accel group
- * that is being affected (gets an accelerator removed or added,
- * when the notifier function is executed).
- */
-void
-gtk_accel_map_add_notifer (const gchar *accel_path,
- gpointer notify_data,
- GtkAccelMapNotify notify_func,
- GtkAccelGroup *accel_group)
-{
- AccelEntry *entry;
- AccelHook *ahook;
- GHook *hook;
-
- g_return_if_fail (gtk_accel_path_is_valid (accel_path));
- g_return_if_fail (notify_func != NULL);
- if (accel_group)
- g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
-
- entry = accel_path_lookup (accel_path);
- if (!entry)
- {
- gtk_accel_map_add_entry (accel_path, 0, 0);
- entry = accel_path_lookup (accel_path);
- }
- if (!entry->hooks)
- {
- entry->hooks = g_new (GHookList, 1);
- g_hook_list_init (entry->hooks, sizeof (AccelHook));
- entry->hooks->finalize_hook = accel_hook_finalize;
- }
- hook = g_hook_alloc (entry->hooks);
- hook->data = notify_data;
- hook->func = notify_func;
- hook->destroy = NULL;
- ahook = (AccelHook*) hook;
- ahook->accel_group = accel_group ? g_object_ref (accel_group) : NULL;
- g_hook_append (entry->hooks, hook);
-}
-
-/**
- * gtk_accel_map_remove_notifer
- * @accel_path: valid accelerator path
- * @notify_data: data argument to the notifier
- * @notify_func: the notifier function
- *
- * Remove a notifier function, previously installed through
- * gtk_accel_map_add_notifer().
- */
-void
-gtk_accel_map_remove_notifer (const gchar *accel_path,
- gpointer notify_data,
- GtkAccelMapNotify notify_func)
-{
- AccelEntry *entry;
-
- g_return_if_fail (gtk_accel_path_is_valid (accel_path));
- g_return_if_fail (notify_func != NULL);
-
- entry = accel_path_lookup (accel_path);
- if (entry && entry->hooks)
- {
- GHook *hook = g_hook_find_func_data (entry->hooks, TRUE, notify_func, notify_data);
-
- if (hook && g_hook_destroy (entry->hooks, hook->hook_id))
- return; /* successfully removed */
- }
- g_warning (G_STRLOC ": no notifier %p(%p) installed for accel path \"%s\"",
- notify_func, notify_data, accel_path);
}
/**
* gtk_accel_map_lookup_entry
* @accel_path: valid accelerator path
* @key: accelerator key to be filled in (optional)
- * @returns: #GQuark for @accel_path or (0) if @accel_path is not known
+ * @returns: %TRUE if @accel_path is known, %FALSE otherwise
*
* Lookup the accelerator entry for @accel_path and fill in @key.
* If the lookup revealed no results, (0) is returned, the entry's
* #GQuark otherwise.
*/
-GQuark
+gboolean
gtk_accel_map_lookup_entry (const gchar *accel_path,
GtkAccelKey *key)
{
AccelEntry *entry;
- g_return_val_if_fail (gtk_accel_path_is_valid (accel_path), 0);
+ g_return_val_if_fail (_gtk_accel_path_is_valid (accel_path), FALSE);
entry = accel_path_lookup (accel_path);
if (entry && key)
{
key->accel_key = entry->accel_key;
key->accel_mods = entry->accel_mods;
- key->accel_flags = 0; // FIXME: global lock?
+ key->accel_flags = 0;
}
- return entry ? g_quark_try_string (entry->accel_path) : 0;
+ return entry ? TRUE : FALSE;
}
static void
@@ -340,9 +223,8 @@ internal_change_entry (const gchar *accel_path,
{
GSList *node, *slist, *win_list, *group_list, *replace_list = NULL;
GHashTable *group_hm, *win_hm;
- gboolean change_accel, removable, can_change = TRUE, seen_accel = FALSE, hooks_may_recurse = TRUE;
+ gboolean change_accel, removable, can_change = TRUE, seen_accel = FALSE;
GQuark entry_quark;
- GHook *hook;
AccelEntry *entry = accel_path_lookup (accel_path);
/* not much todo if there's no entry yet */
@@ -364,7 +246,7 @@ internal_change_entry (const gchar *accel_path,
return FALSE;
/* nobody's interested, easy going */
- if (!entry->hooks)
+ if (!entry->groups)
{
if (!simulate)
{
@@ -379,15 +261,8 @@ internal_change_entry (const gchar *accel_path,
entry_quark = g_quark_try_string (entry->accel_path);
group_hm = g_hash_table_new (NULL, NULL);
win_hm = g_hash_table_new (NULL, NULL);
- hook = g_hook_first_valid (entry->hooks, hooks_may_recurse);
- while (hook)
- {
- AccelHook *ahook = (AccelHook*) hook;
-
- if (ahook->accel_group)
- g_hash_table_insert (group_hm, ahook->accel_group, ahook->accel_group);
- hook = g_hook_next_valid (entry->hooks, hook, hooks_may_recurse);
- }
+ for (slist = entry->groups; slist; slist = slist->next)
+ g_hash_table_insert (group_hm, slist->data, slist->data);
/* 2) collect acceleratables affected */
group_list = g_hash_table_slist_values (group_hm);
@@ -408,62 +283,69 @@ internal_change_entry (const gchar *accel_path,
g_hash_table_insert (group_hm, node->data, node->data);
group_list = g_hash_table_slist_values (group_hm);
g_hash_table_destroy (group_hm);
-
+
/* 4) walk the acceleratables and figure whether they occupy accel_key&accel_mods */
- for (slist = accel_key ? win_list : NULL; slist; slist = slist->next)
- if (GTK_IS_WINDOW (slist->data)) /* bad kludge in lack of a GtkAcceleratable */
- if (_gtk_window_query_nonaccels (slist->data, accel_key, accel_mods))
- {
- seen_accel = TRUE;
- break;
- }
+ if (accel_key)
+ for (slist = win_list; slist; slist = slist->next)
+ if (GTK_IS_WINDOW (slist->data)) /* bad kludge in lack of a GtkAcceleratable */
+ if (_gtk_window_query_nonaccels (slist->data, accel_key, accel_mods))
+ {
+ seen_accel = TRUE;
+ break;
+ }
removable = !seen_accel;
-
+
/* 5) walk all accel groups and search for locks */
- for (slist = removable ? group_list : NULL; slist; slist = slist->next)
- {
- GtkAccelGroup *group = slist->data;
- GtkAccelGroupEntry *ag_entry;
- guint i, n;
-
- n = 0;
- ag_entry = entry->accel_key ? gtk_accel_group_query (group, entry->accel_key, entry->accel_mods, &n) : NULL;
- for (i = 0; i < n; i++)
- if (ag_entry[i].accel_path_quark == entry_quark)
+ if (removable)
+ for (slist = group_list; slist; slist = slist->next)
+ {
+ GtkAccelGroup *group = slist->data;
+ GtkAccelGroupEntry *ag_entry;
+ guint i, n;
+
+ n = 0;
+ ag_entry = entry->accel_key ? gtk_accel_group_query (group, entry->accel_key, entry->accel_mods, &n) : NULL;
+ for (i = 0; i < n; i++)
+ if (ag_entry[i].accel_path_quark == entry_quark)
+ {
+ can_change = !(ag_entry[i].key.accel_flags & GTK_ACCEL_LOCKED);
+ if (!can_change)
+ goto break_loop_step5;
+ }
+
+ n = 0;
+ ag_entry = accel_key ? gtk_accel_group_query (group, accel_key, accel_mods, &n) : NULL;
+ for (i = 0; i < n; i++)
{
- can_change = !(ag_entry[i].key.accel_flags & GTK_ACCEL_LOCKED);
- if (!can_change)
+ seen_accel = TRUE;
+ removable = !group->lock_count && !(ag_entry[i].key.accel_flags & GTK_ACCEL_LOCKED);
+ if (!removable)
goto break_loop_step5;
+ if (ag_entry[i].accel_path_quark)
+ replace_list = g_slist_prepend (replace_list, GUINT_TO_POINTER (ag_entry->accel_path_quark));
}
-
- n = 0;
- ag_entry = accel_key ? gtk_accel_group_query (group, accel_key, accel_mods, &n) : NULL;
- for (i = 0; i < n; i++)
- {
- seen_accel = TRUE;
- removable = !group->lock_count && !(ag_entry[i].key.accel_flags & GTK_ACCEL_LOCKED);
- if (!removable)
- goto break_loop_step5;
- if (ag_entry[i].accel_path_quark)
- replace_list = g_slist_prepend (replace_list, GUINT_TO_POINTER (ag_entry->accel_path_quark));
- }
- }
+ }
break_loop_step5:
/* 6) check whether we can remove existing accelerators */
- for (slist = removable ? replace_list : NULL; slist; slist = slist->next)
- if (!internal_change_entry (g_quark_to_string (GPOINTER_TO_UINT (slist->data)), 0, 0, FALSE, TRUE))
- {
- removable = FALSE;
- break;
- }
-
+ if (removable && can_change)
+ for (slist = replace_list; slist; slist = slist->next)
+ if (!internal_change_entry (g_quark_to_string (GPOINTER_TO_UINT (slist->data)), 0, 0, FALSE, TRUE))
+ {
+ removable = FALSE;
+ break;
+ }
+
/* 7) check conditions and proceed if possible */
change_accel = can_change && (!seen_accel || (removable && replace));
-
+
if (change_accel && !simulate)
{
guint old_accel_key, old_accel_mods;
+
+ /* ref accel groups */
+ for (slist = group_list; slist; slist = slist->next)
+ g_object_ref (slist->data);
/* 8) remove existing accelerators */
for (slist = replace_list; slist; slist = slist->next)
@@ -475,25 +357,12 @@ internal_change_entry (const gchar *accel_path,
entry->accel_key = accel_key;
entry->accel_mods = accel_mods;
entry->changed = TRUE;
- hook = g_hook_first_valid (entry->hooks, hooks_may_recurse);
- while (hook)
- {
- gboolean was_in_call, need_destroy = FALSE;
- GtkAccelMapNotify hook_func = hook->func;
- AccelHook *ahook = (AccelHook*) hook;
-
- was_in_call = G_HOOK_IN_CALL (hook);
- hook->flags |= G_HOOK_FLAG_IN_CALL;
- /* need_destroy = */ hook_func (hook->data, g_quark_try_string (entry->accel_path),
- entry->accel_key, entry->accel_mods,
- ahook->accel_group,
- old_accel_key, old_accel_mods);
- if (!was_in_call)
- hook->flags &= ~G_HOOK_FLAG_IN_CALL;
- if (need_destroy)
- g_hook_destroy_link (entry->hooks, hook);
- hook = g_hook_next_valid (entry->hooks, hook, hooks_may_recurse);
- }
+ for (slist = group_list; slist; slist = slist->next)
+ _gtk_accel_group_reconnect (slist->data, g_quark_from_string (entry->accel_path));
+
+ /* unref accel groups */
+ for (slist = group_list; slist; slist = slist->next)
+ g_object_unref (slist->data);
}
g_slist_free (replace_list);
g_slist_free (group_list);
@@ -513,12 +382,9 @@ internal_change_entry (const gchar *accel_path,
* Change the @accel_key and @accel_mods currently associated with @accel_path.
* Due to conflicts with other accelerators, a change may not alwys be possible,
* @replace indicates whether other accelerators may be deleted to resolve such
- * conflicts. A change will only occour if all conflicts could be resolved (which
- * might not be the case if conflicting accelerators are locked). Succesfull
+ * conflicts. A change will only occur if all conflicts could be resolved (which
+ * might not be the case if conflicting accelerators are locked). Succesful
* changes are indicated by a %TRUE return value.
- * Changes occouring are also indicated by invocation of notifiers attached to
- * @accel_path (see gtk_accel_map_add_notifer() on this) and other accelerators
- * that are being deleted.
*/
gboolean
gtk_accel_map_change_entry (const gchar *accel_path,
@@ -526,7 +392,7 @@ gtk_accel_map_change_entry (const gchar *accel_path,
GdkModifierType accel_mods,
gboolean replace)
{
- g_return_val_if_fail (gtk_accel_path_is_valid (accel_path), FALSE);
+ g_return_val_if_fail (_gtk_accel_path_is_valid (accel_path), FALSE);
return internal_change_entry (accel_path, accel_key, accel_key ? accel_mods : 0, replace, FALSE);
}
@@ -865,3 +731,34 @@ gtk_accel_map_add_filter (const gchar *filter_pattern)
}
accel_filters = g_slist_prepend (accel_filters, pspec);
}
+
+void
+_gtk_accel_map_add_group (const gchar *accel_path,
+ GtkAccelGroup *accel_group)
+{
+ AccelEntry *entry;
+
+ g_return_if_fail (_gtk_accel_path_is_valid (accel_path));
+ g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
+
+ entry = accel_path_lookup (accel_path);
+ if (!entry)
+ {
+ gtk_accel_map_add_entry (accel_path, 0, 0);
+ entry = accel_path_lookup (accel_path);
+ }
+ entry->groups = g_slist_prepend (entry->groups, accel_group);
+}
+
+void
+_gtk_accel_map_remove_group (const gchar *accel_path,
+ GtkAccelGroup *accel_group)
+{
+ AccelEntry *entry;
+
+ entry = accel_path_lookup (accel_path);
+ g_return_if_fail (entry != NULL);
+ g_return_if_fail (g_slist_find (entry->groups, accel_group));
+
+ entry->groups = g_slist_remove (entry->groups, accel_group);
+}
diff --git a/gtk/gtkaccelmap.h b/gtk/gtkaccelmap.h
index 99d0887ff3..7a59b2d808 100644
--- a/gtk/gtkaccelmap.h
+++ b/gtk/gtkaccelmap.h
@@ -26,13 +26,6 @@ G_BEGIN_DECLS
/* --- notifier --- */
-typedef void (*GtkAccelMapNotify) (gpointer data,
- GQuark accel_path_quark,
- guint accel_key,
- guint accel_mods,
- GtkAccelGroup *accel_group,
- guint old_accel_key,
- guint old_accel_mods);
typedef void (*GtkAccelMapForeach) (gpointer data,
const gchar *accel_path,
guint accel_key,
@@ -41,17 +34,10 @@ typedef void (*GtkAccelMapForeach) (gpointer data,
/* --- public API --- */
-GQuark gtk_accel_map_add_entry (const gchar *accel_path,
+void gtk_accel_map_add_entry (const gchar *accel_path,
guint accel_key,
guint accel_mods);
-void gtk_accel_map_add_notifer (const gchar *accel_path,
- gpointer notify_data,
- GtkAccelMapNotify notify_func,
- GtkAccelGroup *accel_group);
-void gtk_accel_map_remove_notifer (const gchar *accel_path,
- gpointer notify_data,
- GtkAccelMapNotify notify_func);
-GQuark gtk_accel_map_lookup_entry (const gchar *accel_path,
+gboolean gtk_accel_map_lookup_entry (const gchar *accel_path,
GtkAccelKey *key);
gboolean gtk_accel_map_change_entry (const gchar *accel_path,
guint accel_key,
@@ -75,6 +61,12 @@ void gtk_accel_map_foreach_unfilterd (gpointer data,
/* --- internal API --- */
void _gtk_accel_map_init (void);
+void _gtk_accel_map_add_group (const gchar *accel_path,
+ GtkAccelGroup *accel_group);
+void _gtk_accel_map_remove_group (const gchar *accel_path,
+ GtkAccelGroup *accel_group);
+gboolean _gtk_accel_path_is_valid (const gchar *accel_path);
+
G_END_DECLS
diff --git a/gtk/gtkitemfactory.c b/gtk/gtkitemfactory.c
index 02fa3df2e6..a97abae70d 100644
--- a/gtk/gtkitemfactory.c
+++ b/gtk/gtkitemfactory.c
@@ -293,7 +293,7 @@ gtk_item_factory_add_foreign (GtkWidget *accel_widget,
*/
if (gtk_signal_lookup ("activate", GTK_OBJECT_TYPE (accel_widget)))
{
- if (accel_key && accel_group)
+ if (accel_group)
{
gtk_accel_map_add_entry (full_path, accel_key, accel_mods);
_gtk_widget_set_accel_path (accel_widget, full_path, accel_group);
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c
index 375b348c40..7a066aef4f 100644
--- a/gtk/gtkmenu.c
+++ b/gtk/gtkmenu.c
@@ -133,6 +133,9 @@ static void gtk_menu_reparent (GtkMenu *menu,
static void gtk_menu_remove (GtkContainer *menu,
GtkWidget *widget);
+static void _gtk_menu_refresh_accel_paths (GtkMenu *menu,
+ gboolean group_changed);
+
static GtkMenuShellClass *parent_class = NULL;
static const gchar *attach_data_key = "gtk-menu-attach-data";
@@ -866,8 +869,8 @@ gtk_menu_get_accel_group (GtkMenu *menu)
* each menu item of this menu, that contains a label describing its purpose,
* automatically gets an accel path assigned. For example, a menu containing
* menu items "New" and "Exit", will, after gtk_menu_set_accel_path (menu,
- * "<Gnumeric-Sheet>/File"); has been called, assign its items the accel paths:
- * "<Gnumeric-Sheet>/File/New" and "<Gnumeric-Sheet>/File/Exit".
+ * "&lt;Gnumeric-Sheet&gt;/File"); has been called, assign its items the accel paths:
+ * "&lt;Gnumeric-Sheet&gt;/File/New" and "&lt;Gnumeric-Sheet&gt;/File/Exit".
* Assigning accel paths to menu items then enables the user to change
* their accelerators at runtime. More details about accelerator paths
* and their default setups can be found at gtk_accel_map_add_entry().
@@ -892,7 +895,7 @@ typedef struct {
} AccelPropagation;
static void
-refresh_accel_paths_froeach (GtkWidget *widget,
+refresh_accel_paths_foreach (GtkWidget *widget,
gpointer data)
{
AccelPropagation *prop = data;
@@ -904,7 +907,7 @@ refresh_accel_paths_froeach (GtkWidget *widget,
prop->group_changed);
}
-void
+static void
_gtk_menu_refresh_accel_paths (GtkMenu *menu,
gboolean group_changed)
{
@@ -917,7 +920,7 @@ _gtk_menu_refresh_accel_paths (GtkMenu *menu,
prop.menu = menu;
prop.group_changed = group_changed;
gtk_container_foreach (GTK_CONTAINER (menu),
- refresh_accel_paths_froeach,
+ refresh_accel_paths_foreach,
&prop);
}
}
diff --git a/gtk/gtkmenu.h b/gtk/gtkmenu.h
index 225c9a90b2..cdd858a840 100644
--- a/gtk/gtkmenu.h
+++ b/gtk/gtkmenu.h
@@ -149,8 +149,6 @@ void gtk_menu_set_accel_group (GtkMenu *menu,
GtkAccelGroup* gtk_menu_get_accel_group (GtkMenu *menu);
void gtk_menu_set_accel_path (GtkMenu *menu,
const gchar *accel_path);
-void _gtk_menu_refresh_accel_paths (GtkMenu *menu,
- gboolean group_changed);
/* A reference count is kept for a widget when it is attached to
* a particular widget. This is typically a menu item; it may also
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index b65e0d68fe..bb64921cf3 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -2615,6 +2615,8 @@ gtk_widget_add_accelerator (GtkWidget *widget,
closure = widget_new_accel_closure (widget, query.signal_id);
+ g_object_ref (widget);
+
/* install the accelerator. since we don't map this onto an accel_path,
* the accelerator will automatically be locked.
*/
@@ -2622,10 +2624,11 @@ gtk_widget_add_accelerator (GtkWidget *widget,
accel_key,
accel_mods,
accel_flags | GTK_ACCEL_LOCKED,
- closure,
- 0);
+ closure);
g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
+
+ g_object_unref (widget);
}
/**
@@ -2646,24 +2649,31 @@ gtk_widget_remove_accelerator (GtkWidget *widget,
guint accel_mods)
{
GtkAccelGroupEntry *ag_entry;
- GSList *slist;
- guint n, i;
+ GList *slist, *clist;
+ guint n;
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
g_return_val_if_fail (GTK_IS_ACCEL_GROUP (accel_group), FALSE);
ag_entry = gtk_accel_group_query (accel_group, accel_key, accel_mods, &n);
- for (slist = _gtk_widget_get_accel_closures (widget); slist; slist = slist->next)
+ clist = gtk_widget_list_accel_closures (widget);
+ for (slist = clist; slist; slist = slist->next)
{
- /* paranoid sanity checking */
+ guint i;
+
for (i = 0; i < n; i++)
if (slist->data == (gpointer) ag_entry[i].closure)
{
- gboolean is_removed = gtk_accel_groups_disconnect_closure (slist->data);
+ gboolean is_removed = gtk_accel_group_disconnect (accel_group, slist->data);
+
g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
+
+ g_list_free (clist);
+
return is_removed;
}
}
+ g_list_free (clist);
g_warning (G_STRLOC ": no accelerator (%u,%u) installed in accel group (%p) for %s (%p)",
accel_key, accel_mods, accel_group,
@@ -2672,73 +2682,48 @@ gtk_widget_remove_accelerator (GtkWidget *widget,
return FALSE;
}
-GSList*
-_gtk_widget_get_accel_closures (GtkWidget *widget)
+/**
+ * gtk_widget_list_accel_closures
+ * @widget: widget to list accelerator closures for
+ * @returns: a newly allocated #GList of closures
+ *
+ * List the closures used by @widget for accelerator group connections
+ * with gtk_accel_group_connect_by_path() or gtk_accel_group_connect().
+ * The closures can be used to monitor accelerator changes on @widget,
+ * by connecting to the ::accel_changed signal of the #GtkAccelGroup
+ * of a closure which can be found out with gtk_accel_group_from_accel_closure().
+ */
+GList*
+gtk_widget_list_accel_closures (GtkWidget *widget)
{
+ GSList *slist;
+ GList *clist = NULL;
+
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
- return g_object_get_qdata (G_OBJECT (widget), quark_accel_closures);
+ for (slist = g_object_get_qdata (G_OBJECT (widget), quark_accel_closures); slist; slist = slist->next)
+ if (gtk_accel_group_from_accel_closure (slist->data))
+ clist = g_list_prepend (clist, slist->data);
+ return clist;
}
typedef struct {
+ GQuark path_quark;
GtkWidget *widget;
GtkAccelGroup *accel_group;
- const gchar *path;
GClosure *closure;
} AccelPath;
static void
-accel_path_changed (gpointer data,
- GQuark accel_path_quark,
- guint accel_key,
- guint accel_mods,
- GtkAccelGroup *accel_group,
- guint old_accel_key,
- guint old_accel_mods)
-{
- AccelPath *apath = data;
- gboolean notify = FALSE;
-
- if (apath->closure)
- {
- /* the closure might have been removed already (due to replacements) */
- gtk_accel_groups_disconnect_closure (apath->closure);
- g_closure_unref (apath->closure);
- apath->closure = NULL;
- notify = TRUE;
- }
- if (accel_key)
- {
- apath->closure = widget_new_accel_closure (apath->widget, GTK_WIDGET_GET_CLASS (apath->widget)->activate_signal);
- g_closure_ref (apath->closure);
- /* need to specify path to get an unlocked accelerator */
- gtk_accel_group_connect (apath->accel_group,
- accel_key,
- accel_mods,
- GTK_ACCEL_VISIBLE,
- apath->closure,
- accel_path_quark);
- notify = TRUE;
- }
- if (notify)
- g_signal_emit (apath->widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
-}
-
-static void
destroy_accel_path (gpointer data)
{
AccelPath *apath = data;
- /* stop notification */
- gtk_accel_map_remove_notifer (apath->path, apath, accel_path_changed);
+ gtk_accel_group_disconnect (apath->accel_group, apath->closure);
- /* if the closure is currently connected, get rid of that connection */
- if (apath->closure)
- {
- gtk_accel_groups_disconnect_closure (apath->closure);
- g_closure_unref (apath->closure);
- }
+ /* closures_destroy takes care of unrefing the closure */
g_object_unref (apath->accel_group);
+
g_free (apath);
}
@@ -2753,25 +2738,21 @@ _gtk_widget_set_accel_path (GtkWidget *widget,
GtkAccelGroup *accel_group)
{
AccelPath *apath;
- GtkAccelKey key;
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (GTK_WIDGET_GET_CLASS (widget)->activate_signal != 0);
- if (accel_path)
- g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
if (accel_path)
{
- GQuark quark_path = gtk_accel_map_add_entry (accel_path, 0, 0);
-
- if (!quark_path)
- return; /* pathologic anyway */
+ g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
+ g_return_if_fail (_gtk_accel_path_is_valid (accel_path));
+ gtk_accel_map_add_entry (accel_path, 0, 0);
apath = g_new (AccelPath, 1);
apath->widget = widget;
apath->accel_group = g_object_ref (accel_group);
- apath->path = g_quark_to_string (quark_path);
- apath->closure = NULL;
+ apath->path_quark = g_quark_from_string (accel_path);
+ apath->closure = widget_new_accel_closure (apath->widget, GTK_WIDGET_GET_CLASS (apath->widget)->activate_signal);
}
else
apath = NULL;
@@ -2780,14 +2761,9 @@ _gtk_widget_set_accel_path (GtkWidget *widget,
g_object_set_qdata_full (G_OBJECT (widget), quark_accel_path, apath, destroy_accel_path);
if (apath)
- {
- /* setup accel path hooks to react to changes */
- gtk_accel_map_add_notifer (apath->path, apath, accel_path_changed, apath->accel_group);
+ gtk_accel_group_connect_by_path (apath->accel_group, g_quark_to_string (apath->path_quark), apath->closure);
- /* install accelerators for this path */
- if (gtk_accel_map_lookup_entry (apath->path, &key))
- accel_path_changed (apath, g_quark_try_string (apath->path), key.accel_key, key.accel_mods, NULL, 0, 0);
- }
+ g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0);
}
const gchar*
@@ -2798,7 +2774,7 @@ _gtk_widget_get_accel_path (GtkWidget *widget)
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
apath = g_object_get_qdata (G_OBJECT (widget), quark_accel_path);
- return apath ? apath->path : NULL;
+ return apath ? g_quark_to_string (apath->path_quark) : NULL;
}
gboolean
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index ee464fa436..08940458b0 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -492,7 +492,7 @@ void _gtk_widget_set_accel_path (GtkWidget *widget,
const gchar *accel_path,
GtkAccelGroup *accel_group);
const gchar* _gtk_widget_get_accel_path (GtkWidget *widget);
-GSList* _gtk_widget_get_accel_closures (GtkWidget *widget);
+GList* gtk_widget_list_accel_closures (GtkWidget *widget);
gboolean gtk_widget_mnemonic_activate (GtkWidget *widget,
gboolean group_cycling);
gboolean gtk_widget_event (GtkWidget *widget,
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 27c5eed10d..1039a577ea 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -46,7 +46,7 @@ enum {
ACTIVATE_FOCUS,
ACTIVATE_DEFAULT,
MOVE_FOCUS,
- ACCELS_CHANGED,
+ KEYS_CHANGED,
LAST_SIGNAL
};
@@ -222,7 +222,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 void gtk_window_notify_keys_changed (GtkWindow *window);
static GSList *toplevel_list = NULL;
static GHashTable *mnemonic_hash_table = NULL;
@@ -350,7 +350,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;
+ klass->keys_changed = NULL;
/* Construct */
g_object_class_install_property (gobject_class,
@@ -500,11 +500,11 @@ gtk_window_class_init (GtkWindowClass *klass)
1,
GTK_TYPE_DIRECTION_TYPE);
- window_signals[ACCELS_CHANGED] =
- g_signal_new ("accels_changed",
+ window_signals[KEYS_CHANGED] =
+ g_signal_new ("keys_changed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
- GTK_SIGNAL_OFFSET (GtkWindowClass, accels_changed),
+ GTK_SIGNAL_OFFSET (GtkWindowClass, keys_changed),
NULL, NULL,
gtk_marshal_VOID__VOID,
G_TYPE_NONE,
@@ -1042,30 +1042,30 @@ gtk_window_set_policy (GtkWindow *window,
}
static gboolean
-handle_accels_changed (gpointer data)
+handle_keys_changed (gpointer data)
{
GtkWindow *window;
GDK_THREADS_ENTER ();
window = GTK_WINDOW (data);
- if (window->accels_changed_handler)
+ if (window->keys_changed_handler)
{
- gtk_idle_remove (window->accels_changed_handler);
- window->accels_changed_handler = 0;
+ gtk_idle_remove (window->keys_changed_handler);
+ window->keys_changed_handler = 0;
}
- g_signal_emit (window, window_signals[ACCELS_CHANGED], 0);
+ g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
GDK_THREADS_LEAVE ();
return FALSE;
}
static void
-gtk_window_notify_accels_changed (GtkWindow *window)
+gtk_window_notify_keys_changed (GtkWindow *window)
{
- if (!window->accels_changed_handler)
- window->accels_changed_handler = gtk_idle_add (handle_accels_changed, window);
+ if (!window->keys_changed_handler)
+ window->keys_changed_handler = gtk_idle_add (handle_keys_changed, window);
}
/**
@@ -1078,15 +1078,15 @@ gtk_window_notify_accels_changed (GtkWindow *window)
* in @accel_group.
**/
void
-gtk_window_add_accel_group (GtkWindow *window,
- GtkAccelGroup *accel_group)
+gtk_window_add_accel_group (GtkWindow *window,
+ GtkAccelGroup *accel_group)
{
g_return_if_fail (GTK_IS_WINDOW (window));
- g_return_if_fail (accel_group != NULL);
+ g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
_gtk_accel_group_attach (accel_group, G_OBJECT (window));
g_signal_connect_object (accel_group, "accel_changed",
- G_CALLBACK (gtk_window_notify_accels_changed),
+ G_CALLBACK (gtk_window_notify_keys_changed),
window, G_CONNECT_SWAPPED);
}
@@ -1098,14 +1098,14 @@ gtk_window_add_accel_group (GtkWindow *window,
* Reverses the effects of gtk_window_add_accel_group().
**/
void
-gtk_window_remove_accel_group (GtkWindow *window,
- GtkAccelGroup *accel_group)
+gtk_window_remove_accel_group (GtkWindow *window,
+ GtkAccelGroup *accel_group)
{
g_return_if_fail (GTK_IS_WINDOW (window));
g_return_if_fail (accel_group != NULL);
g_signal_handlers_disconnect_by_func (accel_group,
- G_CALLBACK (gtk_window_notify_accels_changed),
+ G_CALLBACK (gtk_window_notify_keys_changed),
window);
_gtk_accel_group_detach (accel_group, G_OBJECT (window));
}
@@ -1137,7 +1137,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);
+ gtk_window_notify_keys_changed (window);
}
void
@@ -1163,7 +1163,7 @@ gtk_window_remove_mnemonic (GtkWindow *window,
g_hash_table_remove (mnemonic_hash_table, mnemonic);
g_free (mnemonic);
}
- gtk_window_notify_accels_changed (window);
+ gtk_window_notify_keys_changed (window);
}
gboolean
@@ -1231,7 +1231,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);
+ gtk_window_notify_keys_changed (window);
}
/**
@@ -2929,10 +2929,10 @@ gtk_window_finalize (GObject *object)
g_free (window->geometry_info);
}
- if (window->accels_changed_handler)
+ if (window->keys_changed_handler)
{
- gtk_idle_remove (window->accels_changed_handler);
- window->accels_changed_handler = 0;
+ gtk_idle_remove (window->keys_changed_handler);
+ window->keys_changed_handler = 0;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
diff --git a/gtk/gtkwindow.h b/gtk/gtkwindow.h
index 3a6dd6de9e..2ebfaea759 100644
--- a/gtk/gtkwindow.h
+++ b/gtk/gtkwindow.h
@@ -105,7 +105,7 @@ struct _GtkWindow
guint frame_right;
guint frame_bottom;
- guint accels_changed_handler;
+ guint keys_changed_handler;
GdkModifierType mnemonic_modifier;
gpointer gtk_reserved1; /* For future GdkScreen * */
@@ -126,7 +126,7 @@ struct _GtkWindowClass
void (* activate_default) (GtkWindow *window);
void (* move_focus) (GtkWindow *window,
GtkDirectionType direction);
- void (*accels_changed) (GtkWindow *window);
+ void (*keys_changed) (GtkWindow *window);
};
#define GTK_TYPE_WINDOW_GROUP (gtk_window_group_get_type ())