[Libreoffice-commits] core.git: vcl/inc vcl/qt5 vcl/source

Jan-Marek Glogowski (via logerrit) logerrit at kemper.freedesktop.org
Wed Jun 12 21:25:02 UTC 2019


 vcl/inc/qt5/Qt5Frame.hxx       |    3 ---
 vcl/inc/qt5/Qt5Object.hxx      |    2 ++
 vcl/inc/salobj.hxx             |    7 ++++---
 vcl/qt5/Qt5Frame.cxx           |   13 +------------
 vcl/qt5/Qt5Object.cxx          |   12 ++++++++++++
 vcl/source/window/syschild.cxx |    6 ++++--
 6 files changed, 23 insertions(+), 20 deletions(-)

New commits:
commit 2dc6bdd1d5789ace0500cad90f5d2eb930888bb9
Author:     Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Wed Jun 5 17:39:45 2019 +0000
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Wed Jun 12 23:22:56 2019 +0200

    tdf#125692 SalObject always holds a SystemChildWindow
    
    Let's just face reality and store it as a VclPtr.
    
    And this is needed, because Qt, like VCL, uses deferred deletion,
    and has no way to filter events to QObjects out of its event queue
    easily. This way the qt5 plugin can report focus changes for
    SalObjects without a crash, which happens when you close a
    presentation with a video by click.
    
    And in addition it reverts the workaround introduced in commit
    e770bacc85a0 ("Qt5 workaround modal change after show bug"), as it
    seems this bug is a use-after-free error, introduced by LO.
    Thanks Michael Weghorn for catching that!
    
    Maybe someone should also rename SalObject...
    
    Change-Id: I0bc64ea64f95dfc7a838799c4a04de183adfefcf
    Reviewed-on: https://gerrit.libreoffice.org/73567
    Tested-by: Jenkins
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>

diff --git a/vcl/inc/qt5/Qt5Frame.hxx b/vcl/inc/qt5/Qt5Frame.hxx
index 3b590bd8e28c..c70171869aa8 100644
--- a/vcl/inc/qt5/Qt5Frame.hxx
+++ b/vcl/inc/qt5/Qt5Frame.hxx
@@ -111,9 +111,6 @@ class VCLPLUG_QT5_PUBLIC Qt5Frame : public QObject, public SalFrame
     void TriggerPaintEvent();
     void TriggerPaintEvent(QRect aRect);
 
-private:
-    void setVisible(bool);
-
 Q_SIGNALS:
     void tooltipRequest(const OUString& rTooltip);
 
diff --git a/vcl/inc/qt5/Qt5Object.hxx b/vcl/inc/qt5/Qt5Object.hxx
index e27d549ca51d..6bfdd81b0327 100644
--- a/vcl/inc/qt5/Qt5Object.hxx
+++ b/vcl/inc/qt5/Qt5Object.hxx
@@ -66,6 +66,8 @@ class Qt5ObjectWindow : public QWindow
     Qt5Object& m_rParent;
 
     bool event(QEvent*) override;
+    void focusInEvent(QFocusEvent*) override;
+    void focusOutEvent(QFocusEvent*) override;
     void mousePressEvent(QMouseEvent*) override;
     void mouseReleaseEvent(QMouseEvent*) override;
     // keyPressEvent(QKeyEvent*) is handled via event(QEvent*); see comment in Qt5Widget::event
diff --git a/vcl/inc/salobj.hxx b/vcl/inc/salobj.hxx
index 56ca04985a7d..83024fec339d 100644
--- a/vcl/inc/salobj.hxx
+++ b/vcl/inc/salobj.hxx
@@ -21,16 +21,17 @@
 #define INCLUDED_VCL_INC_SALOBJ_HXX
 
 #include <vcl/dllapi.h>
+#include <vcl/syschild.hxx>
 #include <com/sun/star/uno/Sequence.hxx>
 #include "salwtype.hxx"
 
 struct SystemEnvData;
 
