[Libreoffice-commits] core.git: Branch 'libreoffice-6-3' - vcl/unx

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Thu Oct 3 09:08:37 UTC 2019


 vcl/unx/gtk3/gtk3gtkinst.cxx |   51 ++++++++++++++++++++++++++++---------------
 1 file changed, 34 insertions(+), 17 deletions(-)

New commits:
commit af0c51990e6d0f578f75b72383ce129f52bea859
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Thu Sep 26 13:05:27 2019 +0100
Commit:     Xisco Faulí <xiscofauli at libreoffice.org>
CommitDate: Thu Oct 3 11:07:40 2019 +0200

    Resolves: tdf#127262 validity out of order focus in and out problem
    
    Resolves: tdf#127904 modal depth dips below 0
    
    when validation dialog is run modally, but changed itself to unmodal
    during execution.
    
    only NotifyModalHierarchy on modal<->unmodal transition and not on
    modality depth
    
    Change-Id: I06f5fd0ce32a9f2d799f6003b7d22b13e865b8c6
    Reviewed-on: https://gerrit.libreoffice.org/79612
    Tested-by: Jenkins
    Reviewed-by: Xisco Faulí <xiscofauli at libreoffice.org>

diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 05f0a341b9fd..5b7efd8ce43a 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -1259,15 +1259,16 @@ protected:
     GtkInstanceBuilder* m_pBuilder;
 
     DECL_LINK(async_signal_focus_in, void*, void);
+    DECL_LINK(async_signal_focus_out, void*, void);
 
     void launch_signal_focus_in()
     {
         // in e.g. function wizard RefEdits we want to select all when we get focus
         // but there are pending gtk handlers which change selection after our handler
         // post our focus in event to happen after those finish
-        if (m_pFocusEvent)
-            Application::RemoveUserEvent(m_pFocusEvent);
-        m_pFocusEvent = Application::PostUserEvent(LINK(this, GtkInstanceWidget, async_signal_focus_in));
+        if (m_pFocusInEvent)
+            Application::RemoveUserEvent(m_pFocusInEvent);
+        m_pFocusInEvent = Application::PostUserEvent(LINK(this, GtkInstanceWidget, async_signal_focus_in));
     }
 
     static gboolean signalFocusIn(GtkWidget*, GdkEvent*, gpointer widget)
@@ -1294,11 +1295,20 @@ protected:
         return m_aMnemonicActivateHdl.Call(*this);
     }
 
+    void launch_signal_focus_out()
+    {
+        // tdf#127262 because focus in is async, focus out must not appear out
+        // of sequence to focus in
+        if (m_pFocusOutEvent)
+            Application::RemoveUserEvent(m_pFocusOutEvent);
+        m_pFocusOutEvent = Application::PostUserEvent(LINK(this, GtkInstanceWidget, async_signal_focus_out));
+    }
+
     static gboolean signalFocusOut(GtkWidget*, GdkEvent*, gpointer widget)
     {
         GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget);
         SolarMutexGuard aGuard;
-        pThis->signal_focus_out();
+        pThis->launch_signal_focus_out();
         return false;
     }
 
@@ -1389,7 +1399,8 @@ private:
     bool m_bDraggedOver;
     sal_uInt16 m_nLastMouseButton;
     sal_uInt16 m_nLastMouseClicks;
-    ImplSVEvent* m_pFocusEvent;
+    ImplSVEvent* m_pFocusInEvent;
+    ImplSVEvent* m_pFocusOutEvent;
     gulong m_nFocusInSignalId;
     gulong m_nMnemonicActivateSignalId;
     gulong m_nFocusOutSignalId;
@@ -1591,7 +1602,8 @@ public:
         , m_bDraggedOver(false)
         , m_nLastMouseButton(0)
         , m_nLastMouseClicks(0)
-        , m_pFocusEvent(nullptr)
+        , m_pFocusInEvent(nullptr)
+        , m_pFocusOutEvent(nullptr)
         , m_nFocusInSignalId(0)
         , m_nMnemonicActivateSignalId(0)
         , m_nFocusOutSignalId(0)
@@ -2095,8 +2107,10 @@ public:
 
     virtual ~GtkInstanceWidget() override
     {
-        if (m_pFocusEvent)
-            Application::RemoveUserEvent(m_pFocusEvent);
+        if (m_pFocusInEvent)
+            Application::RemoveUserEvent(m_pFocusInEvent);
+        if (m_pFocusOutEvent)
+            Application::RemoveUserEvent(m_pFocusOutEvent);
         if (m_nDragMotionSignalId)
             g_signal_handler_disconnect(m_pWidget, m_nDragMotionSignalId);
         if (m_nDragDropSignalId)
@@ -2184,10 +2198,16 @@ public:
 
 IMPL_LINK_NOARG(GtkInstanceWidget, async_signal_focus_in, void*, void)
 {
-    m_pFocusEvent = nullptr;
+    m_pFocusInEvent = nullptr;
     signal_focus_in();
 }
 
+IMPL_LINK_NOARG(GtkInstanceWidget, async_signal_focus_out, void*, void)
+{
+    m_pFocusOutEvent = nullptr;
+    signal_focus_out();
+}
+
 namespace
 {
     OString MapToGtkAccelerator(const OUString &rStr)
@@ -2983,8 +3003,9 @@ struct DialogRunner
         if (m_xFrameWindow)
         {
             m_xFrameWindow->IncModalCount();
+            if (m_nModalDepth == 0)
+                m_xFrameWindow->ImplGetFrame()->NotifyModalHierarchy(true);
             ++m_nModalDepth;
-            m_xFrameWindow->ImplGetFrame()->NotifyModalHierarchy(true);
         }
     }
 
@@ -2994,7 +3015,8 @@ struct DialogRunner
         {
             m_xFrameWindow->DecModalCount();
             --m_nModalDepth;
-            m_xFrameWindow->ImplGetFrame()->NotifyModalHierarchy(false);
+            if (m_nModalDepth == 0)
+                m_xFrameWindow->ImplGetFrame()->NotifyModalHierarchy(false);
         }
     }
 
@@ -3050,13 +3072,8 @@ struct DialogRunner
             // if, like the calc validation dialog does, the modality was
             // toggled off during execution ensure that on cleanup the parent
             // is left in the state it was found
-            SalFrame* pFrame = m_xFrameWindow->ImplGetFrame();
-            do
-            {
+            while (m_nModalDepth++ < 0)
                 m_xFrameWindow->IncModalCount();
-                pFrame->NotifyModalHierarchy(true);
-            }
-            while (++m_nModalDepth < 0);
         }
     }
 };


More information about the Libreoffice-commits mailing list