menutrackeritem: Make submenu-actions work again

This broke when GtkActionMuxer stopped being a
GActionGroup.
This commit is contained in:
Matthias Clasen 2021-03-08 00:45:35 -05:00
parent 46d1f04a7c
commit db2e5648c9

View File

@ -809,13 +809,57 @@ gtk_menu_tracker_item_activated (GtkMenuTrackerItem *self)
g_variant_unref (action_target); g_variant_unref (action_target);
} }
typedef struct typedef struct {
{ GObject parent;
GtkMenuTrackerItem *item; GtkMenuTrackerItem *item;
char *submenu_action; char *submenu_action;
gboolean first_time; gboolean first_time;
} GtkMenuTrackerOpener; } GtkMenuTrackerOpener;
typedef struct {
GObjectClass parent_class;
} GtkMenuTrackerOpenerClass;
static void gtk_menu_tracker_opener_observer_iface_init (GtkActionObserverInterface *iface);
GType gtk_menu_tracker_opener_get_type (void) G_GNUC_CONST;
G_DEFINE_TYPE_WITH_CODE (GtkMenuTrackerOpener, gtk_menu_tracker_opener, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTION_OBSERVER, gtk_menu_tracker_opener_observer_iface_init))
static void
gtk_menu_tracker_opener_init (GtkMenuTrackerOpener *self)
{
}
static void
gtk_menu_tracker_opener_finalize (GObject *object)
{
GtkMenuTrackerOpener *opener = (GtkMenuTrackerOpener *)object;
gtk_action_observable_unregister_observer (opener->item->observable,
opener->submenu_action,
(GtkActionObserver *)opener);
if (GTK_IS_ACTION_MUXER (opener->item->observable))
gtk_action_muxer_change_action_state (GTK_ACTION_MUXER (opener->item->observable),
opener->submenu_action,
g_variant_new_boolean (FALSE));
gtk_menu_tracker_item_set_submenu_shown (opener->item, FALSE);
g_free (opener->submenu_action);
G_OBJECT_CLASS (gtk_menu_tracker_opener_parent_class)->finalize (object);
}
static void
gtk_menu_tracker_opener_class_init (GtkMenuTrackerOpenerClass *class)
{
G_OBJECT_CLASS (class)->finalize = gtk_menu_tracker_opener_finalize;
}
static void static void
gtk_menu_tracker_opener_update (GtkMenuTrackerOpener *opener) gtk_menu_tracker_opener_update (GtkMenuTrackerOpener *opener)
{ {
@ -862,57 +906,49 @@ gtk_menu_tracker_opener_update (GtkMenuTrackerOpener *opener)
} }
static void static void
gtk_menu_tracker_opener_added (GActionGroup *group, gtk_menu_tracker_opener_added (GtkActionObserver *observer,
GtkActionObservable *observable,
const char *action_name, const char *action_name,
gpointer user_data) const GVariantType *parameter_type,
gboolean enabled,
GVariant *state)
{ {
GtkMenuTrackerOpener *opener = user_data; gtk_menu_tracker_opener_update ((GtkMenuTrackerOpener *)observer);
if (g_str_equal (action_name, opener->submenu_action))
gtk_menu_tracker_opener_update (opener);
} }
static void static void
gtk_menu_tracker_opener_removed (GActionGroup *action_group, gtk_menu_tracker_opener_removed (GtkActionObserver *observer,
const char *action_name, GtkActionObservable *observable,
gpointer user_data) const char *action_name)
{ {
GtkMenuTrackerOpener *opener = user_data; gtk_menu_tracker_opener_update ((GtkMenuTrackerOpener *)observer);
if (g_str_equal (action_name, opener->submenu_action))
gtk_menu_tracker_opener_update (opener);
} }
static void static void
gtk_menu_tracker_opener_changed (GActionGroup *action_group, gtk_menu_tracker_opener_enabled_changed (GtkActionObserver *observer,
GtkActionObservable *observable,
const char *action_name, const char *action_name,
GVariant *new_state, gboolean enabled)
gpointer user_data)
{ {
GtkMenuTrackerOpener *opener = user_data; gtk_menu_tracker_opener_update ((GtkMenuTrackerOpener *)observer);
if (g_str_equal (action_name, opener->submenu_action))
gtk_menu_tracker_opener_update (opener);
} }
static void static void
gtk_menu_tracker_opener_free (gpointer data) gtk_menu_tracker_opener_state_changed (GtkActionObserver *observer,
GtkActionObservable *observable,
const char *action_name,
GVariant *state)
{ {
GtkMenuTrackerOpener *opener = data; gtk_menu_tracker_opener_update ((GtkMenuTrackerOpener *)observer);
}
g_signal_handlers_disconnect_by_func (opener->item->observable, gtk_menu_tracker_opener_added, opener); static void
g_signal_handlers_disconnect_by_func (opener->item->observable, gtk_menu_tracker_opener_removed, opener); gtk_menu_tracker_opener_observer_iface_init (GtkActionObserverInterface *iface)
g_signal_handlers_disconnect_by_func (opener->item->observable, gtk_menu_tracker_opener_changed, opener); {
iface->action_added = gtk_menu_tracker_opener_added;
g_action_group_change_action_state (G_ACTION_GROUP (opener->item->observable), iface->action_removed = gtk_menu_tracker_opener_removed;
opener->submenu_action, iface->action_enabled_changed = gtk_menu_tracker_opener_enabled_changed;
g_variant_new_boolean (FALSE)); iface->action_state_changed = gtk_menu_tracker_opener_state_changed;
gtk_menu_tracker_item_set_submenu_shown (opener->item, FALSE);
g_free (opener->submenu_action);
g_slice_free (GtkMenuTrackerOpener, opener);
} }
static GtkMenuTrackerOpener * static GtkMenuTrackerOpener *
@ -921,7 +957,8 @@ gtk_menu_tracker_opener_new (GtkMenuTrackerItem *item,
{ {
GtkMenuTrackerOpener *opener; GtkMenuTrackerOpener *opener;
opener = g_slice_new (GtkMenuTrackerOpener); opener = g_object_new (gtk_menu_tracker_opener_get_type (), NULL);
opener->first_time = TRUE; opener->first_time = TRUE;
opener->item = item; opener->item = item;
@ -930,9 +967,9 @@ gtk_menu_tracker_opener_new (GtkMenuTrackerItem *item,
else else
opener->submenu_action = g_strdup (submenu_action); opener->submenu_action = g_strdup (submenu_action);
g_signal_connect (item->observable, "action-added", G_CALLBACK (gtk_menu_tracker_opener_added), opener); gtk_action_observable_register_observer (item->observable,
g_signal_connect (item->observable, "action-removed", G_CALLBACK (gtk_menu_tracker_opener_removed), opener); opener->submenu_action,
g_signal_connect (item->observable, "action-state-changed", G_CALLBACK (gtk_menu_tracker_opener_changed), opener); (GtkActionObserver *)opener);
gtk_menu_tracker_opener_update (opener); gtk_menu_tracker_opener_update (opener);
@ -962,7 +999,7 @@ gtk_menu_tracker_item_request_submenu_shown (GtkMenuTrackerItem *self,
if (shown) if (shown)
g_object_set_data_full (G_OBJECT (self), "submenu-opener", g_object_set_data_full (G_OBJECT (self), "submenu-opener",
gtk_menu_tracker_opener_new (self, submenu_action), gtk_menu_tracker_opener_new (self, submenu_action),
gtk_menu_tracker_opener_free); g_object_unref);
else else
g_object_set_data (G_OBJECT (self), "submenu-opener", NULL); g_object_set_data (G_OBJECT (self), "submenu-opener", NULL);
} }