diff options
author | Alexander Köplinger <alex.koeplinger@outlook.com> | 2018-12-21 18:19:50 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-21 18:19:50 +0300 |
commit | c9434ec024b7e6a4d648163fe0b3afbc068c7bb5 (patch) | |
tree | da36dadc17fd3ed5d8dc490856601f8ecf3b5cde | |
parent | dbd96d8564a82f58b68c0e71917e2b0ce3f0cb01 (diff) | |
parent | 455f970ffef13f169a62f2b21df3b4d3acbd9dd9 (diff) |
Merge pull request #82 from mono/vsts737323
[GTK] Fix focus handling to better handle subviews for GtkNSView
-rw-r--r-- | packages/gtk+.py | 6 | ||||
-rw-r--r-- | packages/patches/gtk/gtk-nsview-focus-tabbing.patch | 68 | ||||
-rw-r--r-- | packages/patches/gtk/gtk-nsview-subview-focus-fixes.patch | 93 |
3 files changed, 166 insertions, 1 deletions
diff --git a/packages/gtk+.py b/packages/gtk+.py index 9c9d516..d6af9fa 100644 --- a/packages/gtk+.py +++ b/packages/gtk+.py @@ -213,7 +213,11 @@ class GtkPackage (GitHubPackage): #'patches/gtk/gtk-fix-find_nsview_at_pos-recursive.patch', # https://devdiv.visualstudio.com/DevDiv/_workitems/edit/569768 - 'patches/gtk/gtk-imquartz-commit-on-focus-out.patch' + 'patches/gtk/gtk-imquartz-commit-on-focus-out.patch', + + # https://devdiv.visualstudio.com/DevDiv/_workitems/edit/737323 + 'patches/gtk/gtk-nsview-subview-focus-fixes.patch', + 'patches/gtk/gtk-nsview-focus-tabbing.patch' ]) def prep(self): diff --git a/packages/patches/gtk/gtk-nsview-focus-tabbing.patch b/packages/patches/gtk/gtk-nsview-focus-tabbing.patch new file mode 100644 index 0000000..e0d3a6d --- /dev/null +++ b/packages/patches/gtk/gtk-nsview-focus-tabbing.patch @@ -0,0 +1,68 @@ +diff --git a/gtk/gtknsview.c b/gtk/gtknsview.c +index 5b9961eb14..515bc369fc 100644 +--- a/gtk/gtknsview.c ++++ b/gtk/gtknsview.c +@@ -739,54 +739,17 @@ gtk_ns_view_key_press (GtkWidget *widget, + GtkNSView *ns_view = GTK_NS_VIEW (widget); + NSEvent *nsevent = gdk_quartz_event_get_nsevent ((GdkEvent *) event); + +- if (gtk_ns_view_forward_event (widget, event)) +- { +- NSWindow *ns_window = [ns_view->priv->view window]; +- NSResponder *responder = [ns_window firstResponder]; +- +- gint command_mask = gdk_quartz_get_fix_modifiers () ? GDK_MOD2_MASK : GDK_MOD1_MASK; ++ if ([nsevent type] != NSEventTypeKeyDown) { ++ return GTK_WIDGET_CLASS (gtk_ns_view_parent_class)->key_press_event (widget, event); ++ } + +- if ([responder isKindOfClass: [NSTextView class]] && +- (event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | +- GDK_MOD1_MASK | GDK_MOD2_MASK)) == command_mask) +- { +- NSTextView *text_view = (NSTextView *) responder; +- NSRange range = [text_view selectedRange]; +- gboolean has_selection = range.length > 0; ++ NSWindow *ns_window = [ns_view->priv->view window]; ++ NSResponder *responder = [ns_window firstResponder]; ++ if (responder) { ++ [[ns_window firstResponder] interpretKeyEvents:@[nsevent]]; + +- switch (event->keyval) +- { +- case GDK_KEY_c: /* copy */ +- if (has_selection) +- [text_view copy: text_view]; +- return TRUE; +- +- case GDK_KEY_x: /* cut */ +- if (has_selection) +- [text_view cut: text_view]; +- return TRUE; +- +- case GDK_KEY_v: /* paste */ +- [text_view paste: text_view]; +- return TRUE; +- +- case GDK_KEY_a: /* all */ +- range.location = 0; +- range.length = [[text_view string] length]; +- [text_view setSelectedRange: range]; +- return TRUE; +- +- default: +- break; +- } +- } +- else +- { +- [ns_window sendEvent:nsevent]; +- +- return TRUE; +- } +- } ++ return TRUE; ++ } + + return GTK_WIDGET_CLASS (gtk_ns_view_parent_class)->key_press_event (widget, event); + } diff --git a/packages/patches/gtk/gtk-nsview-subview-focus-fixes.patch b/packages/patches/gtk/gtk-nsview-subview-focus-fixes.patch new file mode 100644 index 0000000..74dc49a --- /dev/null +++ b/packages/patches/gtk/gtk-nsview-subview-focus-fixes.patch @@ -0,0 +1,93 @@ +diff --git a/gtk/gtknsview.c b/gtk/gtknsview.c +index a4b4dd4dbe..5b9961eb14 100644 +--- a/gtk/gtknsview.c ++++ b/gtk/gtknsview.c +@@ -49,6 +49,7 @@ enum + struct _GtkNSViewPrivate + { + NSView *view; ++ NSResponder *responder; + guint map_timeout; + gboolean enable_swizzle; + }; +@@ -442,15 +443,29 @@ gtk_ns_view_replace_draw_insertion_point (void) + } + } + ++gboolean ++does_accept_first_responder_recursively (NSView *view) ++{ ++ if ([view acceptsFirstResponder]) { ++ return TRUE; ++ } ++ ++ for (NSView *subview in [view subviews]) { ++ return does_accept_first_responder_recursively (subview); ++ } ++ ++ return FALSE; ++} ++ + static void + gtk_ns_view_constructed (GObject *object) + { + GtkNSView *ns_view = GTK_NS_VIEW (object); ++ gboolean can_focus = does_accept_first_responder_recursively (ns_view->priv->view); + + G_OBJECT_CLASS (gtk_ns_view_parent_class)->constructed (object); + +- gtk_widget_set_can_focus (GTK_WIDGET (ns_view), +- [ns_view->priv->view acceptsFirstResponder]); ++ gtk_widget_set_can_focus (GTK_WIDGET (ns_view), can_focus); + + #if DEBUG_FOCUS + g_printerr ("%s can focus: %d\n", +@@ -549,10 +564,12 @@ gtk_ns_view_notify (GObject *object, + gtk_widget_has_focus (GTK_WIDGET (object))); + #endif + +- if (gtk_widget_has_focus (GTK_WIDGET (object))) +- [ns_window makeFirstResponder:ns_view->priv->view]; +- else if ([ns_window firstResponder] == ns_view->priv->view || (GTK_IS_WINDOW (toplevel) && !gtk_window_is_active (GTK_WINDOW (toplevel)))) ++ if (gtk_widget_has_focus (GTK_WIDGET (object))) { ++ [ns_window makeFirstResponder:(ns_view->priv->responder ? ns_view->priv->responder : ns_view->priv->view)]; ++ // ns_view->priv->responder = NULL; ++ } else if ([ns_window firstResponder] == ns_view->priv->view || (GTK_IS_WINDOW (toplevel) && !gtk_window_is_active (GTK_WINDOW (toplevel)))) { + [ns_window makeFirstResponder:nil]; ++ } + } + } + +@@ -712,7 +729,7 @@ gtk_ns_view_grab_focus (GtkWidget *widget) + GTK_WIDGET_CLASS (gtk_ns_view_parent_class)->grab_focus (widget); + + ns_window = [ns_view->priv->view window]; +- [ns_window makeFirstResponder:ns_view->priv->view]; ++ [ns_window makeFirstResponder:(ns_view->priv->responder != NULL ? ns_view->priv->responder : ns_view->priv->view)]; + } + + static gboolean +@@ -818,15 +835,20 @@ gtk_ns_view_native_child_event (GdkWindow *window, + + if (hit && + (hit == view || +- [hit ancestorSharedWithView: view] == view) && +- ([hit acceptsFirstResponder] || +- [view acceptsFirstResponder])) ++ [hit ancestorSharedWithView: view] == view)) + { ++ NSResponder *responder = (NSResponder *)hit; ++ while (responder) { ++ if ([responder acceptsFirstResponder]) ++ break; ++ responder = [responder nextResponder]; ++ } + #if DEBUG_FOCUS + g_printerr ("grabbing focus on %s\n", + class_getName ([ns_view->priv->view class])); + #endif + ++ ns_view->priv->responder = responder; + gtk_widget_grab_focus (GTK_WIDGET (ns_view)); + } + } |