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 <caol...@redhat.com> AuthorDate: Thu Jan 28 20:20:56 2021 +0000 Commit: Caolán McNamara <caol...@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 <caol...@redhat.com> Reviewed-by: Caolán McNamara <caol...@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) ); } } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits