vcl/inc/qt5/Qt5Frame.hxx  |    7 +++++++
 vcl/inc/qt5/Qt5Widget.hxx |    1 +
 vcl/qt5/Qt5Frame.cxx      |   10 ++++++----
 vcl/qt5/Qt5Widget.cxx     |   24 +++++++++++++++++-------
 4 files changed, 31 insertions(+), 11 deletions(-)

New commits:
commit ea2f19827db330a21c7962bdd13b1b838821bd4c
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Fri Jul 30 05:25:37 2021 +0200
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Fri Jul 30 22:19:21 2021 +0200

    tdf#143580 Qt5 don't use Qt::Popup for FLOAT wins
    
    Main problem is, that Qt::Popup grabs the focus and therefore
    generates a focus-out event for the combobox, which then closes
    the just shown popup window. The grab happens inside QWidget
    private code and there is no way around it. But instead of
    "faking" Qt::Tooltip, this uses Qt::Widget with additional flags.
    
    Regression from commit 7e6fee830116823b9cd8e46d6962df4ea2bc1ea6
    ("Qt5 fix Qt::Popup window handling").
    
    Change-Id: Ia1f8e33d98f7ec36cf1ebc350886121dfaadd658
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119691
    Tested-by: Jenkins
    Reviewed-by: Jan-Marek Glogowski <glo...@fbihome.de>
    (cherry picked from commit 9dcf5816c90e9819861332f11e014ef7b78e2fe7)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119621
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/vcl/inc/qt5/Qt5Frame.hxx b/vcl/inc/qt5/Qt5Frame.hxx
index ed82c2a7a8fb..01b93ad3b825 100644
--- a/vcl/inc/qt5/Qt5Frame.hxx
+++ b/vcl/inc/qt5/Qt5Frame.hxx
@@ -210,6 +210,7 @@ public:
     inline bool CallCallback(SalEvent nEvent, const void* pEvent) const;
 
     void setInputLanguage(LanguageType);
+    inline bool isPopup() const;
 };
 
 inline bool Qt5Frame::CallCallback(SalEvent nEvent, const void* pEvent) const
@@ -218,4 +219,10 @@ inline bool Qt5Frame::CallCallback(SalEvent nEvent, const 
void* pEvent) const
     return SalFrame::CallCallback(nEvent, pEvent);
 }
 
