Skip to content

Commit 6708246

Browse files
tdf#164093 tdf#157001 a11y: Improve menu window disposal
In MenuFloatingWindow::dispose, unset the accessible before calling the base class implementation, to prevent the accessible from getting disposed there as well. This is necessary because the MenuFloatingWindow doesn't create (and therefore own) its accessible object, but returns that from its menu in MenuFloatingWindow::CreateAccessible. Therefore, the PopupMenu as the owner is responsible for disposing the accessible as well, not the MenuFloatingWindow. This logic was already implemented in Menu::dispose, but that doesn't help in cases where the MenuFloatingWindow gets disposed independently. In Menu::dispose, drop the extra logic and just call `m_pWindow.disposeAndClear` so that MenuFloatingWindow::dispose can take care of everything that's needed. (For the MenuBar case, MenuBar::dispose calls MenuBar::ImplDestroy, which unsets Menu::m_pWindow, so other than for PopupMenu, this change to MenuBar::ImplDestroy method doesn't make a difference for that class.) Don't dispose the current Menu::m_pWindow in PopupMenu::FinishRun, but instead in PopupMenu::ImplExecute (if set) before assigning a new one, to ensure that the old one gets disposed. Drop the SAL_WARN_IF(GetWindow(), "vcl", "Win?!"); because that case is handled fine now. Without this change in place, I saw that warning getting triggered while debugging (potentially because PopupMenu::FinishRun never got reached as the menu didn't show, maybe due to switching focus to the IDE when reaching a breakpoint or different timing,...). This commit by itself doesn't yet fix the crash from tdf#164093 seen on Windows with NVDA running because the menu's accessible still incorrectly gets disposed by the MenuFloatingWindow's VCLXWindow (toolkit window peer). That will be addressed in a separate commit. Change-Id: Ia2931bee23204395e8b3396927acf4fa1d0f077c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177883 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]>
1 parent 13a9a23 commit 6708246

File tree

2 files changed

+8
-11
lines changed

2 files changed

+8
-11
lines changed

vcl/source/window/menu.cxx

+3-11
Original file line numberDiff line numberDiff line change
@@ -189,15 +189,7 @@ void Menu::dispose()
189189
{
190190
ImplCallEventListeners( VclEventId::ObjectDying, ITEMPOS_INVALID );
191191

192-
// at the window free the reference to the accessible component
193-
// and make sure the MenuFloatingWindow knows about our destruction
194-
if (m_pWindow)
195-
{
196-
MenuFloatingWindow* pFloat = static_cast<MenuFloatingWindow*>(m_pWindow.get());
197-
if( pFloat->pMenu.get() == this )
198-
pFloat->pMenu.clear();
199-
m_pWindow->SetAccessible( css::uno::Reference< css::accessibility::XAccessible >() );
200-
}
192+
m_pWindow.disposeAndClear();
201193

202194
// dispose accessible components
203195
comphelper::disposeComponent(mxAccessible);
@@ -2890,7 +2882,6 @@ sal_uInt16 PopupMenu::ImplExecute(const VclPtr<vcl::Window>& pParentWin, const t
28902882
| FloatWinPopupEndFlags::CloseAll);
28912883
}
28922884

2893-
SAL_WARN_IF(GetWindow(), "vcl", "Win?!");
28942885
tools::Rectangle aRect(rRect);
28952886
aRect.SetPos(pParentWin->OutputToScreenPixel(aRect.TopLeft()));
28962887

@@ -2951,6 +2942,8 @@ sal_uInt16 PopupMenu::ImplExecute(const VclPtr<vcl::Window>& pParentWin, const t
29512942
pWin->SetBorderStyle( WindowBorderStyle::NOBORDER );
29522943
else
29532944
pWin->SetBorderStyle( pWin->GetBorderStyle() | WindowBorderStyle::MENU );
2945+
2946+
m_pWindow.disposeAndClear();
29542947
m_pWindow = pWin;
29552948

29562949
Size aSz = ImplCalcSize( pWin );
@@ -3084,7 +3077,6 @@ void PopupMenu::FinishRun(const VclPtr<MenuFloatingWindow>& pWin, const VclPtr<v
30843077
pWin->StopExecute();
30853078

30863079
pWin->doShutdown();
3087-
m_pWindow.disposeAndClear();
30883080
ImplClosePopupToolBox(pParentWin);
30893081
ImplFlushPendingSelect();
30903082
}

vcl/source/window/menufloatingwindow.cxx

+5
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ void MenuFloatingWindow::dispose()
125125
pMenu.clear();
126126
pActivePopup.clear();
127127
xSaveFocusId.clear();
128+
129+
// unset accessible taken from the PopupMenu (s. CreateAccessible),
130+
// it is owned and therefore disposed by the PopupMenu
131+
SetAccessible(nullptr);
132+
128133
FloatingWindow::dispose();
129134
}
130135

0 commit comments

Comments
 (0)