mirror of
https://gitlab.gnome.org/GNOME/gimp.git
synced 2025-07-03 17:33:25 +00:00
app: properly remove action from the application when no longer used.
When an action is removed from a group, we verify if it's not in any group anymore. If so, we remove it from the GimpApp action map. This fixes some CRITICALs happening when some actions were dynamically deleted and re-created, in particular the "windows-display-XXXX" actions.
This commit is contained in:
parent
50a3bb57ee
commit
6bed6e1ef8
4 changed files with 67 additions and 18 deletions
|
@ -31,11 +31,16 @@
|
|||
|
||||
#include "core/gimp.h"
|
||||
|
||||
#include "gimpaction.h"
|
||||
#include "gimpactionfactory.h"
|
||||
#include "gimpactiongroup.h"
|
||||
|
||||
|
||||
static void gimp_action_factory_finalize (GObject *object);
|
||||
static void gimp_action_factory_finalize (GObject *object);
|
||||
|
||||
static void gimp_action_factory_action_removed (GimpActionGroup *group,
|
||||
GimpAction *action,
|
||||
GimpActionFactory *factory);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GimpActionFactory, gimp_action_factory, GIMP_TYPE_OBJECT)
|
||||
|
@ -82,6 +87,40 @@ gimp_action_factory_finalize (GObject *object)
|
|||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_action_factory_action_removed (GimpActionGroup *group,
|
||||
GimpAction *action,
|
||||
GimpActionFactory *factory)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
for (list = factory->registered_groups; list; list = g_list_next (list))
|
||||
{
|
||||
GimpActionFactoryEntry *entry = list->data;
|
||||
|
||||
if (entry->group != NULL && entry->group != group)
|
||||
{
|
||||
GList *actions;
|
||||
|
||||
actions = gimp_action_group_list_actions (entry->group);
|
||||
|
||||
if (g_list_find (actions, action))
|
||||
{
|
||||
g_list_free (actions);
|
||||
break;
|
||||
}
|
||||
g_list_free (actions);
|
||||
}
|
||||
}
|
||||
|
||||
if (list == NULL)
|
||||
g_action_map_remove_action (G_ACTION_MAP (factory->gimp->app),
|
||||
gimp_action_get_name (action));
|
||||
}
|
||||
|
||||
|
||||
/* Public functions */
|
||||
|
||||
GimpActionFactory *
|
||||
gimp_action_factory_new (Gimp *gimp)
|
||||
{
|
||||
|
@ -155,6 +194,10 @@ gimp_action_factory_get_group (GimpActionFactory *factory,
|
|||
entry->setup_func (group);
|
||||
|
||||
entry->group = group;
|
||||
|
||||
g_signal_connect_object (group, "action-removed",
|
||||
G_CALLBACK (gimp_action_factory_action_removed),
|
||||
factory, 0);
|
||||
}
|
||||
|
||||
return entry->group;
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
enum
|
||||
{
|
||||
ACTION_ADDED,
|
||||
ACTION_REMOVED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
|
@ -123,6 +124,14 @@ gimp_action_group_class_init (GimpActionGroupClass *klass)
|
|||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1,
|
||||
GIMP_TYPE_ACTION);
|
||||
signals[ACTION_REMOVED] =
|
||||
g_signal_new ("action-removed",
|
||||
G_OBJECT_CLASS_TYPE (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GimpActionGroupClass, action_removed),
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1,
|
||||
GIMP_TYPE_ACTION);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -347,13 +356,7 @@ gimp_action_group_remove_action (GimpActionGroup *group,
|
|||
{
|
||||
group->actions = g_list_remove (group->actions, action);
|
||||
|
||||
/* TODO GAction: we should also check if the action is still present in
|
||||
* another group (maybe if each action keeps track of its own groups, or with
|
||||
* gimp_ui_manager_find_action(), or a "action-removed" signal tracked by the
|
||||
* GimpUIManager which would verify other groups).
|
||||
* If it's not in any group anymore, we should remove the action with
|
||||
* g_action_map_remove_action().
|
||||
*/
|
||||
g_signal_emit (group, signals[ACTION_REMOVED], 0, action);
|
||||
}
|
||||
|
||||
GimpAction *
|
||||
|
|
|
@ -55,8 +55,10 @@ struct _GimpActionGroupClass
|
|||
GHashTable *groups;
|
||||
|
||||
/* signals */
|
||||
void (* action_added) (GimpActionGroup *group,
|
||||
GimpAction *action);
|
||||
void (* action_added) (GimpActionGroup *group,
|
||||
GimpAction *action);
|
||||
void (* action_removed) (GimpActionGroup *group,
|
||||
GimpAction *action);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -906,8 +906,6 @@ gimp_menu_model_ui_removed (GimpUIManager *manager,
|
|||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (app), action_name);
|
||||
|
||||
g_return_val_if_fail (action != NULL, FALSE);
|
||||
|
||||
removed = TRUE;
|
||||
|
||||
for (GList *iter = model->priv->items; iter; iter = iter->next)
|
||||
|
@ -938,12 +936,15 @@ gimp_menu_model_ui_removed (GimpUIManager *manager,
|
|||
|
||||
if (item)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (action,
|
||||
G_CALLBACK (gimp_menu_model_action_notify_visible),
|
||||
model);
|
||||
g_signal_handlers_disconnect_by_func (action,
|
||||
G_CALLBACK (gimp_menu_model_action_notify_label),
|
||||
item);
|
||||
if (action != NULL)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (action,
|
||||
G_CALLBACK (gimp_menu_model_action_notify_visible),
|
||||
model);
|
||||
g_signal_handlers_disconnect_by_func (action,
|
||||
G_CALLBACK (gimp_menu_model_action_notify_label),
|
||||
item);
|
||||
}
|
||||
g_object_unref (item);
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue