vcl/inc/qt5/QtFrame.hxx |    1 
 vcl/qt5/QtFrame.cxx     |   77 ++++++------------------------------------------
 vcl/qt5/QtWidget.cxx    |    8 +---
 3 files changed, 13 insertions(+), 73 deletions(-)

New commits:
commit fbf739198aa7f02975d531521c6525073783c7f1
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Mon Apr 4 18:02:28 2022 +0200
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Wed Apr 6 09:52:11 2022 +0200

    tdf#144585 Qt fix Wayland LO fake popups
    
    So Michael Weghorn was somehow reminded of an abandoned
    commit from me ("Qt5 rework parent handling") archived in
    https://gerrit.libreoffice.org/c/core/+/73463.
    
    The bug introducing the new QWidget parenting, tdf#145363, was
    resolved in a better way by explicitly setting parents for the
    modal dialogs, so LO doesn't break Qt anymore. The actual problem
    is, that an additional modal dialog needs to be stacked to the
    previous modal dialog; no "parallel" modal dialogs are allowed,
    which my original fix tried to enforce by reparenting.
    
    Then there is the problem with Qt::Popup's focus grabbing on show,
    which breaks LO's editable ComboBox. So LO's popup / FLOAT windows
    are mapped to Qt::ToolTip, which are automatically advertised as
    tooltips via accessibility. For X11 / xcb, Qt:Window with the
    Qt::BypassWindowManagerHint works well enough as an alternative,
    but WASM and Wayland don't seem to implement it correctly, so this
    just handles popups as Qt::ToolTip on all platforms.
    
    This reverts commit b00a68a8e19370e106cd76258a3c1825f43613ee
    ("tdf#145363 Qt reparent modal dialogs on show").
    In addition the popup widgets are switched back to Qt::ToolTip.
    
    Change-Id: If726771b4e9cc3f639f21cf502b3ec5985873643
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132526
    Reviewed-by: Jan-Marek Glogowski <glo...@fbihome.de>
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>
    Tested-by: Jenkins

diff --git a/vcl/inc/qt5/QtFrame.hxx b/vcl/inc/qt5/QtFrame.hxx
index 9aa31504bcd3..c6edaa58304d 100644
--- a/vcl/inc/qt5/QtFrame.hxx
+++ b/vcl/inc/qt5/QtFrame.hxx
@@ -132,7 +132,6 @@ class VCLPLUG_QT_PUBLIC QtFrame : public QObject, public 
SalFrame
     int menuBarOffset() const;
 
     void fixICCCMwindowGroup();
-    void modalReparent(bool bVisible);
 
 public:
     QtFrame(QtFrame* pParent, SalFrameStyleFlags nSalFrameStyle, bool 
bUseCairo);
diff --git a/vcl/qt5/QtFrame.cxx b/vcl/qt5/QtFrame.cxx
index 6c2e4757f84a..2e396fa8ce07 100644
--- a/vcl/qt5/QtFrame.cxx
+++ b/vcl/qt5/QtFrame.cxx
@@ -147,15 +147,14 @@ QtFrame::QtFrame(QtFrame* pParent, SalFrameStyleFlags 
nStyle, bool bUseCairo)
             aWinFlags = Qt::Tool | Qt::FramelessWindowHint;
         else if (nStyle & SalFrameStyleFlags::TOOLTIP)
             aWinFlags = Qt::ToolTip;
-        // Can't use Qt::Popup, because it grabs the input focus and generates
-        // a focus-out event, reaching the combo box. This used to map to
-        // Qt::ToolTip, which doesn't feel that correct...
+        // Can't use Qt::Popup, because it grabs the input focus and generates 
a focus-out event,
+        // instantly auto-closing the LO's editable ComboBox popup.
+        // On X11, the alternative Qt::Window | Qt::FramelessWindowHint | 
Qt::BypassWindowManagerHint
+        // seems to work well enough, but at least on Wayland and WASM, this 
results in problems.
+        // So while using Qt::ToolTip, the popups are wrongly advertised via 
accessibility, at least
+        // the GUI seems to work on all platforms... what a mess.
         else if (isPopup())
-#ifdef EMSCRIPTEN
             aWinFlags = Qt::ToolTip | Qt::FramelessWindowHint;
-#else
-            aWinFlags = Qt::Window | Qt::FramelessWindowHint | 
Qt::BypassWindowManagerHint;
-#endif
         else if (nStyle & SalFrameStyleFlags::TOOLWINDOW)
             aWinFlags = Qt::Tool;
         // top level windows can't be transient in Qt, so make them dialogs, 
if they have a parent. At least
@@ -170,7 +169,7 @@ QtFrame::QtFrame(QtFrame* pParent, SalFrameStyleFlags 
nStyle, bool bUseCairo)
     if (aWinFlags == Qt::Window)
     {
         m_pTopLevel = new QtMainWindow(*this, aWinFlags);
-        m_pQWidget = new QtWidget(*this, aWinFlags);
+        m_pQWidget = new QtWidget(*this);
         m_pTopLevel->setCentralWidget(m_pQWidget);
         m_pTopLevel->setFocusProxy(m_pQWidget);
     }
