[Libreoffice-commits] core.git: vcl/unx
Caolán McNamara (via logerrit)
logerrit at kemper.freedesktop.org
Fri Jan 29 09:17:30 UTC 2021
vcl/unx/gtk3/gtk3gtkframe.cxx | 5 +++++
vcl/unx/gtk3/gtk3gtkinst.cxx | 10 ++++++++++
vcl/unx/gtk3/gtk3gtkobject.cxx | 30 +++++++++++++++++++++++++-----
3 files changed, 40 insertions(+), 5 deletions(-)
New commits:
commit 697399a78f17f5277d3e2962aa7b92e610619abe
Author: Caolán McNamara <caolanm at redhat.com>
AuthorDate: Thu Jan 28 20:20:56 2021 +0000
Commit: Caolán McNamara <caolanm at redhat.com>
CommitDate: Fri Jan 29 10:16:48 2021 +0100
keep focus in GtkSalObject child on gtk_widget_hide
gtk will take the focus out on hiding the GtkSalObject's child widget,
we want to keep it in. e.g. writer's comments in margin feature put
cursor in a sidebar comment and scroll the page so the comment is
invisible, we want the focus to stay in the invisible widget, so its
there when we scroll back or on a keypress the widget gets the keystroke
and scrolls back to make it visible again
Change-Id: If200779ef1b9cdfa9c4b027c27eca0afd5013ac5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110094
Tested-by: Caolán McNamara <caolanm at redhat.com>
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx
index 4243763a3158..fb013d2a95ca 100644
--- a/vcl/unx/gtk3/gtk3gtkframe.cxx
+++ b/vcl/unx/gtk3/gtk3gtkframe.cxx
@@ -3188,6 +3188,11 @@ void GtkSalFrame::signalSetFocus(GtkWindow*, GtkWidget* pWidget, gpointer frame)
else
pGrabWidget = GTK_WIDGET(pThis->m_pFixedContainer);
+ GtkWidget* pTopLevel = gtk_widget_get_toplevel(pGrabWidget);
+ // see commentary in GtkSalObjectWidgetClip::Show
+ if (pTopLevel && g_object_get_data(G_OBJECT(pTopLevel), "g-lo-BlockFocusChange"))
+ return;
+
// tdf#129634 interpret losing focus as focus passing explicitly to another widget
bool bLoseFocus = pWidget && pWidget != pGrabWidget;
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index a42dbd5f4d8b..38708be5d273 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -1935,6 +1935,11 @@ protected:
void launch_signal_focus_in()
{
+ GtkWidget* pTopLevel = gtk_widget_get_toplevel(m_pWidget);
+ // see commentary in GtkSalObjectWidgetClip::Show
+ if (pTopLevel && g_object_get_data(G_OBJECT(pTopLevel), "g-lo-BlockFocusChange"))
+ return;
+
// 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
@@ -1969,6 +1974,11 @@ protected:
void launch_signal_focus_out()
{
+ GtkWidget* pTopLevel = gtk_widget_get_toplevel(m_pWidget);
+ // see commentary in GtkSalObjectWidgetClip::Show
+ if (pTopLevel && g_object_get_data(G_OBJECT(pTopLevel), "g-lo-BlockFocusChange"))
+ return;
+
// tdf#127262 because focus in is async, focus out must not appear out
// of sequence to focus in
if (m_pFocusOutEvent)
diff --git a/vcl/unx/gtk3/gtk3gtkobject.cxx b/vcl/unx/gtk3/gtk3gtkobject.cxx
index d9de95926611..5923088b79ee 100644
--- a/vcl/unx/gtk3/gtk3gtkobject.cxx
+++ b/vcl/unx/gtk3/gtk3gtkobject.cxx
@@ -415,12 +415,32 @@ void GtkSalObjectWidgetClip::Reparent(SalFrame* pFrame)
void GtkSalObjectWidgetClip::Show( bool bVisible )
{
- if( m_pSocket )
+ if (!m_pSocket)
+ return;
+ bool bCurrentVis = gtk_widget_get_visible(m_pScrolledWindow);
+ if (bVisible == bCurrentVis)
+ return;
+ if( bVisible )
+ gtk_widget_show(m_pScrolledWindow);
+ else
{
- if( bVisible )
- gtk_widget_show(m_pScrolledWindow);
- else
- gtk_widget_hide(m_pScrolledWindow);
+ // on hiding the widget, if a child has focus gtk will want to move the focus out of the widget
+ // but we want to keep the focus where it is, e.g. writer's comments in margin feature put
+ // cursor in a sidebar comment and scroll the page so the comment is invisible, we want the focus
+ // to stay in the invisible widget, so its there when we scroll back or on a keypress the widget
+ // gets the keystroke and scrolls back to make it visible again
+ GtkWidget* pTopLevel = gtk_widget_get_toplevel(m_pScrolledWindow);
+ GtkWidget* pOldFocus = GTK_IS_WINDOW(pTopLevel) ? gtk_window_get_focus(GTK_WINDOW(pTopLevel)) : nullptr;
+
+ g_object_set_data(G_OBJECT(pTopLevel), "g-lo-BlockFocusChange", GINT_TO_POINTER(true) );
+
+ gtk_widget_hide(m_pScrolledWindow);
+
+ GtkWidget* pNewFocus = GTK_IS_WINDOW(pTopLevel) ? gtk_window_get_focus(GTK_WINDOW(pTopLevel)) : nullptr;
+ if (pOldFocus && pOldFocus != pNewFocus)
+ gtk_widget_grab_focus(pOldFocus);
+
+ g_object_set_data(G_OBJECT(pTopLevel), "g-lo-BlockFocusChange", GINT_TO_POINTER(false) );
}
}
More information about the Libreoffice-commits
mailing list