linux-packaging-mono/external/bockbuild/packages/patches/gtk/0050-nsview-clip-text-field-cursor-drawing.patch
Xamarin Public Jenkins (auto-signing) 6bdd276d05 Imported Upstream version 5.0.0.42
Former-commit-id: fd56571888259555122d8a0f58c68838229cea2b
2017-04-10 11:41:01 +00:00

222 lines
8.1 KiB
Diff

From daf0f5ecb7b9a71d93d7e41b000369d977ea4816 Mon Sep 17 00:00:00 2001
From: Michael Natterer <mitch@gimp.org>
Date: Thu, 25 Apr 2013 14:52:18 +0200
Subject: [PATCH 50/68] nsview: clip text field cursor drawing
by replacing (not "normal" swizzling) drawInsertionPointInRect. This
fixes cursor clipping for the *blinking* cursor, but not if the
cusor moves. Patch patially from Kris..
---
gtk/gtknsview.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 159 insertions(+), 3 deletions(-)
diff --git a/gtk/gtknsview.c b/gtk/gtknsview.c
index bc3cbfb..5e3aa59 100644
--- a/gtk/gtknsview.c
+++ b/gtk/gtknsview.c
@@ -145,14 +145,23 @@ static void gtk_ns_view_swizzle_draw_rect_recursive (NSView *view,
gpointer associated_object);
@implementation NSView (myDidAddSubview)
-- (void) myDidAddSubview:(NSView *)aView
+- (void) myDidAddSubview: (NSView *) aView
{
void *associated_object;
associated_object = objc_getAssociatedObject (self, "gtknsview");
if (associated_object)
- gtk_ns_view_swizzle_draw_rect_recursive (aView, "gtknsview", associated_object);
+ {
+ gtk_ns_view_swizzle_draw_rect_recursive (aView, "gtknsview", associated_object);
+ }
+ else
+ {
+ associated_object = objc_getAssociatedObject (self, "gtkwindow");
+
+ if (associated_object)
+ gtk_ns_view_swizzle_draw_rect_recursive (aView, "gtkwindow", associated_object);
+ }
[self myDidAddSubview:aView];
}
@@ -256,6 +265,110 @@ static void gtk_ns_view_swizzle_draw_rect_recursive (NSView *view,
}
@end
+@implementation NSTextView (myDrawInsertionPointInRect)
+- (void) myDrawInsertionPointInRect: (NSRect) aRect
+ color: (NSColor *) aColor
+ turnedOn: (BOOL) flag
+{
+ GtkNSView *ns_view;
+ GtkWidget *viewport;
+ CGContextRef cg_context;
+
+ ns_view = (GtkNSView *) objc_getAssociatedObject (self, "gtknsview");
+
+ if (! ns_view && ([self class] == [NSTextView class]))
+ {
+ /* if it's not a GtkNSView, check if it's the NSWindow's cell
+ * editor editing an NSTextField managed by a GtkNSView
+ */
+ GtkWindow *window = (GtkWindow *) objc_getAssociatedObject (self, "gtkwindow");
+
+ if (GTK_IS_WINDOW (window))
+ {
+ GtkWidget *focus = gtk_window_get_focus (window);
+
+ if (GTK_IS_NS_VIEW (focus))
+ ns_view = GTK_NS_VIEW (focus);
+ }
+ }
+
+ if (! ns_view ||
+ ns_view->priv->view != [ns_view->priv->view ancestorSharedWithView: self])
+ {
+ [self myDrawInsertionPointInRect: aRect
+ color: aColor
+ turnedOn: flag];
+ return;
+ }
+
+ cg_context = [[NSGraphicsContext currentContext] graphicsPort];
+ CGContextSaveGState (cg_context);
+
+ for (viewport = gtk_widget_get_ancestor (GTK_WIDGET (ns_view), GTK_TYPE_VIEWPORT);
+ viewport;
+ viewport = gtk_widget_get_ancestor (gtk_widget_get_parent (viewport),
+ GTK_TYPE_VIEWPORT))
+ {
+ GdkWindow *window;
+ GtkAllocation viewport_allocation;
+ CGRect rect;
+
+ gtk_widget_get_allocation (viewport, &viewport_allocation);
+
+ /* evil: don't clip to the viewport's width/height but to that
+ * of its parent window, because we know we hacked an
+ * overshoot_window into GtkScrolledWindow and need to restrict
+ * rendering to its area
+ */
+ window = gtk_widget_get_parent_window (viewport);
+
+ viewport_allocation.width = gdk_window_get_width (window);
+ viewport_allocation.height = gdk_window_get_height (window);
+
+ if (gtk_viewport_get_shadow_type (GTK_VIEWPORT (viewport)) != GTK_SHADOW_NONE)
+ {
+ GtkStyle *style = gtk_widget_get_style (viewport);
+
+ viewport_allocation.x += style->xthickness;
+ viewport_allocation.y += style->ythickness;
+ viewport_allocation.width -= 2 * style->xthickness;
+ viewport_allocation.height -= 2 * style->ythickness;
+ }
+
+ gtk_widget_translate_coordinates (viewport, GTK_WIDGET (ns_view),
+ viewport_allocation.x,
+ viewport_allocation.y,
+ &viewport_allocation.x,
+ &viewport_allocation.y);
+
+ rect.origin.x = viewport_allocation.x;
+ rect.origin.y = viewport_allocation.y;
+ rect.size.width = viewport_allocation.width;
+ rect.size.height = viewport_allocation.height;
+
+ /* need to translate rect if this is not the view itself but a subview */
+ if (ns_view->priv->view != self)
+ {
+ NSRect offset = NSMakeRect (0, 0, 0, 0);
+
+ offset = [ns_view->priv->view convertRect: offset
+ fromView: self];
+
+ rect.origin.x -= offset.origin.x;
+ rect.origin.y -= offset.origin.y;
+ }
+
+ CGContextClipToRect (cg_context, rect);
+ }
+
+ [self myDrawInsertionPointInRect: aRect
+ color: aColor
+ turnedOn: flag];
+
+ CGContextRestoreGState (cg_context);
+}
+@end
+
static void
gtk_ns_view_swizzle_draw_rect_recursive (NSView *view,
const gchar *associated_key,
@@ -310,7 +423,6 @@ gtk_ns_view_swizzle_draw_rect_recursive (NSView *view,
method_getTypeEncoding (my_didAddSubview));
}
-
objc_setAssociatedObject (view, associated_key, (id) associated_object,
OBJC_ASSOCIATION_ASSIGN);
@@ -325,6 +437,49 @@ gtk_ns_view_swizzle_draw_rect_recursive (NSView *view,
}
static void
+gtk_ns_view_replace_draw_insertion_point (void)
+{
+ static volatile gsize draw_insertion_point_replaced = 0;
+
+ /* We replace the drawInsertPointInRect:color:turnedOn: method of the
+ * NSTextView class. This should only be done once per application
+ * instance.
+ */
+
+ if (g_once_init_enter (&draw_insertion_point_replaced))
+ {
+ Method original_drawInsertionPointInRect;
+ Method my_drawInsertionPointInRect;
+ IMP original_implementation;
+ Class text_view_class = [NSTextView class];
+
+ /* Get the original method and an explicit reference to the
+ * implementation behind this method. This because after the
+ * first replace method call, the method will point at a different
+ * implementation.
+ */
+ original_drawInsertionPointInRect = class_getInstanceMethod (text_view_class,
+ @selector (drawInsertionPointInRect:color:turnedOn:));
+ original_implementation = method_getImplementation (original_drawInsertionPointInRect);
+
+ my_drawInsertionPointInRect = class_getInstanceMethod (text_view_class,
+ @selector (myDrawInsertionPointInRect:color:turnedOn:));
+
+ class_replaceMethod (text_view_class,
+ @selector (drawInsertionPointInRect:color:turnedOn:),
+ method_getImplementation (my_drawInsertionPointInRect),
+ method_getTypeEncoding (my_drawInsertionPointInRect));
+
+ class_replaceMethod (text_view_class,
+ @selector (myDrawInsertionPointInRect:color:turnedOn:),
+ original_implementation,
+ method_getTypeEncoding (original_drawInsertionPointInRect));
+
+ g_once_init_leave (&draw_insertion_point_replaced, TRUE);
+ }
+}
+
+static void
gtk_ns_view_constructed (GObject *object)
{
GtkNSView *ns_view = GTK_NS_VIEW (object);
@@ -340,6 +495,7 @@ gtk_ns_view_constructed (GObject *object)
gtk_widget_get_can_focus (GTK_WIDGET (ns_view)));
#endif
+ gtk_ns_view_replace_draw_insertion_point ();
gtk_ns_view_swizzle_draw_rect_recursive (ns_view->priv->view,
"gtknsview", ns_view);
}
--
1.7.10.2 (Apple Git-33)