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