summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2021-02-08 13:49:53 +0000
committerMichael Weghorn <m.weghorn@posteo.de>2021-02-23 17:05:11 +0100
commita6a48971abe61747dc84840890c4bbcbd4c717bf (patch)
treea41d7e7eeab8eb651c988883b5875bb9e70aed5f
parent1f0cc101380c20113c86aebc7e80170e675e31ed (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.cxx13
-rw-r--r--vcl/unx/gtk3/gtk3gtksalmenu.cxx28
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);
}