diff options
| author | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2026-06-11 20:54:41 +0200 |
|---|---|---|
| committer | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2026-06-11 20:54:41 +0200 |
| commit | f33cda5c57dab104163fe6884e2e15f3bac79c07 (patch) | |
| tree | 28eea2f0fc5bdde3430b1c20030cb3664eaeadec | |
| parent | 4fd46b91b1b9935ed14a8aae5873906574d60684 (diff) | |
| download | qmenumodel-f33cda5c57dab104163fe6884e2e15f3bac79c07.tar.gz qmenumodel-f33cda5c57dab104163fe6884e2e15f3bac79c07.tar.bz2 qmenumodel-f33cda5c57dab104163fe6884e2e15f3bac79c07.zip | |
Revert "src/gtk Update gtk part to version 3.24.8"
This reverts commit ceaa2df6e9f96245a0e99edeb29a8b28c39c79b1.
| -rw-r--r-- | libqmenumodel/src/ayatanamenumodel.cpp | 23 | ||||
| -rw-r--r-- | libqmenumodel/src/gtk/gtkactionmuxer.c | 211 | ||||
| -rw-r--r-- | libqmenumodel/src/gtk/gtkactionmuxer.h | 17 | ||||
| -rw-r--r-- | libqmenumodel/src/gtk/gtkactionobserver.c | 40 | ||||
| -rw-r--r-- | libqmenumodel/src/gtk/gtkactionobserver.h | 8 | ||||
| -rw-r--r-- | libqmenumodel/src/gtk/gtkmenutracker.c | 245 | ||||
| -rw-r--r-- | libqmenumodel/src/gtk/gtkmenutracker.h | 12 | ||||
| -rw-r--r-- | libqmenumodel/src/gtk/gtkmenutrackeritem.c | 370 | ||||
| -rw-r--r-- | libqmenumodel/src/gtk/gtkmenutrackeritem.h | 28 |
9 files changed, 206 insertions, 748 deletions
diff --git a/libqmenumodel/src/ayatanamenumodel.cpp b/libqmenumodel/src/ayatanamenumodel.cpp index 265309d..9ab0ff4 100644 --- a/libqmenumodel/src/ayatanamenumodel.cpp +++ b/libqmenumodel/src/ayatanamenumodel.cpp @@ -210,16 +210,9 @@ void AyatanaMenuModelPrivate::updateMenuModel() GDBusMenuModel *menu; menu = g_dbus_menu_model_get (this->connection, this->nameOwner, this->menuObjectPath.constData()); - this->menutracker = gtk_menu_tracker_new(GTK_ACTION_OBSERVABLE (this->muxer), - G_MENU_MODEL (menu), - TRUE, - FALSE, - FALSE, - NULL, - NULL, - menuItemInserted, - menuItemRemoved, - this); + this->menutracker = gtk_menu_tracker_new (GTK_ACTION_OBSERVABLE (this->muxer), + G_MENU_MODEL (menu), TRUE, NULL, + menuItemInserted, menuItemRemoved, this); g_object_unref (menu); } @@ -506,7 +499,7 @@ QVariant AyatanaMenuModel::data(const QModelIndex &index, int role) const return QKeySequence(gtk_menu_tracker_item_get_accel (item), QKeySequence::NativeText); case HasSubmenuRole: - return gtk_menu_tracker_item_get_has_link (item, G_MENU_LINK_SUBMENU) != FALSE; + return gtk_menu_tracker_item_get_has_submenu (item) != FALSE; default: return QVariant(); @@ -556,7 +549,7 @@ QObject * AyatanaMenuModel::submenu(int position, QQmlComponent* actionStatePars } item = (GtkMenuTrackerItem *) g_sequence_get (it); - if (!item || !gtk_menu_tracker_item_get_has_link (item, G_MENU_LINK_SUBMENU)) { + if (!item || !gtk_menu_tracker_item_get_has_submenu (item)) { return NULL; } @@ -571,14 +564,10 @@ QObject * AyatanaMenuModel::submenu(int position, QQmlComponent* actionStatePars } } - model->priv->menutracker = gtk_menu_tracker_new_for_item_link (item, - G_MENU_LINK_SUBMENU, - FALSE, - FALSE, + model->priv->menutracker = gtk_menu_tracker_new_for_item_submenu (item, AyatanaMenuModelPrivate::menuItemInserted, AyatanaMenuModelPrivate::menuItemRemoved, model->priv); - g_object_set_qdata (G_OBJECT (item), ayatana_submenu_model_quark (), model); } diff --git a/libqmenumodel/src/gtk/gtkactionmuxer.c b/libqmenumodel/src/gtk/gtkactionmuxer.c index 3080b4b..4618564 100644 --- a/libqmenumodel/src/gtk/gtkactionmuxer.c +++ b/libqmenumodel/src/gtk/gtkactionmuxer.c @@ -26,7 +26,7 @@ #include <string.h> -/*< private > +/** * SECTION:gtkactionmuxer * @short_description: Aggregate and monitor several action groups * @@ -37,19 +37,19 @@ * particular context into a single action group, with namespacing. * * Consider the case of two action groups -- one containing actions - * applicable to an entire application (such as “quit”) and one + * applicable to an entire application (such as 'quit') and one * containing actions applicable to a particular window in the - * application (such as “fullscreen”). + * application (such as 'fullscreen'). * * In this case, each of these action groups could be added to a - * #GtkActionMuxer with the prefixes “app” and “win”, respectively. This - * would expose the actions as “app.quit” and “win.fullscreen” on the + * #GtkActionMuxer with the prefixes "app" and "win", respectively. This + * would expose the actions as "app.quit" and "win.fullscreen" on the * #GActionGroup interface presented by the #GtkActionMuxer. * * Activations and state change requests on the #GtkActionMuxer are wired * through to the underlying action group in the expected way. * - * This class is typically only used at the site of “consumption” of + * This class is typically only used at the site of "consumption" of * actions (eg: when displaying a menu that contains many actions on * different objects). */ @@ -65,7 +65,6 @@ struct _GtkActionMuxer GHashTable *observed_actions; GHashTable *groups; - GHashTable *primary_accels; GtkActionMuxer *parent; }; @@ -82,8 +81,6 @@ enum static GParamSpec *properties[NUM_PROPERTIES]; -guint accel_signal; - typedef struct { GtkActionMuxer *muxer; @@ -137,7 +134,7 @@ gtk_action_muxer_list_actions (GActionGroup *action_group) actions); } - return (gchar **)(void *) g_array_free (actions, FALSE); + return (gchar **) g_array_free (actions, FALSE); } static Group * @@ -336,39 +333,6 @@ gtk_action_muxer_action_removed_from_parent (GActionGroup *action_group, gtk_action_muxer_action_removed (muxer, action_name); } -static void -gtk_action_muxer_primary_accel_changed (GtkActionMuxer *muxer, - const gchar *action_name, - const gchar *action_and_target) -{ - Action *action; - GSList *node; - - if (!action_name) - action_name = strrchr (action_and_target, '|') + 1; - - action = g_hash_table_lookup (muxer->observed_actions, action_name); - for (node = action ? action->watchers : NULL; node; node = node->next) - gtk_action_observer_primary_accel_changed (node->data, GTK_ACTION_OBSERVABLE (muxer), - action_name, action_and_target); - g_signal_emit (muxer, accel_signal, 0, action_name, action_and_target); -} - -static void -gtk_action_muxer_parent_primary_accel_changed (GtkActionMuxer *parent, - const gchar *action_name, - const gchar *action_and_target, - gpointer user_data) -{ - GtkActionMuxer *muxer = user_data; - - /* If it's in our table then don't let the parent one filter through */ - if (muxer->primary_accels && g_hash_table_lookup (muxer->primary_accels, action_and_target)) - return; - - gtk_action_muxer_primary_accel_changed (muxer, action_name, action_and_target); -} - static gboolean gtk_action_muxer_query_action (GActionGroup *action_group, const gchar *action_name, @@ -534,8 +498,6 @@ gtk_action_muxer_finalize (GObject *object) g_assert_cmpint (g_hash_table_size (muxer->observed_actions), ==, 0); g_hash_table_unref (muxer->observed_actions); g_hash_table_unref (muxer->groups); - if (muxer->primary_accels) - g_hash_table_unref (muxer->primary_accels); G_OBJECT_CLASS (gtk_action_muxer_parent_class) ->finalize (object); @@ -552,7 +514,6 @@ gtk_action_muxer_dispose (GObject *object) g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_action_removed_from_parent, muxer); g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_parent_action_enabled_changed, muxer); g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_parent_action_state_changed, muxer); - g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_parent_primary_accel_changed, muxer); g_clear_object (&muxer->parent); } @@ -632,9 +593,6 @@ gtk_action_muxer_class_init (GObjectClass *class) class->finalize = gtk_action_muxer_finalize; class->dispose = gtk_action_muxer_dispose; - accel_signal = g_signal_new ("primary-accel-changed", GTK_TYPE_ACTION_MUXER, G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); - properties[PROP_PARENT] = g_param_spec_object ("parent", "Parent", "The parent muxer", GTK_TYPE_ACTION_MUXER, @@ -644,7 +602,7 @@ gtk_action_muxer_class_init (GObjectClass *class) g_object_class_install_properties (class, NUM_PROPERTIES, properties); } -/*< private > +/** * gtk_action_muxer_insert: * @muxer: a #GtkActionMuxer * @prefix: the prefix string for the action group @@ -652,15 +610,15 @@ gtk_action_muxer_class_init (GObjectClass *class) * * Adds the actions in @action_group to the list of actions provided by * @muxer. @prefix is prefixed to each action name, such that for each - * action `x` in @action_group, there is an equivalent - * action @prefix`.x` in @muxer. + * action <varname>x</varname> in @action_group, there is an equivalent + * action @prefix<literal>.</literal><varname>x</varname> in @muxer. * - * For example, if @prefix is “`app`” and @action_group - * contains an action called “`quit`”, then @muxer will - * now contain an action called “`app.quit`”. + * For example, if @prefix is "<literal>app</literal>" and @action_group + * contains an action called "<literal>quit</literal>", then @muxer will + * now contain an action called "<literal>app.quit</literal>". * * If any #GtkActionObservers are registered for actions in the group, - * “action_added” notifications will be emitted, as appropriate. + * "action_added" notifications will be emitted, as appropriate. * * @prefix must not contain a dot ('.'). */ @@ -698,7 +656,7 @@ gtk_action_muxer_insert (GtkActionMuxer *muxer, G_CALLBACK (gtk_action_muxer_group_action_state_changed), group); } -/*< private > +/** * gtk_action_muxer_remove: * @muxer: a #GtkActionMuxer * @prefix: the prefix of the action group to remove @@ -706,7 +664,7 @@ gtk_action_muxer_insert (GtkActionMuxer *muxer, * Removes a #GActionGroup from the #GtkActionMuxer. * * If any #GtkActionObservers are registered for actions in the group, - * “action_removed” notifications will be emitted, as appropriate. + * "action_removed" notifications will be emitted, as appropriate. */ void gtk_action_muxer_remove (GtkActionMuxer *muxer, @@ -732,27 +690,7 @@ gtk_action_muxer_remove (GtkActionMuxer *muxer, } } -const gchar ** -gtk_action_muxer_list_prefixes (GtkActionMuxer *muxer) -{ - return (const gchar **) g_hash_table_get_keys_as_array (muxer->groups, NULL); -} - -GActionGroup * -gtk_action_muxer_lookup (GtkActionMuxer *muxer, - const gchar *prefix) -{ - Group *group; - - group = g_hash_table_lookup (muxer->groups, prefix); - - if (group != NULL) - return group->group; - - return NULL; -} - -/*< private > +/** * gtk_action_muxer_new: * * Creates a new #GtkActionMuxer. @@ -763,7 +701,7 @@ gtk_action_muxer_new (void) return g_object_new (GTK_TYPE_ACTION_MUXER, NULL); } -/*< private > +/** * gtk_action_muxer_get_parent: * @muxer: a #GtkActionMuxer * @@ -777,27 +715,7 @@ gtk_action_muxer_get_parent (GtkActionMuxer *muxer) return muxer->parent; } -static void -emit_changed_accels (GtkActionMuxer *muxer, - GtkActionMuxer *parent) -{ - while (parent) - { - if (parent->primary_accels) - { - GHashTableIter iter; - gpointer key; - - g_hash_table_iter_init (&iter, parent->primary_accels); - while (g_hash_table_iter_next (&iter, &key, NULL)) - gtk_action_muxer_primary_accel_changed (muxer, NULL, key); - } - - parent = parent->parent; - } -} - -/*< private > +/** * gtk_action_muxer_set_parent: * @muxer: a #GtkActionMuxer * @parent: (allow-none): the new parent #GtkActionMuxer @@ -824,13 +742,10 @@ gtk_action_muxer_set_parent (GtkActionMuxer *muxer, gtk_action_muxer_action_removed (muxer, *it); g_strfreev (actions); - emit_changed_accels (muxer, muxer->parent); - g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_action_added_to_parent, muxer); g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_action_removed_from_parent, muxer); g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_parent_action_enabled_changed, muxer); g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_parent_action_state_changed, muxer); - g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_parent_primary_accel_changed, muxer); g_object_unref (muxer->parent); } @@ -849,8 +764,6 @@ gtk_action_muxer_set_parent (GtkActionMuxer *muxer, gtk_action_muxer_action_added (muxer, *it, G_ACTION_GROUP (muxer->parent), *it); g_strfreev (actions); - emit_changed_accels (muxer, muxer->parent); - g_signal_connect (muxer->parent, "action-added", G_CALLBACK (gtk_action_muxer_action_added_to_parent), muxer); g_signal_connect (muxer->parent, "action-removed", @@ -859,93 +772,7 @@ gtk_action_muxer_set_parent (GtkActionMuxer *muxer, G_CALLBACK (gtk_action_muxer_parent_action_enabled_changed), muxer); g_signal_connect (muxer->parent, "action-state-changed", G_CALLBACK (gtk_action_muxer_parent_action_state_changed), muxer); - g_signal_connect (muxer->parent, "primary-accel-changed", - G_CALLBACK (gtk_action_muxer_parent_primary_accel_changed), muxer); } g_object_notify_by_pspec (G_OBJECT (muxer), properties[PROP_PARENT]); } - -void -gtk_action_muxer_set_primary_accel (GtkActionMuxer *muxer, - const gchar *action_and_target, - const gchar *primary_accel) -{ - if (!muxer->primary_accels) - muxer->primary_accels = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - - if (primary_accel) - g_hash_table_insert (muxer->primary_accels, g_strdup (action_and_target), g_strdup (primary_accel)); - else - g_hash_table_remove (muxer->primary_accels, action_and_target); - - gtk_action_muxer_primary_accel_changed (muxer, NULL, action_and_target); -} - -const gchar * -gtk_action_muxer_get_primary_accel (GtkActionMuxer *muxer, - const gchar *action_and_target) -{ - if (muxer->primary_accels) - { - const gchar *primary_accel; - - primary_accel = g_hash_table_lookup (muxer->primary_accels, action_and_target); - - if (primary_accel) - return primary_accel; - } - - if (!muxer->parent) - return NULL; - - return gtk_action_muxer_get_primary_accel (muxer->parent, action_and_target); -} - -gchar * -gtk_print_action_and_target (const gchar *action_namespace, - const gchar *action_name, - GVariant *target) -{ - GString *result; - - g_return_val_if_fail (strchr (action_name, '|') == NULL, NULL); - g_return_val_if_fail (action_namespace == NULL || strchr (action_namespace, '|') == NULL, NULL); - - result = g_string_new (NULL); - - if (target) - g_variant_print_string (target, result, TRUE); - g_string_append_c (result, '|'); - - if (action_namespace) - { - g_string_append (result, action_namespace); - g_string_append_c (result, '.'); - } - - g_string_append (result, action_name); - - return g_string_free (result, FALSE); -} - -gchar * -gtk_normalise_detailed_action_name (const gchar *detailed_action_name) -{ - GError *error = NULL; - gchar *action_and_target; - gchar *action_name; - GVariant *target; - - g_action_parse_detailed_name (detailed_action_name, &action_name, &target, &error); - g_assert_no_error (error); - - action_and_target = gtk_print_action_and_target (NULL, action_name, target); - - if (target) - g_variant_unref (target); - - g_free (action_name); - - return action_and_target; -} diff --git a/libqmenumodel/src/gtk/gtkactionmuxer.h b/libqmenumodel/src/gtk/gtkactionmuxer.h index 8d6e347..4014830 100644 --- a/libqmenumodel/src/gtk/gtkactionmuxer.h +++ b/libqmenumodel/src/gtk/gtkactionmuxer.h @@ -42,28 +42,11 @@ void gtk_action_muxer_insert (GtkActi void gtk_action_muxer_remove (GtkActionMuxer *muxer, const gchar *prefix); -const gchar ** gtk_action_muxer_list_prefixes (GtkActionMuxer *muxer); -GActionGroup * gtk_action_muxer_lookup (GtkActionMuxer *muxer, - const gchar *prefix); GtkActionMuxer * gtk_action_muxer_get_parent (GtkActionMuxer *muxer); void gtk_action_muxer_set_parent (GtkActionMuxer *muxer, GtkActionMuxer *parent); -void gtk_action_muxer_set_primary_accel (GtkActionMuxer *muxer, - const gchar *action_and_target, - const gchar *primary_accel); - -const gchar * gtk_action_muxer_get_primary_accel (GtkActionMuxer *muxer, - const gchar *action_and_target); - -/* No better place for these... */ -gchar * gtk_print_action_and_target (const gchar *action_namespace, - const gchar *action_name, - GVariant *target); - -gchar * gtk_normalise_detailed_action_name (const gchar *detailed_action_name); - G_END_DECLS #endif /* __GTK_ACTION_MUXER_H__ */ diff --git a/libqmenumodel/src/gtk/gtkactionobserver.c b/libqmenumodel/src/gtk/gtkactionobserver.c index fda0ae7..cf70b20 100644 --- a/libqmenumodel/src/gtk/gtkactionobserver.c +++ b/libqmenumodel/src/gtk/gtkactionobserver.c @@ -23,7 +23,7 @@ G_DEFINE_INTERFACE (GtkActionObserver, gtk_action_observer, G_TYPE_OBJECT) -/*< private > +/** * SECTION:gtkactionobserver * @short_description: an interface implemented by objects that are * interested in monitoring actions for changes @@ -54,7 +54,7 @@ gtk_action_observer_default_init (GtkActionObserverInterface *class) { } -/*< private > +/** * gtk_action_observer_action_added: * @observer: a #GtkActionObserver * @observable: the source of the event @@ -85,7 +85,7 @@ gtk_action_observer_action_added (GtkActionObserver *observer, ->action_added (observer, observable, action_name, parameter_type, enabled, state); } -/*< private > +/** * gtk_action_observer_action_enabled_changed: * @observer: a #GtkActionObserver * @observable: the source of the event @@ -110,7 +110,7 @@ gtk_action_observer_action_enabled_changed (GtkActionObserver *observer, ->action_enabled_changed (observer, observable, action_name, enabled); } -/*< private > +/** * gtk_action_observer_action_state_changed: * @observer: a #GtkActionObserver * @observable: the source of the event @@ -135,7 +135,7 @@ gtk_action_observer_action_state_changed (GtkActionObserver *observer, ->action_state_changed (observer, observable, action_name, state); } -/*< private > +/** * gtk_action_observer_action_removed: * @observer: a #GtkActionObserver * @observable: the source of the event @@ -157,33 +157,3 @@ gtk_action_observer_action_removed (GtkActionObserver *observer, GTK_ACTION_OBSERVER_GET_IFACE (observer) ->action_removed (observer, observable, action_name); } - -/*< private > - * gtk_action_observer_primary_accel_changed: - * @observer: a #GtkActionObserver - * @observable: the source of the event - * @action_name: the name of the action - * @action_and_target: detailed action of the changed accel, in “action and target” format - * - * This function is called when an action that the observer is - * registered to receive events for has one of its accelerators changed. - * - * Accelerator changes are reported for all targets associated with the - * action. The @action_and_target string should be used to check if the - * reported target is the one that the observer is interested in. - */ -void -gtk_action_observer_primary_accel_changed (GtkActionObserver *observer, - GtkActionObservable *observable, - const gchar *action_name, - const gchar *action_and_target) -{ - GtkActionObserverInterface *iface; - - g_return_if_fail (GTK_IS_ACTION_OBSERVER (observer)); - - iface = GTK_ACTION_OBSERVER_GET_IFACE (observer); - - if (iface->primary_accel_changed) - iface->primary_accel_changed (observer, observable, action_name, action_and_target); -} diff --git a/libqmenumodel/src/gtk/gtkactionobserver.h b/libqmenumodel/src/gtk/gtkactionobserver.h index a4e9659..83629a7 100644 --- a/libqmenumodel/src/gtk/gtkactionobserver.h +++ b/libqmenumodel/src/gtk/gtkactionobserver.h @@ -57,10 +57,6 @@ struct _GtkActionObserverInterface void (* action_removed) (GtkActionObserver *observer, GtkActionObservable *observable, const gchar *action_name); - void (* primary_accel_changed) (GtkActionObserver *observer, - GtkActionObservable *observable, - const gchar *action_name, - const gchar *action_and_target); }; GType gtk_action_observer_get_type (void); @@ -81,10 +77,6 @@ void gtk_action_observer_action_state_changed (GtkActi void gtk_action_observer_action_removed (GtkActionObserver *observer, GtkActionObservable *observable, const gchar *action_name); -void gtk_action_observer_primary_accel_changed (GtkActionObserver *observer, - GtkActionObservable *observable, - const gchar *action_name, - const gchar *action_and_target); G_END_DECLS diff --git a/libqmenumodel/src/gtk/gtkmenutracker.c b/libqmenumodel/src/gtk/gtkmenutracker.c index 95e08bc..8b72965 100644 --- a/libqmenumodel/src/gtk/gtkmenutracker.c +++ b/libqmenumodel/src/gtk/gtkmenutracker.c @@ -12,7 +12,9 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. * * Author: Ryan Lortie <desrt@desrt.ca> */ @@ -21,7 +23,7 @@ #include "gtkmenutracker.h" -/*< private > +/** * SECTION:gtkmenutracker * @Title: GtkMenuTracker * @Short_description: A helper class for interpreting #GMenuModel @@ -46,11 +48,11 @@ * * Certain properties on the #GtkMenuTrackerItem are mutable, and you must * listen for changes in the item. For more details, see the documentation - * for #GtkMenuTrackerItem along with https://wiki.gnome.org/Projects/GLib/GApplication/GMenuModel. + * for #GtkMenuTrackerItem along with https://live.gnome.org/GApplication/GMenuModel. * * The idea of @with_separators is for special cases where menu models may * be tracked in places where separators are not available, like in toplevel - * "File", “Edit” menu bars. Ignoring separator items is wrong, as #GtkMenuTracker + * "File", "Edit" menu bars. Ignoring separator items is wrong, as #GtkMenuTracker * expects the position to change, so we must tell #GtkMenuTracker to ignore * separators itself. */ @@ -60,8 +62,6 @@ typedef struct _GtkMenuTrackerSection GtkMenuTrackerSection; struct _GtkMenuTracker { GtkActionObservable *observable; - guint merge_sections : 1; - guint mac_os_mode : 1; GtkMenuTrackerInsertFunc insert_func; GtkMenuTrackerRemoveFunc remove_func; gpointer user_data; @@ -71,14 +71,12 @@ struct _GtkMenuTracker struct _GtkMenuTrackerSection { - gpointer model; /* may be a GtkMenuTrackerItem or a GMenuModel */ + GMenuModel *model; GSList *items; gchar *action_namespace; - guint separator_label : 1; guint with_separators : 1; guint has_separator : 1; - guint is_fake : 1; gulong handler; }; @@ -86,7 +84,6 @@ struct _GtkMenuTrackerSection static GtkMenuTrackerSection * gtk_menu_tracker_section_new (GtkMenuTracker *tracker, GMenuModel *model, gboolean with_separators, - gboolean separator_label, gint offset, const gchar *action_namespace, GPtrArray *items_already_created); @@ -94,7 +91,7 @@ static void gtk_menu_tracker_section_free (GtkMenuTrackerS static GtkMenuTrackerSection * gtk_menu_tracker_section_find_model (GtkMenuTrackerSection *section, - gpointer model, + GMenuModel *model, gint *offset) { GSList *item; @@ -122,7 +119,7 @@ gtk_menu_tracker_section_find_model (GtkMenuTrackerSection *section, (*offset)++; } - return NULL; + return FALSE; } /* this is responsible for syncing the showing of a separator for a @@ -130,7 +127,7 @@ gtk_menu_tracker_section_find_model (GtkMenuTrackerSection *section, * * we only ever show separators if we have _actual_ children (ie: we do * not show a separator if the section contains only empty child - * sections). it’s difficult to determine this on-the-fly, so we have + * sections). it's difficult to determine this on-the-fly, so we have * this separate function to come back later and figure it out. * * 'section' is that section. @@ -145,11 +142,11 @@ gtk_menu_tracker_section_find_model (GtkMenuTrackerSection *section, * * could_have_separator is true in two situations: * - * - our parent section had with_separators defined and there are items - * before us (ie: we should add a separator if we have content in + * - our parent section had with_separators defined and we are not the + * first section (ie: we should add a separator if we have content in * order to divide us from the items above) * - * - if we had a “label” attribute set for this section + * - if we had a 'label' attribute set for this section * * parent_model and parent_index are passed in so that we can give them * to the insertion callback so that it can see the label (and anything @@ -171,7 +168,6 @@ gtk_menu_tracker_section_sync_separators (GtkMenuTrackerSection *section, gboolean should_have_separator; gint n_items = 0; GSList *item; - GPtrArray *items = g_ptr_array_new (); gint i = 0; for (item = section->items; item; item = item->next) @@ -180,15 +176,13 @@ gtk_menu_tracker_section_sync_separators (GtkMenuTrackerSection *section, if (subsection) { - gboolean separator; + gboolean could_have_separator; - separator = (section->with_separators && n_items > 0) || subsection->separator_label; + could_have_separator = (section->with_separators && i > 0) || + g_menu_model_get_item_attribute (section->model, i, "label", "s", NULL); - /* Only pass the parent_model and parent_index in case they may be used to create the separator. */ n_items += gtk_menu_tracker_section_sync_separators (subsection, tracker, offset + n_items, - separator, - separator ? section->model : NULL, - separator ? i : 0); + could_have_separator, section->model, i); } else n_items++; @@ -196,18 +190,19 @@ gtk_menu_tracker_section_sync_separators (GtkMenuTrackerSection *section, i++; } - should_have_separator = !section->is_fake && could_have_separator && n_items != 0; + should_have_separator = could_have_separator && n_items != 0; if (should_have_separator > section->has_separator) { /* Add a separator */ - GtkMenuTrackerItem *separator; + GtkMenuTrackerItem *item; + GPtrArray *items = g_ptr_array_new (); - separator = _gtk_menu_tracker_item_new (tracker->observable, parent_model, parent_index, FALSE, NULL, TRUE); - g_ptr_array_add (items, (gpointer) separator); + item = _gtk_menu_tracker_item_new (tracker->observable, parent_model, parent_index, NULL, TRUE); + g_ptr_array_add (items, (gpointer) item); (* tracker->insert_func) (items, offset, tracker->user_data); g_ptr_array_unref (items); - g_object_unref (separator); + g_object_unref (item); section->has_separator = TRUE; } @@ -223,41 +218,6 @@ gtk_menu_tracker_section_sync_separators (GtkMenuTrackerSection *section, return n_items; } -static void -gtk_menu_tracker_item_visibility_changed (GtkMenuTrackerItem *item, - GParamSpec *pspec, - gpointer user_data) -{ - GtkMenuTracker *tracker = user_data; - GtkMenuTrackerSection *section; - gboolean is_now_visible; - gboolean was_visible; - gint offset = 0; - - is_now_visible = gtk_menu_tracker_item_get_is_visible (item); - - /* remember: the item is our model */ - section = gtk_menu_tracker_section_find_model (tracker->toplevel, item, &offset); - - was_visible = section->items != NULL; - - if (is_now_visible == was_visible) - return; - - if (is_now_visible) - { - section->items = g_slist_prepend (NULL, NULL); - (* tracker->insert_func) (section->model, offset, tracker->user_data); - } - else - { - section->items = g_slist_delete_link (section->items, section->items); - (* tracker->remove_func) (offset, 1, tracker->user_data); - } - - gtk_menu_tracker_section_sync_separators (tracker->toplevel, tracker, 0, FALSE, NULL, 0); -} - static gint gtk_menu_tracker_section_measure (GtkMenuTrackerSection *section) { @@ -298,7 +258,6 @@ gtk_menu_tracker_remove_items (GtkMenuTracker *tracker, n = gtk_menu_tracker_section_measure (subsection); gtk_menu_tracker_section_free (subsection); - while (n--) n_total_items += n; } @@ -316,32 +275,28 @@ gtk_menu_tracker_add_items (GtkMenuTracker *tracker, GMenuModel *model, gint position, gint n_items, - GPtrArray *items_already_created) + GPtrArray *items_already_created + ) { - GPtrArray *items; - if (items_already_created) - { - items = items_already_created; - } - else - { - items = g_ptr_array_new (); - } + GPtrArray *items; + if (items_already_created) + { + items = items_already_created; + } + else + { + items = g_ptr_array_new (); + } while (n_items--) { GMenuModel *submenu; submenu = g_menu_model_get_item_link (model, position + n_items, G_MENU_LINK_SECTION); g_assert (submenu != model); - - if (submenu != NULL && tracker->merge_sections) + if (submenu != NULL) { GtkMenuTrackerSection *subsection; gchar *action_namespace = NULL; - gboolean has_label; - - has_label = g_menu_model_get_item_attribute (model, position + n_items, - G_MENU_ATTRIBUTE_LABEL, "s", NULL); g_menu_model_get_item_attribute (model, position + n_items, G_MENU_ATTRIBUTE_ACTION_NAMESPACE, "s", &action_namespace); @@ -351,11 +306,11 @@ gtk_menu_tracker_add_items (GtkMenuTracker *tracker, gchar *namespace; namespace = g_strjoin (".", section->action_namespace, action_namespace, NULL); - subsection = gtk_menu_tracker_section_new (tracker, submenu, FALSE, has_label, offset, namespace, items_already_created); + subsection = gtk_menu_tracker_section_new (tracker, submenu, FALSE, offset, namespace, items_already_created); g_free (namespace); } else - subsection = gtk_menu_tracker_section_new (tracker, submenu, FALSE, has_label, offset, action_namespace, items_already_created); + subsection = gtk_menu_tracker_section_new (tracker, submenu, FALSE, offset, section->action_namespace, items_already_created); *change_point = g_slist_prepend (*change_point, subsection); g_free (action_namespace); @@ -366,76 +321,22 @@ gtk_menu_tracker_add_items (GtkMenuTracker *tracker, GtkMenuTrackerItem *item; item = _gtk_menu_tracker_item_new (tracker->observable, model, position + n_items, - tracker->mac_os_mode, - section->action_namespace, submenu != NULL); - - /* In the case that the item may disappear we handle that by - * treating the item that we just created as being its own - * subsection. This happens as so: - * - * - the subsection is created without the possibility of - * showing a separator - * - * - the subsection will have either 0 or 1 item in it at all - * times: either the shown item or not (in the case it is - * hidden) - * - * - the created item acts as the "model" for this section - * and we use its "visiblity-changed" signal in the same - * way that we use the "items-changed" signal from a real - * GMenuModel - * - * We almost never use the '->model' stored in the section for - * anything other than lookups and for dropped the ref and - * disconnecting the signal when we destroy the menu, and we - * need to do exactly those things in this case as well. - * - * The only other thing that '->model' is used for is in the - * case that we want to show a separator, but we will never do - * that because separators are not shown for this fake section. - */ - if (gtk_menu_tracker_item_may_disappear (item)) - { - GtkMenuTrackerSection *fake_section; - - fake_section = g_slice_new0 (GtkMenuTrackerSection); - fake_section->is_fake = TRUE; - fake_section->model = g_object_ref (item); - fake_section->handler = g_signal_connect (item, "notify::is-visible", - G_CALLBACK (gtk_menu_tracker_item_visibility_changed), - tracker); - *change_point = g_slist_prepend (*change_point, fake_section); - - if (gtk_menu_tracker_item_get_is_visible (item)) - { - (* tracker->insert_func) (items, offset, tracker->user_data); - fake_section->items = g_slist_prepend (NULL, NULL); - } - } - else - { - /* In the normal case, we store NULL in the linked list. - * The measurement and lookup code count NULL always as - * exactly 1: an item that will always be there. - */ - g_ptr_array_insert (items, 0, (gpointer) item); - *change_point = g_slist_prepend (*change_point, NULL); - } + section->action_namespace, FALSE); + g_ptr_array_insert (items, 0, (gpointer) item); - g_object_unref (item); + *change_point = g_slist_prepend (*change_point, NULL); } } - if (!items_already_created) - { - if (items->len) - { - (* tracker->insert_func) (items, offset, tracker->user_data); - for (gint i = 0; i < items->len; ++i) - g_object_unref(g_ptr_array_index(items, i)); - } - g_ptr_array_unref (items); - } + { + if (items->len) + { + (* tracker->insert_func) (items, offset, tracker->user_data); + for (gint i = 0; i < items->len; ++i) + g_object_unref(g_ptr_array_index(items, i)); + } + g_ptr_array_unref (items); + } } static void @@ -505,7 +406,6 @@ static GtkMenuTrackerSection * gtk_menu_tracker_section_new (GtkMenuTracker *tracker, GMenuModel *model, gboolean with_separators, - gboolean separator_label, gint offset, const gchar *action_namespace, GPtrArray *items_already_created) @@ -516,7 +416,6 @@ gtk_menu_tracker_section_new (GtkMenuTracker *tracker, section->model = g_object_ref (model); section->with_separators = with_separators; section->action_namespace = g_strdup (action_namespace); - section->separator_label = separator_label; gtk_menu_tracker_add_items (tracker, section, §ion->items, offset, model, 0, g_menu_model_get_n_items (model), items_already_created); section->handler = g_signal_connect (model, "items-changed", G_CALLBACK (gtk_menu_tracker_model_changed), tracker); @@ -529,10 +428,6 @@ gtk_menu_tracker_section_new (GtkMenuTracker *tracker, * @model: the model to flatten * @with_separators: if the toplevel should have separators (ie: TRUE * for menus, FALSE for menubars) - * @merge_sections: if sections should have their items merged in the - * usual way or reported only as separators (which can be queried to - * manually handle the items) - * @mac_os_mode: if this is on behalf of the Mac OS menubar * @action_namespace: the passed-in action namespace * @insert_func: insert callback * @remove_func: remove callback @@ -563,7 +458,7 @@ gtk_menu_tracker_section_new (GtkMenuTracker *tracker, * information about the menu item to insert. @action_namespace is the * action namespace that actions referred to from that item should place * themselves in. Note that if the item is a submenu and the - * “action-namespace” attribute is defined on the item, it will _not_ be + * "action-namespace" attribute is defined on the item, it will _not_ be * applied to the @action_namespace argument as it is meant for the * items inside of the submenu, not the submenu item itself. * @@ -571,7 +466,7 @@ gtk_menu_tracker_section_new (GtkMenuTracker *tracker, * separator. @model and @item_index will still be meaningfully set in * this case -- to the section menu item corresponding to the separator. * This is useful if the section specifies a label, for example. If - * there is an “action-namespace” attribute on this menu item then it + * there is an "action-namespace" attribute on this menu item then it * should be ignored by the consumer because #GtkMenuTracker has already * handled it. * @@ -583,10 +478,7 @@ GtkMenuTracker * gtk_menu_tracker_new (GtkActionObservable *observable, GMenuModel *model, gboolean with_separators, - gboolean merge_sections, - gboolean mac_os_mode, const gchar *action_namespace, - GPtrArray *items_already_created, GtkMenuTrackerInsertFunc insert_func, GtkMenuTrackerRemoveFunc remove_func, gpointer user_data) @@ -594,43 +486,28 @@ gtk_menu_tracker_new (GtkActionObservable *observable, GtkMenuTracker *tracker; tracker = g_slice_new (GtkMenuTracker); - tracker->merge_sections = merge_sections; - tracker->mac_os_mode = mac_os_mode; tracker->observable = g_object_ref (observable); tracker->insert_func = insert_func; tracker->remove_func = remove_func; tracker->user_data = user_data; - tracker->toplevel = gtk_menu_tracker_section_new (tracker, model, with_separators, FALSE, 0, action_namespace, NULL); + tracker->toplevel = gtk_menu_tracker_section_new (tracker, model, with_separators, 0, action_namespace, NULL); gtk_menu_tracker_section_sync_separators (tracker->toplevel, tracker, 0, FALSE, NULL, 0); return tracker; } GtkMenuTracker * -gtk_menu_tracker_new_for_item_link (GtkMenuTrackerItem *item, - const gchar *link_name, - gboolean merge_sections, - gboolean mac_os_mode, - GtkMenuTrackerInsertFunc insert_func, - GtkMenuTrackerRemoveFunc remove_func, - gpointer user_data) +gtk_menu_tracker_new_for_item_submenu (GtkMenuTrackerItem *item, + GtkMenuTrackerInsertFunc insert_func, + GtkMenuTrackerRemoveFunc remove_func, + gpointer user_data) { - GtkMenuTracker *tracker; - GMenuModel *submenu; - gchar *namespace; - - submenu = _gtk_menu_tracker_item_get_link (item, link_name); - namespace = _gtk_menu_tracker_item_get_link_namespace (item); - - tracker = gtk_menu_tracker_new (_gtk_menu_tracker_item_get_observable (item), submenu, - TRUE, merge_sections, mac_os_mode, - namespace, NULL, insert_func, remove_func, user_data); - - g_object_unref (submenu); - g_free (namespace); - - return tracker; + return gtk_menu_tracker_new (_gtk_menu_tracker_item_get_observable (item), + _gtk_menu_tracker_item_get_submenu (item), + TRUE, + _gtk_menu_tracker_item_get_submenu_namespace (item), + insert_func, remove_func, user_data); } /*< private > diff --git a/libqmenumodel/src/gtk/gtkmenutracker.h b/libqmenumodel/src/gtk/gtkmenutracker.h index 2ff0455..1ade63f 100644 --- a/libqmenumodel/src/gtk/gtkmenutracker.h +++ b/libqmenumodel/src/gtk/gtkmenutracker.h @@ -12,7 +12,9 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. * * Author: Ryan Lortie <desrt@desrt.ca> */ @@ -36,18 +38,12 @@ typedef void (* GtkMenuTrackerRemoveFunc) (gint GtkMenuTracker * gtk_menu_tracker_new (GtkActionObservable *observer, GMenuModel *model, gboolean with_separators, - gboolean merge_sections, - gboolean mac_os_mode, const gchar *action_namespace, - GPtrArray *items_already_created, GtkMenuTrackerInsertFunc insert_func, GtkMenuTrackerRemoveFunc remove_func, gpointer user_data); -GtkMenuTracker * gtk_menu_tracker_new_for_item_link (GtkMenuTrackerItem *item, - const gchar *link_name, - gboolean merge_sections, - gboolean mac_os_mode, +GtkMenuTracker * gtk_menu_tracker_new_for_item_submenu (GtkMenuTrackerItem *item, GtkMenuTrackerInsertFunc insert_func, GtkMenuTrackerRemoveFunc remove_func, gpointer user_data); diff --git a/libqmenumodel/src/gtk/gtkmenutrackeritem.c b/libqmenumodel/src/gtk/gtkmenutrackeritem.c index d05f1ba..650e719 100644 --- a/libqmenumodel/src/gtk/gtkmenutrackeritem.c +++ b/libqmenumodel/src/gtk/gtkmenutrackeritem.c @@ -12,7 +12,9 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. * * Author: Ryan Lortie <desrt@desrt.ca> */ @@ -20,13 +22,8 @@ #include "config.h" #include "gtkmenutrackeritem.h" -#include "gtkactionmuxer.h" -#include "gtkactionmuxer.h" - -#include <string.h> - -/*< private > +/** * SECTION:gtkmenutrackeritem * @Title: GtkMenuTrackerItem * @Short_description: Small helper for model menu items @@ -37,7 +34,7 @@ * * If an item is one of the non-normal classes (submenu, separator), only the * label of the item needs to be respected. Otherwise, all the properties - * of the item contribute to the item’s appearance and state. + * of the item contribute to the item's appearance and state. * * Implementing the appearance of the menu item is up to toolkits, and certain * toolkits may choose to ignore certain properties, like icon or accel. The @@ -66,7 +63,7 @@ * Applications using submenus may want to lazily build their submenus in * response to the user clicking on it, as building a submenu may be expensive. * - * Thus, the submenu has two special controls -- the submenu’s visibility + * Thus, the submenu has two special controls -- the submenu's visibility * should be controlled by the GtkMenuTrackerItem::submenu-shown property, * and if a user clicks on the submenu, do not immediately show the menu, * but call gtk_menu_tracker_item_request_submenu_shown() and wait for the @@ -86,7 +83,6 @@ struct _GtkMenuTrackerItem GtkActionObservable *observable; gchar *action_namespace; - gchar *action_and_target; GMenuItem *item; GtkMenuTrackerItemRole role : 4; guint is_separator : 1; @@ -95,30 +91,23 @@ struct _GtkMenuTrackerItem guint toggled : 1; guint submenu_shown : 1; guint submenu_requested : 1; - guint hidden_when : 2; - guint is_visible : 1; GVariant *action_state; }; -#define HIDDEN_NEVER 0 -#define HIDDEN_WHEN_MISSING 1 -#define HIDDEN_WHEN_DISABLED 2 -#define HIDDEN_WHEN_ALWAYS 3 - enum { PROP_0, PROP_IS_SEPARATOR, + PROP_HAS_SUBMENU, PROP_LABEL, PROP_ICON, - PROP_VERB_ICON, PROP_SENSITIVE, + PROP_VISIBLE, PROP_ROLE, PROP_TOGGLED, PROP_ACCEL, PROP_SUBMENU_SHOWN, PROP_ACTION_NAME, PROP_ACTION_STATE, - PROP_IS_VISIBLE, N_PROPS }; @@ -164,18 +153,21 @@ gtk_menu_tracker_item_get_property (GObject *object, case PROP_IS_SEPARATOR: g_value_set_boolean (value, gtk_menu_tracker_item_get_is_separator (self)); break; + case PROP_HAS_SUBMENU: + g_value_set_boolean (value, gtk_menu_tracker_item_get_has_submenu (self)); + break; case PROP_LABEL: g_value_set_string (value, gtk_menu_tracker_item_get_label (self)); break; case PROP_ICON: - g_value_take_object (value, gtk_menu_tracker_item_get_icon (self)); - break; - case PROP_VERB_ICON: - g_value_take_object (value, gtk_menu_tracker_item_get_verb_icon (self)); + g_value_set_object (value, gtk_menu_tracker_item_get_icon (self)); break; case PROP_SENSITIVE: g_value_set_boolean (value, gtk_menu_tracker_item_get_sensitive (self)); break; + case PROP_VISIBLE: + g_value_set_boolean (value, gtk_menu_tracker_item_get_visible (self)); + break; case PROP_ROLE: g_value_set_enum (value, gtk_menu_tracker_item_get_role (self)); break; @@ -188,12 +180,10 @@ gtk_menu_tracker_item_get_property (GObject *object, case PROP_SUBMENU_SHOWN: g_value_set_boolean (value, gtk_menu_tracker_item_get_submenu_shown (self)); break; - case PROP_ACTION_STATE: - g_value_set_variant (value, self->action_state); case PROP_ACTION_NAME: g_value_take_string (value, gtk_menu_tracker_item_get_action_name (self)); - case PROP_IS_VISIBLE: - g_value_set_boolean (value, gtk_menu_tracker_item_get_is_visible (self)); + case PROP_ACTION_STATE: + g_value_set_variant (value, self->action_state); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -207,7 +197,6 @@ gtk_menu_tracker_item_finalize (GObject *object) GtkMenuTrackerItem *self = GTK_MENU_TRACKER_ITEM (object); g_free (self->action_namespace); - g_free (self->action_and_target); if (self->observable) g_object_unref (self->observable); @@ -233,14 +222,16 @@ gtk_menu_tracker_item_class_init (GtkMenuTrackerItemClass *class) gtk_menu_tracker_item_pspecs[PROP_IS_SEPARATOR] = g_param_spec_boolean ("is-separator", "", "", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE); + gtk_menu_tracker_item_pspecs[PROP_HAS_SUBMENU] = + g_param_spec_boolean ("has-submenu", "", "", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE); gtk_menu_tracker_item_pspecs[PROP_LABEL] = g_param_spec_string ("label", "", "", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE); gtk_menu_tracker_item_pspecs[PROP_ICON] = g_param_spec_object ("icon", "", "", G_TYPE_ICON, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE); - gtk_menu_tracker_item_pspecs[PROP_VERB_ICON] = - g_param_spec_object ("verb-icon", "", "", G_TYPE_ICON, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE); gtk_menu_tracker_item_pspecs[PROP_SENSITIVE] = g_param_spec_boolean ("sensitive", "", "", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE); + gtk_menu_tracker_item_pspecs[PROP_VISIBLE] = + g_param_spec_boolean ("visible", "", "", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE); gtk_menu_tracker_item_pspecs[PROP_ROLE] = g_param_spec_enum ("role", "", "", GTK_TYPE_MENU_TRACKER_ITEM_ROLE, GTK_MENU_TRACKER_ITEM_ROLE_NORMAL, @@ -255,51 +246,10 @@ gtk_menu_tracker_item_class_init (GtkMenuTrackerItemClass *class) g_param_spec_boolean ("action-name", "", "", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE); gtk_menu_tracker_item_pspecs[PROP_ACTION_STATE] = g_param_spec_boolean ("action-state", "", "", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE); - gtk_menu_tracker_item_pspecs[PROP_IS_VISIBLE] = - g_param_spec_boolean ("is-visible", "", "", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE); g_object_class_install_properties (class, N_PROPS, gtk_menu_tracker_item_pspecs); } -/* This syncs up the visibility for the hidden-when='' case. We call it - * from the action observer functions on changes to the action group and - * on initialisation (via the action observer functions that are invoked - * at that time). - */ -static void -gtk_menu_tracker_item_update_visibility (GtkMenuTrackerItem *self) -{ - gboolean visible; - - switch (self->hidden_when) - { - case HIDDEN_NEVER: - visible = TRUE; - break; - - case HIDDEN_WHEN_MISSING: - visible = self->can_activate; - break; - - case HIDDEN_WHEN_DISABLED: - visible = self->sensitive; - break; - - case HIDDEN_WHEN_ALWAYS: - visible = FALSE; - break; - - default: - g_assert_not_reached (); - } - - if (visible != self->is_visible) - { - self->is_visible = visible; - g_object_notify (G_OBJECT (self), "is-visible"); - } -} - static void gtk_menu_tracker_item_action_added (GtkActionObserver *observer, GtkActionObservable *observable, @@ -359,12 +309,6 @@ gtk_menu_tracker_item_action_added (GtkActionObserver *observer, if (action_target) g_variant_unref (action_target); - - /* In case of hidden-when='', we want to Wait until after refreshing - * all of the properties to emit the signal that will cause the - * tracker to expose us (to prevent too much thrashing). - */ - gtk_menu_tracker_item_update_visibility (self); } static void @@ -384,8 +328,6 @@ gtk_menu_tracker_item_action_enabled_changed (GtkActionObserver *observer, self->sensitive = enabled; g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_SENSITIVE]); - - gtk_menu_tracker_item_update_visibility (self); } static void @@ -431,51 +373,38 @@ gtk_menu_tracker_item_action_removed (GtkActionObserver *observer, const gchar *action_name) { GtkMenuTrackerItem *self = GTK_MENU_TRACKER_ITEM (observer); - gboolean was_sensitive, was_toggled; - GtkMenuTrackerItemRole old_role; if (!self->can_activate) return; - was_sensitive = self->sensitive; - was_toggled = self->toggled; - old_role = self->role; - - self->can_activate = FALSE; - self->sensitive = FALSE; - self->toggled = FALSE; - self->role = GTK_MENU_TRACKER_ITEM_ROLE_NORMAL; - self->action_state = NULL; - - /* Backwards from adding: we want to remove ourselves from the menu - * -before- thrashing the properties. - */ - gtk_menu_tracker_item_update_visibility (self); - g_object_freeze_notify (G_OBJECT (self)); - if (was_sensitive) - g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_SENSITIVE]); - - if (was_toggled) - g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_TOGGLED]); + if (self->sensitive) + { + self->sensitive = FALSE; + g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_SENSITIVE]); + } - if (old_role != GTK_MENU_TRACKER_ITEM_ROLE_NORMAL) - g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_ROLE]); + if (self->toggled) + { + self->toggled = FALSE; + g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_TOGGLED]); + } - g_object_thaw_notify (G_OBJECT (self)); -} + if (self->role != GTK_MENU_TRACKER_ITEM_ROLE_NORMAL) + { + self->role = GTK_MENU_TRACKER_ITEM_ROLE_NORMAL; + g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_ROLE]); + } -static void -gtk_menu_tracker_item_primary_accel_changed (GtkActionObserver *observer, - GtkActionObservable *observable, - const gchar *action_name, - const gchar *action_and_target) -{ - GtkMenuTrackerItem *self = GTK_MENU_TRACKER_ITEM (observer); + if (self->action_state != NULL) + { + g_variant_unref (self->action_state); + self->action_state = NULL; + g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_ACTION_STATE]); + } - if (g_str_equal (action_and_target, self->action_and_target)) - g_object_notify_by_pspec (G_OBJECT (self), gtk_menu_tracker_item_pspecs[PROP_ACCEL]); + g_object_thaw_notify (G_OBJECT (self)); } static void @@ -485,20 +414,17 @@ gtk_menu_tracker_item_init_observer_iface (GtkActionObserverInterface *iface) iface->action_enabled_changed = gtk_menu_tracker_item_action_enabled_changed; iface->action_state_changed = gtk_menu_tracker_item_action_state_changed; iface->action_removed = gtk_menu_tracker_item_action_removed; - iface->primary_accel_changed = gtk_menu_tracker_item_primary_accel_changed; } GtkMenuTrackerItem * _gtk_menu_tracker_item_new (GtkActionObservable *observable, GMenuModel *model, gint item_index, - gboolean mac_os_mode, const gchar *action_namespace, gboolean is_separator) { GtkMenuTrackerItem *self; const gchar *action_name; - const gchar *hidden_when; g_return_val_if_fail (GTK_IS_ACTION_OBSERVABLE (observable), NULL); g_return_val_if_fail (G_IS_MENU_MODEL (model), NULL); @@ -509,72 +435,50 @@ _gtk_menu_tracker_item_new (GtkActionObservable *observable, self->observable = g_object_ref (observable); self->is_separator = is_separator; - if (!is_separator && g_menu_item_get_attribute (self->item, "hidden-when", "&s", &hidden_when)) - { - if (g_str_equal (hidden_when, "action-disabled")) - self->hidden_when = HIDDEN_WHEN_DISABLED; - else if (g_str_equal (hidden_when, "action-missing")) - self->hidden_when = HIDDEN_WHEN_MISSING; - else if (mac_os_mode && g_str_equal (hidden_when, "macos-menubar")) - self->hidden_when = HIDDEN_WHEN_ALWAYS; - - /* Ignore other values -- this code may be running in context of a - * desktop shell or the like and should not spew criticals due to - * application bugs... - * - * Note: if we just set a hidden-when state, but don't get the - * action_name below then our visibility will be FALSE forever. - * That's to be expected since the action is missing... - */ - } - if (!is_separator && g_menu_item_get_attribute (self->item, "action", "&s", &action_name)) { GActionGroup *group = G_ACTION_GROUP (observable); const GVariantType *parameter_type; - GVariant *target; gboolean enabled; GVariant *state; gboolean found; - target = g_menu_item_get_attribute_value (self->item, "target", NULL); - - self->action_and_target = gtk_print_action_and_target (action_namespace, action_name, target); - - if (target) - g_variant_unref (target); - - action_name = strrchr (self->action_and_target, '|') + 1; - state = NULL; - gtk_action_observable_register_observer (self->observable, action_name, GTK_ACTION_OBSERVER (self)); - found = g_action_group_query_action (group, action_name, &enabled, ¶meter_type, NULL, NULL, &state); - - if (found) + if (action_namespace) { - gtk_menu_tracker_item_action_added (GTK_ACTION_OBSERVER (self), observable, NULL, parameter_type, enabled, state); + gchar *full_action; + + full_action = g_strjoin (".", action_namespace, action_name, NULL); + gtk_action_observable_register_observer (self->observable, full_action, GTK_ACTION_OBSERVER (self)); + found = g_action_group_query_action (group, full_action, &enabled, ¶meter_type, NULL, NULL, &state); + g_free (full_action); } else { - gtk_menu_tracker_item_update_visibility (self); + gtk_action_observable_register_observer (self->observable, action_name, GTK_ACTION_OBSERVER (self)); + found = g_action_group_query_action (group, action_name, &enabled, ¶meter_type, NULL, NULL, &state); } + if (found) + gtk_menu_tracker_item_action_added (GTK_ACTION_OBSERVER (self), observable, NULL, parameter_type, enabled, state); + else + gtk_menu_tracker_item_action_removed (GTK_ACTION_OBSERVER (self), observable, NULL); + if (state) g_variant_unref (state); } else { - gtk_menu_tracker_item_update_visibility (self); gboolean submenu_enabled; - if (g_menu_item_get_attribute (self->item, "submenu-enabled", "b", &submenu_enabled)) - { - self->sensitive = submenu_enabled; - } - else - { - self->sensitive = TRUE; - } + if (g_menu_item_get_attribute (self->item, "submenu-enabled", "b", &submenu_enabled)) + { + self->sensitive = submenu_enabled; + } + else + { + self->sensitive = TRUE; + } } return self; @@ -586,11 +490,11 @@ _gtk_menu_tracker_item_get_observable (GtkMenuTrackerItem *self) return self->observable; } -/*< private > +/** * gtk_menu_tracker_item_get_is_separator: * @self: A #GtkMenuTrackerItem instance * - * Returns: whether the menu item is a separator. If so, only + * Returns whether the menu item is a separator. If so, only * certain properties may need to be obeyed. See the documentation * for #GtkMenuTrackerItem. */ @@ -600,21 +504,20 @@ gtk_menu_tracker_item_get_is_separator (GtkMenuTrackerItem *self) return self->is_separator; } -/*< private > +/** * gtk_menu_tracker_item_get_has_submenu: * @self: A #GtkMenuTrackerItem instance * - * Returns: whether the menu item has a submenu. If so, only + * Returns whether the menu item has a submenu. If so, only * certain properties may need to be obeyed. See the documentation * for #GtkMenuTrackerItem. */ gboolean -gtk_menu_tracker_item_get_has_link (GtkMenuTrackerItem *self, - const gchar *link_name) +gtk_menu_tracker_item_get_has_submenu (GtkMenuTrackerItem *self) { GMenuModel *link; - link = g_menu_item_get_link (self->item, link_name); + link = g_menu_item_get_link (self->item, G_MENU_LINK_SUBMENU); if (link) { @@ -635,7 +538,7 @@ gtk_menu_tracker_item_get_label (GtkMenuTrackerItem *self) return label; } -/*< private > +/** * gtk_menu_tracker_item_get_icon: * * Returns: (transfer full): @@ -657,32 +560,16 @@ gtk_menu_tracker_item_get_icon (GtkMenuTrackerItem *self) return icon; } -/*< private > - * gtk_menu_tracker_item_get_verb_icon: - * - * Returns: (transfer full): - */ -GIcon * -gtk_menu_tracker_item_get_verb_icon (GtkMenuTrackerItem *self) +gboolean +gtk_menu_tracker_item_get_sensitive (GtkMenuTrackerItem *self) { - GVariant *icon_data; - GIcon *icon; - - icon_data = g_menu_item_get_attribute_value (self->item, "verb-icon", NULL); - - if (icon_data == NULL) - return NULL; - - icon = g_icon_deserialize (icon_data); - g_variant_unref (icon_data); - - return icon; + return self->sensitive; } gboolean -gtk_menu_tracker_item_get_sensitive (GtkMenuTrackerItem *self) +gtk_menu_tracker_item_get_visible (GtkMenuTrackerItem *self) { - return self->sensitive; + return TRUE; } GtkMenuTrackerItemRole @@ -700,59 +587,21 @@ gtk_menu_tracker_item_get_toggled (GtkMenuTrackerItem *self) const gchar * gtk_menu_tracker_item_get_accel (GtkMenuTrackerItem *self) { - const gchar *accel; - - if (!self->action_and_target) - return NULL; + const gchar *accel = NULL; - if (g_menu_item_get_attribute (self->item, "accel", "&s", &accel)) - return accel; - - if (!GTK_IS_ACTION_MUXER (self->observable)) - return NULL; + g_menu_item_get_attribute (self->item, "accel", "&s", &accel); - return gtk_action_muxer_get_primary_accel (GTK_ACTION_MUXER (self->observable), self->action_and_target); -} - -const gchar * -gtk_menu_tracker_item_get_special (GtkMenuTrackerItem *self) -{ - const gchar *special = NULL; - - g_menu_item_get_attribute (self->item, "x-gtk-private-special", "&s", &special); - - return special; -} - -const gchar * -gtk_menu_tracker_item_get_display_hint (GtkMenuTrackerItem *self) -{ - const gchar *display_hint = NULL; - - g_menu_item_get_attribute (self->item, "display-hint", "&s", &display_hint); - - return display_hint; -} - -const gchar * -gtk_menu_tracker_item_get_text_direction (GtkMenuTrackerItem *self) -{ - const gchar *text_direction = NULL; - - g_menu_item_get_attribute (self->item, "text-direction", "&s", &text_direction); - - return text_direction; + return accel; } GMenuModel * -_gtk_menu_tracker_item_get_link (GtkMenuTrackerItem *self, - const gchar *link_name) +_gtk_menu_tracker_item_get_submenu (GtkMenuTrackerItem *self) { - return g_menu_item_get_link (self->item, link_name); + return g_menu_item_get_link (self->item, "submenu"); } gchar * -_gtk_menu_tracker_item_get_link_namespace (GtkMenuTrackerItem *self) +_gtk_menu_tracker_item_get_submenu_namespace (GtkMenuTrackerItem *self) { const gchar *namespace; @@ -783,7 +632,10 @@ gtk_menu_tracker_item_get_submenu_shown (GtkMenuTrackerItem *self) * gtk_menu_tracker_item_get_action_name: * @self: A #GtkMenuTrackerItem instance * - * Returns the action name + * Returns a newly-allocated string containing the name of the action + * associated with this menu item. + * + * Returns: (transfer full): the action name, free it with g_free() */ gchar * gtk_menu_tracker_item_get_action_name (GtkMenuTrackerItem *self) @@ -791,12 +643,12 @@ gtk_menu_tracker_item_get_action_name (GtkMenuTrackerItem *self) const gchar *action_name; if (!g_menu_item_get_attribute (self->item, G_MENU_ATTRIBUTE_ACTION, "&s", &action_name)) - return NULL; + return NULL; if (self->action_namespace) - return g_strjoin (".", self->action_namespace, action_name, NULL); - else - return g_strdup (action_name); + return g_strjoin (".", self->action_namespace, action_name, NULL); + else + return g_strdup (action_name); } GVariant * @@ -836,10 +688,19 @@ gtk_menu_tracker_item_activated (GtkMenuTrackerItem *self) if (!self->can_activate) return; - action_name = strrchr (self->action_and_target, '|') + 1; + g_menu_item_get_attribute (self->item, G_MENU_ATTRIBUTE_ACTION, "&s", &action_name); action_target = g_menu_item_get_attribute_value (self->item, G_MENU_ATTRIBUTE_TARGET, NULL); - g_action_group_activate_action (G_ACTION_GROUP (self->observable), action_name, action_target); + if (self->action_namespace) + { + gchar *full_action; + + full_action = g_strjoin (".", self->action_namespace, action_name, NULL); + g_action_group_activate_action (G_ACTION_GROUP (self->observable), full_action, action_target); + g_free (full_action); + } + else + g_action_group_activate_action (G_ACTION_GROUP (self->observable), action_name, action_target); if (action_target) g_variant_unref (action_target); @@ -1069,30 +930,3 @@ gtk_menu_tracker_item_get_attribute_value (GtkMenuTrackerItem *self, { return g_menu_item_get_attribute_value (self->item, attribute, expected_type); } - -/** - * gtk_menu_tracker_item_get_is_visible: - * @self: A #GtkMenuTrackerItem instance - * - * Don't use this unless you're tracking items for yourself -- normally - * the tracker will emit add/remove automatically when this changes. - * - * Returns: if the item should currently be shown - */ -gboolean -gtk_menu_tracker_item_get_is_visible (GtkMenuTrackerItem *self) -{ - return self->is_visible; -} - -/** - * gtk_menu_tracker_item_may_disappear: - * @self: A #GtkMenuTrackerItem instance - * - * Returns: if the item may disappear (ie: is-visible property may change) - */ -gboolean -gtk_menu_tracker_item_may_disappear (GtkMenuTrackerItem *self) -{ - return self->hidden_when != HIDDEN_NEVER; -} diff --git a/libqmenumodel/src/gtk/gtkmenutrackeritem.h b/libqmenumodel/src/gtk/gtkmenutrackeritem.h index 3fbec27..dc62bf1 100644 --- a/libqmenumodel/src/gtk/gtkmenutrackeritem.h +++ b/libqmenumodel/src/gtk/gtkmenutrackeritem.h @@ -45,45 +45,32 @@ GType gtk_menu_tracker_item_role_get_type (void) G GtkMenuTrackerItem * _gtk_menu_tracker_item_new (GtkActionObservable *observable, GMenuModel *model, gint item_index, - gboolean mac_os_mode, const gchar *action_namespace, gboolean is_separator); -const gchar * gtk_menu_tracker_item_get_special (GtkMenuTrackerItem *self); - -const gchar * gtk_menu_tracker_item_get_display_hint (GtkMenuTrackerItem *self); - -const gchar * gtk_menu_tracker_item_get_text_direction (GtkMenuTrackerItem *self); - GtkActionObservable * _gtk_menu_tracker_item_get_observable (GtkMenuTrackerItem *self); gboolean gtk_menu_tracker_item_get_is_separator (GtkMenuTrackerItem *self); -gboolean gtk_menu_tracker_item_get_has_link (GtkMenuTrackerItem *self, - const gchar *link_name); +gboolean gtk_menu_tracker_item_get_has_submenu (GtkMenuTrackerItem *self); const gchar * gtk_menu_tracker_item_get_label (GtkMenuTrackerItem *self); GIcon * gtk_menu_tracker_item_get_icon (GtkMenuTrackerItem *self); -GIcon * gtk_menu_tracker_item_get_verb_icon (GtkMenuTrackerItem *self); - gboolean gtk_menu_tracker_item_get_sensitive (GtkMenuTrackerItem *self); +gboolean gtk_menu_tracker_item_get_visible (GtkMenuTrackerItem *self); + GtkMenuTrackerItemRole gtk_menu_tracker_item_get_role (GtkMenuTrackerItem *self); gboolean gtk_menu_tracker_item_get_toggled (GtkMenuTrackerItem *self); const gchar * gtk_menu_tracker_item_get_accel (GtkMenuTrackerItem *self); -GMenuModel * _gtk_menu_tracker_item_get_link (GtkMenuTrackerItem *self, - const gchar *link_name); +GMenuModel * _gtk_menu_tracker_item_get_submenu (GtkMenuTrackerItem *self); -gchar * _gtk_menu_tracker_item_get_link_namespace (GtkMenuTrackerItem *self); - -gboolean gtk_menu_tracker_item_may_disappear (GtkMenuTrackerItem *self); - -gboolean gtk_menu_tracker_item_get_is_visible (GtkMenuTrackerItem *self); +gchar * _gtk_menu_tracker_item_get_submenu_namespace (GtkMenuTrackerItem *self); gboolean gtk_menu_tracker_item_get_should_request_show (GtkMenuTrackerItem *self); @@ -92,12 +79,15 @@ void gtk_menu_tracker_item_activated (GtkMenu void gtk_menu_tracker_item_change_state (GtkMenuTrackerItem *self, GVariant *value); + + + void gtk_menu_tracker_item_request_submenu_shown (GtkMenuTrackerItem *self, gboolean shown); gboolean gtk_menu_tracker_item_get_submenu_shown (GtkMenuTrackerItem *self); -gchar * gtk_menu_tracker_item_get_action_name (GtkMenuTrackerItem *self); +gchar * gtk_menu_tracker_item_get_action_name (GtkMenuTrackerItem *self); GVariant * gtk_menu_tracker_item_get_action_state (GtkMenuTrackerItem *self); |
