tdf#130857 qt weld: Don't always show window when setting state
When setting the window state to normal, maximized, minimized
or fullscreen in QtInstanceWindow::set_window_state,
only set the corresponding window states, but don't call
QWidget::showNormal, QWidget::showMaximized, etc.
The latter would set the window state and in addition
set the widget to visible, which
weld::Window::set_window_state is not supposed to
do.
This resulted in the problem that after starting various
Calc dialogs (with previously saved window state) and then
closing them again wouldn't result in the Calc window
becoming fully usable again, as the SfxDialogController's
Close Method wasn't called.
This could be reproduced e.g. like this:
* start Calc
* "Data" -> "Statistics" -> "Sampling..."
* maximize the dialog
* close the dialog
* start the dialog again
* close the dialog again
When the dialog gets started, the window state would be
restored/set like this and implicitly set the window/dialog
to visible:
1 QtInstanceWindow::set_window_state(vcl::WindowData const&)::$_0::operator()() const QtInstanceWindow.cxx 139 0x7fc1fd354a95
2 std::__invoke_impl<void, QtInstanceWindow::set_window_state(vcl::WindowData const&)::$_0&>(std::__invoke_other, QtInstanceWindow::set_window_state(vcl::WindowData const&)::$_0&) invoke.h 63 0x7fc1fd3548a5
3 std::__invoke_r<void, QtInstanceWindow::set_window_state(vcl::WindowData const&)::$_0&>(QtInstanceWindow::set_window_state(vcl::WindowData const&)::$_0&) invoke.h 113 0x7fc1fd354865
4 std::_Function_handler<void(), QtInstanceWindow::set_window_state(vcl::WindowData const&)::$_0>::_M_invoke std_function.h 292 0x7fc1fd35474d
5 std::function<void()>::operator() std_function.h 593 0x7fc1fd23117e
6 QtInstance::RunInMainThread QtInstance.cxx 216 0x7fc1fd22890f
7 QtInstanceWindow::set_window_state QtInstanceWindow.cxx 120 0x7fc1fd351e64
8 SfxModelessDialogController::Initialize basedlgs.cxx 72 0x7fc20c0d8ee2
9 ScTabViewShell::CreateRefDialogController tabvwshc.cxx 454 0x7fc1c4594310
10 ChildControllerWrapper<(short)26171>::ChildControllerWrapper ChildWindowWrapper.hxx 34 0x7fc1c3b7cf42
11 std::make_unique<ChildControllerWrapper<(short)26171>, vcl::Window *&, unsigned short&, SfxBindings&, SfxChildWinInfo&> unique_ptr.h 1103 0x7fc1c3b7ccc6
12 ChildControllerWrapper<(short)26171>::CreateImpl ChildWindowWrapper.hxx 44 0x7fc1c3b7cc34
13 SfxChildWindow::CreateChildWindow childwin.cxx 244 0x7fc20bec1a32
14 SfxWorkWindow::CreateChildWin_Impl workwin.cxx 1367 0x7fc20bf5abea
15 SfxWorkWindow::ToggleChildWindow_Impl workwin.cxx 1850 0x7fc20bf5cf83
16 SfxWorkWindow::SetChildWindow_Impl workwin.cxx 1948 0x7fc20bf5d7eb
17 SfxViewFrame::SetChildWindow viewfrm.cxx 3780 0x7fc20c649957
18 ScModule::SetRefDialog scmod.cxx 1610 0x7fc1c3b8eac1
19 ScCellShell::ExecuteEdit cellsh1.cxx 1047 0x7fc1c4341a8c
20 SfxStubScCellShellExecuteEdit scslots.hxx 7919 0x7fc1c4336365
... <More>
Due to the dialog already having been set to visible,
the call to weld::Widget::get_visible in
SfxWorkWindow::ShowChildren_Impl would then return true,
so weld::DialogController::runAsync would not be called,
and therefore the function to run when the dialog closes
would not be set, which would have taken care of calling
SfxDialogController::Close:
if (!pCli->xController->getDialog()->get_visible())
{
auto xController = pCli->xController;
weld::DialogController::runAsync(xController,
[=](sal_Int32 nResult){
if (nResult == nCloseResponseToJustHide)
return;
xController->Close();
});
}
Backtrace:
1 QtInstanceWidget::get_visible QtInstanceWidget.cxx 76 0x7fc1fd33d70d
-> 2 SfxWorkWindow::ShowChildren_Impl workwin.cxx 1004 0x7fc20bf55310
3 SfxWorkWindow::ToggleChildWindow_Impl workwin.cxx 1860 0x7fc20bf5cfac
4 SfxWorkWindow::SetChildWindow_Impl workwin.cxx 1948 0x7fc20bf5d7eb
5 SfxViewFrame::SetChildWindow viewfrm.cxx 3780 0x7fc20c649957
6 ScModule::SetRefDialog scmod.cxx 1610 0x7fc1c3b8eac1
7 ScCellShell::ExecuteEdit cellsh1.cxx 1047 0x7fc1c4341a8c
8 SfxStubScCellShellExecuteEdit scslots.hxx 7919 0x7fc1c4336365
9 SfxDispatcher::Call_Impl dispatch.cxx 258 0x7fc20bfc5b2e
10 SfxDispatcher::Execute_ dispatch.cxx 757 0x7fc20bfca1f6
11 SfxBindings::Execute_Impl bindings.cxx 1047 0x7fc20bfb20ae
12 SfxDispatchController_Impl::dispatch unoctitm.cxx 737 0x7fc20c08e2bd
13 SfxOfficeDispatch::dispatch unoctitm.cxx 256 0x7fc20c08cd74
14 framework::(anonymous namespace)::AsyncMenuExecute menubarmanager.cxx 793 0x7fc20d5551a4
15 Link<void *, void>::Call link.hxx 105 0x7fc2062aaf01
16 ImplHandleUserEvent winproc.cxx 2314 0x7fc2062a6841
17 ImplWindowFrameProc winproc.cxx 2869 0x7fc2062a3775
18 SalFrame::CallCallback salframe.hxx 309 0x7fc1fd209a8c
19 QtInstance::ProcessEvent QtInstance.cxx 564 0x7fc1fd22b76f
20 SalUserEventList::DispatchUserEvents(bool)::$_0::operator()() const salusereventlist.cxx 119 0x7fc20687d48d
21 SalUserEventList::DispatchUserEvents salusereventlist.cxx 120 0x7fc20687d364
22 QtInstance::ImplYield QtInstance.cxx 458 0x7fc1fd2280d1
23 QtInstance::DoYield QtInstance.cxx 480 0x7fc1fd22b331
24 InnerYield svapp.cxx 389 0x7fc2069466e6
25 Application::Yield svapp.cxx 502 0x7fc206945f6f
26 Application::Execute svapp.cxx 364 0x7fc206945d50
27 desktop::Desktop::Main app.cxx 1679 0x7fc21031f0f5
28 ImplSVMainRun svmain.cxx 234 0x7fc20696f8cc
29 SalInstance::SVMainRun salinst.hxx 108 0x7fc1fd233851
30 ImplSVMain svmain.cxx 221 0x7fc20696edf2
31 SVMain svmain.cxx 252 0x7fc206970989
32 soffice_main sofficemain.cxx 122 0x7fc21039916a
33 sal_main main.c 51 0x564fe704c9fd
34 main main.c 49 0x564fe704c9d7
Change-Id: Ic3860a83572126244ea625c5e4c97eeebcf8e4b3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/208399
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Tested-by: Jenkins
This commit is contained in:
@@ -132,13 +132,19 @@ void QtInstanceWindow::set_window_state(const vcl::WindowData& rState)
|
||||
|
||||
if (eMask & vcl::WindowDataMask::State)
|
||||
{
|
||||
Qt::WindowStates eWindowStates = getQWidget()->windowState();
|
||||
eWindowStates &= ~(Qt::WindowState::WindowFullScreen | Qt::WindowState::WindowMaximized
|
||||
| Qt::WindowState::WindowMinimized);
|
||||
|
||||
const vcl::WindowState eState = rState.state();
|
||||
if (eState & vcl::WindowState::Normal)
|
||||
getQWidget()->showNormal();
|
||||
if (eState & vcl::WindowState::FullScreen)
|
||||
eWindowStates |= Qt::WindowState::WindowFullScreen;
|
||||
else if (eState & vcl::WindowState::Maximized)
|
||||
getQWidget()->showMaximized();
|
||||
eWindowStates |= Qt::WindowState::WindowMaximized;
|
||||
else if (eState & vcl::WindowState::Minimized)
|
||||
getQWidget()->showMinimized();
|
||||
eWindowStates |= Qt::WindowState::WindowMinimized;
|
||||
|
||||
getQWidget()->setWindowState(eWindowStates);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user