vcl/CustomTarget_qt5_moc.mk | 2 ++ vcl/CustomTarget_qt6_moc.mk | 2 ++ vcl/inc/qt5/QtInstanceContainer.hxx | 6 ++++-- vcl/inc/qt5/QtInstanceDialog.hxx | 2 +- vcl/inc/qt5/QtInstanceWindow.hxx | 4 ++++ vcl/qt5/QtInstanceContainer.cxx | 11 +++++++++-- vcl/qt5/QtInstanceWindow.cxx | 30 +++++++++++++++++++++++++++++- 7 files changed, 51 insertions(+), 6 deletions(-)
New commits: commit 43da73518240138fffac57abc8f3ddf0c2f11664 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri Nov 8 23:18:05 2024 +0100 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Sat Nov 9 19:04:59 2024 +0100 tdf#130857 qt weld: Implement QtInstanceWindow::present The gtk_window_present doc says: > Presents a window to the user. > > This may mean raising the window in the stacking order, unminimizing it, > moving it to the current desktop and/or giving it the keyboard > focus (possibly dependent on the user’s platform, window manager > and preferences). Therefore, call QWindow::requestActivate [2] for the Qt implementation of weld::Window::present. [1] https://docs.gtk.org/gtk4/method.Window.present.html [2] https://doc.qt.io/qt-6/qwindow.html#requestActivate Change-Id: I1c73dba1675523171a92c760836c6702a81f4c12 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176303 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins diff --git a/vcl/qt5/QtInstanceWindow.cxx b/vcl/qt5/QtInstanceWindow.cxx index 344db175764b..aecfa7618c5d 100644 --- a/vcl/qt5/QtInstanceWindow.cxx +++ b/vcl/qt5/QtInstanceWindow.cxx @@ -12,6 +12,8 @@ #include <vcl/qt/QtUtils.hxx> +#include <QtGui/QWindow> + QtInstanceWindow::QtInstanceWindow(QWidget* pWidget) : QtInstanceContainer(pWidget) { @@ -63,7 +65,14 @@ void QtInstanceWindow::set_centered_on_parent(bool) {} bool QtInstanceWindow::has_toplevel_focus() const { return true; } -void QtInstanceWindow::present() {} +void QtInstanceWindow::present() +{ + SolarMutexGuard g; + GetQtInstance().RunInMainThread([&] { + if (QWindow* pWindow = getQWidget()->windowHandle()) + pWindow->requestActivate(); + }); +} void QtInstanceWindow::change_default_widget(weld::Widget*, weld::Widget*) {} commit 028a5259861ee8b2e922008f362eb3906a2d0b36 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri Nov 8 23:03:28 2024 +0100 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Sat Nov 9 19:04:51 2024 +0100 tdf#130857 qt weld: Signal container focus on window (de)activation Set QtInstanceWindow as an event filter for it's QWidget, and call `signal_container_focus_changed` when receiving a QEvent::WindowActivate or QEvent::WindowDeactivate event. This code path got triggered as expected in a quick test switching between e.g. the "Help" -> "About" dialog and other windows in KDE Plasma using the Alt+Tab shortcut. The VCL implementation does something similar by handling VclEventId::WindowActivate and VclEventId::WindowDeactivate events, see SalInstanceContainer::HandleEventListener. For non-top-level containers, a different solution will probably be needed. For now, adjust the assert in QtInstanceContainer::connect_container_focus_changed to only trigger for non-QtInstanceWindow containers. And call the base class implementation, so that the handler is actually set for the QtInstanceWindow case. A potential solution for QtInstanceContainer might be to connect to the QApplication::focusChanged signal in QtInstanceContainer::connect_container_focus_changed and in the slot check whether exactly one of the old and new focus widgets has the container's widget in hierarchy. Change-Id: I945c8bf0999d93ae91cf25dcffd3fd3ce164d214 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176302 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins diff --git a/vcl/CustomTarget_qt5_moc.mk b/vcl/CustomTarget_qt5_moc.mk index 672398d4b03f..5af117c05488 100644 --- a/vcl/CustomTarget_qt5_moc.mk +++ b/vcl/CustomTarget_qt5_moc.mk @@ -15,6 +15,7 @@ $(call gb_CustomTarget_get_target,vcl/qt5) : \ $(gb_CustomTarget_workdir)/vcl/qt5/QtFrame.moc \ $(gb_CustomTarget_workdir)/vcl/qt5/QtInstance.moc \ $(gb_CustomTarget_workdir)/vcl/qt5/QtInstanceComboBox.moc \ + $(gb_CustomTarget_workdir)/vcl/qt5/QtInstanceContainer.moc \ $(gb_CustomTarget_workdir)/vcl/qt5/QtInstanceDialog.moc \ $(gb_CustomTarget_workdir)/vcl/qt5/QtInstanceDrawingArea.moc \ $(gb_CustomTarget_workdir)/vcl/qt5/QtInstanceEntry.moc \ @@ -23,6 +24,7 @@ $(call gb_CustomTarget_get_target,vcl/qt5) : \ $(gb_CustomTarget_workdir)/vcl/qt5/QtInstanceMessageDialog.moc \ $(gb_CustomTarget_workdir)/vcl/qt5/QtInstanceProgressBar.moc \ $(gb_CustomTarget_workdir)/vcl/qt5/QtInstanceRadioButton.moc \ + $(gb_CustomTarget_workdir)/vcl/qt5/QtInstanceWindow.moc \ $(gb_CustomTarget_workdir)/vcl/qt5/QtMainWindow.moc \ $(gb_CustomTarget_workdir)/vcl/qt5/QtMenu.moc \ $(gb_CustomTarget_workdir)/vcl/qt5/QtTransferable.moc \ diff --git a/vcl/CustomTarget_qt6_moc.mk b/vcl/CustomTarget_qt6_moc.mk index 03d3c079771f..ddb805833b66 100644 --- a/vcl/CustomTarget_qt6_moc.mk +++ b/vcl/CustomTarget_qt6_moc.mk @@ -15,6 +15,7 @@ $(call gb_CustomTarget_get_target,vcl/qt6) : \ $(gb_CustomTarget_workdir)/vcl/qt6/QtFrame.moc \ $(gb_CustomTarget_workdir)/vcl/qt6/QtInstance.moc \ $(gb_CustomTarget_workdir)/vcl/qt6/QtInstanceComboBox.moc \ + $(gb_CustomTarget_workdir)/vcl/qt6/QtInstanceContainer.moc \ $(gb_CustomTarget_workdir)/vcl/qt6/QtInstanceDialog.moc \ $(gb_CustomTarget_workdir)/vcl/qt6/QtInstanceDrawingArea.moc \ $(gb_CustomTarget_workdir)/vcl/qt6/QtInstanceEntry.moc \ @@ -23,6 +24,7 @@ $(call gb_CustomTarget_get_target,vcl/qt6) : \ $(gb_CustomTarget_workdir)/vcl/qt6/QtInstanceMessageDialog.moc \ $(gb_CustomTarget_workdir)/vcl/qt6/QtInstanceProgressBar.moc \ $(gb_CustomTarget_workdir)/vcl/qt6/QtInstanceRadioButton.moc \ + $(gb_CustomTarget_workdir)/vcl/qt6/QtInstanceWindow.moc \ $(gb_CustomTarget_workdir)/vcl/qt6/QtMainWindow.moc \ $(gb_CustomTarget_workdir)/vcl/qt6/QtMenu.moc \ $(gb_CustomTarget_workdir)/vcl/qt6/QtTransferable.moc \ diff --git a/vcl/inc/qt5/QtInstanceContainer.hxx b/vcl/inc/qt5/QtInstanceContainer.hxx index 371cc4d46aae..4d5c13dcd12f 100644 --- a/vcl/inc/qt5/QtInstanceContainer.hxx +++ b/vcl/inc/qt5/QtInstanceContainer.hxx @@ -13,8 +13,10 @@ #include <QtWidgets/QLayout> -class QtInstanceContainer : public QtInstanceWidget, public virtual weld::Container +class QtInstanceContainer : public QObject, public QtInstanceWidget, public virtual weld::Container { + Q_OBJECT + public: QtInstanceContainer(QWidget* pWidget); @@ -24,7 +26,7 @@ public: virtual void child_grab_focus() override; - virtual void connect_container_focus_changed(const Link<Container&, void>&) override; + virtual void connect_container_focus_changed(const Link<Container&, void>& rLink) override; private: QLayout& getLayout(); diff --git a/vcl/inc/qt5/QtInstanceDialog.hxx b/vcl/inc/qt5/QtInstanceDialog.hxx index d4c8dc3ff9b1..f4ed8d4423c8 100644 --- a/vcl/inc/qt5/QtInstanceDialog.hxx +++ b/vcl/inc/qt5/QtInstanceDialog.hxx @@ -13,7 +13,7 @@ #include <QtWidgets/QAbstractButton> -class QtInstanceDialog : public QObject, public QtInstanceWindow, public virtual weld::Dialog +class QtInstanceDialog : public QtInstanceWindow, public virtual weld::Dialog { Q_OBJECT diff --git a/vcl/inc/qt5/QtInstanceWindow.hxx b/vcl/inc/qt5/QtInstanceWindow.hxx index e84a6071b3f0..ee2cbcb757c6 100644 --- a/vcl/inc/qt5/QtInstanceWindow.hxx +++ b/vcl/inc/qt5/QtInstanceWindow.hxx @@ -13,6 +13,8 @@ class QtInstanceWindow : public QtInstanceContainer, public virtual weld::Window { + Q_OBJECT + public: QtInstanceWindow(QWidget* pWidget); @@ -45,6 +47,8 @@ public: virtual VclPtr<VirtualDevice> screenshot() override; virtual const vcl::ILibreOfficeKitNotifier* GetLOKNotifier() override; + + bool eventFilter(QObject* pObject, QEvent* pEvent) override; }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/qt5/QtInstanceContainer.cxx b/vcl/qt5/QtInstanceContainer.cxx index 8f8742387235..83909a83675e 100644 --- a/vcl/qt5/QtInstanceContainer.cxx +++ b/vcl/qt5/QtInstanceContainer.cxx @@ -8,6 +8,9 @@ */ #include <QtInstanceContainer.hxx> +#include <QtInstanceContainer.moc> + +#include <QtInstanceWindow.hxx> QtInstanceContainer::QtInstanceContainer(QWidget* pWidget) : QtInstanceWidget(pWidget) @@ -43,9 +46,13 @@ css::uno::Reference<css::awt::XWindow> QtInstanceContainer::CreateChildFrame() void QtInstanceContainer::child_grab_focus() { assert(false && "Not implemented yet"); } -void QtInstanceContainer::connect_container_focus_changed(const Link<Container&, void>&) +void QtInstanceContainer::connect_container_focus_changed(const Link<Container&, void>& rLink) { - assert(false && "Not implemented yet"); + // for QtInstanceWindow, no special handling is needed, activate/deactivate events trigger the signal + if (!qobject_cast<QtInstanceWindow*>(this)) + assert(false && "Not implemented yet"); + + weld::Container::connect_container_focus_changed(rLink); } QLayout& QtInstanceContainer::getLayout() diff --git a/vcl/qt5/QtInstanceWindow.cxx b/vcl/qt5/QtInstanceWindow.cxx index a3c6b3de3687..344db175764b 100644 --- a/vcl/qt5/QtInstanceWindow.cxx +++ b/vcl/qt5/QtInstanceWindow.cxx @@ -8,12 +8,15 @@ */ #include <QtInstanceWindow.hxx> +#include <QtInstanceWindow.moc> #include <vcl/qt/QtUtils.hxx> QtInstanceWindow::QtInstanceWindow(QWidget* pWidget) : QtInstanceContainer(pWidget) { + // install event filter to handle window activation/deactivation events + pWidget->installEventFilter(this); } void QtInstanceWindow::set_title(const OUString& rTitle) @@ -93,4 +96,20 @@ VclPtr<VirtualDevice> QtInstanceWindow::screenshot() { return nullptr; } const vcl::ILibreOfficeKitNotifier* QtInstanceWindow::GetLOKNotifier() { return nullptr; } +bool QtInstanceWindow::eventFilter(QObject* pObject, QEvent* pEvent) +{ + if (pObject != getQWidget()) + return false; + + switch (pEvent->type()) + { + case QEvent::WindowActivate: + case QEvent::WindowDeactivate: + signal_container_focus_changed(); + return false; + default: + return false; + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */