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:
Michael Weghorn
2026-07-23 23:22:13 +02:00
parent 5f725594d8
commit 5430322773
+10 -4
View File
@@ -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);
}
});
}