From ba9fc7aead9a1a8e18e12dcf15a44e234b0e12d0 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Fri, 24 Aug 2018 07:34:23 +0200 Subject: [PATCH] widget: Remove gtk_widget_add_accelerator() People should use shortcut controllers instead (global, capture). A side effect of this is that GtkMenuItem (or rather: GtkAccelLabel) now lost its method to magically look up accelerators to display. Somebody needs to add that back later. --- docs/reference/gtk/gtk4-sections.txt | 3 - gtk/gtkaccellabel.c | 13 +- gtk/gtkmenuitem.c | 46 ---- gtk/gtkwidget.c | 366 +-------------------------- gtk/gtkwidget.h | 14 - gtk/gtkwidgetprivate.h | 3 - 6 files changed, 2 insertions(+), 443 deletions(-) diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt index a60bd59e2d..e518bf6e3f 100644 --- a/docs/reference/gtk/gtk4-sections.txt +++ b/docs/reference/gtk/gtk4-sections.txt @@ -4404,9 +4404,6 @@ gtk_widget_allocate gtk_widget_class_add_shortcut gtk_widget_class_add_binding gtk_widget_class_add_binding_signal -gtk_widget_add_accelerator -gtk_widget_remove_accelerator -gtk_widget_list_accel_closures gtk_widget_can_activate_accel gtk_widget_event gtk_widget_activate diff --git a/gtk/gtkaccellabel.c b/gtk/gtkaccellabel.c index 3ab681af10..e14f41e537 100644 --- a/gtk/gtkaccellabel.c +++ b/gtk/gtkaccellabel.c @@ -380,22 +380,11 @@ static void refetch_widget_accel_closure (GtkAccelLabel *accel_label) { GtkAccelLabelPrivate *priv = gtk_accel_label_get_instance_private (accel_label); - GClosure *closure = NULL; - GList *clist, *list; g_return_if_fail (GTK_IS_ACCEL_LABEL (accel_label)); g_return_if_fail (GTK_IS_WIDGET (priv->accel_widget)); - clist = gtk_widget_list_accel_closures (priv->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); + gtk_accel_label_set_accel_closure (accel_label, NULL); } static void diff --git a/gtk/gtkmenuitem.c b/gtk/gtkmenuitem.c index 578802a731..707b8756b0 100644 --- a/gtk/gtkmenuitem.c +++ b/gtk/gtkmenuitem.c @@ -192,11 +192,6 @@ static void gtk_menu_item_buildable_add_child (GtkBuildable *buildab GtkBuilder *builder, GObject *child, const gchar *type); -static void gtk_menu_item_buildable_custom_finished(GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *tagname, - gpointer user_data); static void gtk_menu_item_actionable_interface_init (GtkActionableInterface *iface); @@ -825,7 +820,6 @@ gtk_menu_item_buildable_interface_init (GtkBuildableIface *iface) { parent_buildable_iface = g_type_interface_peek_parent (iface); iface->add_child = gtk_menu_item_buildable_add_child; - iface->custom_finished = gtk_menu_item_buildable_custom_finished; } static void @@ -841,46 +835,6 @@ gtk_menu_item_buildable_add_child (GtkBuildable *buildable, parent_buildable_iface->add_child (buildable, builder, child, type); } - -static void -gtk_menu_item_buildable_custom_finished (GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *tagname, - gpointer user_data) -{ - GtkWidget *toplevel; - - if (strcmp (tagname, "accelerator") == 0) - { - GtkMenuShell *menu_shell; - GtkWidget *attach; - - menu_shell = gtk_menu_item_get_menu_shell (GTK_MENU_ITEM (buildable)); - if (menu_shell) - { - while (GTK_IS_MENU (menu_shell) && - (attach = gtk_menu_get_attach_widget (GTK_MENU (menu_shell))) != NULL) - menu_shell = GTK_MENU_SHELL (gtk_widget_get_parent (attach)); - - toplevel = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (menu_shell))); - } - else - { - /* Fall back to something ... */ - toplevel = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (buildable))); - - g_warning ("found a GtkMenuItem '%s' without a parent GtkMenuShell, assigned accelerators wont work.", - gtk_buildable_get_name (buildable)); - } - - /* Feed the correct toplevel to the GtkWidget accelerator parsing code */ - _gtk_widget_buildable_finish_accelerator (GTK_WIDGET (buildable), toplevel, user_data); - } - else - parent_buildable_iface->custom_finished (buildable, builder, child, tagname, user_data); -} - static void update_arrow_classes (GtkMenuItem *menu_item) { diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index c7ee36bc72..5e0af7b417 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -724,7 +724,6 @@ static gpointer gtk_widget_parent_class = NULL; static guint widget_signals[LAST_SIGNAL] = { 0 }; GtkTextDirection gtk_default_direction = GTK_TEXT_DIR_LTR; -static GQuark quark_accel_closures = 0; static GQuark quark_input_shape_info = 0; static GQuark quark_pango_context = 0; static GQuark quark_mnemonic_labels = 0; @@ -910,7 +909,6 @@ gtk_widget_class_init (GtkWidgetClass *klass) g_type_class_adjust_private_offset (klass, &GtkWidget_private_offset); gtk_widget_parent_class = g_type_class_peek_parent (klass); - quark_accel_closures = g_quark_from_static_string ("gtk-accel-closures"); quark_input_shape_info = g_quark_from_static_string ("gtk-input-shape-info"); quark_pango_context = g_quark_from_static_string ("gtk-pango-context"); quark_mnemonic_labels = g_quark_from_static_string ("gtk-mnemonic-labels"); @@ -4984,216 +4982,6 @@ gtk_widget_can_activate_accel (GtkWidget *widget, return can_activate; } -typedef struct { - GClosure closure; - guint signal_id; -} AccelClosure; - -static void -closure_accel_activate (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) -{ - AccelClosure *aclosure = (AccelClosure*) closure; - gboolean can_activate = gtk_widget_can_activate_accel (closure->data, aclosure->signal_id); - - if (can_activate) - g_signal_emit (closure->data, aclosure->signal_id, 0); - - /* whether accelerator was handled */ - g_value_set_boolean (return_value, can_activate); -} - -static void -closures_destroy (gpointer data) -{ - GSList *slist, *closures = data; - - for (slist = closures; slist; slist = slist->next) - { - g_closure_invalidate (slist->data); - g_closure_unref (slist->data); - } - g_slist_free (closures); -} - -static GClosure* -widget_new_accel_closure (GtkWidget *widget, - guint signal_id) -{ - AccelClosure *aclosure; - GClosure *closure = NULL; - GSList *slist, *closures; - - closures = g_object_steal_qdata (G_OBJECT (widget), quark_accel_closures); - for (slist = closures; slist; slist = slist->next) - if (!gtk_accel_group_from_accel_closure (slist->data)) - { - /* reuse this closure */ - closure = slist->data; - break; - } - if (!closure) - { - closure = g_closure_new_object (sizeof (AccelClosure), G_OBJECT (widget)); - closures = g_slist_prepend (closures, g_closure_ref (closure)); - g_closure_sink (closure); - g_closure_set_marshal (closure, closure_accel_activate); - } - g_object_set_qdata_full (G_OBJECT (widget), quark_accel_closures, closures, closures_destroy); - - aclosure = (AccelClosure*) closure; - g_assert (closure->data == widget); - g_assert (closure->marshal == closure_accel_activate); - aclosure->signal_id = signal_id; - - return closure; -} - -/** - * gtk_widget_add_accelerator: - * @widget: widget to install an accelerator on - * @accel_signal: widget signal to emit on accelerator activation - * @accel_group: accel group for this widget, added to its toplevel - * @accel_key: GDK keyval of the accelerator - * @accel_mods: modifier key combination of the accelerator - * @accel_flags: flag accelerators, e.g. %GTK_ACCEL_VISIBLE - * - * Installs an accelerator for this @widget in @accel_group that causes - * @accel_signal to be emitted if the accelerator is activated. - * The @accel_group needs to be added to the widget’s toplevel via - * gtk_window_add_accel_group(), and the signal must be of type %G_SIGNAL_ACTION. - * Accelerators added through this function are not user changeable during - * runtime. - */ -void -gtk_widget_add_accelerator (GtkWidget *widget, - const gchar *accel_signal, - GtkAccelGroup *accel_group, - guint accel_key, - GdkModifierType accel_mods, - GtkAccelFlags accel_flags) -{ - GClosure *closure; - GSignalQuery query; - - g_return_if_fail (GTK_IS_WIDGET (widget)); - g_return_if_fail (accel_signal != NULL); - g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group)); - - g_signal_query (g_signal_lookup (accel_signal, G_OBJECT_TYPE (widget)), &query); - if (!query.signal_id || - !(query.signal_flags & G_SIGNAL_ACTION) || - query.return_type != G_TYPE_NONE || - query.n_params) - { - /* hmm, should be elaborate enough */ - g_warning (G_STRLOC ": widget '%s' has no activatable signal \"%s\" without arguments", - G_OBJECT_TYPE_NAME (widget), accel_signal); - return; - } - - 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. - */ - gtk_accel_group_connect (accel_group, - accel_key, - accel_mods, - accel_flags | GTK_ACCEL_LOCKED, - closure); - - g_signal_emit (widget, widget_signals[ACCEL_CLOSURES_CHANGED], 0); - - g_object_unref (widget); -} - -/** - * gtk_widget_remove_accelerator: - * @widget: widget to install an accelerator on - * @accel_group: accel group for this widget - * @accel_key: GDK keyval of the accelerator - * @accel_mods: modifier key combination of the accelerator - * - * Removes an accelerator from @widget, previously installed with - * gtk_widget_add_accelerator(). - * - * Returns: whether an accelerator was installed and could be removed - */ -gboolean -gtk_widget_remove_accelerator (GtkWidget *widget, - GtkAccelGroup *accel_group, - guint accel_key, - GdkModifierType accel_mods) -{ - GtkAccelGroupEntry *ag_entry; - 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); - clist = gtk_widget_list_accel_closures (widget); - for (slist = clist; slist; slist = slist->next) - { - guint i; - - for (i = 0; i < n; i++) - if (slist->data == (gpointer) ag_entry[i].closure) - { - 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, - G_OBJECT_TYPE_NAME (widget), widget); - - return FALSE; -} - -/** - * gtk_widget_list_accel_closures: - * @widget: widget to list accelerator closures for - * - * Lists 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 @GtkAccelGroup::accel-changed signal of the - * #GtkAccelGroup of a closure which can be found out with - * gtk_accel_group_from_accel_closure(). - * - * Returns: (transfer container) (element-type GClosure): - * a newly allocated #GList of closures - */ -GList* -gtk_widget_list_accel_closures (GtkWidget *widget) -{ - GSList *slist; - GList *clist = NULL; - - g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); - - 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; -} - /** * gtk_widget_mnemonic_activate: * @widget: a #GtkWidget @@ -8155,9 +7943,6 @@ gtk_widget_real_destroy (GtkWidget *object) priv->accessible = NULL; } - /* wipe accelerator closures (keep order) */ - g_object_set_qdata (G_OBJECT (widget), quark_accel_closures, NULL); - /* Callers of add_mnemonic_label() should disconnect on ::destroy */ g_object_set_qdata (G_OBJECT (widget), quark_mnemonic_labels, NULL); @@ -9738,90 +9523,6 @@ static const GMarkupParser accessibility_parser = accessibility_text, }; -typedef struct -{ - GObject *object; - GtkBuilder *builder; - guint key; - guint modifiers; - gchar *signal; -} AccelGroupParserData; - -static void -accel_group_start_element (GMarkupParseContext *context, - const gchar *element_name, - const gchar **names, - const gchar **values, - gpointer user_data, - GError **error) -{ - AccelGroupParserData *data = (AccelGroupParserData*)user_data; - - if (strcmp (element_name, "accelerator") == 0) - { - const gchar *key_str = NULL; - const gchar *signal = NULL; - const gchar *modifiers_str = NULL; - guint key = 0; - guint modifiers = 0; - - if (!_gtk_builder_check_parent (data->builder, context, "object", error)) - return; - - if (!g_markup_collect_attributes (element_name, names, values, error, - G_MARKUP_COLLECT_STRING, "key", &key_str, - G_MARKUP_COLLECT_STRING, "signal", &signal, - G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "modifiers", &modifiers_str, - G_MARKUP_COLLECT_INVALID)) - { - _gtk_builder_prefix_error (data->builder, context, error); - return; - } - - key = gdk_keyval_from_name (key_str); - if (key == 0) - { - g_set_error (error, - GTK_BUILDER_ERROR, GTK_BUILDER_ERROR_INVALID_VALUE, - "Could not parse key '%s'", key_str); - _gtk_builder_prefix_error (data->builder, context, error); - return; - } - - if (modifiers_str != NULL) - { - GFlagsValue aliases[2] = { - { 0, "primary", "primary" }, - { 0, NULL, NULL } - }; - - aliases[0].value = _gtk_get_primary_accel_mod (); - - if (!_gtk_builder_flags_from_string (GDK_TYPE_MODIFIER_TYPE, aliases, - modifiers_str, &modifiers, error)) - { - _gtk_builder_prefix_error (data->builder, context, error); - return; - } - } - - data->key = key; - data->modifiers = modifiers; - data->signal = g_strdup (signal); - } - else - { - _gtk_builder_error_unhandled_tag (data->builder, context, - "GtkWidget", element_name, - error); - } -} - -static const GMarkupParser accel_group_parser = - { - accel_group_start_element, - }; - typedef struct { GtkBuilder *builder; @@ -10024,20 +9725,6 @@ gtk_widget_buildable_custom_tag_start (GtkBuildable *buildable, GMarkupParser *parser, gpointer *parser_data) { - if (strcmp (tagname, "accelerator") == 0) - { - AccelGroupParserData *data; - - data = g_slice_new0 (AccelGroupParserData); - data->object = (GObject *)g_object_ref (buildable); - data->builder = builder; - - *parser = accel_group_parser; - *parser_data = data; - - return TRUE; - } - if (strcmp (tagname, "accessibility") == 0) { AccessibilitySubParserData *data; @@ -10090,45 +9777,6 @@ gtk_widget_buildable_custom_tag_end (GtkBuildable *buildable, { } -void -_gtk_widget_buildable_finish_accelerator (GtkWidget *widget, - GtkWidget *toplevel, - gpointer user_data) -{ - AccelGroupParserData *accel_data; - GSList *accel_groups; - GtkAccelGroup *accel_group; - - g_return_if_fail (GTK_IS_WIDGET (widget)); - g_return_if_fail (GTK_IS_WIDGET (toplevel)); - g_return_if_fail (user_data != NULL); - - accel_data = (AccelGroupParserData*)user_data; - accel_groups = gtk_accel_groups_from_object (G_OBJECT (toplevel)); - if (g_slist_length (accel_groups) == 0) - { - accel_group = gtk_accel_group_new (); - if (GTK_IS_WINDOW (toplevel)) - gtk_window_add_accel_group (GTK_WINDOW (toplevel), accel_group); - } - else - { - g_assert (g_slist_length (accel_groups) == 1); - accel_group = g_slist_nth_data (accel_groups, 0); - } - - gtk_widget_add_accelerator (GTK_WIDGET (accel_data->object), - accel_data->signal, - accel_group, - accel_data->key, - accel_data->modifiers, - GTK_ACCEL_VISIBLE); - - g_object_unref (accel_data->object); - g_free (accel_data->signal); - g_slice_free (AccelGroupParserData, accel_data); -} - static void gtk_widget_buildable_finish_layout_properties (GtkWidget *widget, GtkWidget *parent, @@ -10202,19 +9850,7 @@ gtk_widget_buildable_custom_finished (GtkBuildable *buildable, const gchar *tagname, gpointer user_data) { - if (strcmp (tagname, "accelerator") == 0) - { - AccelGroupParserData *accel_data; - GtkRoot *root; - - accel_data = (AccelGroupParserData*)user_data; - g_assert (accel_data->object); - - root = _gtk_widget_get_root (GTK_WIDGET (accel_data->object)); - - _gtk_widget_buildable_finish_accelerator (GTK_WIDGET (buildable), GTK_WIDGET (root), user_data); - } - else if (strcmp (tagname, "accessibility") == 0) + if (strcmp (tagname, "accessibility") == 0) { AccessibilitySubParserData *a11y_data; diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index 926cf2a588..05be13b42c 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -442,20 +442,6 @@ GDK_AVAILABLE_IN_ALL void gtk_widget_class_add_shortcut (GtkWidgetClass *widget_class, GtkShortcut *shortcut); -GDK_AVAILABLE_IN_ALL -void gtk_widget_add_accelerator (GtkWidget *widget, - const gchar *accel_signal, - GtkAccelGroup *accel_group, - guint accel_key, - GdkModifierType accel_mods, - GtkAccelFlags accel_flags); -GDK_AVAILABLE_IN_ALL -gboolean gtk_widget_remove_accelerator (GtkWidget *widget, - GtkAccelGroup *accel_group, - guint accel_key, - GdkModifierType accel_mods); -GDK_AVAILABLE_IN_ALL -GList* gtk_widget_list_accel_closures (GtkWidget *widget); GDK_AVAILABLE_IN_ALL gboolean gtk_widget_can_activate_accel (GtkWidget *widget, guint signal_id); diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h index dd56f60a9c..96c61f5ef1 100644 --- a/gtk/gtkwidgetprivate.h +++ b/gtk/gtkwidgetprivate.h @@ -276,9 +276,6 @@ void _gtk_widget_synthesize_crossing (GtkWidget *fro GdkDevice *device, GdkCrossingMode mode); -void _gtk_widget_buildable_finish_accelerator (GtkWidget *widget, - GtkWidget *toplevel, - gpointer user_data); GtkStyleContext * _gtk_widget_peek_style_context (GtkWidget *widget); typedef gboolean (*GtkCapturedEventHandler) (GtkWidget *widget, GdkEvent *event);