app: only <Image> GimpUIManager's actions should be application actions.

This commit is contained in:
Jehan 2023-04-03 22:48:26 +02:00
parent e8294660cc
commit d9b9fa0acd
5 changed files with 141 additions and 78 deletions

View file

@ -69,6 +69,8 @@ struct _GimpActionPrivate
gchar *icon_name;
GIcon *icon;
gchar **accels;
GimpRGB *color;
GimpViewable *viewable;
PangoEllipsizeMode ellipsize;
@ -206,6 +208,7 @@ gimp_action_init (GimpAction *action)
priv->tooltip = NULL;
priv->icon_name = NULL;
priv->icon = NULL;
priv->accels = NULL;
priv->ellipsize = PANGO_ELLIPSIZE_NONE;
priv->max_width_chars = -1;
priv->proxies = NULL;
@ -493,24 +496,16 @@ void
gimp_action_set_accels (GimpAction *action,
const gchar **accels)
{
GimpContext *context;
gchar *detailed_action_name;
GimpActionPrivate *priv = GET_PRIVATE (action);
g_return_if_fail (GIMP_IS_ACTION (action));
context = GET_PRIVATE (action)->context;
if (context == NULL)
if (accels != NULL && priv->accels != NULL &&
g_strv_equal (accels, (const gchar **) priv->accels))
return;
g_return_if_fail (GTK_IS_APPLICATION (context->gimp->app));
detailed_action_name = g_strdup_printf ("app.%s",
g_action_get_name (G_ACTION (action)));
gtk_application_set_accels_for_action (GTK_APPLICATION (context->gimp->app),
detailed_action_name,
accels);
g_free (detailed_action_name);
g_strfreev (priv->accels);
priv->accels = g_strdupv ((gchar **) accels);
g_signal_emit (action, action_signals[ACCELS_CHANGED], 0, accels);
}
@ -525,29 +520,15 @@ gimp_action_set_accels (GimpAction *action,
* Returns: (transfer full): accelerators for @action, as a %NULL-terminated
* array. Free with g_strfreev() when no longer needed
*/
gchar **
const gchar **
gimp_action_get_accels (GimpAction *action)
{
gchar **accels;
GimpContext *context;
gchar *detailed_action_name;
g_return_val_if_fail (GIMP_IS_ACTION (action), NULL);
context = GET_PRIVATE (action)->context;
if (context == NULL)
return NULL;
g_return_val_if_fail (GTK_IS_APPLICATION (context->gimp->app), NULL);
detailed_action_name = g_strdup_printf ("app.%s",
g_action_get_name (G_ACTION (action)));
accels = gtk_application_get_accels_for_action (GTK_APPLICATION (context->gimp->app),
detailed_action_name);
g_free (detailed_action_name);
return accels;
if (GET_PRIVATE (action)->accels != NULL)
return (const gchar **) GET_PRIVATE (action)->accels;
else
return (const gchar **) { NULL };
}
/**
@ -568,9 +549,9 @@ gimp_action_get_display_accels (GimpAction *action)
g_return_val_if_fail (GIMP_IS_ACTION (action), NULL);
accels = gimp_action_get_accels (action);
accels = g_strdupv (GET_PRIVATE (action)->accels);
for (i = 0; accels[i] != NULL; i++)
for (i = 0; accels != NULL && accels[i] != NULL; i++)
{
guint accel_key = 0;
GdkModifierType accel_mods = 0;
@ -1086,6 +1067,8 @@ gimp_action_private_finalize (GimpActionPrivate *priv)
g_free (priv->icon_name);
g_clear_object (&priv->icon);
g_strfreev (priv->accels);
for (GList *iter = priv->proxies; iter; iter = iter->next)
{
/* TODO GAction: if an action associated to a proxy menu item disappears,

View file

@ -109,7 +109,7 @@ gboolean gimp_action_is_sensitive (GimpAction *action,
void gimp_action_set_accels (GimpAction *action,
const gchar **accels);
gchar ** gimp_action_get_accels (GimpAction *action);
const gchar ** gimp_action_get_accels (GimpAction *action);
gchar ** gimp_action_get_display_accels (GimpAction *action);
void gimp_action_activate (GimpAction *action);

View file

@ -197,6 +197,7 @@ gimp_action_group_finalize (GObject *object)
g_clear_pointer (&group->label, g_free);
g_clear_pointer (&group->icon_name, g_free);
g_list_free_full (group->actions, g_object_unref);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -377,15 +378,13 @@ gimp_action_group_add_action_with_accel (GimpActionGroup *group,
GimpAction *action,
const gchar *accelerator)
{
/* Making sure all our Gimp*Action classes are also GAction. */
g_return_if_fail (G_IS_ACTION (action));
g_return_if_fail (GIMP_IS_ACTION (action));
if (! g_list_find (group->actions, action))
{
group->actions = g_list_prepend (group->actions, action);
group->actions = g_list_prepend (group->actions, g_object_ref (action));
g_action_map_add_action (G_ACTION_MAP (group->gimp->app), G_ACTION (action));
g_signal_emit_by_name (group, "action-added", gimp_action_get_name (action));
if ((accelerator != NULL && g_strcmp0 (accelerator, "") != 0))
gimp_action_set_accels (action, (const char*[]) { accelerator, NULL });
@ -396,9 +395,12 @@ void
gimp_action_group_remove_action (GimpActionGroup *group,
GimpAction *action)
{
group->actions = g_list_remove (group->actions, action);
g_signal_emit_by_name (group, "action-removed", gimp_action_get_name (action));
if (g_list_find (group->actions, action))
{
group->actions = g_list_remove (group->actions, action);
g_signal_emit_by_name (group, "action-removed", gimp_action_get_name (action));
g_object_unref (action);
}
}
GimpAction *
@ -498,7 +500,6 @@ gimp_action_group_add_actions (GimpActionGroup *group,
gimp_action_group_add_action_with_accel (group, GIMP_ACTION (action),
entries[i].accelerator);
g_signal_emit_by_name (group, "action-added", entries[i].name);
g_object_unref (action);
}
@ -556,7 +557,6 @@ gimp_action_group_add_toggle_actions (GimpActionGroup *group,
gimp_action_group_add_action_with_accel (group, GIMP_ACTION (action),
entries[i].accelerator);
g_signal_emit_by_name (group, "action-added", entries[i].name);
g_object_unref (action);
}
@ -619,7 +619,6 @@ gimp_action_group_add_radio_actions (GimpActionGroup *group,
gimp_toggle_action_set_active (GIMP_TOGGLE_ACTION (action), TRUE);
gimp_action_group_add_action_with_accel (group, action, entries[i].accelerator);
g_signal_emit_by_name (group, "action-added", entries[i].name);
g_object_unref (action);
}
@ -685,7 +684,6 @@ gimp_action_group_add_enum_actions (GimpActionGroup *group,
gimp_action_group_add_action_with_accel (group, GIMP_ACTION (action),
entries[i].accelerator);
g_signal_emit_by_name (group, "action-added", entries[i].name);
g_object_unref (action);
}
@ -750,7 +748,6 @@ gimp_action_group_add_string_actions (GimpActionGroup *group,
g_object_ref (action);
}
g_signal_emit_by_name (group, "action-added", entries[i].name);
g_object_unref (action);
}
}
@ -806,7 +803,6 @@ gimp_action_group_add_double_actions (GimpActionGroup *group,
gimp_action_group_add_action_with_accel (group, GIMP_ACTION (action),
entries[i].accelerator);
g_signal_emit_by_name (group, "action-added", entries[i].name);
g_object_unref (action);
}
@ -861,7 +857,6 @@ gimp_action_group_add_procedure_actions (GimpActionGroup *group,
gimp_action_group_add_action_with_accel (group, GIMP_ACTION (action),
entries[i].accelerator);
g_signal_emit_by_name (group, "action-added", entries[i].name);
g_object_unref (action);
}

