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);
}
typedef struct
{
typedef struct {
GObject parent;
GtkMenuTrackerItem *item;
char *submenu_action;
gboolean first_time;
} 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
gtk_menu_tracker_opener_update (GtkMenuTrackerOpener *opener)
{
@ -862,57 +906,49 @@ gtk_menu_tracker_opener_update (GtkMenuTrackerOpener *opener)
}
static void
gtk_menu_tracker_opener_added (GActionGroup *group,
const char *action_name,
gpointer user_data)
gtk_menu_tracker_opener_added (GtkActionObserver *observer,
GtkActionObservable *observable,
const char *action_name,
const GVariantType *parameter_type,
gboolean enabled,
GVariant *state)
{
GtkMenuTrackerOpener *opener = user_data;
if (g_str_equal (action_name, opener->submenu_action))
gtk_menu_tracker_opener_update (opener);
gtk_menu_tracker_opener_update ((GtkMenuTrackerOpener *)observer);
}
static void
gtk_menu_tracker_opener_removed (GActionGroup *action_group,
const char *action_name,
gpointer user_data)
gtk_menu_tracker_opener_removed (GtkActionObserver *observer,
GtkActionObservable *observable,
const char *action_name)
{
GtkMenuTrackerOpener *opener = user_data;
if (g_str_equal (action_name, opener->submenu_action))
gtk_menu_tracker_opener_update (opener);
gtk_menu_tracker_opener_update ((GtkMenuTrackerOpener *)observer);
}
static void
gtk_menu_tracker_opener_changed (GActionGroup *action_group,
const char *action_name,
GVariant *new_state,
gpointer user_data)
gtk_menu_tracker_opener_enabled_changed (GtkActionObserver *observer,
GtkActionObservable *observable,
const char *action_name,
gboolean enabled)
{
GtkMenuTrackerOpener *opener = user_data;
if (g_str_equal (action_name, opener->submenu_action))
gtk_menu_tracker_opener_update (opener);
gtk_menu_tracker_opener_update ((GtkMenuTrackerOpener *)observer);
}
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);
g_signal_handlers_disconnect_by_func (opener->item->observable, gtk_menu_tracker_opener_removed, opener);
g_signal_handlers_disconnect_by_func (opener->item->observable, gtk_menu_tracker_opener_changed, opener);
g_action_group_change_action_state (G_ACTION_GROUP (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_slice_free (GtkMenuTrackerOpener, opener);
static void
gtk_menu_tracker_opener_observer_iface_init (GtkActionObserverInterface *iface)
{
iface->action_added = gtk_menu_tracker_opener_added;
iface->action_removed = gtk_menu_tracker_opener_removed;
iface->action_enabled_changed = gtk_menu_tracker_opener_enabled_changed;
iface->action_state_changed = gtk_menu_tracker_opener_state_changed;
}
static GtkMenuTrackerOpener *
@ -921,7 +957,8 @@ gtk_menu_tracker_opener_new (GtkMenuTrackerItem *item,
{
GtkMenuTrackerOpener *opener;
opener = g_slice_new (GtkMenuTrackerOpener);
opener = g_object_new (gtk_menu_tracker_opener_get_type (), NULL);
opener->first_time = TRUE;
opener->item = item;
@ -930,9 +967,9 @@ gtk_menu_tracker_opener_new (GtkMenuTrackerItem *item,
else
opener->submenu_action = g_strdup (submenu_action);
g_signal_connect (item->observable, "action-added", G_CALLBACK (gtk_menu_tracker_opener_added), opener);
g_signal_connect (item->observable, "action-removed", G_CALLBACK (gtk_menu_tracker_opener_removed), opener);
g_signal_connect (item->observable, "action-state-changed", G_CALLBACK (gtk_menu_tracker_opener_changed), opener);
gtk_action_observable_register_observer (item->observable,
opener->submenu_action,
(GtkActionObserver *)opener);
gtk_menu_tracker_opener_update (opener);
@ -962,7 +999,7 @@ gtk_menu_tracker_item_request_submenu_shown (GtkMenuTrackerItem *self,
if (shown)
g_object_set_data_full (G_OBJECT (self), "submenu-opener",
gtk_menu_tracker_opener_new (self, submenu_action),
gtk_menu_tracker_opener_free);
g_object_unref);
else
g_object_set_data (G_OBJECT (self), "submenu-opener", NULL);
}