vcl/inc/qt5/QtWidget.hxx |    2 +-
 vcl/qt5/QtFilePicker.cxx |   14 +++++++-------
 vcl/qt5/QtWidget.cxx     |   17 ++++++++++++++---
 3 files changed, 22 insertions(+), 11 deletions(-)

New commits:
commit eac62756e7e74d0cf2ff78d52b1c24e9f6c5800c
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Thu Sep 19 10:56:05 2024 +0200
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Thu Sep 19 15:36:31 2024 +0200

    qt: Use qobject_cast in QtFilePicker
    
    Use `qobject_cast` instead of `dynamic_cast`
    when casting to native Qt widgets.
    It should be faster.
    
    Quoting from the doc [1]:
    
    > The qobject_cast() function behaves similarly to the standard C++
    > dynamic_cast(), with the advantages that it doesn't require RTTI support
    > and it works across dynamic library boundaries.
    
    [1] https://doc.qt.io/qt-6/qobject.html#qobject_cast
    
    Change-Id: I20d4cca6936eeeb6f8367f82a9d11f12ada63e2d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173659
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/vcl/qt5/QtFilePicker.cxx b/vcl/qt5/QtFilePicker.cxx
index c8ab150b0775..70fa7ef96483 100644
--- a/vcl/qt5/QtFilePicker.cxx
+++ b/vcl/qt5/QtFilePicker.cxx
@@ -108,7 +108,7 @@ 
QtFilePicker::QtFilePicker(css::uno::Reference<css::uno::XComponentContext> cont
         
m_pFileDialog->setWindowTitle(toQString(FpsResId(STR_SVT_FOLDERPICKER_DEFAULT_TITLE)));
     }
 
-    m_pLayout = dynamic_cast<QGridLayout*>(m_pFileDialog->layout());
+    m_pLayout = qobject_cast<QGridLayout*>(m_pFileDialog->layout());
 
     setMultiSelectionMode(false);
 