View file

@ -204,15 +204,13 @@ gimp_action_view_new (Gimp *gimp,
if (show_shortcuts)
{
gchar **accels = NULL;
const gchar **accels = NULL;
accels = gimp_action_get_accels (GIMP_ACTION (action));
/* TODO: support multiple accelerators! */
/* TODO GAction: support multiple accelerators! */
if (accels && accels[0])
gtk_accelerator_parse (accels[0], &accel_key, &accel_mask);
g_strfreev (accels);
}
gtk_tree_store_append (store, &action_iter, &group_iter);
@ -506,7 +504,7 @@ gimp_action_view_accels_changed (GimpAction *action,
if (it_action == action)
{
gchar **accels;
const gchar **accels;
guint accel_key = 0;
GdkModifierType accel_mask = 0;

View file

@ -72,33 +72,43 @@ typedef struct
} GimpUIManagerMenuItem;
static void gimp_ui_manager_constructed (GObject *object);
static void gimp_ui_manager_dispose (GObject *object);
static void gimp_ui_manager_finalize (GObject *object);
static void gimp_ui_manager_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_ui_manager_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void gimp_ui_manager_real_update (GimpUIManager *manager,
gpointer update_data);
static void gimp_ui_manager_constructed (GObject *object);
static void gimp_ui_manager_dispose (GObject *object);
static void gimp_ui_manager_finalize (GObject *object);
static void gimp_ui_manager_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_ui_manager_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void gimp_ui_manager_real_update (GimpUIManager *manager,
gpointer update_data);
static GimpUIManagerUIEntry *
gimp_ui_manager_entry_get (GimpUIManager *manager,
const gchar *ui_path);
gimp_ui_manager_entry_get (GimpUIManager *manager,
const gchar *ui_path);
static GimpUIManagerUIEntry *
gimp_ui_manager_entry_ensure (GimpUIManager *manager,
const gchar *path);
static void gimp_ui_manager_delete_popdown_data (GtkWidget *widget,
GimpUIManager *manager);
gimp_ui_manager_entry_ensure (GimpUIManager *manager,
const gchar *path);
static void gimp_ui_manager_delete_popdown_data (GtkWidget *widget,
GimpUIManager *manager);
static void gimp_ui_manager_menu_item_free (GimpUIManagerMenuItem *item);
static void gimp_ui_manager_menu_item_free (GimpUIManagerMenuItem *item);
static void gimp_ui_manager_popup_hidden (GtkMenuShell *popup,
gpointer user_data);
static gboolean gimp_ui_manager_popup_destroy (GtkWidget *popup);
static void gimp_ui_manager_popup_hidden (GtkMenuShell *popup,
gpointer user_data);
static gboolean gimp_ui_manager_popup_destroy (GtkWidget *popup);
static void gimp_ui_manager_image_action_added (GimpActionGroup *group,
gchar *action_name,
GimpUIManager *manager);
static void gimp_ui_manager_image_action_removed (GimpActionGroup *group,
gchar *action_name,
GimpUIManager *manager);
static void gimp_ui_manager_image_accels_changed (GimpAction *action,
const gchar **accels,
GimpUIManager *manager);
G_DEFINE_TYPE (GimpUIManager, gimp_ui_manager, GIMP_TYPE_OBJECT)
@ -393,6 +403,26 @@ gimp_ui_manager_add_action_group (GimpUIManager *manager,
{
if (! g_list_find (manager->action_groups, group))
manager->action_groups = g_list_prepend (manager->action_groups, g_object_ref (group));
/* Special-case the <Image> UI Manager which should be unique and represent
* global application actions.
*/
if (g_strcmp0 (manager->name, "<Image>") == 0)
{
gchar **actions = g_action_group_list_actions (G_ACTION_GROUP (group));
for (int i = 0; i < g_strv_length (actions); i++)
gimp_ui_manager_image_action_added (group, actions[i], manager);
g_signal_connect_object (group, "action-added",
G_CALLBACK (gimp_ui_manager_image_action_added),
manager, 0);
g_signal_connect_object (group, "action-removed",
G_CALLBACK (gimp_ui_manager_image_action_removed),
manager, 0);
g_strfreev (actions);
}
}
GimpActionGroup *
@ -931,3 +961,60 @@ gimp_ui_manager_popup_destroy (GtkWidget *popup)
return G_SOURCE_REMOVE;
}
static void
gimp_ui_manager_image_action_added (GimpActionGroup *group,
gchar *action_name,
GimpUIManager *manager)
{
GimpAction *action;
const gchar **accels;
g_return_if_fail (GIMP_IS_UI_MANAGER (manager));
/* The action should not already exist in the application. */
g_return_if_fail (g_action_map_lookup_action (G_ACTION_MAP (manager->gimp->app), action_name) == NULL);
action = gimp_action_group_get_action (group, action_name);
g_return_if_fail (action != NULL);
g_action_map_add_action (G_ACTION_MAP (manager->gimp->app), G_ACTION (action));
g_signal_connect_object (action, "accels-changed",
G_CALLBACK (gimp_ui_manager_image_accels_changed),
manager, 0);
accels = gimp_action_get_accels (action);
if (accels && g_strv_length ((gchar **) accels) > 0)
gimp_ui_manager_image_accels_changed (action, gimp_action_get_accels (action), manager);
}
static void
gimp_ui_manager_image_action_removed (GimpActionGroup *group,
gchar *action_name,
GimpUIManager *manager)
{
GAction *action;
action = g_action_map_lookup_action (G_ACTION_MAP (manager->gimp->app), action_name);
if (action != NULL)
{
g_action_map_remove_action (G_ACTION_MAP (manager->gimp->app), action_name);
g_signal_handlers_disconnect_by_func (action,
G_CALLBACK (gimp_ui_manager_image_accels_changed),
manager);
}
}
static void
gimp_ui_manager_image_accels_changed (GimpAction *action,
const gchar **accels,
GimpUIManager *manager)
{
gchar *detailed_action_name;
detailed_action_name = g_strdup_printf ("app.%s", g_action_get_name (G_ACTION (action)));
gtk_application_set_accels_for_action (GTK_APPLICATION (manager->gimp->app),
detailed_action_name,
accels);
g_free (detailed_action_name);
}