From ec63a2da8b8a40761cfffbfcbf5adae91052b018 Mon Sep 17 00:00:00 2001 From: Cody Russell Date: Wed, 16 Oct 2019 19:03:33 +0800 Subject: [GTK] Autoscroll GtkViewport when focus moves (#126) Partially Fixes VSTS #752820 --- packages/gtk+.py | 4 +- packages/patches/gtk/gtkviewport-autoscroll.patch | 109 ++++++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 packages/patches/gtk/gtkviewport-autoscroll.patch diff --git a/packages/gtk+.py b/packages/gtk+.py index 291e027..ff42b5f 100644 --- a/packages/gtk+.py +++ b/packages/gtk+.py @@ -224,7 +224,9 @@ class GtkPackage (GitHubPackage): # https://devdiv.visualstudio.com/DevDiv/_workitems/edit/821841 'patches/gtk/nsview-embedding-skip-hidden-subviews.patch', - 'patches/gtk/0001-gtk-combo-box-native-menu-hook.patch' + 'patches/gtk/0001-gtk-combo-box-native-menu-hook.patch', + + 'patches/gtk/gtkviewport-autoscroll.patch' ]) def prep(self): diff --git a/packages/patches/gtk/gtkviewport-autoscroll.patch b/packages/patches/gtk/gtkviewport-autoscroll.patch new file mode 100644 index 0000000..799e66c --- /dev/null +++ b/packages/patches/gtk/gtkviewport-autoscroll.patch @@ -0,0 +1,109 @@ +diff --git a/gtk/gtkviewport.c b/gtk/gtkviewport.c +index e564b9af5..24dd9f099 100644 +--- a/gtk/gtkviewport.c ++++ b/gtk/gtkviewport.c +@@ -26,6 +26,7 @@ + + #include "config.h" + #include "gtkviewport.h" ++#include "gtkwindow.h" + #include "gtkintl.h" + #include "gtkmarshalers.h" + #include "gtkprivate.h" +@@ -87,6 +88,8 @@ static void gtk_viewport_adjustment_value_changed (GtkAdjustment *adjustment, + gpointer data); + static void gtk_viewport_style_set (GtkWidget *widget, + GtkStyle *previous_style); ++static void gtk_viewport_set_focus_child (GtkContainer *container, ++ GtkWidget *child); + + G_DEFINE_TYPE (GtkViewport, gtk_viewport, GTK_TYPE_BIN) + +@@ -114,8 +117,9 @@ gtk_viewport_class_init (GtkViewportClass *class) + widget_class->size_request = gtk_viewport_size_request; + widget_class->size_allocate = gtk_viewport_size_allocate; + widget_class->style_set = gtk_viewport_style_set; +- ++ + container_class->add = gtk_viewport_add; ++ container_class->set_focus_child = gtk_viewport_set_focus_child; + + class->set_scroll_adjustments = gtk_viewport_set_scroll_adjustments; + +@@ -758,6 +762,76 @@ gtk_viewport_add (GtkContainer *container, + GTK_CONTAINER_CLASS (gtk_viewport_parent_class)->add (container, child); + } + ++static gboolean ++set_focus_child_cb (gpointer data) ++{ ++ GtkWidget *widget; ++ GtkViewport *viewport; ++ GtkWidget *toplevel; ++ GtkWidget *focus; ++ GtkAdjustment *adj; ++ int x, y; ++ GtkAllocation widget_alloc; ++ GtkAllocation focus_alloc; ++ gdouble value; ++ ++ widget = (GtkWidget *)data; ++ g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); ++ ++ toplevel = gtk_widget_get_toplevel (widget); ++ g_return_val_if_fail (GTK_IS_WIDGET (toplevel), FALSE); ++ ++ focus = gtk_window_get_focus (GTK_WINDOW (toplevel)); ++ if (focus == NULL) ++ return FALSE; ++ ++ viewport = GTK_VIEWPORT (widget); ++ ++ gtk_widget_get_allocation (focus, &focus_alloc); ++ gtk_widget_get_allocation (widget, &widget_alloc); ++ gtk_widget_translate_coordinates (focus, widget, 0, 0, &x, &y); ++ ++ /* Do we need to move vertically? */ ++ if (y + focus_alloc.height >= widget_alloc.height) ++ { ++ adj = gtk_viewport_get_vadjustment (viewport); ++ value = gtk_adjustment_get_value (adj) + (y + focus_alloc.height - widget_alloc.height); ++ gtk_adjustment_set_value (adj, value); ++ } ++ else if (y <= widget_alloc.y) ++ { ++ adj = gtk_viewport_get_vadjustment (viewport); ++ value = gtk_adjustment_get_value (adj) - (widget_alloc.y - y); ++ gtk_adjustment_set_value (adj, value); ++ } ++ ++ /* Do we need to move horizontally? */ ++ if (x + focus_alloc.width >= widget_alloc.width) ++ { ++ adj = gtk_viewport_get_hadjustment (viewport); ++ value = gtk_adjustment_get_value (adj) + (x + focus_alloc.width - widget_alloc.width); ++ gtk_adjustment_set_value (adj, value); ++ } ++ else if (x <= widget_alloc.x) ++ { ++ adj = gtk_viewport_get_hadjustment (viewport); ++ value = gtk_adjustment_get_value (adj) - (widget_alloc.x - x); ++ gtk_adjustment_set_value (adj, value); ++ } ++ ++ return FALSE; ++} ++ ++static void ++gtk_viewport_set_focus_child (GtkContainer *container, ++ GtkWidget *child) ++{ ++ if (child == NULL) ++ return; ++ ++ g_idle_add (set_focus_child_cb, container); ++} ++ + static void + gtk_viewport_size_request (GtkWidget *widget, + GtkRequisition *requisition) -- cgit v1.2.3