From 56e863ef4b425c1ac79e53d35f9b8b9649cec7d3 Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Fri, 15 Mar 2013 14:49:59 +0100 Subject: [PATCH 47/68] gtk: first attempt to also clip NSWindow's field editor Also, factor out the method swizzling to a utility function. --- gtk/gtknsview.c | 75 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 17 deletions(-) diff --git a/gtk/gtknsview.c b/gtk/gtknsview.c index 1e0b7e6..b58a2c8 100644 --- a/gtk/gtknsview.c +++ b/gtk/gtknsview.c @@ -29,6 +29,7 @@ #include "gtknsview.h" #include "gtkviewport.h" +#include "gtkwindow.h" #include "gtkprivate.h" #include "gtkintl.h" #include "gtkalias.h" @@ -147,6 +148,22 @@ gtk_ns_view_init (GtkNSView *ns_view) 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) { [self myDrawRect: dirtyRect]; @@ -208,38 +225,45 @@ gtk_ns_view_init (GtkNSView *ns_view) @end static void -gtk_ns_view_constructed (GObject *object) +gtk_ns_view_swizzle_draw_rect (NSView *view) { - GtkNSView *ns_view = GTK_NS_VIEW (object); Method original_drawRect; Method my_drawRect; - G_OBJECT_CLASS (gtk_ns_view_parent_class)->constructed (object); - - gtk_widget_set_can_focus (GTK_WIDGET (ns_view), - [ns_view->priv->view acceptsFirstResponder]); - -#if DEBUG_FOCUS - g_printerr ("%s can focus: %d\n", - class_getName ([ns_view->priv->view class]), - gtk_widget_get_can_focus (GTK_WIDGET (ns_view))); -#endif - - original_drawRect = class_getInstanceMethod ([ns_view->priv->view class], + original_drawRect = class_getInstanceMethod ([view class], @selector (drawRect:)); - my_drawRect = class_getInstanceMethod ([ns_view->priv->view class], + my_drawRect = class_getInstanceMethod ([view class], @selector (myDrawRect:)); - if (class_addMethod ([ns_view->priv->view class], + if (class_addMethod ([view class], @selector (myDrawRect:), method_getImplementation (original_drawRect), method_getTypeEncoding (original_drawRect))) { - class_replaceMethod ([ns_view->priv->view class], + class_replaceMethod ([view class], @selector (drawRect:), method_getImplementation (my_drawRect), method_getTypeEncoding (my_drawRect)); } +} + +static void +gtk_ns_view_constructed (GObject *object) +{ + GtkNSView *ns_view = GTK_NS_VIEW (object); + + G_OBJECT_CLASS (gtk_ns_view_parent_class)->constructed (object); + + gtk_widget_set_can_focus (GTK_WIDGET (ns_view), + [ns_view->priv->view acceptsFirstResponder]); + +#if DEBUG_FOCUS + g_printerr ("%s can focus: %d\n", + class_getName ([ns_view->priv->view class]), + gtk_widget_get_can_focus (GTK_WIDGET (ns_view))); +#endif + + gtk_ns_view_swizzle_draw_rect (ns_view->priv->view); objc_setAssociatedObject (ns_view->priv->view, "gtknsview", (id) ns_view, OBJC_ASSOCIATION_ASSIGN); @@ -375,6 +399,7 @@ gtk_ns_view_map (GtkWidget *widget) GtkWidget *toplevel = gtk_widget_get_toplevel (widget); GtkAllocation allocation; NSView *parent_view; + NSWindow *window; gtk_widget_get_allocation (widget, &allocation); gtk_ns_view_position_view (ns_view, &allocation); @@ -393,6 +418,22 @@ gtk_ns_view_map (GtkWidget *widget) G_OBJECT (widget), 0); GTK_WIDGET_CLASS (gtk_ns_view_parent_class)->map (widget); + + window = [ns_view->priv->view window]; + + if (window) + { + NSText *text = [window fieldEditor: YES + forObject: nil]; + + if (text) + { + gtk_ns_view_swizzle_draw_rect (text); + + objc_setAssociatedObject (text, "gtkwindow", (id) toplevel, + OBJC_ASSOCIATION_ASSIGN); + } + } } static void -- 1.7.10.2 (Apple Git-33)