summaryrefslogtreecommitdiff
path: root/formula/source
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2021-02-18 14:56:01 +0000
committerCaolán McNamara <caolanm@redhat.com>2021-02-18 21:04:32 +0100
commitc56e0c791a79dc414108e1b2fbf0f7eb38657f10 (patch)
tree902ac8d87e5e8021353720467dbe379fbc46f546 /formula/source
parent28557f54caf924240e6d698a9d2f1e2bc1cf3ab4 (diff)
move async focus-in/focus-out workaround to known client that needs it
and for the normal case process immediately. Use-case is the bibliography editor, modified uncommitted entry, click in browser column margin area to select a new row, the entry should commit its old contents to the old row before filling from the new row Change-Id: Ib41d96afcfa86bcd1075b9512d4cfab593afa66d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111152 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'formula/source')
-rw-r--r--formula/source/ui/dlg/funcutl.cxx48
1 files changed, 43 insertions, 5 deletions
diff --git a/formula/source/ui/dlg/funcutl.cxx b/formula/source/ui/dlg/funcutl.cxx
index f64b6aff9bd5..361ec4c9ebaa 100644
--- a/formula/source/ui/dlg/funcutl.cxx
+++ b/formula/source/ui/dlg/funcutl.cxx
@@ -21,6 +21,7 @@
#include <formula/funcutl.hxx>
#include <formula/IControlReferenceHandler.hxx>
+#include <vcl/svapp.hxx>
#include "ControlHelper.hxx"
#include "parawin.hxx"
#include <strings.hrc>
@@ -265,9 +266,11 @@ RefEdit::RefEdit(std::unique_ptr<weld::Entry> xControl)
, aIdle("formula RefEdit Idle")
, pAnyRefDlg(nullptr)
, pLabelWidget(nullptr)
+ , mpFocusInEvent(nullptr)
+ , mpFocusOutEvent(nullptr)
{
- xEntry->connect_focus_in(LINK(this, RefEdit, GetFocus));
- xEntry->connect_focus_out(LINK(this, RefEdit, LoseFocus));
+ xEntry->connect_focus_in(LINK(this, RefEdit, GetFocusHdl));
+ xEntry->connect_focus_out(LINK(this, RefEdit, LoseFocusHdl));
xEntry->connect_key_press(LINK(this, RefEdit, KeyInputHdl));
xEntry->connect_changed(LINK(this, RefEdit, Modify));
aIdle.SetInvokeHandler( LINK( this, RefEdit, UpdateHdl ) );
@@ -275,6 +278,10 @@ RefEdit::RefEdit(std::unique_ptr<weld::Entry> xControl)
RefEdit::~RefEdit()
{
+ if (mpFocusInEvent)
+ Application::RemoveUserEvent(mpFocusInEvent);
+ if (mpFocusOutEvent)
+ Application::RemoveUserEvent(mpFocusOutEvent);
aIdle.ClearInvokeHandler();
aIdle.Stop();
}
@@ -355,22 +362,53 @@ void RefEdit::GrabFocus()
bool bHadFocus = xEntry->has_focus();
xEntry->grab_focus();
if (!bHadFocus && xEntry->has_focus())
- GetFocus(*xEntry);
+ GetFocus();
}
-IMPL_LINK_NOARG(RefEdit, GetFocus, weld::Widget&, void)
+void RefEdit::GetFocus()
{
maGetFocusHdl.Call(*this);
StartUpdateData();
}
-IMPL_LINK_NOARG(RefEdit, LoseFocus, weld::Widget&, void)
+void RefEdit::LoseFocus()
{
maLoseFocusHdl.Call(*this);
if( pAnyRefDlg )
pAnyRefDlg->HideReference();
}
+IMPL_LINK_NOARG(RefEdit, GetFocusHdl, weld::Widget&, void)
+{
+ // in e.g. function wizard RefEdits we want to select all when we get focus
+ // but in the gtk case there are pending gtk handlers which change selection
+ // after our handler, so post our focus in event to happen after those complete
+ if (mpFocusInEvent)
+ Application::RemoveUserEvent(mpFocusInEvent);
+ mpFocusInEvent = Application::PostUserEvent(LINK(this, RefEdit, AsyncFocusInHdl));
+}
+
+IMPL_LINK_NOARG(RefEdit, LoseFocusHdl, weld::Widget&, void)
+{
+ // tdf#127262 because focus in is async, focus out must not appear out
+ // of sequence to focus in
+ if (mpFocusOutEvent)
+ Application::RemoveUserEvent(mpFocusOutEvent);
+ mpFocusOutEvent = Application::PostUserEvent(LINK(this, RefEdit, AsyncFocusOutHdl));
+}
+
+IMPL_LINK_NOARG(RefEdit, AsyncFocusInHdl, void*, void)
+{
+ mpFocusInEvent = nullptr;
+ GetFocus();
+}
+
+IMPL_LINK_NOARG(RefEdit, AsyncFocusOutHdl, void*, void)
+{
+ mpFocusOutEvent = nullptr;
+ LoseFocus();
+}
+
IMPL_LINK_NOARG(RefEdit, UpdateHdl, Timer *, void)
{
if( pAnyRefDlg )