3b8fb3716dc8f293bc2e026be2856b9f75d36fdb
[mono.git] / bockbuild / mac-sdk / patches / gtk / 0040-gtk-add-new-widget-GtkNSView-which-alows-to-embed-an.patch
1 From 99be0cbaccfc53b374055085f778a971a5758566 Mon Sep 17 00:00:00 2001
2 From: Michael Natterer <mitch@lanedo.com>
3 Date: Tue, 29 Nov 2011 16:09:31 +0100
4 Subject: [PATCH 40/68] gtk: add new widget GtkNSView which alows to embed an
5  NSView
6
7 ---
8  gtk/Makefile.am    |    2 +
9  gtk/gtk.h          |    4 +
10  gtk/gtknsview.c    |  470 ++++++++++++++++++++++++++++++++++++++++++++++++++++
11  gtk/gtknsview.h    |   62 +++++++
12  tests/Makefile.am  |   10 +-
13  tests/testnsview.c |  190 +++++++++++++++++++++
14  6 files changed, 737 insertions(+), 1 deletion(-)
15  create mode 100644 gtk/gtknsview.c
16  create mode 100644 gtk/gtknsview.h
17  create mode 100644 tests/testnsview.c
18
19 diff --git a/gtk/Makefile.am b/gtk/Makefile.am
20 index 31dfd19..59a6742 100644
21 --- a/gtk/Makefile.am
22 +++ b/gtk/Makefile.am
23 @@ -737,6 +737,7 @@ gtk_use_win32_c_sources = \
24         gtkwin32embedwidget.c \
25         gtkmountoperation-stub.c
26  gtk_use_quartz_c_sources =     \
27 +       gtknsview.c             \
28         gtksearchenginequartz.c \
29         gtkplug-stub.c          \
30         gtksocket-stub.c        \
31 @@ -757,6 +758,7 @@ else
32  if USE_QUARTZ
33  libgtk_quartz_2_0_la_CFLAGS = "-xobjective-c"
34  gtk_private_h_sources += gtksearchenginequartz.h
35 +gtk_public_h_sources += gtknsview.h
36  gtk_c_sources += $(gtk_use_quartz_c_sources)
37  else
38  gtk_c_sources += $(gtk_use_stub_c_sources)
39 diff --git a/gtk/gtk.h b/gtk/gtk.h
40 index 94e0b61..cc5834a 100644
41 --- a/gtk/gtk.h
42 +++ b/gtk/gtk.h
43 @@ -218,6 +218,10 @@
44  #include <gtk/gtkwidget.h>
45  #include <gtk/gtkwindow.h>
46
47 +#ifdef GDK_WINDOWING_QUARTZ
48 +#include <gtk/gtknsview.h>
49 +#endif
50 +
51  /* Broken */
52  #include <gtk/gtktext.h>
53  #include <gtk/gtktree.h>
54 diff --git a/gtk/gtknsview.c b/gtk/gtknsview.c
55 new file mode 100644
56 index 0000000..40c6a9b
57 --- /dev/null
58 +++ b/gtk/gtknsview.c
59 @@ -0,0 +1,470 @@
60 +/* GTK - The GIMP Toolkit
61 + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
62 + *
63 + * GtkNSView - Native NSView embedding widget
64 + * Copyright (C) 2011 Michael Natterer <mitch@lanedo.com>
65 + *
66 + * This library is free software; you can redistribute it and/or
67 + * modify it under the terms of the GNU Library General Public
68 + * License as published by the Free Software Foundation; either
69 + * version 2 of the License, or (at your option) any later version.
70 + *
71 + * This library is distributed in the hope that it will be useful,
72 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
73 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
74 + * Library General Public License for more details.
75 + *
76 + * You should have received a copy of the GNU Library General Public
77 + * License along with this library; if not, write to the
78 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
79 + * Boston, MA 02111-1307, USA.
80 + */
81 +
82 +#include "config.h"
83 +
84 +#include <gdk/gdk.h>
85 +#include <gdk/gdkkeysyms.h>
86 +#include <gdk/quartz/gdkquartz.h>
87 +#include <objc/runtime.h>
88 +
89 +#include "gtknsview.h"
90 +#include "gtkprivate.h"
91 +#include "gtkintl.h"
92 +#include "gtkalias.h"
93 +
94 +
95 +/* #define DEBUG_FOCUS 1 */
96 +
97 +
98 +enum
99 +{
100 +  PROP_0,
101 +  PROP_VIEW
102 +};
103 +
104 +
105 +struct _GtkNSViewPrivate
106 +{
107 +  NSView *view;
108 +};
109 +
110 +#define GTK_NS_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
111 +                                      GTK_TYPE_NS_VIEW, GtkNSViewPrivate))
112 +
113 +
114 +static void       gtk_ns_view_finalize      (GObject        *object);
115 +static void       gtk_ns_view_set_property  (GObject        *object,
116 +                                             guint           prop_id,
117 +                                             const GValue   *value,
118 +                                             GParamSpec     *pspec);
119 +static void       gtk_ns_view_get_property  (GObject        *object,
120 +                                             guint           prop_id,
121 +                                             GValue         *value,
122 +                                             GParamSpec     *pspec);
123 +static void       gtk_ns_view_notify        (GObject        *object,
124 +                                             GParamSpec     *pspec);
125 +
126 +static void       gtk_ns_view_unrealize     (GtkWidget      *widget);
127 +static void       gtk_ns_view_map           (GtkWidget      *widget);
128 +static void       gtk_ns_view_unmap         (GtkWidget      *widget);
129 +static void       gtk_ns_view_size_request  (GtkWidget      *widget,
130 +                                             GtkRequisition *requisition);
131 +static void       gtk_ns_view_size_allocate (GtkWidget      *widget,
132 +                                             GtkAllocation  *allocation);
133 +static void       gtk_ns_view_grab_focus    (GtkWidget      *widget);
134 +static gboolean   gtk_ns_view_key_press     (GtkWidget      *widget,
135 +                                             GdkEventKey    *event);
136 +static gboolean   gtk_ns_view_key_release   (GtkWidget      *widget,
137 +                                             GdkEventKey    *event);
138 +
139 +static void       gtk_ns_view_native_child_event (GdkWindow     *window,
140 +                                                  NSView        *view,
141 +                                                  NSEvent       *event,
142 +                                                  GtkNSView     *ns_view);
143 +static gboolean   gtk_ns_view_forward_event      (GtkWidget     *widget,
144 +                                                  GdkEventKey   *event);
145 +
146 +
147 +G_DEFINE_TYPE (GtkNSView, gtk_ns_view, GTK_TYPE_WIDGET)
148 +
149 +
150 +static void
151 +gtk_ns_view_class_init (GtkNSViewClass *klass)
152 +{
153 +  GObjectClass *object_class = G_OBJECT_CLASS (klass);
154 +  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
155 +
156 +  g_type_class_add_private (klass, sizeof (GtkNSViewPrivate));
157 +
158 +  object_class->finalize = gtk_ns_view_finalize;
159 +  object_class->set_property = gtk_ns_view_set_property;
160 +  object_class->get_property = gtk_ns_view_get_property;
161 +  object_class->notify = gtk_ns_view_notify;
162 +
163 +  widget_class->unrealize = gtk_ns_view_unrealize;
164 +  widget_class->map = gtk_ns_view_map;
165 +  widget_class->unmap = gtk_ns_view_unmap;
166 +  widget_class->size_request = gtk_ns_view_size_request;
167 +  widget_class->size_allocate = gtk_ns_view_size_allocate;
168 +  widget_class->grab_focus = gtk_ns_view_grab_focus;
169 +  widget_class->key_press_event = gtk_ns_view_key_press;
170 +  widget_class->key_release_event = gtk_ns_view_key_release;
171 +
172 +  /**
173 +   * GtkNSView:view:
174 +   *
175 +   * The widget's NSView.
176 +   *
177 +   * Since: 2.24
178 +   */
179 +  g_object_class_install_property (object_class,
180 +                                  PROP_VIEW,
181 +                                  g_param_spec_pointer ("view",
182 +                                                         P_("View"),
183 +                                                         P_("The NSView"),
184 +                                                         GTK_PARAM_READWRITE |
185 +                                                         G_PARAM_CONSTRUCT_ONLY));
186 +}
187 +
188 +static void
189 +gtk_ns_view_init (GtkNSView *ns_view)
190 +{
191 +  ns_view->priv = GTK_NS_VIEW_GET_PRIVATE (ns_view);
192 +
193 +  gtk_widget_set_has_window (GTK_WIDGET (ns_view), FALSE);
194 +}
195 +
196 +static void
197 +gtk_ns_view_finalize (GObject *object)
198 +{
199 +  GtkNSView *ns_view = GTK_NS_VIEW (object);
200 +
201 +  if (ns_view->priv->view)
202 +    {
203 +      [ns_view->priv->view release];
204 +      ns_view->priv->view = NULL;
205 +    }
206 +
207 +  G_OBJECT_CLASS (gtk_ns_view_parent_class)->finalize (object);
208 +}
209 +
210 +static void
211 +gtk_ns_view_set_property (GObject      *object,
212 +                          guint         prop_id,
213 +                          const GValue *value,
214 +                          GParamSpec   *pspec)
215 +{
216 +  GtkNSView *ns_view = GTK_NS_VIEW (object);
217 +
218 +  switch (prop_id)
219 +    {
220 +    case PROP_VIEW:
221 +      ns_view->priv->view = g_value_get_pointer (value);
222 +      if (ns_view->priv->view)
223 +        {
224 +          [ns_view->priv->view retain];
225 +          gtk_widget_set_can_focus (GTK_WIDGET (ns_view),
226 +                                    [ns_view->priv->view acceptsFirstResponder]);
227 +
228 +#if DEBUG_FOCUS
229 +          g_printerr ("%s can focus: %d\n",
230 +                      class_getName ([ns_view->priv->view class]),
231 +                      gtk_widget_get_can_focus (GTK_WIDGET (ns_view)));
232 +#endif
233 +        }
234 +      break;
235 +
236 +    default:
237 +      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
238 +      break;
239 +    }
240 +}
241 +
242 +static void
243 +gtk_ns_view_get_property (GObject      *object,
244 +                          guint         prop_id,
245 +                          GValue       *value,
246 +                          GParamSpec   *pspec)
247 +{
248 +  GtkNSView *ns_view = GTK_NS_VIEW (object);
249 +
250 +  switch (prop_id)
251 +    {
252 +    case PROP_VIEW:
253 +      g_value_set_pointer (value, ns_view->priv->view);
254 +      break;
255 +
256 +    default:
257 +      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
258 +      break;
259 +    }
260 +}
261 +
262 +static void
263 +gtk_ns_view_notify (GObject    *object,
264 +                    GParamSpec *pspec)
265 +{
266 +  GtkNSView *ns_view = GTK_NS_VIEW (object);
267 +
268 +  if (G_OBJECT_CLASS (gtk_ns_view_parent_class)->notify)
269 +    G_OBJECT_CLASS (gtk_ns_view_parent_class)->notify (object, pspec);
270 +
271 +  if (!strcmp (pspec->name, "has-focus"))
272 +    {
273 +      NSWindow *ns_window = [ns_view->priv->view window];
274 +
275 +#if DEBUG_FOCUS
276 +      g_printerr ("%s has-focus: %d\n",
277 +                  class_getName ([ns_view->priv->view class]),
278 +                  gtk_widget_has_focus (GTK_WIDGET (object)));
279 +#endif
280 +
281 +      if (gtk_widget_has_focus (GTK_WIDGET (object)))
282 +        [ns_window makeFirstResponder:ns_view->priv->view];
283 +      else
284 +        [ns_window makeFirstResponder:nil];
285 +    }
286 +}
287 +
288 +static void
289 +gtk_ns_view_position_view (GtkNSView     *ns_view,
290 +                           GtkAllocation *allocation)
291 +{
292 +  GdkWindow *window = gtk_widget_get_window (GTK_WIDGET (ns_view));
293 +  GdkWindow *native;
294 +  gdouble x, y;
295 +  NSSize size;
296 +  NSPoint origin;
297 +
298 +  x = allocation->x;
299 +  y = allocation->y;
300 +
301 +  /* convert to the coordinate system of the innermost parent window
302 +   * that has an NSView
303 +   */
304 +  native = window;
305 +  while (! gdk_window_has_native (native))
306 +    {
307 +      gdk_window_coords_to_parent (native, x, y, &x, &y);
308 +      native = gdk_window_get_parent (native);
309 +    }
310 +
311 +  size.width = allocation->width;
312 +  size.height = allocation->height;
313 +  [ns_view->priv->view setFrameSize:size];
314 +
315 +  origin.x = x;
316 +  origin.y = y;
317 +  [ns_view->priv->view setFrameOrigin:origin];
318 +}
319 +
320 +static void
321 +gtk_ns_view_unrealize (GtkWidget *widget)
322 +{
323 +  if (gtk_widget_get_mapped (widget))
324 +    gtk_widget_unmap (widget);
325 +
326 +  GTK_WIDGET_CLASS (gtk_ns_view_parent_class)->unrealize (widget);
327 +}
328 +
329 +static void
330 +gtk_ns_view_map (GtkWidget *widget)
331 +{
332 +  GtkNSView *ns_view = GTK_NS_VIEW (widget);
333 +  GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
334 +  GtkAllocation allocation;
335 +  NSView *parent_view;
336 +
337 +  gtk_widget_get_allocation (widget, &allocation);
338 +  gtk_ns_view_position_view (ns_view, &allocation);
339 +
340 +  parent_view = gdk_quartz_window_get_nsview (gtk_widget_get_window (widget));
341 +  [parent_view addSubview:ns_view->priv->view];
342 +
343 +  [ns_view->priv->view setNextKeyView:nil];
344 +
345 +  g_signal_connect_object (gtk_widget_get_window (toplevel), "native-child-event",
346 +                           G_CALLBACK (gtk_ns_view_native_child_event),
347 +                           G_OBJECT (widget), 0);
348 +
349 +  GTK_WIDGET_CLASS (gtk_ns_view_parent_class)->map (widget);
350 +}
351 +
352 +static void
353 +gtk_ns_view_unmap (GtkWidget *widget)
354 +{
355 +  GtkNSView *ns_view = GTK_NS_VIEW (widget);
356 +  GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
357 +
358 +  g_signal_handlers_disconnect_by_func (gtk_widget_get_window (toplevel),
359 +                                        gtk_ns_view_native_child_event,
360 +                                        widget);
361 +
362 +  [ns_view->priv->view removeFromSuperview];
363 +
364 +  GTK_WIDGET_CLASS (gtk_ns_view_parent_class)->unmap (widget);
365 +}
366 +
367 +static void
368 +gtk_ns_view_size_request (GtkWidget      *widget,
369 +                          GtkRequisition *requisition)
370 +{
371 +  requisition->width = 1;
372 +  requisition->height = 1;
373 +}
374 +
375 +static void
376 +gtk_ns_view_size_allocate (GtkWidget     *widget,
377 +                           GtkAllocation *allocation)
378 +{
379 +  GtkNSView *ns_view = GTK_NS_VIEW (widget);
380 +
381 +  widget->allocation = *allocation;
382 +
383 +  if (gtk_widget_get_mapped (widget))
384 +    gtk_ns_view_position_view (ns_view, allocation);
385 +}
386 +
387 +static void
388 +gtk_ns_view_grab_focus (GtkWidget *widget)
389 +{
390 +  GtkNSView *ns_view = GTK_NS_VIEW (widget);
391 +  NSWindow *ns_window;
392 +
393 +  GTK_WIDGET_CLASS (gtk_ns_view_parent_class)->grab_focus (widget);
394 +
395 +  ns_window = [ns_view->priv->view window];
396 +  [ns_window makeFirstResponder:ns_view->priv->view];
397 +}
398 +
399 +static gboolean
400 +gtk_ns_view_key_press (GtkWidget   *widget,
401 +                       GdkEventKey *event)
402 +{
403 +  GtkNSView *ns_view = GTK_NS_VIEW (widget);
404 +  NSEvent *nsevent = gdk_quartz_event_get_nsevent ((GdkEvent *) event);
405 +  NSWindow *ns_window;
406 +
407 +  if (gtk_ns_view_forward_event (widget, event))
408 +    {
409 +      ns_window = [ns_view->priv->view window];
410 +      [ns_window sendEvent:nsevent];
411 +
412 +      return TRUE;
413 +    }
414 +
415 +  return GTK_WIDGET_CLASS (gtk_ns_view_parent_class)->key_press_event (widget, event);
416 +}
417 +
418 +static gboolean
419 +gtk_ns_view_key_release (GtkWidget   *widget,
420 +                         GdkEventKey *event)
421 +{
422 +  GtkNSView *ns_view = GTK_NS_VIEW (widget);
423 +  NSEvent *nsevent = gdk_quartz_event_get_nsevent ((GdkEvent *) event);
424 +  NSWindow *ns_window;
425 +
426 +  if (gtk_ns_view_forward_event (widget, event))
427 +    {
428 +      ns_window = [ns_view->priv->view window];
429 +      [ns_window sendEvent:nsevent];
430 +
431 +      return TRUE;
432 +    }
433 +
434 +  return GTK_WIDGET_CLASS (gtk_ns_view_parent_class)->key_release_event (widget, event);
435 +}
436 +
437 +static void
438 +gtk_ns_view_native_child_event (GdkWindow *window,
439 +                                NSView    *view,
440 +                                NSEvent   *event,
441 +                                GtkNSView *ns_view)
442 +{
443 +  if (view == ns_view->priv->view)
444 +    {
445 +#if 0
446 +      g_printerr ("native child event on %s\n",
447 +                  class_getName ([ns_view->priv->view class]));
448 +#endif
449 +
450 +      switch ([event type])
451 +        {
452 +        case NSLeftMouseDown:
453 +          if (! gtk_widget_has_focus (GTK_WIDGET (ns_view)) &&
454 +
455 +              /*  other code can set can-focus, so check for both  */
456 +              gtk_widget_get_can_focus (GTK_WIDGET (ns_view)) &&
457 +              [ns_view->priv->view acceptsFirstResponder])
458 +            {
459 +#if DEBUG_FOCUS
460 +              g_printerr ("grabbing focus on %s\n",
461 +                          class_getName ([ns_view->priv->view class]));
462 +#endif
463 +
464 +              gtk_widget_grab_focus (GTK_WIDGET (ns_view));
465 +            }
466 +          break;
467 +
468 +        default:
469 +          break;
470 +        }
471 +    }
472 +}
473 +
474 +static gboolean
475 +gtk_ns_view_forward_event (GtkWidget   *widget,
476 +                           GdkEventKey *event)
477 +{
478 +  GtkNSView *ns_view = GTK_NS_VIEW (widget);
479 +  NSWindow *ns_window;
480 +  NSResponder *first_responder;
481 +  NSView *next_key_view;
482 +
483 +  if (event->type != GDK_KEY_PRESS ||
484 +      (event->keyval != GDK_KEY_Tab &&
485 +       event->keyval != GDK_KEY_ISO_Left_Tab))
486 +    {
487 +      return TRUE;
488 +    }
489 +
490 +  ns_window = [ns_view->priv->view window];
491 +  first_responder = [ns_window firstResponder];
492 +
493 +#if DEBUG_FOCUS
494 +  g_printerr ("first reponder: %p  %s\n", first_responder,
495 +              class_getName ([first_responder class]));
496 +#endif
497 +
498 +  if (event->keyval == GDK_KEY_Tab)
499 +    next_key_view = [first_responder nextValidKeyView];
500 +  else
501 +    next_key_view = [first_responder previousValidKeyView];
502 +
503 +#if DEBUG_FOCUS
504 +  g_printerr ("next key view: %p  %s\n", next_key_view,
505 +              class_getName ([next_key_view class]));
506 +#endif
507 +
508 +  if (next_key_view &&
509 +      next_key_view != ns_view->priv->view &&
510 +      [next_key_view isDescendantOf:ns_view->priv->view])
511 +    {
512 +      return TRUE;
513 +    }
514 +
515 +  return FALSE;
516 +}
517 +
518 +GtkWidget *
519 +gtk_ns_view_new (gpointer nsview)
520 +{
521 +  g_return_val_if_fail (nsview != NULL, NULL);
522 +
523 +  return g_object_new (GTK_TYPE_NS_VIEW,
524 +                       "view", nsview,
525 +                       NULL);
526 +}
527 +
528 +#define __GTK_NS_VIEW_C__
529 +#include "gtkaliasdef.c"
530 diff --git a/gtk/gtknsview.h b/gtk/gtknsview.h
531 new file mode 100644
532 index 0000000..2c0aab7
533 --- /dev/null
534 +++ b/gtk/gtknsview.h
535 @@ -0,0 +1,62 @@
536 +/* GTK - The GIMP Toolkit
537 + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
538 + *
539 + * GtkNSView - Native NSView embedding widget
540 + * Copyright (C) 2011 Michael Natterer <mitch@lanedo.com>
541 + *
542 + * This library is free software; you can redistribute it and/or
543 + * modify it under the terms of the GNU Library General Public
544 + * License as published by the Free Software Foundation; either
545 + * version 2 of the License, or (at your option) any later version.
546 + *
547 + * This library is distributed in the hope that it will be useful,
548 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
549 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
550 + * Library General Public License for more details.
551 + *
552 + * You should have received a copy of the GNU Library General Public
553 + * License along with this library; if not, write to the
554 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
555 + * Boston, MA 02111-1307, USA.
556 + */
557 +
558 +#ifndef __GTK_NS_VIEW_H__
559 +#define __GTK_NS_VIEW_H__
560 +
561 +#if defined(GTK_DISABLE_SINGLE_INCLUDES) && !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
562 +#error "Only <gtk/gtk.h> can be included directly."
563 +#endif
564 +
565 +#include <gtk/gtkwidget.h>
566 +
567 +G_BEGIN_DECLS
568 +
569 +#define GTK_TYPE_NS_VIEW            (gtk_ns_view_get_type ())
570 +#define GTK_NS_VIEW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_NS_VIEW, GtkNSView))
571 +#define GTK_NS_VIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_NS_VIEW, GtkNSViewClass))
572 +#define GTK_IS_NS_VIEW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_NS_VIEW))
573 +#define GTK_IS_NS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_NS_VIEW))
574 +#define GTK_NS_VIEW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_NS_VIEW, GtkNSViewClass))
575 +
576 +typedef struct _GtkNSView        GtkNSView;
577 +typedef struct _GtkNSViewClass   GtkNSViewClass;
578 +typedef struct _GtkNSViewPrivate GtkNSViewPrivate;
579 +
580 +struct _GtkNSView
581 +{
582 +  GtkWidget parent_instance;
583 +
584 +  GtkNSViewPrivate *priv;
585 +};
586 +
587 +struct _GtkNSViewClass
588 +{
589 +  GtkWidgetClass parent_class;
590 +};
591 +
592 +GType       gtk_ns_view_get_type (void) G_GNUC_CONST;
593 +GtkWidget * gtk_ns_view_new      (gpointer  nsview);
594 +
595 +G_END_DECLS
596 +
597 +#endif /* __GTK_NS_VIEW_H__ */
598 diff --git a/tests/Makefile.am b/tests/Makefile.am
599 index 3888826..af098f6 100644
600 --- a/tests/Makefile.am
601 +++ b/tests/Makefile.am
602 @@ -8,7 +8,8 @@ INCLUDES =                              \
603         -DGDK_DISABLE_DEPRECATED        \
604         -DGTK_DISABLE_DEPRECATED        \
605         $(GTK_DEBUG_FLAGS)              \
606 -       $(GTK_DEP_CFLAGS)
607 +       $(GTK_DEP_CFLAGS)               \
608 +       -xobjective-c
609
610  DEPS =                                                                 \
611         $(top_builddir)/gdk/$(gdktargetlib)                             \
612 @@ -57,6 +58,7 @@ noinst_PROGRAMS =  $(TEST_PROGS)      \
613         testmultiscreen                 \
614         testnotebookdnd                 \
615         testnouiprint                   \
616 +       testnsview                      \
617         testoffscreen                   \
618         testoffscreenwindow             \
619         testorientable                  \
620 @@ -134,6 +136,7 @@ testmultidisplay_DEPENDENCIES = $(TEST_DEPS)
621  testmultiscreen_DEPENDENCIES = $(TEST_DEPS)
622  testnotebookdnd_DEPENDENCIES = $(TEST_DEPS)
623  testnouiprint_DEPENDENCIES = $(TEST_DEPS)
624 +testnsview_DEPENDENCIES = $(TEST_DEPS)
625  testoffscreen_DEPENDENCIES = $(TEST_DEPS)
626  testoffscreenwindow_DEPENDENCIES = $(TEST_DEPS)
627  testorientable_DEPENDENCIES = $(TEST_DEPS)
628 @@ -166,6 +169,8 @@ testtooltips_DEPENDENCIES = $(TEST_DEPS)
629  testvolumebutton_DEPENDENCIES = $(TEST_DEPS)
630  testwindows_DEPENDENCIES = $(TEST_DEPS)
631
632 +testnsview_LDFLAGS = -framework WebKit
633 +
634  testentrycompletion_SOURCES =  \
635         prop-editor.c           \
636         testentrycompletion.c
637 @@ -262,6 +267,9 @@ testrecentchoosermenu_SOURCES =     \
638  testvolumebutton_SOURCES =     \
639         testvolumebutton.c
640
641 +testnsview_SOURCES =           \
642 +       testnsview.c
643 +
644  testoffscreen_SOURCES =        \
645         gtkoffscreenbox.c       \
646         gtkoffscreenbox.h       \
647 diff --git a/tests/testnsview.c b/tests/testnsview.c
648 new file mode 100644
649 index 0000000..7c9ccb7
650 --- /dev/null
651 +++ b/tests/testnsview.c
652 @@ -0,0 +1,190 @@
653 +/* testnsview.c
654 + * Copyright (C) 2011 Michael Natterer <mitch@lanedo.com>
655 + *
656 + * This library is free software; you can redistribute it and/or
657 + * modify it under the terms of the GNU Library General Public
658 + * License as published by the Free Software Foundation; either
659 + * version 2 of the License, or (at your option) any later version.
660 + *
661 + * This library is distributed in the hope that it will be useful,
662 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
663 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
664 + * Library General Public License for more details.
665 + *
666 + * You should have received a copy of the GNU Library General Public
667 + * License along with this library; if not, write to the
668 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
669 + * Boston, MA 02111-1307, USA.
670 + */
671 +
672 +#include "config.h"
673 +
674 +#include <WebKit/WebKit.h>
675 +#include <gtk/gtk.h>
676 +
677 +
678 +static void
679 +back_clicked (GtkToolItem *item,
680 +              WebView     *webview)
681 +{
682 +  [webview goBack];
683 +}
684 +
685 +static void
686 +forward_clicked (GtkToolItem *item,
687 +                 WebView     *webview)
688 +{
689 +  [webview goForward];
690 +}
691 +
692 +gint
693 +main (gint   argc,
694 +      gchar *argv[])
695 +{
696 +  GtkWidget *window;
697 +  GtkWidget *vbox;
698 +  GtkWidget *toolbar;
699 +  GtkToolItem *item;
700 +  WebView *webview;
701 +  NSRect web_rect = { { 0.0, 0.0 }, { 100.0, 100.0 } };
702 +  NSURL *url;
703 +  NSURLRequest *request;
704 +  GtkWidget *ns_view;
705 +
706 +  gtk_init (&argc, &argv);
707 +
708 +  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
709 +  gtk_window_set_title (GTK_WINDOW (window), "GtkNSView featuring WebView");
710 +
711 +  g_signal_connect (window, "destroy",
712 +                    G_CALLBACK (gtk_main_quit),
713 +                    NULL);
714 +
715 +  vbox = gtk_vbox_new (FALSE, 0);
716 +  gtk_container_add (GTK_CONTAINER (window), vbox);
717 +  gtk_widget_show (vbox);
718 +
719 +  toolbar = gtk_toolbar_new ();
720 +  gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0);
721 +  gtk_widget_show (toolbar);
722 +
723 +  webview = [WebView alloc];
724 +
725 +  item = gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK);
726 +  gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
727 +  gtk_widget_show (GTK_WIDGET (item));
728 +
729 +  g_signal_connect (item, "clicked",
730 +                    G_CALLBACK (back_clicked),
731 +                    webview);
732 +
733 +  item = gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD);
734 +  gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
735 +  gtk_widget_show (GTK_WIDGET (item));
736 +
737 +  g_signal_connect (item, "clicked",
738 +                    G_CALLBACK (forward_clicked),
739 +                    webview);
740 +
741 +  [webview initWithFrame:web_rect
742 +               frameName:@"foo"
743 +               groupName:@"bar"];
744 +
745 +  url = [NSURL URLWithString:@"http://www.gimp.org/"];
746 +  request = [NSURLRequest requestWithURL:url];
747 +
748 +  [[webview mainFrame] loadRequest:request];
749 +
750 +  ns_view = gtk_ns_view_new ((NSView *) webview);
751 +  gtk_widget_set_size_request (ns_view, 300, 200);
752 +  gtk_box_pack_end (GTK_BOX (vbox), ns_view, TRUE, TRUE, 0);
753 +  gtk_widget_show (ns_view);
754 +
755 +  [webview release];
756 +
757 +  {
758 +    GtkWidget *button;
759 +
760 +    button = gtk_button_new_with_label ("hide webview");
761 +    gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
762 +    gtk_widget_show (button);
763 +
764 +    g_signal_connect_swapped (button, "clicked",
765 +                              G_CALLBACK (gtk_widget_hide),
766 +                              ns_view);
767 +
768 +    button = gtk_button_new_with_label ("show webview");
769 +    gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
770 +    gtk_widget_show (button);
771 +
772 +    g_signal_connect_swapped (button, "clicked",
773 +                              G_CALLBACK (gtk_widget_show),
774 +                              ns_view);
775 +  }
776 +
777 +  /* add an entry in an event box to test living inside another gdkwindow */
778 +  {
779 +    GtkWidget *event_box;
780 +    GtkWidget *abox;
781 +    GtkWidget *hbox;
782 +    NSRect label_rect = { { 0.0, 0.0 }, { 100.0, 12.0 } };
783 +    NSRect text_rect = { { 0.0, 0.0 }, { 100.0, 12.0 } };
784 +    NSTextField *text_field;
785 +
786 +    event_box = gtk_event_box_new ();
787 +    gtk_widget_set_state (event_box, GTK_STATE_ACTIVE);
788 +    gtk_box_pack_start (GTK_BOX (vbox), event_box, FALSE, FALSE, 0);
789 +    gtk_widget_show (event_box);
790 +
791 +    abox = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
792 +    gtk_container_set_border_width (GTK_CONTAINER (abox), 10);
793 +    gtk_container_add (GTK_CONTAINER (event_box), abox);
794 +    gtk_widget_show (abox);
795 +
796 +    hbox = gtk_hbox_new (FALSE, 10);
797 +    gtk_container_add (GTK_CONTAINER (abox), hbox);
798 +    gtk_widget_show (hbox);
799 +
800 +    /* a non-editable text label */
801 +    text_field = [[NSTextField alloc] initWithFrame:label_rect];
802 +    [text_field setEditable:NO];
803 +    [text_field setDrawsBackground:NO];
804 +    [text_field setBordered:NO];
805 +    [text_field setStringValue:@"A Text Label"];
806 +
807 +    ns_view = gtk_ns_view_new ((NSView *) text_field);
808 +    gtk_widget_set_size_request (ns_view, 100, 20);
809 +    gtk_box_pack_start (GTK_BOX (hbox), ns_view, FALSE, FALSE, 0);
810 +    gtk_widget_show (ns_view);
811 +
812 +    [text_field release];
813 +
814 +    /* an editable text field */
815 +    text_field = [[NSTextField alloc] initWithFrame:text_rect];
816 +    [text_field setEditable:YES];
817 +    [text_field setStringValue:@"An editable text entry"];
818 +
819 +    ns_view = gtk_ns_view_new ((NSView *) text_field);
820 +    gtk_widget_set_size_request (ns_view, 100, 20);
821 +    gtk_box_pack_start (GTK_BOX (hbox), ns_view, TRUE, TRUE, 0);
822 +    gtk_widget_show (ns_view);
823 +
824 +    [text_field release];
825 +  }
826 +
827 +  /* and a normal GtkEntry to check focus */
828 +  {
829 +    GtkWidget *entry;
830 +
831 +    entry = gtk_entry_new ();
832 +    gtk_entry_set_text (GTK_ENTRY (entry), "Normal GTK+ entry");
833 +    gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
834 +    gtk_widget_show (entry);
835 +  }
836 +
837 +  gtk_widget_show (window);
838 +
839 +  gtk_main ();
840 +
841 +  return 0;
842 +}
843 --
844 1.7.10.2 (Apple Git-33)