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: */

Reply via email to