diff options
author | Caolán McNamara <caolanm@redhat.com> | 2021-02-08 13:49:53 +0000 |
---|---|---|
committer | Michael Weghorn <m.weghorn@posteo.de> | 2021-02-23 17:05:11 +0100 |
commit | a6a48971abe61747dc84840890c4bbcbd4c717bf (patch) | |
tree | a41d7e7eeab8eb651c988883b5875bb9e70aed5f | |
parent | 1f0cc101380c20113c86aebc7e80170e675e31ed (diff) |
tdf#140225 call cancel before destroying menubar
a) in case there are some menus open cancel them before removing
their parent menubar
b) before a GtkSalMenu is deleted clear the action-group of its members
squash of...
Related: tdf#140225 ignore activate/deactivate of a disposed VclMenu
prep work for improved solution for tdf#140225
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110699
Tested-by: Caolán McNamara <caolanm@redhat.com>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Related: tdf#140225 when clearing pItemList, keep SalMenu in sync
with their removal during menu teardown
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110703
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Resolves: tdf#140225 remove action when item is removed from GtkSalMenu
and we have previously ensured that all items are removed by
Menu::dispose before GtkSalMenu dtor is called
Change-Id: I9ec59c52c72b8b58976a8ee41727ca7612ebf6b1
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110564
Tested-by: Jenkins
Reviewed-by: Adolfo Jayme Barrientos <fitojb@ubuntu.com>
(cherry picked from commit 4abe4e9c92641896b4a0949e8a64a231d2f41c86)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110867
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Michael Weghorn <m.weghorn@posteo.de>
-rw-r--r-- | vcl/source/window/menu.cxx | 13 | ||||
-rw-r--r-- | vcl/unx/gtk3/gtk3gtksalmenu.cxx | 28 |
2 files changed, 36 insertions, 5 deletions
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index eacfb865ffcd..7d4a34678ada 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -213,7 +213,18 @@ void Menu::dispose() bKilled = true; - pItemList->Clear(); + // tdf#140225 when clearing pItemList, keep SalMenu in sync with + // their removal during menu teardown + for (size_t n = pItemList->size(); n;) + { + --n; + if (mpSalMenu) + mpSalMenu->RemoveItem(n); + pItemList->Remove(n); + } + + assert(!pItemList->size()); + mpLayoutData.reset(); // Native-support: destroy SalMenu diff --git a/vcl/unx/gtk3/gtk3gtksalmenu.cxx b/vcl/unx/gtk3/gtk3gtksalmenu.cxx index f78bbab0081f..3ed2487ff4f3 100644 --- a/vcl/unx/gtk3/gtk3gtksalmenu.cxx +++ b/vcl/unx/gtk3/gtk3gtksalmenu.cxx @@ -596,13 +596,15 @@ GtkSalMenu::~GtkSalMenu() { SolarMutexGuard aGuard; + // tdf#140225 we expect all items to be removed by Menu::dispose + // before this dtor is called + assert(maItems.empty()); + DestroyMenuBarWidget(); if (mpMenuModel) g_object_unref(mpMenuModel); - maItems.clear(); - if (mpFrame) mpFrame->SetMenu(nullptr); } @@ -630,6 +632,16 @@ void GtkSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos ) void GtkSalMenu::RemoveItem( unsigned nPos ) { SolarMutexGuard aGuard; + + // tdf#140225 clear associated action when the item is removed + if (mpActionGroup) + { + GLOActionGroup* pActionGroup = G_LO_ACTION_GROUP(mpActionGroup); + gchar* pCommand = GetCommandForItem(maItems[nPos]); + g_lo_action_group_remove(pActionGroup, pCommand); + g_free(pCommand); + } + maItems.erase( maItems.begin() + nPos ); SetNeedsUpdate(); } @@ -998,6 +1010,10 @@ void GtkSalMenu::DestroyMenuBarWidget() { if (mpMenuBarContainerWidget) { + // tdf#140225 call cancel before destroying it in case there are some + // active menus popped open + gtk_menu_shell_cancel(GTK_MENU_SHELL(mpMenuBarWidget)); + gtk_widget_destroy(mpMenuBarContainerWidget); mpMenuBarContainerWidget = nullptr; mpCloseButton = nullptr; @@ -1345,8 +1361,10 @@ void GtkSalMenu::Activate(const gchar* pCommand) { MenuAndId aMenuAndId = decode_command(pCommand); GtkSalMenu* pSalMenu = aMenuAndId.first; - GtkSalMenu* pTopLevel = pSalMenu->GetTopLevel(); Menu* pVclMenu = pSalMenu->GetMenu(); + if (pVclMenu->isDisposed()) + return; + GtkSalMenu* pTopLevel = pSalMenu->GetTopLevel(); Menu* pVclSubMenu = pVclMenu->GetPopupMenu(aMenuAndId.second); GtkSalMenu* pSubMenu = pSalMenu->GetItemAtPos(pVclMenu->GetItemPos(aMenuAndId.second))->mpSubMenu; @@ -1360,8 +1378,10 @@ void GtkSalMenu::Deactivate(const gchar* pCommand) { MenuAndId aMenuAndId = decode_command(pCommand); GtkSalMenu* pSalMenu = aMenuAndId.first; - GtkSalMenu* pTopLevel = pSalMenu->GetTopLevel(); Menu* pVclMenu = pSalMenu->GetMenu(); + if (pVclMenu->isDisposed()) + return; + GtkSalMenu* pTopLevel = pSalMenu->GetTopLevel(); Menu* pVclSubMenu = pVclMenu->GetPopupMenu(aMenuAndId.second); pTopLevel->GetMenu()->HandleMenuDeActivateEvent(pVclSubMenu); } |