include/svx/dialog/ThemeDialog.hxx | 1 include/vcl/weld.hxx | 10 +-- svx/source/dialog/ThemeDialog.cxx | 3 - vcl/inc/qt5/QtInstanceDialog.hxx | 3 + vcl/inc/qt5/QtInstanceWindow.hxx | 3 - vcl/inc/salvtables.hxx | 16 +++--- vcl/qt5/QtInstanceBuilder.cxx | 1 vcl/qt5/QtInstanceDialog.cxx | 11 ++++ vcl/qt5/QtInstanceWindow.cxx | 11 ---- vcl/source/app/salvtables.cxx | 94 ++++++++++++++++++------------------- vcl/unx/gtk3/gtkinst.cxx | 66 ++++++++++++------------- 11 files changed, 109 insertions(+), 110 deletions(-)
New commits: commit 7766ac1e4b6f8c52aa3231757cf4eb9f1e8941ca Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Sat Jul 26 00:36:10 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Tue Jul 29 05:20:48 2025 +0200 tdf#130857 weld: Move methods to set default widget to Dialog The GTK 4 doc e.g. says for gtk_window_set_default_widget [1]: > The default widget is the widget that is activated when the user > presses Enter in a dialog (for example). For Qt, that concept of a default widget (or rather, a default button) applies for dialogs only, see [2]. In LO, it's also exclusively used for dialogs, so move weld::Window::is_default_widget and weld::Window::change_default_widget to the weld::Dialog subclass. [1] https://docs.gtk.org/gtk4/method.Window.set_default_widget.html [2] https://doc.qt.io/qt-6/qdialog.html#default-button Change-Id: If5042dce9b10c9c4f3450a1aa1299bec81c16771 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188379 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index cdd4f7647319..0ff0deb58c93 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -582,11 +582,6 @@ public: virtual bool has_toplevel_focus() const = 0; virtual void present() = 0; - // with pOld of null, automatically find the old default widget and unset - // it, otherwise use as hint to the old default - virtual void change_default_widget(weld::Widget* pOld, weld::Widget* pNew) = 0; - virtual bool is_default_widget(const weld::Widget* pCandidate) const = 0; - virtual void set_window_state(const OUString& rStr) = 0; virtual OUString get_window_state(vcl::WindowDataMask nMask) const = 0; @@ -664,6 +659,11 @@ public: virtual std::unique_ptr<Button> weld_button_for_response(int response) = 0; virtual std::unique_ptr<weld::Container> weld_content_area() = 0; + // with pOld of null, automatically find the old default widget and unset + // it, otherwise use as hint to the old default + virtual void change_default_widget(weld::Widget* pOld, weld::Widget* pNew) = 0; + virtual bool is_default_widget(const weld::Widget* pCandidate) const = 0; + // shrink the dialog down to shown just these widgets virtual void collapse(weld::Widget* pEdit, weld::Widget* pButton) = 0; // undo previous dialog collapse diff --git a/vcl/inc/qt5/QtInstanceDialog.hxx b/vcl/inc/qt5/QtInstanceDialog.hxx index 72f97ef0f1ac..7d503ab4e893 100644 --- a/vcl/inc/qt5/QtInstanceDialog.hxx +++ b/vcl/inc/qt5/QtInstanceDialog.hxx @@ -62,6 +62,9 @@ public: virtual std::unique_ptr<weld::Container> weld_content_area() override; + virtual void change_default_widget(weld::Widget*, weld::Widget*) override; + virtual bool is_default_widget(const weld::Widget*) const override; + static QDialogButtonBox* findButtonBox(const QDialog* pDialog); static void handleButtonClick(QDialog& rDialog, QAbstractButton& rButton); diff --git a/vcl/inc/qt5/QtInstanceWindow.hxx b/vcl/inc/qt5/QtInstanceWindow.hxx index e22ec9a4cb76..f1f44739eff6 100644 --- a/vcl/inc/qt5/QtInstanceWindow.hxx +++ b/vcl/inc/qt5/QtInstanceWindow.hxx @@ -33,9 +33,6 @@ public: virtual bool has_toplevel_focus() const override; virtual void present() override; - virtual void change_default_widget(weld::Widget*, weld::Widget*) override; - virtual bool is_default_widget(const weld::Widget*) const override; - virtual void set_window_state(const OUString& rStr) override; virtual OUString get_window_state(vcl::WindowDataMask eMask) const override; diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx index 5a000d1c31fa..4accdc655816 100644 --- a/vcl/inc/salvtables.hxx +++ b/vcl/inc/salvtables.hxx @@ -452,10 +452,6 @@ private: void clear_child_help(vcl::Window* pParent); - void recursively_unset_default_buttons(); - - void implResetDefault(const vcl::Window* _pWindow); - public: SalInstanceWindow(vcl::Window* pWindow, SalInstanceBuilder* pBuilder, bool bTakeOwnership); @@ -483,10 +479,6 @@ public: virtual void present() override; - virtual void change_default_widget(weld::Widget* pOld, weld::Widget* pNew) override; - - virtual bool is_default_widget(const weld::Widget* pCandidate) const override; - virtual void set_window_state(const OUString& rStr) override; virtual OUString get_window_state(vcl::WindowDataMask nMask) const override; @@ -516,6 +508,10 @@ private: DECL_LINK(PopupScreenShotMenuHdl, const CommandEvent&, bool); + void recursively_unset_default_buttons(); + + void implResetDefault(const vcl::Window* _pWindow); + public: SalInstanceDialog(::Dialog* pDialog, SalInstanceBuilder* pBuilder, bool bTakeOwnership); @@ -551,6 +547,10 @@ public: virtual std::unique_ptr<weld::Container> weld_content_area() override; + virtual void change_default_widget(weld::Widget* pOld, weld::Widget* pNew) override; + + virtual bool is_default_widget(const weld::Widget* pCandidate) const override; + ::Dialog* getDialog() { return m_xDialog; } }; diff --git a/vcl/qt5/QtInstanceDialog.cxx b/vcl/qt5/QtInstanceDialog.cxx index e9b5af5642bb..647b12c1e3da 100644 --- a/vcl/qt5/QtInstanceDialog.cxx +++ b/vcl/qt5/QtInstanceDialog.cxx @@ -190,6 +190,17 @@ std::unique_ptr<weld::Container> QtInstanceDialog::weld_content_area() return std::make_unique<QtInstanceContainer>(m_pContentArea); } +void QtInstanceDialog::change_default_widget(weld::Widget*, weld::Widget*) +{ + assert(false && "Not implemented yet"); +} + +bool QtInstanceDialog::is_default_widget(const weld::Widget*) const +{ + assert(false && "Not implemented yet"); + return true; +} + void QtInstanceDialog::dialogFinished(int nResult) { SolarMutexGuard g; diff --git a/vcl/qt5/QtInstanceWindow.cxx b/vcl/qt5/QtInstanceWindow.cxx index e03626882e9a..8de97acbcbaf 100644 --- a/vcl/qt5/QtInstanceWindow.cxx +++ b/vcl/qt5/QtInstanceWindow.cxx @@ -110,17 +110,6 @@ void QtInstanceWindow::present() }); } -void QtInstanceWindow::change_default_widget(weld::Widget*, weld::Widget*) -{ - assert(false && "Not implemented yet"); -} - -bool QtInstanceWindow::is_default_widget(const weld::Widget*) const -{ - assert(false && "Not implemented yet"); - return true; -} - void QtInstanceWindow::set_window_state(const OUString& rStr) { SolarMutexGuard g; diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 600c208c283a..65665e0fced2 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -1667,53 +1667,6 @@ void SalInstanceWindow::present() m_xWindow->ToTop(ToTopFlags::RestoreWhenMin | ToTopFlags::ForegroundTask); } -void SalInstanceWindow::implResetDefault(const vcl::Window* _pWindow) -{ - vcl::Window* pChildLoop = _pWindow->GetWindow(GetWindowType::FirstChild); - while (pChildLoop) - { - // does the window participate in the tabbing order? - if (pChildLoop->GetStyle() & WB_DIALOGCONTROL) - implResetDefault(pChildLoop); - - // is it a button? - WindowType eType = pChildLoop->GetType(); - if ((WindowType::PUSHBUTTON == eType) || (WindowType::OKBUTTON == eType) - || (WindowType::CANCELBUTTON == eType) || (WindowType::HELPBUTTON == eType) - || (WindowType::IMAGEBUTTON == eType) || (WindowType::MENUBUTTON == eType) - || (WindowType::MOREBUTTON == eType)) - { - pChildLoop->SetStyle(pChildLoop->GetStyle() & ~WB_DEFBUTTON); - } - - // the next one ... - pChildLoop = pChildLoop->GetWindow(GetWindowType::Next); - } -} - -void SalInstanceWindow::recursively_unset_default_buttons() { implResetDefault(m_xWindow.get()); } - -void SalInstanceWindow::change_default_widget(weld::Widget* pOld, weld::Widget* pNew) -{ - SalInstanceWidget* pVclNew = dynamic_cast<SalInstanceWidget*>(pNew); - vcl::Window* pWidgetNew = pVclNew ? pVclNew->getWidget() : nullptr; - SalInstanceWidget* pVclOld = dynamic_cast<SalInstanceWidget*>(pOld); - vcl::Window* pWidgetOld = pVclOld ? pVclOld->getWidget() : nullptr; - if (pWidgetOld) - pWidgetOld->set_property(u"has-default"_ustr, OUString::boolean(false)); - else - recursively_unset_default_buttons(); - if (pWidgetNew) - pWidgetNew->set_property(u"has-default"_ustr, OUString::boolean(true)); -} - -bool SalInstanceWindow::is_default_widget(const weld::Widget* pCandidate) const -{ - const SalInstanceWidget* pVclCandidate = dynamic_cast<const SalInstanceWidget*>(pCandidate); - vcl::Window* pWidget = pVclCandidate ? pVclCandidate->getWidget() : nullptr; - return pWidget && pWidget->GetStyle() & WB_DEFBUTTON; -} - void SalInstanceWindow::set_window_state(const OUString& rStr) { SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get()); @@ -1977,6 +1930,53 @@ std::unique_ptr<weld::Container> SalInstanceDialog::weld_content_area() return std::make_unique<SalInstanceContainer>(m_xDialog->get_content_area(), m_pBuilder, false); } +void SalInstanceDialog::implResetDefault(const vcl::Window* _pWindow) +{ + vcl::Window* pChildLoop = _pWindow->GetWindow(GetWindowType::FirstChild); + while (pChildLoop) + { + // does the window participate in the tabbing order? + if (pChildLoop->GetStyle() & WB_DIALOGCONTROL) + implResetDefault(pChildLoop); + + // is it a button? + WindowType eType = pChildLoop->GetType(); + if ((WindowType::PUSHBUTTON == eType) || (WindowType::OKBUTTON == eType) + || (WindowType::CANCELBUTTON == eType) || (WindowType::HELPBUTTON == eType) + || (WindowType::IMAGEBUTTON == eType) || (WindowType::MENUBUTTON == eType) + || (WindowType::MOREBUTTON == eType)) + { + pChildLoop->SetStyle(pChildLoop->GetStyle() & ~WB_DEFBUTTON); + } + + // the next one ... + pChildLoop = pChildLoop->GetWindow(GetWindowType::Next); + } +} + +void SalInstanceDialog::recursively_unset_default_buttons() { implResetDefault(m_xDialog.get()); } + +void SalInstanceDialog::change_default_widget(weld::Widget* pOld, weld::Widget* pNew) +{ + SalInstanceWidget* pVclNew = dynamic_cast<SalInstanceWidget*>(pNew); + vcl::Window* pWidgetNew = pVclNew ? pVclNew->getWidget() : nullptr; + SalInstanceWidget* pVclOld = dynamic_cast<SalInstanceWidget*>(pOld); + vcl::Window* pWidgetOld = pVclOld ? pVclOld->getWidget() : nullptr; + if (pWidgetOld) + pWidgetOld->set_property(u"has-default"_ustr, OUString::boolean(false)); + else + recursively_unset_default_buttons(); + if (pWidgetNew) + pWidgetNew->set_property(u"has-default"_ustr, OUString::boolean(true)); +} + +bool SalInstanceDialog::is_default_widget(const weld::Widget* pCandidate) const +{ + const SalInstanceWidget* pVclCandidate = dynamic_cast<const SalInstanceWidget*>(pCandidate); + vcl::Window* pWidget = pVclCandidate ? pVclCandidate->getWidget() : nullptr; + return pWidget && pWidget->GetStyle() & WB_DEFBUTTON; +} + IMPL_LINK(SalInstanceDialog, PopupScreenShotMenuHdl, const CommandEvent&, rCEvt, bool) { if (CommandEventId::ContextMenu == rCEvt.GetCommand()) diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx index c41ccc5ea056..54b15c0d6f9b 100644 --- a/vcl/unx/gtk3/gtkinst.cxx +++ b/vcl/unx/gtk3/gtkinst.cxx @@ -6518,39 +6518,6 @@ public: gtk_window_present(m_pWindow); } - virtual void change_default_widget(weld::Widget* pOld, weld::Widget* pNew) override - { - GtkInstanceWidget* pGtkNew = dynamic_cast<GtkInstanceWidget*>(pNew); - GtkWidget* pWidgetNew = pGtkNew ? pGtkNew->getWidget() : nullptr; -#if GTK_CHECK_VERSION(4, 0, 0) - gtk_window_set_default_widget(m_pWindow, pWidgetNew); - (void)pOld; -#else - GtkInstanceWidget* pGtkOld = dynamic_cast<GtkInstanceWidget*>(pOld); - GtkWidget* pWidgetOld = pGtkOld ? pGtkOld->getWidget() : nullptr; - if (pWidgetOld) - g_object_set(G_OBJECT(pWidgetOld), "has-default", false, nullptr); - else - recursively_unset_default_buttons(); - if (pWidgetNew) - g_object_set(G_OBJECT(pWidgetNew), "has-default", true, nullptr); -#endif - } - - virtual bool is_default_widget(const weld::Widget* pCandidate) const override - { - const GtkInstanceWidget* pGtkCandidate = dynamic_cast<const GtkInstanceWidget*>(pCandidate); - GtkWidget* pWidget = pGtkCandidate ? pGtkCandidate->getWidget() : nullptr; -#if GTK_CHECK_VERSION(4, 0, 0) - return pWidget && gtk_window_get_default_widget(m_pWindow) == pWidget; -#else - gboolean has_default(false); - if (pWidget) - g_object_get(G_OBJECT(pWidget), "has-default", &has_default, nullptr); - return has_default; -#endif - } - virtual void set_window_state(const OUString& rStr) override { const vcl::WindowData aData(rStr); @@ -7271,6 +7238,39 @@ public: #endif } + virtual void change_default_widget(weld::Widget* pOld, weld::Widget* pNew) override + { + GtkInstanceWidget* pGtkNew = dynamic_cast<GtkInstanceWidget*>(pNew); + GtkWidget* pWidgetNew = pGtkNew ? pGtkNew->getWidget() : nullptr; +#if GTK_CHECK_VERSION(4, 0, 0) + gtk_window_set_default_widget(m_pDialog, pWidgetNew); + (void)pOld; +#else + GtkInstanceWidget* pGtkOld = dynamic_cast<GtkInstanceWidget*>(pOld); + GtkWidget* pWidgetOld = pGtkOld ? pGtkOld->getWidget() : nullptr; + if (pWidgetOld) + g_object_set(G_OBJECT(pWidgetOld), "has-default", false, nullptr); + else + recursively_unset_default_buttons(); + if (pWidgetNew) + g_object_set(G_OBJECT(pWidgetNew), "has-default", true, nullptr); +#endif + } + + virtual bool is_default_widget(const weld::Widget* pCandidate) const override + { + const GtkInstanceWidget* pGtkCandidate = dynamic_cast<const GtkInstanceWidget*>(pCandidate); + GtkWidget* pWidget = pGtkCandidate ? pGtkCandidate->getWidget() : nullptr; +#if GTK_CHECK_VERSION(4, 0, 0) + return pWidget && gtk_window_get_default_widget(m_pDialog) == pWidget; +#else + gboolean has_default(false); + if (pWidget) + g_object_get(G_OBJECT(pWidget), "has-default", &has_default, nullptr); + return has_default; +#endif + } + virtual void collapse(weld::Widget* pEdit, weld::Widget* pButton) override { GtkInstanceWidget* pVclEdit = dynamic_cast<GtkInstanceWidget*>(pEdit); commit 0c4bbb8b05d0f2f7118e3e6e099622a4a3346213 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri Jul 25 23:57:10 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Tue Jul 29 05:20:41 2025 +0200 tdf#130857 qt weld: Support "Theme" dialog This means that native Qt widgets are used for that dialog now when using the qt5 or qt6 VCL plugin and starting LO with environment variable SAL_VCL_QT_USE_WELDED_WIDGETS=1 set. To trigger the dialog from Writer: "Format" -> "Theme" Change-Id: I6ce3be8e8f657ec8162a936b16aa8a50cd7aeb4e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188378 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins diff --git a/vcl/qt5/QtInstanceBuilder.cxx b/vcl/qt5/QtInstanceBuilder.cxx index 00a4c89ac9f4..a6161964c5da 100644 --- a/vcl/qt5/QtInstanceBuilder.cxx +++ b/vcl/qt5/QtInstanceBuilder.cxx @@ -162,6 +162,7 @@ bool QtInstanceBuilder::IsUIFileSupported(const OUString& rUIFile, const weld::W u"svx/ui/gotopagedialog.ui"_ustr, u"svx/ui/safemodedialog.ui"_ustr, u"svx/ui/themecoloreditdialog.ui"_ustr, + u"svx/ui/themedialog.ui"_ustr, u"uui/ui/password.ui"_ustr, u"vcl/ui/openlockedquerybox.ui"_ustr, u"vcl/ui/printerdevicepage.ui"_ustr, commit 6550cb6074891f7e6c35b2a65f072e5918113033 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri Jul 25 23:49:01 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Tue Jul 29 05:20:34 2025 +0200 svx: Set proper parent for "Theme Color Edit" dialog The parent for this modal dialog is the "Theme" dialog from which the "Theme Color Edit" dialog is started, and not the "Theme" dialog's parent. Setting the proper parent e.g. ensures that dialog modality on top of the parent works as expected with qt6 and gtk3, while it was previously not enforced that the dialog was always shown on top of the "Theme" dialog. Change-Id: Id9655cf84d6b53edcae9b1575f34f9cfbcd33dd8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188377 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins diff --git a/include/svx/dialog/ThemeDialog.hxx b/include/svx/dialog/ThemeDialog.hxx index 0dbb4ef9b23d..1f06b13365be 100644 --- a/include/svx/dialog/ThemeDialog.hxx +++ b/include/svx/dialog/ThemeDialog.hxx @@ -24,7 +24,6 @@ namespace svx class SVX_DLLPUBLIC ThemeDialog final : public weld::GenericDialogController { private: - weld::Window* mpWindow; model::Theme* mpTheme; std::shared_ptr<svx::ThemeColorEditDialog> mxSubDialog; std::vector<model::ColorSet> maColorSets; diff --git a/svx/source/dialog/ThemeDialog.cxx b/svx/source/dialog/ThemeDialog.cxx index 2b299c0cc1f8..6dd20e24d2b4 100644 --- a/svx/source/dialog/ThemeDialog.cxx +++ b/svx/source/dialog/ThemeDialog.cxx @@ -19,7 +19,6 @@ namespace svx { ThemeDialog::ThemeDialog(weld::Window* pParent, model::Theme* pTheme) : GenericDialogController(pParent, u"svx/ui/themedialog.ui"_ustr, u"ThemeDialog"_ustr) - , mpWindow(pParent) , mpTheme(pTheme) , mxIconViewThemeColors(m_xBuilder->weld_icon_view(u"iconview_theme_colors"_ustr)) , mxAdd(m_xBuilder->weld_button(u"button_add"_ustr)) @@ -132,7 +131,7 @@ void ThemeDialog::runThemeColorEditDialog() if (mxSubDialog) return; - mxSubDialog = std::make_shared<svx::ThemeColorEditDialog>(mpWindow, *mpCurrentColorSet); + mxSubDialog = std::make_shared<svx::ThemeColorEditDialog>(getDialog(), *mpCurrentColorSet); weld::DialogController::runAsync(mxSubDialog, [this](sal_uInt32 nResult) { if (nResult != RET_OK)