From 543032277307ae9505c10aebf0a2ac3161f837cb Mon Sep 17 00:00:00 2001 From: Michael Weghorn Date: Tue, 21 Jul 2026 15:41:23 +0200 Subject: [PATCH] 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(std::__invoke_other, QtInstanceWindow::set_window_state(vcl::WindowData const&)::$_0&) invoke.h 63 0x7fc1fd3548a5 3 std::__invoke_r(QtInstanceWindow::set_window_state(vcl::WindowData const&)::$_0&) invoke.h 113 0x7fc1fd354865 4 std::_Function_handler::_M_invoke std_function.h 292 0x7fc1fd35474d 5 std::function::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, 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 ... 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::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 Tested-by: Jenkins --- vcl/qt5/QtInstanceWindow.cxx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/vcl/qt5/QtInstanceWindow.cxx b/vcl/qt5/QtInstanceWindow.cxx index 756c5c588e83..fdc67261b5e1 100644 --- a/vcl/qt5/QtInstanceWindow.cxx +++ b/vcl/qt5/QtInstanceWindow.cxx @@ -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); } }); }