3 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * Copyright (C) 2005-2007 Imendio AB
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
23 #include <Carbon/Carbon.h>
26 #include "gdkdeviceprivate.h"
27 #include "gdkwindowimpl.h"
28 #include "gdkprivate-quartz.h"
29 #include "gdkscreen-quartz.h"
30 #include "gdkinputprivate.h"
32 static gpointer parent_class;
33 static gpointer root_window_parent_class;
35 static GSList *update_nswindows;
36 static gboolean in_process_all_updates = FALSE;
38 static GSList *main_window_stack;
40 #define FULLSCREEN_DATA "fullscreen-data"
46 GdkWMDecoration decor;
47 } FullscreenSavedGeometry;
50 static void update_toplevel_order (void);
51 static void clear_toplevel_order (void);
53 static FullscreenSavedGeometry *get_fullscreen_geometry (GdkWindow *window);
55 #define WINDOW_IS_TOPLEVEL(window) \
56 (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
57 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
58 GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
60 static void gdk_window_impl_iface_init (GdkWindowImplIface *iface);
63 gdk_quartz_window_get_nsview (GdkWindow *window)
65 GdkWindowObject *private = (GdkWindowObject *)window;
67 if (GDK_WINDOW_DESTROYED (window))
70 return ((GdkWindowImplQuartz *)private->impl)->view;
74 gdk_quartz_window_get_nswindow (GdkWindow *window)
76 GdkWindowObject *private = (GdkWindowObject *)window;
78 if (GDK_WINDOW_DESTROYED (window))
81 return ((GdkWindowImplQuartz *)private->impl)->toplevel;
85 gdk_window_impl_quartz_get_context (GdkDrawable *drawable,
88 GdkDrawableImplQuartz *drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
89 GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (drawable);
90 CGContextRef cg_context;
92 if (GDK_WINDOW_DESTROYED (drawable_impl->wrapper))
95 /* Lock focus when not called as part of a drawRect call. This
96 * is needed when called from outside "real" expose events, for
97 * example for synthesized expose events when realizing windows
98 * and for widgets that send fake expose events like the arrow
99 * buttons in spinbuttons or the position marker in rulers.
101 if (window_impl->in_paint_rect_count == 0)
103 if (![window_impl->view lockFocusIfCanDraw])
107 cg_context = [[NSGraphicsContext currentContext] graphicsPort];
108 CGContextSaveGState (cg_context);
109 CGContextSetAllowsAntialiasing (cg_context, antialias);
111 /* We'll emulate the clipping caused by double buffering here */
112 if (window_impl->begin_paint_count != 0)
118 n_rects = cairo_region_num_rectangles (window_impl->paint_clip_region);
123 cg_rects = g_new (CGRect, n_rects);
125 for (i = 0; i < n_rects; i++)
127 cairo_rectangle_int_t cairo_rect;
128 cairo_region_get_rectangle (window_impl->paint_clip_region,
130 cg_rects[i].origin.x = cairo_rect.x;
131 cg_rects[i].origin.y = cairo_rect.y;
132 cg_rects[i].size.width = cairo_rect.width;
133 cg_rects[i].size.height = cairo_rect.height;
136 CGContextClipToRects (cg_context, cg_rects, n_rects);
138 if (cg_rects != &rect)
146 gdk_window_impl_quartz_release_context (GdkDrawable *drawable,
147 CGContextRef cg_context)
149 GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (drawable);
151 CGContextRestoreGState (cg_context);
152 CGContextSetAllowsAntialiasing (cg_context, TRUE);
154 /* See comment in gdk_quartz_drawable_get_context(). */
155 if (window_impl->in_paint_rect_count == 0)
157 _gdk_quartz_drawable_flush (drawable);
158 [window_impl->view unlockFocus];
163 check_grab_unmap (GdkWindow *window)
166 GdkDisplay *display = gdk_window_get_display (window);
167 GdkDeviceManager *device_manager;
169 device_manager = gdk_display_get_device_manager (display);
170 list = gdk_device_manager_list_devices (device_manager,
171 GDK_DEVICE_TYPE_FLOATING);
172 for (l = list; l; l = l->next)
174 _gdk_display_end_device_grab (display, l->data, 0, window, TRUE);
181 check_grab_destroy (GdkWindow *window)
184 GdkDisplay *display = gdk_window_get_display (window);
185 GdkDeviceManager *device_manager;
187 /* Make sure there is no lasting grab in this native window */
188 device_manager = gdk_display_get_device_manager (display);
189 list = gdk_device_manager_list_devices (device_manager,
190 GDK_DEVICE_TYPE_MASTER);
192 for (l = list; l; l = l->next)
194 GdkDeviceGrabInfo *grab;
196 grab = _gdk_display_get_last_device_grab (display, l->data);
197 if (grab && grab->native_window == window)
199 /* Serials are always 0 in quartz, but for clarity: */
200 grab->serial_end = grab->serial_start;
201 grab->implicit_ungrab = TRUE;
209 gdk_window_impl_quartz_finalize (GObject *object)
211 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (object);
213 check_grab_destroy (GDK_DRAWABLE_IMPL_QUARTZ (object)->wrapper);
215 if (impl->paint_clip_region)
216 cairo_region_destroy (impl->paint_clip_region);
218 if (impl->transient_for)
219 g_object_unref (impl->transient_for);
221 G_OBJECT_CLASS (parent_class)->finalize (object);
225 gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass)
227 GObjectClass *object_class = G_OBJECT_CLASS (klass);
228 GdkDrawableImplQuartzClass *drawable_quartz_class = GDK_DRAWABLE_IMPL_QUARTZ_CLASS (klass);
230 parent_class = g_type_class_peek_parent (klass);
232 object_class->finalize = gdk_window_impl_quartz_finalize;
234 drawable_quartz_class->get_context = gdk_window_impl_quartz_get_context;
235 drawable_quartz_class->release_context = gdk_window_impl_quartz_release_context;
239 gdk_window_impl_quartz_init (GdkWindowImplQuartz *impl)
241 impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
245 gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable,
247 const cairo_region_t *region)
249 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
250 GdkWindowObject *private = (GdkWindowObject*) window;
251 cairo_region_t *clipped_and_offset_region;
254 clipped_and_offset_region = cairo_region_copy (region);
256 cairo_region_intersect (clipped_and_offset_region,
257 private->clip_region_with_children);
258 cairo_region_translate (clipped_and_offset_region,
259 private->abs_x, private->abs_y);
261 if (impl->begin_paint_count == 0)
262 impl->paint_clip_region = cairo_region_reference (clipped_and_offset_region);
264 cairo_region_union (impl->paint_clip_region, clipped_and_offset_region);
266 impl->begin_paint_count++;
268 if (cairo_region_is_empty (clipped_and_offset_region))
271 cr = gdk_cairo_create (window);
273 cairo_translate (cr, -private->abs_x, -private->abs_y);
275 gdk_cairo_region (cr, clipped_and_offset_region);
278 while (private->background == NULL && private->parent)
280 cairo_translate (cr, -private->x, private->y);
281 private = private->parent;
284 if (private->background)
285 cairo_set_source (cr, private->background);
287 cairo_set_source_rgba (cr, 0, 0, 0, 0);
289 /* Can use cairo_paint() here, we clipped above */
295 cairo_region_destroy (clipped_and_offset_region);
299 gdk_window_impl_quartz_end_paint (GdkPaintable *paintable)
301 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
303 impl->begin_paint_count--;
305 if (impl->begin_paint_count == 0)
307 cairo_region_destroy (impl->paint_clip_region);
308 impl->paint_clip_region = NULL;
313 _gdk_quartz_window_set_needs_display_in_region (GdkWindow *window,
314 cairo_region_t *region)
316 GdkWindowObject *private;
317 GdkWindowImplQuartz *impl;
320 private = GDK_WINDOW_OBJECT (window);
321 impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
323 if (!impl->needs_display_region)
324 impl->needs_display_region = cairo_region_create ();
326 cairo_region_union (impl->needs_display_region, region);
328 n_rects = cairo_region_num_rectangles (region);
329 for (i = 0; i < n_rects; i++)
331 cairo_rectangle_int_t rect;
332 cairo_region_get_rectangle (region, i, &rect);
333 [impl->view setNeedsDisplayInRect:NSMakeRect (rect.x, rect.y,
334 rect.width, rect.height)];
339 _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
340 cairo_region_t *region)
342 /* Make sure to only flush each toplevel at most once if we're called
343 * from process_all_updates.
345 if (in_process_all_updates)
349 toplevel = gdk_window_get_effective_toplevel (window);
350 if (toplevel && WINDOW_IS_TOPLEVEL (toplevel))
352 GdkWindowObject *toplevel_private;
353 GdkWindowImplQuartz *toplevel_impl;
356 toplevel_private = (GdkWindowObject *)toplevel;
357 toplevel_impl = (GdkWindowImplQuartz *)toplevel_private->impl;
358 nswindow = toplevel_impl->toplevel;
360 /* In theory, we could skip the flush disabling, since we only
363 if (nswindow && ![nswindow isFlushWindowDisabled])
366 [nswindow disableFlushWindow];
367 update_nswindows = g_slist_prepend (update_nswindows, nswindow);
372 if (WINDOW_IS_TOPLEVEL (window))
373 _gdk_quartz_window_set_needs_display_in_region (window, region);
375 _gdk_window_process_updates_recurse (window, region);
377 /* NOTE: I'm not sure if we should displayIfNeeded here. It slows down a
378 * lot (since it triggers the beam syncing) and things seem to work
384 _gdk_windowing_before_process_all_updates (void)
386 in_process_all_updates = TRUE;
388 NSDisableScreenUpdates ();
392 _gdk_windowing_after_process_all_updates (void)
394 GSList *old_update_nswindows = update_nswindows;
395 GSList *tmp_list = update_nswindows;
397 update_nswindows = NULL;
401 NSWindow *nswindow = tmp_list->data;
403 [[nswindow contentView] displayIfNeeded];
405 _gdk_quartz_drawable_flush (NULL);
407 [nswindow enableFlushWindow];
408 [nswindow flushWindow];
411 tmp_list = tmp_list->next;
414 g_slist_free (old_update_nswindows);
416 in_process_all_updates = FALSE;
418 NSEnableScreenUpdates ();
422 gdk_window_impl_quartz_paintable_init (GdkPaintableIface *iface)
424 iface->begin_paint_region = gdk_window_impl_quartz_begin_paint_region;
425 iface->end_paint = gdk_window_impl_quartz_end_paint;
429 _gdk_window_impl_quartz_get_type (void)
431 static GType object_type = 0;
435 const GTypeInfo object_info =
437 sizeof (GdkWindowImplQuartzClass),
438 (GBaseInitFunc) NULL,
439 (GBaseFinalizeFunc) NULL,
440 (GClassInitFunc) gdk_window_impl_quartz_class_init,
441 NULL, /* class_finalize */
442 NULL, /* class_data */
443 sizeof (GdkWindowImplQuartz),
445 (GInstanceInitFunc) gdk_window_impl_quartz_init,
448 const GInterfaceInfo paintable_info =
450 (GInterfaceInitFunc) gdk_window_impl_quartz_paintable_init,
455 const GInterfaceInfo window_impl_info =
457 (GInterfaceInitFunc) gdk_window_impl_iface_init,
462 object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_QUARTZ,
463 "GdkWindowImplQuartz",
465 g_type_add_interface_static (object_type,
468 g_type_add_interface_static (object_type,
469 GDK_TYPE_WINDOW_IMPL,
477 get_default_title (void)
481 title = g_get_application_name ();
483 title = g_get_prgname ();
489 get_ancestor_coordinates_from_child (GdkWindow *child_window,
492 GdkWindow *ancestor_window,
496 GdkWindowObject *child_private = GDK_WINDOW_OBJECT (child_window);
497 GdkWindowObject *ancestor_private = GDK_WINDOW_OBJECT (ancestor_window);
499 while (child_private != ancestor_private)
501 child_x += child_private->x;
502 child_y += child_private->y;
504 child_private = child_private->parent;
507 *ancestor_x = child_x;
508 *ancestor_y = child_y;
512 _gdk_quartz_window_debug_highlight (GdkWindow *window, gint number)
514 GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
519 static NSWindow *debug_window[10];
520 static NSRect old_rect[10];
524 g_return_if_fail (number >= 0 && number <= 9);
526 if (window == _gdk_root)
531 if (debug_window[number])
532 [debug_window[number] close];
533 debug_window[number] = NULL;
538 toplevel = gdk_window_get_toplevel (window);
539 get_ancestor_coordinates_from_child (window, 0, 0, toplevel, &x, &y);
541 gdk_window_get_origin (toplevel, &tx, &ty);
545 _gdk_quartz_window_gdk_xy_to_xy (x, y + private->height,
548 rect = NSMakeRect (gx, gy, private->width, private->height);
550 if (debug_window[number] && NSEqualRects (rect, old_rect[number]))
553 old_rect[number] = rect;
555 if (debug_window[number])
556 [debug_window[number] close];
558 debug_window[number] = [[NSWindow alloc] initWithContentRect:rect
559 styleMask:NSBorderlessWindowMask
560 backing:NSBackingStoreBuffered
566 color = [NSColor redColor];
569 color = [NSColor blueColor];
572 color = [NSColor greenColor];
575 color = [NSColor yellowColor];
578 color = [NSColor brownColor];
581 color = [NSColor purpleColor];
584 color = [NSColor blackColor];
588 [debug_window[number] setBackgroundColor:color];
589 [debug_window[number] setAlphaValue:0.4];
590 [debug_window[number] setOpaque:NO];
591 [debug_window[number] setReleasedWhenClosed:YES];
592 [debug_window[number] setIgnoresMouseEvents:YES];
593 [debug_window[number] setLevel:NSFloatingWindowLevel];
595 [debug_window[number] orderFront:nil];
599 _gdk_quartz_window_is_ancestor (GdkWindow *ancestor,
602 if (ancestor == NULL || window == NULL)
605 return (gdk_window_get_parent (window) == ancestor ||
606 _gdk_quartz_window_is_ancestor (ancestor,
607 gdk_window_get_parent (window)));
611 /* See notes on top of gdkscreen-quartz.c */
613 _gdk_quartz_window_gdk_xy_to_xy (gint gdk_x,
618 GdkScreenQuartz *screen_quartz = GDK_SCREEN_QUARTZ (_gdk_screen);
621 *ns_y = screen_quartz->height - gdk_y + screen_quartz->min_y;
624 *ns_x = gdk_x + screen_quartz->min_x;
628 _gdk_quartz_window_xy_to_gdk_xy (gint ns_x,
633 GdkScreenQuartz *screen_quartz = GDK_SCREEN_QUARTZ (_gdk_screen);
636 *gdk_y = screen_quartz->height - ns_y + screen_quartz->min_y;
639 *gdk_x = ns_x - screen_quartz->min_x;
643 _gdk_quartz_window_nspoint_to_gdk_xy (NSPoint point,
647 _gdk_quartz_window_xy_to_gdk_xy (point.x, point.y,
652 find_child_window_helper (GdkWindow *window,
657 gboolean get_toplevel)
659 GdkWindowImplQuartz *impl;
662 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
664 if (window == _gdk_root)
665 update_toplevel_order ();
667 for (l = impl->sorted_children; l; l = l->next)
669 GdkWindowObject *child_private = l->data;
670 GdkWindowImplQuartz *child_impl = GDK_WINDOW_IMPL_QUARTZ (child_private->impl);
673 if (!GDK_WINDOW_IS_MAPPED (child_private))
676 temp_x = x_offset + child_private->x;
677 temp_y = y_offset + child_private->y;
679 /* Special-case the root window. We have to include the title
680 * bar in the checks, otherwise the window below the title bar
681 * will be found i.e. events punch through. (If we can find a
682 * better way to deal with the events in gdkevents-quartz, this
683 * might not be needed.)
685 if (window == _gdk_root)
687 NSRect frame = NSMakeRect (0, 0, 100, 100);
692 mask = [child_impl->toplevel styleMask];
694 /* Get the title bar height. */
695 content = [NSWindow contentRectForFrameRect:frame
697 titlebar_height = frame.size.height - content.size.height;
699 if (titlebar_height > 0 &&
700 x >= temp_x && y >= temp_y - titlebar_height &&
701 x < temp_x + child_private->width && y < temp_y)
703 /* The root means "unknown" i.e. a window not managed by
706 return (GdkWindow *)_gdk_root;
710 if ((!get_toplevel || (get_toplevel && window == _gdk_root)) &&
711 x >= temp_x && y >= temp_y &&
712 x < temp_x + child_private->width && y < temp_y + child_private->height)
714 /* Look for child windows. */
715 return find_child_window_helper (l->data,
725 /* Given a GdkWindow and coordinates relative to it, returns the
726 * innermost subwindow that contains the point. If the coordinates are
727 * outside the passed in window, NULL is returned.
730 _gdk_quartz_window_find_child (GdkWindow *window,
733 gboolean get_toplevel)
735 GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
737 if (x >= 0 && y >= 0 && x < private->width && y < private->height)
738 return find_child_window_helper (window, x, y, 0, 0, get_toplevel);
745 _gdk_quartz_window_did_become_main (GdkWindow *window)
747 main_window_stack = g_slist_remove (main_window_stack, window);
749 if (GDK_WINDOW_OBJECT (window)->window_type != GDK_WINDOW_TEMP)
750 main_window_stack = g_slist_prepend (main_window_stack, window);
752 clear_toplevel_order ();
756 _gdk_quartz_window_did_resign_main (GdkWindow *window)
758 GdkWindow *new_window = NULL;
760 if (main_window_stack)
761 new_window = main_window_stack->data;
766 toplevels = gdk_screen_get_toplevel_windows (gdk_screen_get_default ());
768 new_window = toplevels->data;
769 g_list_free (toplevels);
773 new_window != window &&
774 GDK_WINDOW_IS_MAPPED (new_window) &&
775 WINDOW_IS_TOPLEVEL (new_window))
777 GdkWindowObject *private = (GdkWindowObject *) new_window;
778 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
780 [impl->toplevel makeKeyAndOrderFront:impl->toplevel];
783 clear_toplevel_order ();
787 get_nsscreen_for_point (gint x, gint y)
791 NSScreen *screen = NULL;
793 GDK_QUARTZ_ALLOC_POOL;
795 screens = [NSScreen screens];
797 for (i = 0; i < [screens count]; i++)
799 NSRect rect = [[screens objectAtIndex:i] frame];
801 if (x >= rect.origin.x && x <= rect.origin.x + rect.size.width &&
802 y >= rect.origin.y && y <= rect.origin.y + rect.size.height)
804 screen = [screens objectAtIndex:i];
809 GDK_QUARTZ_RELEASE_POOL;
815 _gdk_window_impl_new (GdkWindow *window,
816 GdkWindow *real_parent,
818 GdkEventMask event_mask,
819 GdkWindowAttr *attributes,
820 gint attributes_mask)
822 GdkWindowObject *private;
823 GdkWindowImplQuartz *impl;
824 GdkDrawableImplQuartz *draw_impl;
825 GdkWindowImplQuartz *parent_impl;
827 GDK_QUARTZ_ALLOC_POOL;
829 private = (GdkWindowObject *)window;
831 impl = g_object_new (GDK_TYPE_WINDOW_IMPL_QUARTZ, NULL);
832 private->impl = (GdkDrawable *)impl;
833 draw_impl = GDK_DRAWABLE_IMPL_QUARTZ (impl);
834 draw_impl->wrapper = GDK_DRAWABLE (window);
836 parent_impl = GDK_WINDOW_IMPL_QUARTZ (private->parent->impl);
838 switch (private->window_type)
840 case GDK_WINDOW_TOPLEVEL:
841 case GDK_WINDOW_TEMP:
842 if (GDK_WINDOW_TYPE (private->parent) != GDK_WINDOW_ROOT)
844 /* The common code warns for this case */
845 parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (_gdk_root)->impl);
849 /* Maintain the z-ordered list of children. */
850 if (private->parent != (GdkWindowObject *)_gdk_root)
851 parent_impl->sorted_children = g_list_prepend (parent_impl->sorted_children, window);
853 clear_toplevel_order ();
855 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
856 (attributes->cursor) :
861 switch (attributes->window_type)
863 case GDK_WINDOW_TOPLEVEL:
864 case GDK_WINDOW_TEMP:
869 NSUInteger style_mask;
873 /* initWithContentRect will place on the mainScreen by default.
874 * We want to select the screen to place on ourselves. We need
875 * to find the screen the window will be on and correct the
876 * content_rect coordinates to be relative to that screen.
878 _gdk_quartz_window_gdk_xy_to_xy (private->x, private->y, &nx, &ny);
880 screen = get_nsscreen_for_point (nx, ny);
881 screen_rect = [screen frame];
882 nx -= screen_rect.origin.x;
883 ny -= screen_rect.origin.y;
885 content_rect = NSMakeRect (nx, ny - private->height,
889 if (attributes->window_type == GDK_WINDOW_TEMP ||
890 attributes->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
892 style_mask = NSBorderlessWindowMask;
896 style_mask = (NSTitledWindowMask |
897 NSClosableWindowMask |
898 NSMiniaturizableWindowMask |
899 NSResizableWindowMask);
902 impl->toplevel = [[GdkQuartzWindow alloc] initWithContentRect:content_rect
904 backing:NSBackingStoreBuffered
908 if (attributes_mask & GDK_WA_TITLE)
909 title = attributes->title;
911 title = get_default_title ();
913 gdk_window_set_title (window, title);
915 if (gdk_window_get_visual (window) == gdk_screen_get_rgba_visual (_gdk_screen))
917 [impl->toplevel setOpaque:NO];
918 [impl->toplevel setBackgroundColor:[NSColor clearColor]];
921 content_rect.origin.x = 0;
922 content_rect.origin.y = 0;
924 impl->view = [[GdkQuartzView alloc] initWithFrame:content_rect];
925 [impl->view setGdkWindow:window];
926 [impl->toplevel setContentView:impl->view];
927 [impl->view release];
931 case GDK_WINDOW_CHILD:
933 GdkWindowImplQuartz *parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (private->parent)->impl);
935 if (!private->input_only)
937 NSRect frame_rect = NSMakeRect (private->x + private->parent->abs_x,
938 private->y + private->parent->abs_y,
942 impl->view = [[GdkQuartzView alloc] initWithFrame:frame_rect];
944 [impl->view setGdkWindow:window];
946 /* GdkWindows should be hidden by default */
947 [impl->view setHidden:YES];
948 [parent_impl->view addSubview:impl->view];
949 [impl->view release];
955 g_assert_not_reached ();
958 GDK_QUARTZ_RELEASE_POOL;
960 if (attributes_mask & GDK_WA_TYPE_HINT)
961 gdk_window_set_type_hint (window, attributes->type_hint);
965 _gdk_quartz_window_update_position (GdkWindow *window)
969 GdkWindowObject *private = (GdkWindowObject *)window;
970 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
972 GDK_QUARTZ_ALLOC_POOL;
974 frame_rect = [impl->toplevel frame];
975 content_rect = [impl->toplevel contentRectForFrameRect:frame_rect];
977 _gdk_quartz_window_xy_to_gdk_xy (content_rect.origin.x,
978 content_rect.origin.y + content_rect.size.height,
979 &private->x, &private->y);
982 GDK_QUARTZ_RELEASE_POOL;
986 _gdk_windowing_update_window_sizes (GdkScreen *screen)
988 GList *windows, *list;
989 GdkWindowObject *private = (GdkWindowObject *)_gdk_root;
991 /* The size of the root window is so that it can contain all
992 * monitors attached to this machine. The monitors are laid out
993 * within this root window. We calculate the size of the root window
994 * and the positions of the different monitors in gdkscreen-quartz.c.
996 * This data is updated when the monitor configuration is changed.
1002 private->width = gdk_screen_get_width (screen);
1003 private->height = gdk_screen_get_height (screen);
1005 windows = gdk_screen_get_toplevel_windows (screen);
1007 for (list = windows; list; list = list->next)
1008 _gdk_quartz_window_update_position (list->data);
1010 g_list_free (windows);
1014 _gdk_windowing_window_init (void)
1016 GdkWindowObject *private;
1017 GdkWindowImplQuartz *impl;
1018 GdkDrawableImplQuartz *drawable_impl;
1020 g_assert (_gdk_root == NULL);
1022 _gdk_root = g_object_new (GDK_TYPE_WINDOW, NULL);
1024 private = (GdkWindowObject *)_gdk_root;
1025 private->impl = g_object_new (_gdk_root_window_impl_quartz_get_type (), NULL);
1026 private->impl_window = private;
1027 private->visual = gdk_screen_get_system_visual (_gdk_screen);
1029 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (_gdk_root)->impl);
1031 _gdk_windowing_update_window_sizes (_gdk_screen);
1033 private->state = 0; /* We don't want GDK_WINDOW_STATE_WITHDRAWN here */
1034 private->window_type = GDK_WINDOW_ROOT;
1035 private->depth = 24;
1036 private->viewable = TRUE;
1038 drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (private->impl);
1040 drawable_impl->wrapper = GDK_DRAWABLE (private);
1044 _gdk_quartz_window_destroy (GdkWindow *window,
1046 gboolean foreign_destroy)
1048 GdkWindowObject *private;
1049 GdkWindowImplQuartz *impl;
1050 GdkWindowObject *parent;
1052 private = GDK_WINDOW_OBJECT (window);
1053 impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1055 main_window_stack = g_slist_remove (main_window_stack, window);
1057 g_list_free (impl->sorted_children);
1058 impl->sorted_children = NULL;
1060 parent = private->parent;
1063 GdkWindowImplQuartz *parent_impl = GDK_WINDOW_IMPL_QUARTZ (parent->impl);
1065 parent_impl->sorted_children = g_list_remove (parent_impl->sorted_children, window);
1068 _gdk_quartz_drawable_finish (GDK_DRAWABLE (impl));
1070 if (!recursing && !foreign_destroy)
1072 GDK_QUARTZ_ALLOC_POOL;
1075 [impl->toplevel close];
1076 else if (impl->view)
1077 [impl->view removeFromSuperview];
1079 GDK_QUARTZ_RELEASE_POOL;
1083 static cairo_surface_t *
1084 gdk_window_quartz_resize_cairo_surface (GdkWindow *window,
1085 cairo_surface_t *surface,
1089 /* Quartz surfaces cannot be resized */
1090 cairo_surface_destroy (surface);
1096 _gdk_windowing_window_destroy_foreign (GdkWindow *window)
1098 /* Foreign windows aren't supported in OSX. */
1101 /* FIXME: This might be possible to simplify with client-side windows. Also
1102 * note that already_mapped is not used yet, see the x11 backend.
1105 gdk_window_quartz_show (GdkWindow *window, gboolean already_mapped)
1107 GdkWindowObject *private = (GdkWindowObject *)window;
1108 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1109 gboolean focus_on_map;
1111 GDK_QUARTZ_ALLOC_POOL;
1113 if (!GDK_WINDOW_IS_MAPPED (window))
1114 focus_on_map = private->focus_on_map;
1116 focus_on_map = TRUE;
1118 if (WINDOW_IS_TOPLEVEL (window) && impl->toplevel)
1122 make_key = (private->accept_focus && focus_on_map &&
1123 private->window_type != GDK_WINDOW_TEMP);
1125 [(GdkQuartzWindow*)impl->toplevel showAndMakeKey:make_key];
1126 clear_toplevel_order ();
1128 _gdk_quartz_events_send_map_event (window);
1132 [impl->view setHidden:NO];
1135 [impl->view setNeedsDisplay:YES];
1137 gdk_synthesize_window_state (window, GDK_WINDOW_STATE_WITHDRAWN, 0);
1139 if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
1140 gdk_window_maximize (window);
1142 if (private->state & GDK_WINDOW_STATE_ICONIFIED)
1143 gdk_window_iconify (window);
1145 if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
1146 _gdk_quartz_window_attach_to_parent (window);
1148 GDK_QUARTZ_RELEASE_POOL;
1151 /* Temporarily unsets the parent window, if the window is a
1155 _gdk_quartz_window_detach_from_parent (GdkWindow *window)
1157 GdkWindowImplQuartz *impl;
1159 g_return_if_fail (GDK_IS_WINDOW (window));
1161 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1163 g_return_if_fail (impl->toplevel != NULL);
1165 if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
1167 GdkWindowImplQuartz *parent_impl;
1169 parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (impl->transient_for)->impl);
1170 [parent_impl->toplevel removeChildWindow:impl->toplevel];
1171 clear_toplevel_order ();
1175 /* Re-sets the parent window, if the window is a transient. */
1177 _gdk_quartz_window_attach_to_parent (GdkWindow *window)
1179 GdkWindowImplQuartz *impl;
1181 g_return_if_fail (GDK_IS_WINDOW (window));
1183 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1185 g_return_if_fail (impl->toplevel != NULL);
1187 if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
1189 GdkWindowImplQuartz *parent_impl;
1191 parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (impl->transient_for)->impl);
1192 [parent_impl->toplevel addChildWindow:impl->toplevel ordered:NSWindowAbove];
1193 clear_toplevel_order ();
1198 gdk_window_quartz_hide (GdkWindow *window)
1200 GdkWindowObject *private = (GdkWindowObject *)window;
1201 GdkWindowImplQuartz *impl;
1203 /* Make sure we're not stuck in fullscreen mode. */
1204 if (get_fullscreen_geometry (window))
1205 SetSystemUIMode (kUIModeNormal, 0);
1207 check_grab_unmap (window);
1209 _gdk_window_clear_update_area (window);
1211 impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1213 if (WINDOW_IS_TOPLEVEL (window))
1215 /* Update main window. */
1216 main_window_stack = g_slist_remove (main_window_stack, window);
1217 if ([NSApp mainWindow] == impl->toplevel)
1218 _gdk_quartz_window_did_resign_main (window);
1220 if (impl->transient_for)
1221 _gdk_quartz_window_detach_from_parent (window);
1223 [(GdkQuartzWindow*)impl->toplevel hide];
1225 else if (impl->view)
1227 [impl->view setHidden:YES];
1232 gdk_window_quartz_withdraw (GdkWindow *window)
1234 gdk_window_hide (window);
1238 move_resize_window_internal (GdkWindow *window,
1244 GdkWindowObject *private = (GdkWindowObject *)window;
1245 GdkWindowImplQuartz *impl;
1246 GdkRectangle old_visible;
1247 GdkRectangle new_visible;
1248 GdkRectangle scroll_rect;
1249 cairo_region_t *old_region;
1250 cairo_region_t *expose_region;
1253 if (GDK_WINDOW_DESTROYED (window))
1256 impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1258 if ((x == -1 || (x == private->x)) &&
1259 (y == -1 || (y == private->y)) &&
1260 (width == -1 || (width == private->width)) &&
1261 (height == -1 || (height == private->height)))
1266 if (!impl->toplevel)
1268 /* The previously visible area of this window in a coordinate
1269 * system rooted at the origin of this window.
1271 old_visible.x = -private->x;
1272 old_visible.y = -private->y;
1274 old_visible.width = private->width;
1275 old_visible.height = private->height;
1280 delta.width = x - private->x;
1290 delta.height = y - private->y;
1299 private->width = width;
1302 private->height = height;
1304 GDK_QUARTZ_ALLOC_POOL;
1308 NSRect content_rect;
1312 _gdk_quartz_window_gdk_xy_to_xy (private->x, private->y + private->height,
1315 content_rect = NSMakeRect (gx, gy, private->width, private->height);
1317 frame_rect = [impl->toplevel frameRectForContentRect:content_rect];
1318 [impl->toplevel setFrame:frame_rect display:YES];
1322 if (!private->input_only)
1326 nsrect = NSMakeRect (private->x, private->y, private->width, private->height);
1328 /* The newly visible area of this window in a coordinate
1329 * system rooted at the origin of this window.
1331 new_visible.x = -private->x;
1332 new_visible.y = -private->y;
1333 new_visible.width = old_visible.width; /* parent has not changed size */
1334 new_visible.height = old_visible.height; /* parent has not changed size */
1336 expose_region = cairo_region_create_rectangle (&new_visible);
1337 old_region = cairo_region_create_rectangle (&old_visible);
1338 cairo_region_subtract (expose_region, old_region);
1340 /* Determine what (if any) part of the previously visible
1341 * part of the window can be copied without a redraw
1343 scroll_rect = old_visible;
1344 scroll_rect.x -= delta.width;
1345 scroll_rect.y -= delta.height;
1346 gdk_rectangle_intersect (&scroll_rect, &old_visible, &scroll_rect);
1348 if (!cairo_region_is_empty (expose_region))
1350 if (scroll_rect.width != 0 && scroll_rect.height != 0)
1352 [impl->view scrollRect:NSMakeRect (scroll_rect.x,
1359 [impl->view setFrame:nsrect];
1361 _gdk_quartz_window_set_needs_display_in_region (window, expose_region);
1365 [impl->view setFrame:nsrect];
1366 [impl->view setNeedsDisplay:YES];
1369 cairo_region_destroy (expose_region);
1370 cairo_region_destroy (old_region);
1374 GDK_QUARTZ_RELEASE_POOL;
1378 window_quartz_move (GdkWindow *window,
1382 g_return_if_fail (GDK_IS_WINDOW (window));
1384 if (((GdkWindowObject *)window)->state & GDK_WINDOW_STATE_FULLSCREEN)
1387 move_resize_window_internal (window, x, y, -1, -1);
1391 window_quartz_resize (GdkWindow *window,
1395 g_return_if_fail (GDK_IS_WINDOW (window));
1397 if (((GdkWindowObject *)window)->state & GDK_WINDOW_STATE_FULLSCREEN)
1405 move_resize_window_internal (window, -1, -1, width, height);
1409 window_quartz_move_resize (GdkWindow *window,
1420 move_resize_window_internal (window, x, y, width, height);
1424 gdk_window_quartz_move_resize (GdkWindow *window,
1431 if (with_move && (width < 0 && height < 0))
1432 window_quartz_move (window, x, y);
1436 window_quartz_move_resize (window, x, y, width, height);
1438 window_quartz_resize (window, width, height);
1442 /* FIXME: This might need fixing (reparenting didn't work before client-side
1446 gdk_window_quartz_reparent (GdkWindow *window,
1447 GdkWindow *new_parent,
1451 GdkWindowObject *private, *old_parent_private, *new_parent_private;
1452 GdkWindowImplQuartz *impl, *old_parent_impl, *new_parent_impl;
1453 NSView *view, *new_parent_view;
1455 if (new_parent == _gdk_root)
1457 /* Could be added, just needs implementing. */
1458 g_warning ("Reparenting to root window is not supported yet in the Mac OS X backend");
1462 private = GDK_WINDOW_OBJECT (window);
1463 impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1466 new_parent_private = GDK_WINDOW_OBJECT (new_parent);
1467 new_parent_impl = GDK_WINDOW_IMPL_QUARTZ (new_parent_private->impl);
1468 new_parent_view = new_parent_impl->view;
1470 old_parent_private = GDK_WINDOW_OBJECT (private->parent);
1471 old_parent_impl = GDK_WINDOW_IMPL_QUARTZ (old_parent_private->impl);
1475 [view removeFromSuperview];
1476 [new_parent_view addSubview:view];
1480 private->parent = new_parent_private;
1482 if (old_parent_private)
1484 old_parent_impl->sorted_children = g_list_remove (old_parent_impl->sorted_children, window);
1487 new_parent_impl->sorted_children = g_list_prepend (new_parent_impl->sorted_children, window);
1492 /* Get the toplevel ordering from NSApp and update our own list. We do
1493 * this on demand since the NSApp's list is not up to date directly
1494 * after we get windowDidBecomeMain.
1497 update_toplevel_order (void)
1499 GdkWindowObject *root;
1500 GdkWindowImplQuartz *root_impl;
1501 NSEnumerator *enumerator;
1503 GList *toplevels = NULL;
1505 root = GDK_WINDOW_OBJECT (_gdk_root);
1506 root_impl = GDK_WINDOW_IMPL_QUARTZ (root->impl);
1508 if (root_impl->sorted_children)
1511 GDK_QUARTZ_ALLOC_POOL;
1513 enumerator = [[NSApp orderedWindows] objectEnumerator];
1514 while ((nswindow = [enumerator nextObject]))
1518 if (![[nswindow contentView] isKindOfClass:[GdkQuartzView class]])
1521 window = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
1522 toplevels = g_list_prepend (toplevels, window);
1525 GDK_QUARTZ_RELEASE_POOL;
1527 root_impl->sorted_children = g_list_reverse (toplevels);
1531 clear_toplevel_order (void)
1533 GdkWindowObject *root;
1534 GdkWindowImplQuartz *root_impl;
1536 root = GDK_WINDOW_OBJECT (_gdk_root);
1537 root_impl = GDK_WINDOW_IMPL_QUARTZ (root->impl);
1539 g_list_free (root_impl->sorted_children);
1540 root_impl->sorted_children = NULL;
1544 gdk_window_quartz_raise (GdkWindow *window)
1546 if (GDK_WINDOW_DESTROYED (window))
1549 if (WINDOW_IS_TOPLEVEL (window))
1551 GdkWindowImplQuartz *impl;
1553 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1554 [impl->toplevel orderFront:impl->toplevel];
1556 clear_toplevel_order ();
1560 GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
1564 GdkWindowImplQuartz *impl;
1566 impl = (GdkWindowImplQuartz *)parent->impl;
1568 impl->sorted_children = g_list_remove (impl->sorted_children, window);
1569 impl->sorted_children = g_list_prepend (impl->sorted_children, window);
1575 gdk_window_quartz_lower (GdkWindow *window)
1577 if (GDK_WINDOW_DESTROYED (window))
1580 if (WINDOW_IS_TOPLEVEL (window))
1582 GdkWindowImplQuartz *impl;
1584 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1585 [impl->toplevel orderBack:impl->toplevel];
1587 clear_toplevel_order ();
1591 GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
1595 GdkWindowImplQuartz *impl;
1597 impl = (GdkWindowImplQuartz *)parent->impl;
1599 impl->sorted_children = g_list_remove (impl->sorted_children, window);
1600 impl->sorted_children = g_list_append (impl->sorted_children, window);
1606 gdk_window_quartz_restack_toplevel (GdkWindow *window,
1610 /* FIXME: Implement this */
1614 gdk_window_quartz_set_background (GdkWindow *window,
1615 cairo_pattern_t *pattern)
1617 /* FIXME: We could theoretically set the background color for toplevels
1618 * here. (Currently we draw the background before emitting expose events)
1623 gdk_window_quartz_set_device_cursor (GdkWindow *window,
1627 GdkCursorPrivate *cursor_private;
1630 cursor_private = (GdkCursorPrivate *)cursor;
1632 if (GDK_WINDOW_DESTROYED (window))
1636 nscursor = [NSCursor arrowCursor];
1638 nscursor = cursor_private->nscursor;
1644 gdk_window_quartz_get_geometry (GdkWindow *window,
1651 GdkWindowImplQuartz *impl;
1652 GdkWindowObject *private;
1655 if (GDK_WINDOW_DESTROYED (window))
1658 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1659 private = GDK_WINDOW_OBJECT (window);
1660 if (window == _gdk_root)
1668 *width = private->width;
1670 *height = private->height;
1672 else if (WINDOW_IS_TOPLEVEL (window))
1674 ns_rect = [impl->toplevel contentRectForFrameRect:[impl->toplevel frame]];
1676 /* This doesn't work exactly as in X. There doesn't seem to be a
1677 * way to get the coords relative to the parent window (usually
1678 * the window frame), but that seems useless except for
1679 * borderless windows where it's relative to the root window. So
1680 * we return (0, 0) (should be something like (0, 22)) for
1681 * windows with borders and the root relative coordinates
1684 if ([impl->toplevel styleMask] == NSBorderlessWindowMask)
1686 _gdk_quartz_window_xy_to_gdk_xy (ns_rect.origin.x,
1687 ns_rect.origin.y + ns_rect.size.height,
1699 *width = ns_rect.size.width;
1701 *height = ns_rect.size.height;
1705 ns_rect = [impl->view frame];
1708 *x = ns_rect.origin.x;
1710 *y = ns_rect.origin.y;
1712 *width = ns_rect.size.width;
1714 *height = ns_rect.size.height;
1718 *depth = gdk_visual_get_depth (gdk_window_get_visual (window));
1722 gdk_window_quartz_get_root_coords (GdkWindow *window,
1728 GdkWindowObject *private;
1729 int tmp_x = 0, tmp_y = 0;
1730 GdkWindow *toplevel;
1731 NSRect content_rect;
1732 GdkWindowImplQuartz *impl;
1734 if (GDK_WINDOW_DESTROYED (window))
1744 if (window == _gdk_root)
1754 private = GDK_WINDOW_OBJECT (window);
1756 toplevel = gdk_window_get_toplevel (window);
1757 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
1759 content_rect = [impl->toplevel contentRectForFrameRect:[impl->toplevel frame]];
1761 _gdk_quartz_window_xy_to_gdk_xy (content_rect.origin.x,
1762 content_rect.origin.y + content_rect.size.height,
1768 while (private != GDK_WINDOW_OBJECT (toplevel))
1770 if (_gdk_window_has_impl ((GdkWindow *)private))
1772 tmp_x += private->x;
1773 tmp_y += private->y;
1776 private = private->parent;
1788 gdk_window_get_root_origin (GdkWindow *window,
1797 gdk_window_get_frame_extents (window, &rect);
1806 /* Returns coordinates relative to the passed in window. */
1808 gdk_window_quartz_get_device_state_helper (GdkWindow *window,
1812 GdkModifierType *mask)
1814 GdkWindowObject *toplevel;
1815 GdkWindowObject *private;
1818 GdkWindow *found_window;
1820 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1822 if (GDK_WINDOW_DESTROYED (window))
1830 toplevel = GDK_WINDOW_OBJECT (gdk_window_get_toplevel (window));
1832 *mask = _gdk_quartz_events_get_current_event_mask ();
1834 /* Get the y coordinate, needs to be flipped. */
1835 if (window == _gdk_root)
1837 point = [NSEvent mouseLocation];
1838 _gdk_quartz_window_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
1842 GdkWindowImplQuartz *impl;
1845 impl = GDK_WINDOW_IMPL_QUARTZ (toplevel->impl);
1846 private = GDK_WINDOW_OBJECT (toplevel);
1847 nswindow = impl->toplevel;
1849 point = [nswindow mouseLocationOutsideOfEventStream];
1852 y_tmp = private->height - point.y;
1854 window = (GdkWindow *)toplevel;
1857 found_window = _gdk_quartz_window_find_child (window, x_tmp, y_tmp,
1860 /* We never return the root window. */
1861 if (found_window == _gdk_root)
1862 found_window = NULL;
1867 return found_window;
1871 gdk_window_quartz_get_device_state (GdkWindow *window,
1875 GdkModifierType *mask)
1877 return gdk_window_quartz_get_device_state_helper (window,
1879 x, y, mask) != NULL;
1882 /* Returns coordinates relative to the root. */
1884 _gdk_windowing_get_device_state (GdkDisplay *display,
1889 GdkModifierType *mask)
1891 g_return_if_fail (display == _gdk_display);
1893 *screen = _gdk_screen;
1894 gdk_window_quartz_get_device_state_helper (_gdk_root, device, x, y, mask);
1898 gdk_display_warp_pointer (GdkDisplay *display,
1903 CGDisplayMoveCursorToPoint (CGMainDisplayID (), CGPointMake (x, y));
1906 /* Returns coordinates relative to the found window. */
1908 _gdk_windowing_window_at_pointer (GdkDisplay *display,
1911 GdkModifierType *mask,
1912 gboolean get_toplevel)
1914 GdkWindow *found_window;
1916 GdkModifierType tmp_mask = 0;
1918 found_window = gdk_window_quartz_get_device_state_helper (_gdk_root,
1919 display->core_pointer,
1924 GdkWindowObject *private;
1926 /* The coordinates returned above are relative the root, we want
1927 * coordinates relative the window here.
1929 private = GDK_WINDOW_OBJECT (found_window);
1930 while (private != GDK_WINDOW_OBJECT (_gdk_root))
1935 private = private->parent;
1943 /* Mimic the X backend here, -1,-1 for unknown windows. */
1953 GdkWindowObject *w = (GdkWindowObject *)found_window;
1954 /* Requested toplevel, find it. */
1955 /* TODO: This can be implemented more efficient by never
1956 recursing into children in the first place */
1959 /* Convert to toplevel */
1960 while (w->parent != NULL &&
1961 w->parent->window_type != GDK_WINDOW_ROOT)
1967 found_window = (GdkWindow *)w;
1971 return found_window;
1975 _gdk_windowing_window_at_device_position (GdkDisplay *display,
1979 GdkModifierType *mask,
1980 gboolean get_toplevel)
1982 return GDK_DEVICE_GET_CLASS (device)->window_at_position (device,
1990 gdk_window_quartz_get_events (GdkWindow *window)
1992 if (GDK_WINDOW_DESTROYED (window))
1995 return GDK_WINDOW_OBJECT (window)->event_mask;
1999 gdk_window_quartz_set_events (GdkWindow *window,
2000 GdkEventMask event_mask)
2002 /* The mask is set in the common code. */
2006 gdk_window_set_urgency_hint (GdkWindow *window,
2009 if (GDK_WINDOW_DESTROYED (window) ||
2010 !WINDOW_IS_TOPLEVEL (window))
2013 /* FIXME: Implement */
2017 gdk_window_set_geometry_hints (GdkWindow *window,
2018 const GdkGeometry *geometry,
2019 GdkWindowHints geom_mask)
2021 GdkWindowImplQuartz *impl;
2023 g_return_if_fail (geometry != NULL);
2025 if (GDK_WINDOW_DESTROYED (window) ||
2026 !WINDOW_IS_TOPLEVEL (window))
2029 impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl);
2030 if (!impl->toplevel)
2033 if (geom_mask & GDK_HINT_POS)
2035 /* FIXME: Implement */
2038 if (geom_mask & GDK_HINT_USER_POS)
2040 /* FIXME: Implement */
2043 if (geom_mask & GDK_HINT_USER_SIZE)
2045 /* FIXME: Implement */
2048 if (geom_mask & GDK_HINT_MIN_SIZE)
2052 size.width = geometry->min_width;
2053 size.height = geometry->min_height;
2055 [impl->toplevel setContentMinSize:size];
2058 if (geom_mask & GDK_HINT_MAX_SIZE)
2062 size.width = geometry->max_width;
2063 size.height = geometry->max_height;
2065 [impl->toplevel setContentMaxSize:size];
2068 if (geom_mask & GDK_HINT_BASE_SIZE)
2070 /* FIXME: Implement */
2073 if (geom_mask & GDK_HINT_RESIZE_INC)
2077 size.width = geometry->width_inc;
2078 size.height = geometry->height_inc;
2080 [impl->toplevel setContentResizeIncrements:size];
2083 if (geom_mask & GDK_HINT_ASPECT)
2085 /* FIXME: Implement */
2088 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2090 /* FIXME: Implement */
2095 gdk_window_set_title (GdkWindow *window,
2098 GdkWindowImplQuartz *impl;
2100 g_return_if_fail (title != NULL);
2102 if (GDK_WINDOW_DESTROYED (window) ||
2103 !WINDOW_IS_TOPLEVEL (window))
2106 impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *)window)->impl);
2110 GDK_QUARTZ_ALLOC_POOL;
2111 [impl->toplevel setTitle:[NSString stringWithUTF8String:title]];
2112 GDK_QUARTZ_RELEASE_POOL;
2117 gdk_window_set_role (GdkWindow *window,
2120 if (GDK_WINDOW_DESTROYED (window) ||
2121 WINDOW_IS_TOPLEVEL (window))
2124 /* FIXME: Implement */
2128 gdk_window_set_transient_for (GdkWindow *window,
2131 GdkWindowImplQuartz *window_impl;
2132 GdkWindowImplQuartz *parent_impl;
2134 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (parent) ||
2135 !WINDOW_IS_TOPLEVEL (window))
2138 window_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2139 if (!window_impl->toplevel)
2142 GDK_QUARTZ_ALLOC_POOL;
2144 if (window_impl->transient_for)
2146 _gdk_quartz_window_detach_from_parent (window);
2148 g_object_unref (window_impl->transient_for);
2149 window_impl->transient_for = NULL;
2152 parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (parent)->impl);
2153 if (parent_impl->toplevel)
2155 /* We save the parent because it needs to be unset/reset when
2156 * hiding and showing the window.
2159 /* We don't set transients for tooltips, they are already
2160 * handled by the window level being the top one. If we do, then
2161 * the parent window will be brought to the top just because the
2162 * tooltip is, which is not what we want.
2164 if (gdk_window_get_type_hint (window) != GDK_WINDOW_TYPE_HINT_TOOLTIP)
2166 window_impl->transient_for = g_object_ref (parent);
2168 /* We only add the window if it is shown, otherwise it will
2169 * be shown unconditionally here. If it is not shown, the
2170 * window will be added in show() instead.
2172 if (!(GDK_WINDOW_OBJECT (window)->state & GDK_WINDOW_STATE_WITHDRAWN))
2173 _gdk_quartz_window_attach_to_parent (window);
2177 GDK_QUARTZ_RELEASE_POOL;
2181 gdk_window_quartz_shape_combine_region (GdkWindow *window,
2182 const cairo_region_t *shape,
2186 /* FIXME: Implement */
2190 gdk_window_quartz_input_shape_combine_region (GdkWindow *window,
2191 const cairo_region_t *shape_region,
2195 /* FIXME: Implement */
2199 gdk_window_set_override_redirect (GdkWindow *window,
2200 gboolean override_redirect)
2202 /* FIXME: Implement */
2206 gdk_window_set_accept_focus (GdkWindow *window,
2207 gboolean accept_focus)
2209 GdkWindowObject *private;
2211 private = (GdkWindowObject *)window;
2213 private->accept_focus = accept_focus != FALSE;
2217 gdk_window_quartz_set_static_gravities (GdkWindow *window,
2218 gboolean use_static)
2220 if (GDK_WINDOW_DESTROYED (window) ||
2221 !WINDOW_IS_TOPLEVEL (window))
2224 /* FIXME: Implement */
2229 gdk_window_set_focus_on_map (GdkWindow *window,
2230 gboolean focus_on_map)
2232 GdkWindowObject *private;
2234 private = (GdkWindowObject *)window;
2236 private->focus_on_map = focus_on_map != FALSE;
2240 gdk_window_set_icon_name (GdkWindow *window,
2243 /* FIXME: Implement */
2247 gdk_window_focus (GdkWindow *window,
2250 GdkWindowObject *private;
2251 GdkWindowImplQuartz *impl;
2253 private = (GdkWindowObject*) window;
2254 impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
2256 if (GDK_WINDOW_DESTROYED (window) ||
2257 !WINDOW_IS_TOPLEVEL (window))
2260 if (private->accept_focus && private->window_type != GDK_WINDOW_TEMP)
2262 GDK_QUARTZ_ALLOC_POOL;
2263 [impl->toplevel makeKeyAndOrderFront:impl->toplevel];
2264 clear_toplevel_order ();
2265 GDK_QUARTZ_RELEASE_POOL;
2270 gint window_type_hint_to_level (GdkWindowTypeHint hint)
2274 case GDK_WINDOW_TYPE_HINT_DOCK:
2275 case GDK_WINDOW_TYPE_HINT_UTILITY:
2276 return NSFloatingWindowLevel;
2278 case GDK_WINDOW_TYPE_HINT_MENU: /* Torn-off menu */
2279 case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU: /* Menu from menubar */
2280 return NSTornOffMenuWindowLevel;
2282 case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
2283 case GDK_WINDOW_TYPE_HINT_TOOLTIP:
2284 return NSStatusWindowLevel;
2286 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
2287 case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
2288 case GDK_WINDOW_TYPE_HINT_COMBO:
2289 case GDK_WINDOW_TYPE_HINT_DND:
2290 return NSPopUpMenuWindowLevel;
2292 case GDK_WINDOW_TYPE_HINT_NORMAL: /* Normal toplevel window */
2293 case GDK_WINDOW_TYPE_HINT_DIALOG: /* Dialog window */
2294 case GDK_WINDOW_TYPE_HINT_TOOLBAR: /* Window used to implement toolbars */
2295 case GDK_WINDOW_TYPE_HINT_DESKTOP: /* N/A */
2302 return NSNormalWindowLevel;
2306 window_type_hint_to_shadow (GdkWindowTypeHint hint)
2310 case GDK_WINDOW_TYPE_HINT_NORMAL: /* Normal toplevel window */
2311 case GDK_WINDOW_TYPE_HINT_DIALOG: /* Dialog window */
2312 case GDK_WINDOW_TYPE_HINT_DOCK:
2313 case GDK_WINDOW_TYPE_HINT_UTILITY:
2314 case GDK_WINDOW_TYPE_HINT_MENU: /* Torn-off menu */
2315 case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU: /* Menu from menubar */
2316 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
2317 case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
2318 case GDK_WINDOW_TYPE_HINT_COMBO:
2319 case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
2320 case GDK_WINDOW_TYPE_HINT_TOOLTIP:
2323 case GDK_WINDOW_TYPE_HINT_TOOLBAR: /* Window used to implement toolbars */
2324 case GDK_WINDOW_TYPE_HINT_DESKTOP: /* N/A */
2325 case GDK_WINDOW_TYPE_HINT_DND:
2337 gdk_window_set_type_hint (GdkWindow *window,
2338 GdkWindowTypeHint hint)
2340 GdkWindowImplQuartz *impl;
2342 if (GDK_WINDOW_DESTROYED (window) ||
2343 !WINDOW_IS_TOPLEVEL (window))
2346 impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl);
2348 impl->type_hint = hint;
2350 /* Match the documentation, only do something if we're not mapped yet. */
2351 if (GDK_WINDOW_IS_MAPPED (window))
2354 [impl->toplevel setHasShadow: window_type_hint_to_shadow (hint)];
2355 [impl->toplevel setLevel: window_type_hint_to_level (hint)];
2359 gdk_window_get_type_hint (GdkWindow *window)
2361 if (GDK_WINDOW_DESTROYED (window) ||
2362 !WINDOW_IS_TOPLEVEL (window))
2363 return GDK_WINDOW_TYPE_HINT_NORMAL;
2365 return GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl)->type_hint;
2369 gdk_window_set_modal_hint (GdkWindow *window,
2372 if (GDK_WINDOW_DESTROYED (window) ||
2373 !WINDOW_IS_TOPLEVEL (window))
2376 /* FIXME: Implement */
2380 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
2381 gboolean skips_taskbar)
2383 if (GDK_WINDOW_DESTROYED (window) ||
2384 !WINDOW_IS_TOPLEVEL (window))
2387 /* FIXME: Implement */
2391 gdk_window_set_skip_pager_hint (GdkWindow *window,
2392 gboolean skips_pager)
2394 if (GDK_WINDOW_DESTROYED (window) ||
2395 !WINDOW_IS_TOPLEVEL (window))
2398 /* FIXME: Implement */
2402 gdk_window_begin_resize_drag (GdkWindow *window,
2409 GdkWindowObject *private;
2410 GdkWindowImplQuartz *impl;
2412 g_return_if_fail (GDK_IS_WINDOW (window));
2414 if (edge != GDK_WINDOW_EDGE_SOUTH_EAST)
2416 g_warning ("Resizing is only implemented for GDK_WINDOW_EDGE_SOUTH_EAST on Mac OS");
2420 if (GDK_WINDOW_DESTROYED (window))
2423 private = GDK_WINDOW_OBJECT (window);
2424 impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
2426 if (!impl->toplevel)
2428 g_warning ("Can't call gdk_window_begin_resize_drag on non-toplevel window");
2432 [(GdkQuartzWindow *)impl->toplevel beginManualResize];
2436 gdk_window_begin_move_drag (GdkWindow *window,
2442 GdkWindowObject *private;
2443 GdkWindowImplQuartz *impl;
2445 if (GDK_WINDOW_DESTROYED (window) ||
2446 !WINDOW_IS_TOPLEVEL (window))
2449 private = GDK_WINDOW_OBJECT (window);
2450 impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
2452 if (!impl->toplevel)
2454 g_warning ("Can't call gdk_window_begin_move_drag on non-toplevel window");
2458 [(GdkQuartzWindow *)impl->toplevel beginManualMove];
2462 gdk_window_set_icon_list (GdkWindow *window,
2465 /* FIXME: Implement */
2469 gdk_window_get_frame_extents (GdkWindow *window,
2472 GdkWindowObject *private;
2473 GdkWindow *toplevel;
2474 GdkWindowImplQuartz *impl;
2477 g_return_if_fail (rect != NULL);
2479 private = GDK_WINDOW_OBJECT (window);
2486 toplevel = gdk_window_get_effective_toplevel (window);
2487 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
2489 ns_rect = [impl->toplevel frame];
2491 _gdk_quartz_window_xy_to_gdk_xy (ns_rect.origin.x,
2492 ns_rect.origin.y + ns_rect.size.height,
2493 &rect->x, &rect->y);
2495 rect->width = ns_rect.size.width;
2496 rect->height = ns_rect.size.height;
2500 gdk_window_set_decorations (GdkWindow *window,
2501 GdkWMDecoration decorations)
2503 GdkWindowImplQuartz *impl;
2504 NSUInteger old_mask, new_mask;
2507 if (GDK_WINDOW_DESTROYED (window) ||
2508 !WINDOW_IS_TOPLEVEL (window))
2511 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2513 if (decorations == 0 || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP ||
2514 impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN )
2516 new_mask = NSBorderlessWindowMask;
2520 /* FIXME: Honor other GDK_DECOR_* flags. */
2521 new_mask = (NSTitledWindowMask | NSClosableWindowMask |
2522 NSMiniaturizableWindowMask | NSResizableWindowMask);
2525 GDK_QUARTZ_ALLOC_POOL;
2527 old_mask = [impl->toplevel styleMask];
2529 /* Note, there doesn't seem to be a way to change this without
2530 * recreating the toplevel. There might be bad side-effects of doing
2531 * that, but it seems alright.
2533 if (old_mask != new_mask)
2537 old_view = [impl->toplevel contentView];
2539 rect = [impl->toplevel frame];
2541 /* Properly update the size of the window when the titlebar is
2544 if (old_mask == NSBorderlessWindowMask &&
2545 new_mask != NSBorderlessWindowMask)
2547 rect = [NSWindow frameRectForContentRect:rect styleMask:new_mask];
2550 else if (old_mask != NSBorderlessWindowMask &&
2551 new_mask == NSBorderlessWindowMask)
2553 rect = [NSWindow contentRectForFrameRect:rect styleMask:old_mask];
2556 impl->toplevel = [impl->toplevel initWithContentRect:rect
2558 backing:NSBackingStoreBuffered
2561 [impl->toplevel setHasShadow: window_type_hint_to_shadow (impl->type_hint)];
2562 [impl->toplevel setLevel: window_type_hint_to_level (impl->type_hint)];
2564 [impl->toplevel setContentView:old_view];
2565 [impl->toplevel setFrame:rect display:YES];
2567 /* Invalidate the window shadow for non-opaque views that have shadow
2568 * enabled, to get the shadow shape updated.
2570 if (![old_view isOpaque] && [impl->toplevel hasShadow])
2571 [(GdkQuartzView*)old_view setNeedsInvalidateShadow:YES];
2574 GDK_QUARTZ_RELEASE_POOL;
2578 gdk_window_get_decorations (GdkWindow *window,
2579 GdkWMDecoration *decorations)
2581 GdkWindowImplQuartz *impl;
2583 if (GDK_WINDOW_DESTROYED (window) ||
2584 !WINDOW_IS_TOPLEVEL (window))
2587 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2591 /* Borderless is 0, so we can't check it as a bit being set. */
2592 if ([impl->toplevel styleMask] == NSBorderlessWindowMask)
2598 /* FIXME: Honor the other GDK_DECOR_* flags. */
2599 *decorations = GDK_DECOR_ALL;
2607 gdk_window_set_functions (GdkWindow *window,
2608 GdkWMFunction functions)
2610 g_return_if_fail (GDK_IS_WINDOW (window));
2612 /* FIXME: Implement */
2616 _gdk_windowing_window_queue_antiexpose (GdkWindow *window,
2617 cairo_region_t *area)
2623 gdk_window_stick (GdkWindow *window)
2625 if (GDK_WINDOW_DESTROYED (window) ||
2626 !WINDOW_IS_TOPLEVEL (window))
2631 gdk_window_unstick (GdkWindow *window)
2633 if (GDK_WINDOW_DESTROYED (window) ||
2634 !WINDOW_IS_TOPLEVEL (window))
2639 gdk_window_maximize (GdkWindow *window)
2641 GdkWindowImplQuartz *impl;
2643 if (GDK_WINDOW_DESTROYED (window) ||
2644 !WINDOW_IS_TOPLEVEL (window))
2647 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2649 if (GDK_WINDOW_IS_MAPPED (window))
2651 GDK_QUARTZ_ALLOC_POOL;
2653 if (impl->toplevel && ![impl->toplevel isZoomed])
2654 [impl->toplevel zoom:nil];
2656 GDK_QUARTZ_RELEASE_POOL;
2660 gdk_synthesize_window_state (window,
2662 GDK_WINDOW_STATE_MAXIMIZED);
2667 gdk_window_unmaximize (GdkWindow *window)
2669 GdkWindowImplQuartz *impl;
2671 if (GDK_WINDOW_DESTROYED (window) ||
2672 !WINDOW_IS_TOPLEVEL (window))
2675 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2677 if (GDK_WINDOW_IS_MAPPED (window))
2679 GDK_QUARTZ_ALLOC_POOL;
2681 if (impl->toplevel && [impl->toplevel isZoomed])
2682 [impl->toplevel zoom:nil];
2684 GDK_QUARTZ_RELEASE_POOL;
2688 gdk_synthesize_window_state (window,
2689 GDK_WINDOW_STATE_MAXIMIZED,
2695 gdk_window_iconify (GdkWindow *window)
2697 GdkWindowImplQuartz *impl;
2699 if (GDK_WINDOW_DESTROYED (window) ||
2700 !WINDOW_IS_TOPLEVEL (window))
2703 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2705 if (GDK_WINDOW_IS_MAPPED (window))
2707 GDK_QUARTZ_ALLOC_POOL;
2710 [impl->toplevel miniaturize:nil];
2712 GDK_QUARTZ_RELEASE_POOL;
2716 gdk_synthesize_window_state (window,
2718 GDK_WINDOW_STATE_ICONIFIED);
2723 gdk_window_deiconify (GdkWindow *window)
2725 GdkWindowImplQuartz *impl;
2727 if (GDK_WINDOW_DESTROYED (window) ||
2728 !WINDOW_IS_TOPLEVEL (window))
2731 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2733 if (GDK_WINDOW_IS_MAPPED (window))
2735 GDK_QUARTZ_ALLOC_POOL;
2738 [impl->toplevel deminiaturize:nil];
2740 GDK_QUARTZ_RELEASE_POOL;
2744 gdk_synthesize_window_state (window,
2745 GDK_WINDOW_STATE_ICONIFIED,
2750 static FullscreenSavedGeometry *
2751 get_fullscreen_geometry (GdkWindow *window)
2753 return g_object_get_data (G_OBJECT (window), FULLSCREEN_DATA);
2757 gdk_window_fullscreen (GdkWindow *window)
2759 FullscreenSavedGeometry *geometry;
2760 GdkWindowObject *private = (GdkWindowObject *) window;
2763 if (GDK_WINDOW_DESTROYED (window) ||
2764 !WINDOW_IS_TOPLEVEL (window))
2767 geometry = get_fullscreen_geometry (window);
2770 geometry = g_new (FullscreenSavedGeometry, 1);
2772 geometry->x = private->x;
2773 geometry->y = private->y;
2774 geometry->width = private->width;
2775 geometry->height = private->height;
2777 if (!gdk_window_get_decorations (window, &geometry->decor))
2778 geometry->decor = GDK_DECOR_ALL;
2780 g_object_set_data_full (G_OBJECT (window),
2781 FULLSCREEN_DATA, geometry,
2784 gdk_window_set_decorations (window, 0);
2786 frame = [[NSScreen mainScreen] frame];
2787 move_resize_window_internal (window,
2789 frame.size.width, frame.size.height);
2792 SetSystemUIMode (kUIModeAllHidden, kUIOptionAutoShowMenuBar);
2794 gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
2798 gdk_window_unfullscreen (GdkWindow *window)
2800 FullscreenSavedGeometry *geometry;
2802 if (GDK_WINDOW_DESTROYED (window) ||
2803 !WINDOW_IS_TOPLEVEL (window))
2806 geometry = get_fullscreen_geometry (window);
2809 SetSystemUIMode (kUIModeNormal, 0);
2811 move_resize_window_internal (window,
2817 gdk_window_set_decorations (window, geometry->decor);
2819 g_object_set_data (G_OBJECT (window), FULLSCREEN_DATA, NULL);
2821 gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
2826 gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
2828 GdkWindowObject *private = (GdkWindowObject *) window;
2829 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
2832 g_return_if_fail (GDK_IS_WINDOW (window));
2834 if (GDK_WINDOW_DESTROYED (window) ||
2835 !WINDOW_IS_TOPLEVEL (window))
2838 level = window_type_hint_to_level (gdk_window_get_type_hint (window));
2840 /* Adjust normal window level by one if necessary. */
2841 [impl->toplevel setLevel: level + (setting ? 1 : 0)];
2845 gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
2847 GdkWindowObject *private = (GdkWindowObject *) window;
2848 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
2851 g_return_if_fail (GDK_IS_WINDOW (window));
2853 if (GDK_WINDOW_DESTROYED (window) ||
2854 !WINDOW_IS_TOPLEVEL (window))
2857 level = window_type_hint_to_level (gdk_window_get_type_hint (window));
2859 /* Adjust normal window level by one if necessary. */
2860 [impl->toplevel setLevel: level - (setting ? 1 : 0)];
2864 gdk_window_get_group (GdkWindow *window)
2866 g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
2868 if (GDK_WINDOW_DESTROYED (window) ||
2869 !WINDOW_IS_TOPLEVEL (window))
2872 /* FIXME: Implement */
2878 gdk_window_set_group (GdkWindow *window,
2881 /* FIXME: Implement */
2885 gdk_window_foreign_new_for_display (GdkDisplay *display,
2886 GdkNativeWindow anid)
2888 /* Foreign windows aren't supported in Mac OS X */
2893 gdk_window_lookup (GdkNativeWindow anid)
2895 /* Foreign windows aren't supported in Mac OS X */
2900 gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
2902 /* Foreign windows aren't supported in Mac OS X */
2907 gdk_window_enable_synchronized_configure (GdkWindow *window)
2912 gdk_window_configure_finished (GdkWindow *window)
2917 gdk_window_destroy_notify (GdkWindow *window)
2919 check_grab_destroy (window);
2923 _gdk_windowing_window_beep (GdkWindow *window)
2925 g_return_if_fail (GDK_IS_WINDOW (window));
2927 gdk_display_beep (_gdk_display);
2931 gdk_window_set_opacity (GdkWindow *window,
2934 GdkWindowObject *private = (GdkWindowObject *) window;
2935 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
2937 g_return_if_fail (GDK_IS_WINDOW (window));
2938 g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
2940 if (GDK_WINDOW_DESTROYED (window) ||
2941 !WINDOW_IS_TOPLEVEL (window))
2946 else if (opacity > 1)
2949 [impl->toplevel setAlphaValue: opacity];
2953 _gdk_windowing_window_set_composited (GdkWindow *window, gboolean composited)
2958 _gdk_windowing_window_get_shape (GdkWindow *window)
2960 /* FIXME: implement */
2965 _gdk_windowing_window_get_input_shape (GdkWindow *window)
2967 /* FIXME: implement */
2972 gdk_window_impl_iface_init (GdkWindowImplIface *iface)
2974 iface->show = gdk_window_quartz_show;
2975 iface->hide = gdk_window_quartz_hide;
2976 iface->withdraw = gdk_window_quartz_withdraw;
2977 iface->set_events = gdk_window_quartz_set_events;
2978 iface->get_events = gdk_window_quartz_get_events;
2979 iface->raise = gdk_window_quartz_raise;
2980 iface->lower = gdk_window_quartz_lower;
2981 iface->restack_toplevel = gdk_window_quartz_restack_toplevel;
2982 iface->move_resize = gdk_window_quartz_move_resize;
2983 iface->set_background = gdk_window_quartz_set_background;
2984 iface->reparent = gdk_window_quartz_reparent;
2985 iface->set_device_cursor = gdk_window_quartz_set_device_cursor;
2986 iface->get_geometry = gdk_window_quartz_get_geometry;
2987 iface->get_root_coords = gdk_window_quartz_get_root_coords;
2988 iface->get_device_state = gdk_window_quartz_get_device_state;
2989 iface->shape_combine_region = gdk_window_quartz_shape_combine_region;
2990 iface->input_shape_combine_region = gdk_window_quartz_input_shape_combine_region;
2991 iface->set_static_gravities = gdk_window_quartz_set_static_gravities;
2992 iface->queue_antiexpose = _gdk_quartz_window_queue_antiexpose;
2993 iface->translate = _gdk_quartz_window_translate;
2994 iface->destroy = _gdk_quartz_window_destroy;
2995 iface->resize_cairo_surface = gdk_window_quartz_resize_cairo_surface;
3000 gdk_root_window_impl_quartz_get_context (GdkDrawable *drawable,
3003 GdkDrawableImplQuartz *drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
3004 CGColorSpaceRef colorspace;
3005 CGContextRef cg_context;
3007 if (GDK_WINDOW_DESTROYED (drawable_impl->wrapper))
3010 /* We do not have the notion of a root window on OS X. We fake this
3011 * by creating a 1x1 bitmap and return a context to that.
3013 colorspace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB);
3014 cg_context = CGBitmapContextCreate (NULL,
3015 1, 1, 8, 4, colorspace,
3016 kCGImageAlphaPremultipliedLast);
3017 CGColorSpaceRelease (colorspace);
3023 gdk_root_window_impl_quartz_release_context (GdkDrawable *drawable,
3024 CGContextRef cg_context)
3026 CGContextRelease (cg_context);
3030 gdk_root_window_impl_quartz_class_init (GdkRootWindowImplQuartzClass *klass)
3032 GdkDrawableImplQuartzClass *drawable_quartz_class = GDK_DRAWABLE_IMPL_QUARTZ_CLASS (klass);
3034 root_window_parent_class = g_type_class_peek_parent (klass);
3036 drawable_quartz_class->get_context = gdk_root_window_impl_quartz_get_context;
3037 drawable_quartz_class->release_context = gdk_root_window_impl_quartz_release_context;
3041 gdk_root_window_impl_quartz_init (GdkRootWindowImplQuartz *impl)
3046 _gdk_root_window_impl_quartz_get_type (void)
3048 static GType object_type = 0;
3052 const GTypeInfo object_info =
3054 sizeof (GdkRootWindowImplQuartzClass),
3055 (GBaseInitFunc) NULL,
3056 (GBaseFinalizeFunc) NULL,
3057 (GClassInitFunc) gdk_root_window_impl_quartz_class_init,
3058 NULL, /* class_finalize */
3059 NULL, /* class_data */
3060 sizeof (GdkRootWindowImplQuartz),
3061 0, /* n_preallocs */
3062 (GInstanceInitFunc) gdk_root_window_impl_quartz_init,
3065 object_type = g_type_register_static (GDK_TYPE_WINDOW_IMPL_QUARTZ,
3066 "GdkRootWindowQuartz",