-typedef void (*SALOBJECTPROC)( void* pInst, SalObjEvent nEvent );
+typedef void (*SALOBJECTPROC)(SystemChildWindow* pInst, SalObjEvent nEvent);
 
 class VCL_PLUGIN_PUBLIC SalObject
 {
-    void*               m_pInst;
+    VclPtr<SystemChildWindow> m_pInst;
     SALOBJECTPROC       m_pCallback;
     bool                m_bMouseTransparent:1,
                         m_bEraseBackground:1;
@@ -54,7 +55,7 @@ public:
 
     virtual const SystemEnvData*    GetSystemData() const = 0;
 
-    void                            SetCallback( void* pInst, SALOBJECTPROC pProc )
+    void                            SetCallback( SystemChildWindow* pInst, SALOBJECTPROC pProc )
                                         { m_pInst = pInst; m_pCallback = pProc; }
     void                            CallCallback( SalObjEvent nEvent )
                                         { if (m_pCallback) m_pCallback( m_pInst, nEvent ); }
diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx
index 8e63a35cc5c8..270885249298 100644
--- a/vcl/qt5/Qt5Frame.cxx
+++ b/vcl/qt5/Qt5Frame.cxx
@@ -362,8 +362,6 @@ void Qt5Frame::DrawMenuBar() { /* not needed */}
 
 void Qt5Frame::SetExtendedFrameStyle(SalExtStyle /*nExtStyle*/) { /* not needed */}
 
-void Qt5Frame::setVisible(bool bVisible) { asChild()->setVisible(bVisible); }
-
 void Qt5Frame::Show(bool bVisible, bool /*bNoActivate*/)
 {
     assert(m_pQWidget);
@@ -373,7 +371,7 @@ void Qt5Frame::Show(bool bVisible, bool /*bNoActivate*/)
 
     auto* pSalInst(static_cast<Qt5Instance*>(GetSalData()->m_pInstance));
     assert(pSalInst);
-    pSalInst->RunInMainThread([this, bVisible]() { setVisible(bVisible); });
+    pSalInst->RunInMainThread([this, bVisible]() { asChild()->setVisible(bVisible); });
 }
 
 void Qt5Frame::SetMinClientSize(long nWidth, long nHeight)
@@ -514,16 +512,7 @@ void Qt5Frame::SetModal(bool bModal)
 
             // modality change is only effective if the window is hidden
             if (bWasVisible)
-            {
                 pChild->hide();
-                if (QGuiApplication::platformName() == "xcb")
-                {
-                    SAL_WARN("vcl.qt5", "SetModal called after Show - apply delay");
-                    // give QXcbConnection some time to recover from unmap
-                    // ~/.xsession-errors => (BadWindow) (ChangeProperty)
-                    QThread::msleep(250);
-                }
-            }
 
             pChild->setWindowModality(bModal ? Qt::WindowModal : Qt::NonModal);
 
diff --git a/vcl/qt5/Qt5Object.cxx b/vcl/qt5/Qt5Object.cxx
index 12d8b39a52ae..6c5238f012dc 100644
--- a/vcl/qt5/Qt5Object.cxx
+++ b/vcl/qt5/Qt5Object.cxx
@@ -109,6 +109,18 @@ Qt5ObjectWindow::Qt5ObjectWindow(Qt5Object& rParent)
     assert(m_rParent.frame() && m_rParent.frame()->GetQWidget());
 }
 
+void Qt5ObjectWindow::focusInEvent(QFocusEvent* pEvent)
+{
+    m_rParent.CallCallback(SalObjEvent::GetFocus);
+    QWindow::focusInEvent(pEvent);
+}
+
+void Qt5ObjectWindow::focusOutEvent(QFocusEvent* pEvent)
+{
+    m_rParent.CallCallback(SalObjEvent::LoseFocus);
+    QWindow::focusOutEvent(pEvent);
+}
+
 void Qt5ObjectWindow::mousePressEvent(QMouseEvent* pEvent)
 {
     m_rParent.CallCallback(SalObjEvent::ToTop);
diff --git a/vcl/source/window/syschild.cxx b/vcl/source/window/syschild.cxx
index 28063ce19c63..e6f3e6013400 100644
--- a/vcl/source/window/syschild.cxx
+++ b/vcl/source/window/syschild.cxx
@@ -42,9 +42,9 @@
 
 using namespace ::com::sun::star;
 
-static void ImplSysChildProc( void* pInst, SalObjEvent nEvent )
+static void ImplSysChildProc( SystemChildWindow* pInst, SalObjEvent nEvent )
 {
-    VclPtr<SystemChildWindow> pWindow = static_cast<SystemChildWindow*>(pInst);
+    VclPtr<SystemChildWindow> pWindow = pInst;
 
     switch ( nEvent )
     {
@@ -68,6 +68,8 @@ static void ImplSysChildProc( void* pInst, SalObjEvent nEvent )
         case SalObjEvent::LoseFocus:
             // trigger a LoseFocus which matches the status
             // of the window with matching Activate-Status
+            if (pWindow->IsDisposed())
+                break;
             pWindow->ImplGetFrameData()->mbSysObjFocus = false;
             if ( !pWindow->ImplGetFrameData()->mnFocusId )
             {


More information about the Libreoffice-commits mailing list