Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/bockbuild.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Köplinger <alex.koeplinger@outlook.com>2018-12-21 18:19:50 +0300
committerGitHub <noreply@github.com>2018-12-21 18:19:50 +0300
commitc9434ec024b7e6a4d648163fe0b3afbc068c7bb5 (patch)
treeda36dadc17fd3ed5d8dc490856601f8ecf3b5cde
parentdbd96d8564a82f58b68c0e71917e2b0ce3f0cb01 (diff)
parent455f970ffef13f169a62f2b21df3b4d3acbd9dd9 (diff)
Merge pull request #82 from mono/vsts737323
[GTK] Fix focus handling to better handle subviews for GtkNSView
-rw-r--r--packages/gtk+.py6
-rw-r--r--packages/patches/gtk/gtk-nsview-focus-tabbing.patch68
-rw-r--r--packages/patches/gtk/gtk-nsview-subview-focus-fixes.patch93
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));
+ }
+ }