diff options
author | Caolán McNamara <caolanm@redhat.com> | 2019-09-26 13:05:27 +0100 |
---|---|---|
committer | Xisco Faulí <xiscofauli@libreoffice.org> | 2019-10-03 11:07:40 +0200 |
commit | af0c51990e6d0f578f75b72383ce129f52bea859 (patch) | |
tree | 409cc78edef8aada7c7b1560236ed3fe7146aff1 /vcl | |
parent | 3c55f6570833509b548968c050ed4a87b742e7b0 (diff) |
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@libreoffice.org>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkinst.cxx | 51 |
1 files changed, 34 insertions, 17 deletions
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); } } }; |