+inline bool Qt5Frame::isPopup() const
+{
+    return ((m_nStyle & SalFrameStyleFlags::FLOAT)
+            && !(m_nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION));
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/qt5/Qt5Widget.hxx b/vcl/inc/qt5/Qt5Widget.hxx
index 7bf7ead6ae9a..60db1a306efd 100644
--- a/vcl/inc/qt5/Qt5Widget.hxx
+++ b/vcl/inc/qt5/Qt5Widget.hxx
@@ -75,6 +75,7 @@ class Qt5Widget : public QWidget
 
     void inputMethodEvent(QInputMethodEvent*) override;
     QVariant inputMethodQuery(Qt::InputMethodQuery) const override;
+    static void closePopup();
 
 public:
     Qt5Widget(Qt5Frame& rFrame, Qt::WindowFlags f = Qt::WindowFlags());
diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx
index 02032d149d29..a4c78d1b71a7 100644
--- a/vcl/qt5/Qt5Frame.cxx
+++ b/vcl/qt5/Qt5Frame.cxx
@@ -146,9 +146,11 @@ Qt5Frame::Qt5Frame(Qt5Frame* pParent, SalFrameStyleFlags 
nStyle, bool bUseCairo)
             aWinFlags |= Qt::Tool | Qt::FramelessWindowHint;
         else if (nStyle & SalFrameStyleFlags::TOOLTIP)
             aWinFlags |= Qt::ToolTip;
-        else if ((nStyle & SalFrameStyleFlags::FLOAT)
-                 && !(nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION))
-            aWinFlags |= Qt::Popup;
+        // Can't use Qt::Popup, because it grabs the input focus and generates
+        // a focus-out event, reaking the compbo box. This used to map to
+        // Qt::ToolTip, which doesn't feel that correct...
+        else if (isPopup())
+            aWinFlags = Qt::Widget | Qt::FramelessWindowHint | 
Qt::BypassWindowManagerHint;
         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
@@ -426,7 +428,7 @@ void Qt5Frame::Show(bool bVisible, bool bNoActivate)
     pSalInst->RunInMainThread([this, bVisible, bNoActivate]() {
         asChild()->setVisible(bVisible);
         asChild()->raise();
-        if (!bNoActivate)
+        if (!bNoActivate && !isPopup())
         {
             asChild()->activateWindow();
             asChild()->setFocus();
diff --git a/vcl/qt5/Qt5Widget.cxx b/vcl/qt5/Qt5Widget.cxx
index ebb11cef51ff..864701340ad3 100644
--- a/vcl/qt5/Qt5Widget.cxx
+++ b/vcl/qt5/Qt5Widget.cxx
@@ -46,6 +46,7 @@
 #include <cairo.h>
 #include <vcl/commandevent.hxx>
 #include <vcl/event.hxx>
+#include <vcl/toolkit/floatwin.hxx>
 #include <window.h>
 #include <tools/diagnose_ex.h>
 
@@ -179,11 +180,10 @@ void Qt5Widget::handleMouseButtonEvent(const Qt5Frame& 
rFrame, const QMouseEvent
 
 void Qt5Widget::mousePressEvent(QMouseEvent* pEvent)
 {
-    if ((windowFlags() & Qt::Popup)
-        && !geometry().translated(geometry().topLeft() * 
-1).contains(pEvent->pos()))
-        close();
-    else
-        handleMousePressEvent(m_rFrame, pEvent);
+    handleMousePressEvent(m_rFrame, pEvent);
+    if (m_rFrame.isPopup()
+        || !geometry().translated(geometry().topLeft() * 
-1).contains(pEvent->pos()))
+        closePopup();
 }
 
 void Qt5Widget::mouseReleaseEvent(QMouseEvent* pEvent)
@@ -593,10 +593,21 @@ void Qt5Widget::keyReleaseEvent(QKeyEvent* pEvent)
 
 void Qt5Widget::focusInEvent(QFocusEvent*) { 
m_rFrame.CallCallback(SalEvent::GetFocus, nullptr); }
 
+void Qt5Widget::closePopup()
+{
+    VclPtr<FloatingWindow> pFirstFloat = 
ImplGetSVData()->mpWinData->mpFirstFloat;
+    if (pFirstFloat && !(pFirstFloat->GetPopupModeFlags() & 
FloatWinPopupFlags::NoAppFocusClose))
+    {
+        SolarMutexGuard aGuard;
+        pFirstFloat->EndPopupMode(FloatWinPopupEndFlags::Cancel | 
FloatWinPopupEndFlags::CloseAll);
+    }
+}
+
 void Qt5Widget::focusOutEvent(QFocusEvent*)
 {
     endExtTextInput();
     m_rFrame.CallCallback(SalEvent::LoseFocus, nullptr);
+    closePopup();
 }
 
 Qt5Widget::Qt5Widget(Qt5Frame& rFrame, Qt::WindowFlags f)
@@ -608,8 +619,7 @@ Qt5Widget::Qt5Widget(Qt5Frame& rFrame, Qt::WindowFlags f)
 {
     create();
     setMouseTracking(true);
-    if (!(f & Qt::Popup))
-        setFocusPolicy(Qt::StrongFocus);
+    setFocusPolicy(Qt::StrongFocus);
 }
 
 static ExtTextInputAttr lcl_MapUndrelineStyle(QTextCharFormat::UnderlineStyle 
us)

Reply via email to