@@ -425,42 +424,6 @@ void QtFrame::DrawMenuBar() { /* not needed */}
 
 void QtFrame::SetExtendedFrameStyle(SalExtStyle /*nExtStyle*/) { /* not needed 
*/}
 
-void QtFrame::modalReparent(bool bVisible)
-{
-#ifndef NDEBUG
-    auto* pSalInst(GetQtInstance());
-    assert(pSalInst);
-    assert(pSalInst->IsMainThread());
-    assert(!asChild()->isVisible());
-    assert(asChild()->isModal());
-#endif
-
-    if (!bVisible)
-    {
-        QWidget* pNewParent = m_pParent ? m_pParent->asChild() : nullptr;
-        if (pNewParent != m_pQWidget->parent())
-            m_pQWidget->setParent(pNewParent, m_pQWidget->windowFlags());
-        return;
-    }
-
-    const QWindow* pModalWin = QGuiApplication::modalWindow();
-    if (!pModalWin || m_pParent->windowHandle() == pModalWin)
-        return;
-
-    QtInstance* pInst = GetQtInstance();
-    for (auto* pFrame : pInst->getFrames())
-    {
-        QtFrame* pQtFrame = static_cast<QtFrame*>(pFrame);
-        if (pQtFrame->windowHandle() == pModalWin)
-        {
-            QWidget* pNewParent = pQtFrame->asChild();
-            if (pNewParent != m_pQWidget->parent())
-                m_pQWidget->setParent(pNewParent, m_pQWidget->windowFlags());
-            break;
-        }
-    }
-}
-
 void QtFrame::Show(bool bVisible, bool bNoActivate)
 {
     assert(m_pQWidget);
@@ -472,11 +435,7 @@ void QtFrame::Show(bool bVisible, bool bNoActivate)
 
     if (!bVisible) // hide
     {
-        pSalInst->RunInMainThread([this]() {
-            asChild()->setVisible(false);
-            if (m_pQWidget->isModal())
-                modalReparent(false);
-        });
+        pSalInst->RunInMainThread([this]() { asChild()->setVisible(false); });
         return;
     }
 
@@ -485,8 +444,6 @@ void QtFrame::Show(bool bVisible, bool bNoActivate)
 
     pSalInst->RunInMainThread([this, bNoActivate]() {
         QWidget* const pChild = asChild();
-        if (m_pQWidget->isModal())
-            modalReparent(true);
         pChild->setVisible(true);
         pChild->raise();
         if (!bNoActivate)
@@ -688,20 +645,12 @@ void QtFrame::SetModal(bool bModal)
 
         // modality change is only effective if the window is hidden
         if (bWasVisible)
-        {
             pChild->hide();
-            if (!bModal)
-                modalReparent(false);
-        }
 
         pChild->setWindowModality(bModal ? Qt::WindowModal : Qt::NonModal);
 
         if (bWasVisible)
-        {
-            if (bModal)
-                modalReparent(true);
             pChild->show();
-        }
     });
 }
 
@@ -1254,14 +1203,8 @@ void QtFrame::SimulateKeyPress(sal_uInt16 nKeyCode)
     SAL_WARN("vcl.qt", "missing simulate keypress " << nKeyCode);
 }
 
-void QtFrame::SetParent(SalFrame* pNewParent)
-{
-    if (m_pParent == pNewParent)
-        return;
-    m_pParent = static_cast<QtFrame*>(pNewParent);
-    if (!m_pTopLevel)
-        m_pQWidget->setParent(m_pParent->asChild(), m_pQWidget->windowFlags());
-}
+// don't set QWidget parents; this breaks popups on Wayland, like the LO 
ComboBox or ColorPicker!
+void QtFrame::SetParent(SalFrame* pNewParent) { m_pParent = 
static_cast<QtFrame*>(pNewParent); }
 
 void QtFrame::SetPluginParent(SystemParentData* /*pNewParent*/)
 {
diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx
index 9685be9ffa57..6362a1353d54 100644
--- a/vcl/qt5/QtWidget.cxx
+++ b/vcl/qt5/QtWidget.cxx
@@ -620,16 +620,14 @@ void QtWidget::focusOutEvent(QFocusEvent*)
 }
 
 QtWidget::QtWidget(QtFrame& rFrame, Qt::WindowFlags f)
-    : QWidget(!rFrame.GetTopLevelWindow() && rFrame.GetParent()
-                  ? static_cast<QtFrame*>(rFrame.GetParent())->asChild()
-                  : Q_NULLPTR,
-              f)
+    // if you try to set the QWidget parent via the QtFrame, instead of using 
the Q_NULLPTR, at
+    // least test Wayland popups; these horribly broke last time doing this 
(read commits)!
+    : QWidget(Q_NULLPTR, f)
     , m_rFrame(rFrame)
     , m_bNonEmptyIMPreeditSeen(false)
     , m_nDeltaX(0)
     , m_nDeltaY(0)
 {
-    create();
     setMouseTracking(true);
     if (!rFrame.isPopup())
         setFocusPolicy(Qt::StrongFocus);

Reply via email to