@@ -508,12 +508,12 @@ void SAL_CALL QtFilePicker::setValue(sal_Int16 controlId, 
sal_Int16 nControlActi
     if (m_aCustomWidgetsMap.contains(controlId))
     {
         QWidget* widget = m_aCustomWidgetsMap.value(controlId);
-        QCheckBox* cb = dynamic_cast<QCheckBox*>(widget);
+        QCheckBox* cb = qobject_cast<QCheckBox*>(widget);
         if (cb)
             cb->setChecked(value.get<bool>());
         else
         {
-            QComboBox* combo = dynamic_cast<QComboBox*>(widget);
+            QComboBox* combo = qobject_cast<QComboBox*>(widget);
             if (combo)
                 handleSetListValue(combo, nControlAction, value);
         }
@@ -540,12 +540,12 @@ uno::Any SAL_CALL QtFilePicker::getValue(sal_Int16 
controlId, sal_Int16 nControl
     if (m_aCustomWidgetsMap.contains(controlId))
     {
         QWidget* widget = m_aCustomWidgetsMap.value(controlId);
-        QCheckBox* cb = dynamic_cast<QCheckBox*>(widget);
+        QCheckBox* cb = qobject_cast<QCheckBox*>(widget);
         if (cb)
             res <<= cb->isChecked();
         else
         {
-            QComboBox* combo = dynamic_cast<QComboBox*>(widget);
+            QComboBox* combo = qobject_cast<QComboBox*>(widget);
             if (combo)
                 res = handleGetListValue(combo, nControlAction);
         }
@@ -582,7 +582,7 @@ void SAL_CALL QtFilePicker::setLabel(sal_Int16 controlId, 
const OUString& label)
 
     if (m_aCustomWidgetsMap.contains(controlId))
     {
-        QCheckBox* cb = 
dynamic_cast<QCheckBox*>(m_aCustomWidgetsMap.value(controlId));
+        QCheckBox* cb = 
qobject_cast<QCheckBox*>(m_aCustomWidgetsMap.value(controlId));
         if (cb)
             cb->setText(toQString(label));
     }
@@ -605,7 +605,7 @@ OUString SAL_CALL QtFilePicker::getLabel(sal_Int16 
controlId)
     QString label;
     if (m_aCustomWidgetsMap.contains(controlId))
     {
-        QCheckBox* cb = 
dynamic_cast<QCheckBox*>(m_aCustomWidgetsMap.value(controlId));
+        QCheckBox* cb = 
qobject_cast<QCheckBox*>(m_aCustomWidgetsMap.value(controlId));
         if (cb)
             label = cb->text();
     }
commit 2284e26a0731a606568eda706e8e4451aaf880d8
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Thu Sep 19 09:49:57 2024 +0200
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Thu Sep 19 15:36:23 2024 +0200

    qt a11y: Destroy QWindow when popup gets hidden
    
    When a popup gets hidden, destroy its associated
    QWindow.
    
    This prevents a "top-level" a11y object being reported
    when a popup gets shown, then hidden again, e.g. after
    expanding the Paragraph Style combobox in Writer's
    Formatting toolbar, then closing it again.
    
    Showing the popup results in a QWindow being created
    that would not implicitly be destroyed when the
    popup gets hidden again.
    
    Due to popups in LO currently not using the Qt::Popup
    type, but Qt::ToolTip, they are considered for top-level
    a11y children of the app, see the commit message of
    
        Change-Id: I7aff5c435dfa8b6aadcbbedb0d84db19bb86c8ab
        Author: Michael Weghorn <m.wegh...@posteo.de>
        Date:   Thu Sep 19 09:15:37 2024 +0200
    
            qt a11y: Defer QWindow creation until frame gets shown
    
    for more details.
    
    Only delete the QWindow for non-spontaneous hide events,
    as the QWidget::hideEvent doc [1] says:
    
    > Note: A widget receives spontaneous show and hide events when its
    > mapping status is changed by the window system, e.g. a spontaneous hide
    > event when the user minimizes the window, and a spontaneous show event
    > when the window is restored again. After receiving a spontaneous hide
    > event, a widget is still considered visible in the sense of isVisible().
    
    With this commit in place, after starting Writer, opening the
    Paragraph Style combobox, then closing it again, only the
    Writer window is shown as a top-level child of the app
    in Accerciser when using the qt6 VCL plugin, as expected.
    
    Showing the popup again works just fine, as a new QWindow
    is implicitly created then.
    
    [1] https://doc.qt.io/qt-6/qwidget.html#hideEvent
    
    Change-Id: Iefa5d05ea128966c4417d53d122a6a0f1178fc00
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173657
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>
    Tested-by: Jenkins

diff --git a/vcl/inc/qt5/QtWidget.hxx b/vcl/inc/qt5/QtWidget.hxx
index ca0165401e15..142fb60b9fda 100644
--- a/vcl/inc/qt5/QtWidget.hxx
+++ b/vcl/inc/qt5/QtWidget.hxx
@@ -70,7 +70,7 @@ class QtWidget : public QWidget
     virtual void paintEvent(QPaintEvent*) override;
     virtual void resizeEvent(QResizeEvent*) override;
     virtual void showEvent(QShowEvent*) override;
-    virtual void hideEvent(QHideEvent*) override;
+    virtual void hideEvent(QHideEvent* pEvent) override;
     virtual void wheelEvent(QWheelEvent*) override;
     virtual void closeEvent(QCloseEvent*) override;
     virtual void changeEvent(QEvent*) override;
diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx
index 3d5c5976fb94..43adcdf384dc 100644
--- a/vcl/qt5/QtWidget.cxx
+++ b/vcl/qt5/QtWidget.cxx
@@ -310,10 +310,21 @@ void QtWidget::showEvent(QShowEvent*)
     m_rFrame.CallCallback(SalEvent::Paint, &aPaintEvt);
 }
 
-void QtWidget::hideEvent(QHideEvent*)
+void QtWidget::hideEvent(QHideEvent* pEvent)
 {
-    if (m_rFrame.isPopup() && GetQtInstance()->activePopup() == &m_rFrame)
-        GetQtInstance()->setActivePopup(nullptr);
+    if (m_rFrame.isPopup())
+    {
+        if (GetQtInstance()->activePopup() == &m_rFrame)
+            GetQtInstance()->setActivePopup(nullptr);
+
+        // destroy the QWindow as the popup would otherwise still show up
+        // as a top-level child of the app on the a11y level
+        // (Qt explicitly filters out widgets of type Qt::Popup, but
+        // Qt::ToolTip is currently used for popups to work around another
+        // issue, s. the QtFrame ctor)
+        if (!pEvent->spontaneous())
+            destroy();
+    }
 }
 
 void QtWidget::closeEvent(QCloseEvent* /*pEvent*/)

Reply via email to