app: cleanly delete the UI manager and action groups associated to finalized…

… dock windows.

This fixes crashes which happen when switching from multi-window mode to single
window mode.
This commit is contained in:
Jehan 2023-04-11 15:37:01 +02:00
parent 2967020d16
commit df0bd8c183
6 changed files with 92 additions and 6 deletions

View File

@ -512,9 +512,15 @@ GimpMenuFactory *
menus_get_global_menu_factory (Gimp *gimp)
{
static GimpMenuFactory *global_menu_factory = NULL;
static gboolean created = FALSE;
if (global_menu_factory == NULL)
global_menu_factory = gimp_menu_factory_new (gimp, global_action_factory);
if (global_menu_factory == NULL && ! created)
{
global_menu_factory = gimp_menu_factory_new (gimp, global_action_factory);
g_object_add_weak_pointer (G_OBJECT (global_menu_factory),
(gpointer *) &global_menu_factory);
created = TRUE;
}
return global_menu_factory;
}

View File

@ -213,3 +213,31 @@ gimp_action_factory_get_group (GimpActionFactory *factory,
return NULL;
}
void
gimp_action_factory_delete_group (GimpActionFactory *factory,
const gchar *identifier,
gpointer user_data)
{
GList *list;
g_return_if_fail (GIMP_IS_ACTION_FACTORY (factory));
g_return_if_fail (identifier != NULL);
for (list = factory->registered_groups; list; list = g_list_next (list))
{
GimpActionFactoryEntry *entry = list->data;
if (g_strcmp0 (entry->identifier, identifier) == 0)
{
if (! g_hash_table_remove (entry->groups, user_data))
g_warning ("%s: no GimpActionGroup for (id \"%s\", data %p)",
G_STRFUNC, identifier, user_data);
return;
}
}
g_warning ("%s: no entry registered for \"%s\"",
G_STRFUNC, identifier);
}

View File

@ -77,6 +77,9 @@ void gimp_action_factory_group_register (GimpActionFactory
GimpActionGroup * gimp_action_factory_get_group (GimpActionFactory *factory,
const gchar *identifier,
gpointer user_data);
void gimp_action_factory_delete_group (GimpActionFactory *factory,
const gchar *identifier,
gpointer user_data);
#endif /* __GIMP_ACTION_FACTORY_H__ */

View File

@ -485,7 +485,6 @@ gimp_dock_window_dispose (GObject *object)
}
g_clear_object (&dock_window->p->dialog_factory);
g_clear_object (&dock_window->p->context);
G_OBJECT_CLASS (parent_class)->dispose (object);
}
@ -493,9 +492,22 @@ gimp_dock_window_dispose (GObject *object)
static void
gimp_dock_window_finalize (GObject *object)
{
GimpDockWindow *dock_window = GIMP_DOCK_WINDOW (object);
GimpDockWindow *dock_window = GIMP_DOCK_WINDOW (object);
GimpMenuFactory *menu_factory;
Gimp *gimp;
gimp = GIMP (dock_window->p->context->gimp);
menu_factory = menus_get_global_menu_factory (gimp);
/* If the whole GUI is in destruction, global menu factory might already not
* exist anymore.
*/
if (menu_factory != NULL)
gimp_menu_factory_delete_manager (menu_factory,
dock_window->p->ui_manager_name,
dock_window);
g_clear_pointer (&dock_window->p->ui_manager_name, g_free);
g_clear_object (&dock_window->p->context);
G_OBJECT_CLASS (parent_class)->finalize (object);
}

View File

@ -120,6 +120,8 @@ gimp_menu_factory_new (Gimp *gimp,
factory->p->gimp = gimp;
factory->p->action_factory = action_factory;
g_object_add_weak_pointer (G_OBJECT (action_factory),
(gpointer *) &factory->p->action_factory);
return factory;
}
@ -251,3 +253,37 @@ gimp_menu_factory_get_manager (GimpMenuFactory *factory,
return NULL;
}
void
gimp_menu_factory_delete_manager (GimpMenuFactory *factory,
const gchar *identifier,
gpointer callback_data)
{
GList *list;
g_return_if_fail (GIMP_IS_MENU_FACTORY (factory));
g_return_if_fail (identifier != NULL);
for (list = factory->p->registered_menus; list; list = g_list_next (list))
{
GimpMenuFactoryEntry *entry = list->data;
if (g_strcmp0 (entry->identifier, identifier) == 0)
{
if (factory->p->action_factory != NULL)
for (GList *list2 = entry->action_groups; list2; list2 = g_list_next (list2))
gimp_action_factory_delete_group (factory->p->action_factory,
(const gchar *) list2->data,
callback_data);
if (! g_hash_table_remove (entry->managers, callback_data))
g_warning ("%s: no GimpUIManager for (id \"%s\", data %p)",
G_STRFUNC, identifier, callback_data);
return;
}
}
g_warning ("%s: no entry registered for \"%s\"",
G_STRFUNC, identifier);
}

View File

@ -72,8 +72,9 @@ GList * gimp_menu_factory_get_registered_menus (GimpMenuFactory *fac
GimpUIManager * gimp_menu_factory_get_manager (GimpMenuFactory *factory,
const gchar *identifier,
gpointer callback_data);
GimpUIManager * gimp_menu_factory_get_image_manager (GimpMenuFactory *factory);
void gimp_menu_factory_delete_manager (GimpMenuFactory *factory,
const gchar *identifier,
gpointer callback_data);
#endif /* __GIMP_MENU_FACTORY_H__ */