[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