vcl/inc/qt5/QtInstance.hxx |    6 ++++++
 vcl/inc/qt5/QtWidget.hxx   |    1 +
 vcl/qt5/QtInstance.cxx     |    7 +++++++
 vcl/qt5/QtWidget.cxx       |   20 ++++++++++++++++----
 4 files changed, 30 insertions(+), 4 deletions(-)

New commits:
commit 06c51d61e4a16057f945effe85b1ff9457f8cffb
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Thu Apr 21 10:56:42 2022 +0200
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Thu Apr 21 18:57:05 2022 +0200

    tdf#148699 Qt track the active / shown popup
    
    I have no idea, if there can be multiple active popups in LO in
    some way. There can be multiple FloatingWindow and gtk does count
    them in m_nFloats... There is a whole lot going on in gtk3 related
    to isFloatGrabWindow(), with "funny" comments like:
    
    // FIXME: find out who the hell steals the focus from our frame
    
    So this goes with some "optimistic" approach: there is just one
    active popup, so we can track it in QtInstance. It WFM...
    
    Change-Id: I9778587696e1ad9e641dba4f102e2e921266eee6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133249
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>
    (cherry picked from commit 347622a98f512dae709f938a85498dcdcf9f225a)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133260
    Reviewed-by: Jan-Marek Glogowski <glo...@fbihome.de>

diff --git a/vcl/inc/qt5/QtInstance.hxx b/vcl/inc/qt5/QtInstance.hxx
index 9a9853a7a2ce..fd111bb22abe 100644
--- a/vcl/inc/qt5/QtInstance.hxx
+++ b/vcl/inc/qt5/QtInstance.hxx
@@ -35,6 +35,7 @@
 
 #include "QtFilePicker.hxx"
 
+class QtFrame;
 class QtTimer;
 
 class QApplication;
@@ -67,6 +68,8 @@ class VCLPLUG_QT_PUBLIC QtInstance : public QObject,
     Timer m_aUpdateStyleTimer;
     bool m_bUpdateFonts;
 
+    QtFrame* m_pActivePopup;
+
     DECL_DLLPRIVATE_LINK(updateStyleHdl, Timer*, void);
     void AfterAppInit() override;
 
@@ -172,6 +175,9 @@ public:
     void UpdateStyle(bool bFontsChanged);
 
     void* CreateGStreamerSink(const SystemChildWindow*) override;
+
+    QtFrame* activePopup() const { return m_pActivePopup; }
+    void setActivePopup(QtFrame*);
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/qt5/QtWidget.hxx b/vcl/inc/qt5/QtWidget.hxx
index 4a40589b16ba..8f7f6cc319e1 100644
--- a/vcl/inc/qt5/QtWidget.hxx
+++ b/vcl/inc/qt5/QtWidget.hxx
@@ -73,6 +73,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 wheelEvent(QWheelEvent*) override;
     virtual void closeEvent(QCloseEvent*) override;
     virtual void changeEvent(QEvent*) override;
diff --git a/vcl/qt5/QtInstance.cxx b/vcl/qt5/QtInstance.cxx
index d252109e122a..247001443020 100644
--- a/vcl/qt5/QtInstance.cxx
+++ b/vcl/qt5/QtInstance.cxx
@@ -223,6 +223,7 @@ QtInstance::QtInstance(std::unique_ptr<QApplication>& 
pQApp, bool bUseCairo)
     , m_pQApplication(std::move(pQApp))
     , m_aUpdateStyleTimer("vcl::qt5 m_aUpdateStyleTimer")
     , m_bUpdateFonts(false)
+    , m_pActivePopup(nullptr)
 {
     ImplSVData* pSVData = ImplGetSVData();
     const OUString sToolkit = "qt" + OUString::number(QT_VERSION_MAJOR);
@@ -722,6 +723,12 @@ std::unique_ptr<QApplication> 
QtInstance::CreateQApplication(int& nArgc, char**
     return pQApp;
 }
 
+void QtInstance::setActivePopup(QtFrame* pFrame)
+{
+    assert(!pFrame || pFrame->isPopup());
+    m_pActivePopup = pFrame;
+}
+
 extern "C" {
 VCLPLUG_QT_PUBLIC SalInstance* create_SalInstance()
 {
diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx
index 5f07974600e8..8c545fd13377 100644
--- a/vcl/qt5/QtWidget.cxx
+++ b/vcl/qt5/QtWidget.cxx
@@ -317,9 +317,21 @@ void QtWidget::showEvent(QShowEvent*)
     // sequence from QtFrame::SetModal, if the frame was already set visible,
     // resulting in a hidden / unmapped window
     SalPaintEvent aPaintEvt(0, 0, aSize.width(), aSize.height());
+    if (m_rFrame.isPopup())
+    {
+        auto* pQtInst(static_cast<QtInstance*>(GetSalData()->m_pInstance));
+        pQtInst->setActivePopup(&m_rFrame);
+    }
     m_rFrame.CallCallback(SalEvent::Paint, &aPaintEvt);
 }
 
+void QtWidget::hideEvent(QHideEvent*)
+{
+    auto* pQtInst(static_cast<QtInstance*>(GetSalData()->m_pInstance));
+    if (m_rFrame.isPopup() && pQtInst->activePopup() == &m_rFrame)
+        pQtInst->setActivePopup(nullptr);
+}
+
 void QtWidget::closeEvent(QCloseEvent* /*pEvent*/)
 {
     m_rFrame.CallCallback(SalEvent::Close, nullptr);
@@ -627,11 +639,11 @@ bool QtWidget::handleEvent(QtFrame& rFrame, QWidget& 
rWidget, QEvent* pEvent)
     }
     else if (pEvent->type() == QEvent::ToolTip)
     {
-        // Qt's POV on focus is wrong for our fake popup windows, so check 
LO's state.
+        // Qt's POV on the active popup is wrong due to our fake popup, so 
check LO's state.
         // Otherwise Qt will continue handling ToolTip events from the 
"parent" window.
-        const vcl::Window* pFocusWin = Application::GetFocusWindow();
-        if (!rFrame.m_aTooltipText.isEmpty() && pFocusWin
-            && pFocusWin->GetFrameWindow() == rFrame.GetWindow())
+        const QtFrame* pPopupFrame
+            = 
static_cast<QtInstance*>(GetSalData()->m_pInstance)->activePopup();
+        if (!rFrame.m_aTooltipText.isEmpty() && (!pPopupFrame || pPopupFrame 
== &rFrame))
             QToolTip::showText(QCursor::pos(), 
toQString(rFrame.m_aTooltipText), &rWidget,
                                rFrame.m_aTooltipArea);
         else

Reply via email to