diff --git a/include/menu/menu.h b/include/menu/menu.h index f55bc365..4dd98796 100644 --- a/include/menu/menu.h +++ b/include/menu/menu.h @@ -85,6 +85,7 @@ bool menu_call_selected_actions(struct server *server); void menu_init(struct server *server); void menu_finish(struct server *server); +void menu_on_view_destroy(struct view *view); /** * menu_get_by_id - get menu by id diff --git a/src/menu/menu.c b/src/menu/menu.c index 882b1eee..6092ce9e 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -1190,6 +1190,36 @@ menu_finish(struct server *server) current_menu = NULL; } +void +menu_on_view_destroy(struct view *view) +{ + struct server *server = view->server; + + /* If the view being destroy has an open window menu, then close it */ + if (server->menu_current + && server->menu_current->triggered_by_view == view) { + menu_close_root(server); + } + + /* + * TODO: Instead of just setting client_list_view to NULL and deleting + * the actions (as below), consider destroying the item and somehow + * updating the menu and its selection state. + */ + + /* Also nullify the destroyed view in client-list-combined-menu */ + struct menu *menu = menu_get_by_id(server, "client-list-combined-menu"); + if (menu) { + struct menuitem *item; + wl_list_for_each(item, &menu->menuitems, link) { + if (item->client_list_view == view) { + item->client_list_view = NULL; + action_list_free(&item->actions); + } + } + } +} + /* Sets selection (or clears selection if passing NULL) */ static void menu_set_selection(struct menu *menu, struct menuitem *item) diff --git a/src/view.c b/src/view.c index bcb86ea0..bdf386ba 100644 --- a/src/view.c +++ b/src/view.c @@ -2453,11 +2453,7 @@ view_destroy(struct view *view) } } - /* If we spawned a window menu, close it */ - if (server->menu_current - && server->menu_current->triggered_by_view == view) { - menu_close_root(server); - } + menu_on_view_destroy(view); /* * Destroy the view's scene tree. View methods assume this is non-NULL,