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 "gdkwindowimpl.h"
27 #include "gdkprivate-quartz.h"
28 #include "gdkscreen-quartz.h"
29 #include "gdkinputprivate.h"
31 static gpointer parent_class;
33 static GSList *update_nswindows;
34 static gboolean in_process_all_updates = FALSE;
36 static GSList *main_window_stack;
38 #define FULLSCREEN_DATA "fullscreen-data"
44 GdkWMDecoration decor;
45 } FullscreenSavedGeometry;
48 static void update_toplevel_order (void);
49 static void clear_toplevel_order (void);
51 static FullscreenSavedGeometry *get_fullscreen_geometry (GdkWindow *window);
53 #define WINDOW_IS_TOPLEVEL(window) \
54 (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
55 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
56 GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
58 static void gdk_window_impl_iface_init (GdkWindowImplIface *iface);
61 gdk_quartz_window_get_nsview (GdkWindow *window)
63 GdkWindowObject *private = (GdkWindowObject *)window;
65 if (GDK_WINDOW_DESTROYED (window))
68 return ((GdkWindowImplQuartz *)private->impl)->view;
72 gdk_quartz_window_get_nswindow (GdkWindow *window)
74 GdkWindowObject *private = (GdkWindowObject *)window;
76 if (GDK_WINDOW_DESTROYED (window))
79 return ((GdkWindowImplQuartz *)private->impl)->toplevel;
83 gdk_window_impl_quartz_get_context (GdkDrawable *drawable,
86 GdkDrawableImplQuartz *drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable);
87 GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (drawable);
88 CGContextRef cg_context;
90 if (GDK_WINDOW_DESTROYED (drawable_impl->wrapper))
93 /* Lock focus when not called as part of a drawRect call. This
94 * is needed when called from outside "real" expose events, for
95 * example for synthesized expose events when realizing windows
96 * and for widgets that send fake expose events like the arrow
97 * buttons in spinbuttons or the position marker in rulers.
99 if (window_impl->in_paint_rect_count == 0)
101 if (![window_impl->view lockFocusIfCanDraw])
105 cg_context = [[NSGraphicsContext currentContext] graphicsPort];
106 CGContextSaveGState (cg_context);
107 CGContextSetAllowsAntialiasing (cg_context, antialias);
109 /* We'll emulate the clipping caused by double buffering here */
110 if (window_impl->begin_paint_count != 0)
117 gdk_region_get_rectangles (window_impl->paint_clip_region,
123 cg_rects = g_new (CGRect, n_rects);
125 for (i = 0; i < n_rects; i++)
127 cg_rects[i].origin.x = rects[i].x;
128 cg_rects[i].origin.y = rects[i].y;
129 cg_rects[i].size.width = rects[i].width;
130 cg_rects[i].size.height = rects[i].height;
133 CGContextClipToRects (cg_context, cg_rects, n_rects);
136 if (cg_rects != &rect)
144 check_grab_unmap (GdkWindow *window)
146 GdkDisplay *display = gdk_drawable_get_display (window);
148 _gdk_display_end_pointer_grab (display, 0, window, TRUE);
150 if (display->keyboard_grab.window)
152 GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
153 GdkWindowObject *tmp = GDK_WINDOW_OBJECT (display->keyboard_grab.window);
155 while (tmp && tmp != private)
159 _gdk_display_unset_has_keyboard_grab (display, TRUE);
164 check_grab_destroy (GdkWindow *window)
166 GdkDisplay *display = gdk_drawable_get_display (window);
167 GdkPointerGrabInfo *grab;
169 /* Make sure there is no lasting grab in this native window */
170 grab = _gdk_display_get_last_pointer_grab (display);
171 if (grab && grab->native_window == window)
173 /* Serials are always 0 in quartz, but for clarity: */
174 grab->serial_end = grab->serial_start;
175 grab->implicit_ungrab = TRUE;
178 if (window == display->keyboard_grab.native_window &&
179 display->keyboard_grab.window != NULL)
180 _gdk_display_unset_has_keyboard_grab (display, TRUE);
184 gdk_window_impl_quartz_finalize (GObject *object)
186 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (object);
188 check_grab_destroy (GDK_DRAWABLE_IMPL_QUARTZ (object)->wrapper);
190 if (impl->paint_clip_region)
191 gdk_region_destroy (impl->paint_clip_region);
193 if (impl->transient_for)
194 g_object_unref (impl->transient_for);
196 G_OBJECT_CLASS (parent_class)->finalize (object);
200 gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass)
202 GObjectClass *object_class = G_OBJECT_CLASS (klass);
203 GdkDrawableImplQuartzClass *drawable_quartz_class = GDK_DRAWABLE_IMPL_QUARTZ_CLASS (klass);
205 parent_class = g_type_class_peek_parent (klass);
207 object_class->finalize = gdk_window_impl_quartz_finalize;
209 drawable_quartz_class->get_context = gdk_window_impl_quartz_get_context;
213 gdk_window_impl_quartz_init (GdkWindowImplQuartz *impl)
215 impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
219 gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable,
221 const GdkRegion *region)
223 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
224 GdkWindowObject *private = (GdkWindowObject*)window;
226 GdkRectangle *rects = NULL;
227 GdkPixmap *bg_pixmap;
228 GdkRegion *clipped_and_offset_region;
229 gboolean free_clipped_and_offset_region = TRUE;
231 bg_pixmap = private->bg_pixmap;
233 clipped_and_offset_region = gdk_region_copy (region);
235 gdk_region_intersect (clipped_and_offset_region,
236 private->clip_region_with_children);
237 gdk_region_offset (clipped_and_offset_region,
238 private->abs_x, private->abs_y);
240 if (impl->begin_paint_count == 0)
242 impl->paint_clip_region = clipped_and_offset_region;
243 free_clipped_and_offset_region = FALSE;
246 gdk_region_union (impl->paint_clip_region, clipped_and_offset_region);
248 impl->begin_paint_count++;
250 if (bg_pixmap == GDK_NO_BG)
253 gdk_region_get_rectangles (clipped_and_offset_region, &rects, &n_rects);
255 if (bg_pixmap == NULL)
257 CGContextRef cg_context;
261 cg_context = gdk_quartz_drawable_get_context (GDK_DRAWABLE (impl), FALSE);
262 _gdk_quartz_colormap_get_rgba_from_pixel (gdk_drawable_get_colormap (window),
263 private->bg_color.pixel,
265 CGContextSetRGBFillColor (cg_context, r, g, b, a);
267 for (i = 0; i < n_rects; i++)
269 CGContextFillRect (cg_context,
270 CGRectMake (rects[i].x, rects[i].y,
271 rects[i].width, rects[i].height));
274 gdk_quartz_drawable_release_context (GDK_DRAWABLE (impl), cg_context);
279 int x_offset, y_offset;
283 x_offset = y_offset = 0;
285 while (window && bg_pixmap == GDK_PARENT_RELATIVE_BG)
287 /* If this window should have the same background as the parent,
288 * fetch the parent. (And if the same goes for the parent, fetch
289 * the grandparent, etc.)
291 x_offset += ((GdkWindowObject *) window)->x;
292 y_offset += ((GdkWindowObject *) window)->y;
293 window = GDK_WINDOW (((GdkWindowObject *) window)->parent);
294 bg_pixmap = ((GdkWindowObject *) window)->bg_pixmap;
297 if (bg_pixmap == NULL || bg_pixmap == GDK_NO_BG || bg_pixmap == GDK_PARENT_RELATIVE_BG)
299 /* Parent relative background but the parent doesn't have a
305 /* Note: There should be a CG API to draw tiled images, we might
306 * want to look into that for this.
308 gc = gdk_gc_new (GDK_DRAWABLE (impl));
310 gdk_drawable_get_size (GDK_DRAWABLE (bg_pixmap), &width, &height);
313 while (x < (rects[0].x + rects[0].width))
315 if (x + width >= rects[0].x)
318 while (y < (rects[0].y + rects[0].height))
320 if (y + height >= rects[0].y)
321 gdk_draw_drawable (GDK_DRAWABLE (impl), gc, bg_pixmap, 0, 0, x, y, width, height);
333 if (free_clipped_and_offset_region)
334 gdk_region_destroy (clipped_and_offset_region);
339 gdk_window_impl_quartz_end_paint (GdkPaintable *paintable)
341 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
343 impl->begin_paint_count--;
345 if (impl->begin_paint_count == 0)
347 gdk_region_destroy (impl->paint_clip_region);
348 impl->paint_clip_region = NULL;
353 _gdk_quartz_window_set_needs_display_in_rect (GdkWindow *window,
356 GdkWindowObject *private;
357 GdkWindowImplQuartz *impl;
359 private = GDK_WINDOW_OBJECT (window);
360 impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
362 if (!impl->needs_display_region)
363 impl->needs_display_region = gdk_region_new ();
365 gdk_region_union_with_rect (impl->needs_display_region, rect);
367 [impl->view setNeedsDisplayInRect:NSMakeRect (rect->x, rect->y,
368 rect->width, rect->height)];
373 _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
379 /* Make sure to only flush each toplevel at most once if we're called
380 * from process_all_updates.
382 if (in_process_all_updates)
386 toplevel = gdk_window_get_toplevel (window);
389 GdkWindowObject *toplevel_private;
390 GdkWindowImplQuartz *toplevel_impl;
393 toplevel_private = (GdkWindowObject *)toplevel;
394 toplevel_impl = (GdkWindowImplQuartz *)toplevel_private->impl;
395 nswindow = toplevel_impl->toplevel;
397 /* In theory, we could skip the flush disabling, since we only
400 if (nswindow && ![nswindow isFlushWindowDisabled])
403 [nswindow disableFlushWindow];
404 update_nswindows = g_slist_prepend (update_nswindows, nswindow);
409 gdk_region_get_rectangles (region, &rects, &n_rects);
411 for (i = 0; i < n_rects; i++)
412 _gdk_quartz_window_set_needs_display_in_rect (window, &rects[i]);
416 /* NOTE: I'm not sure if we should displayIfNeeded here. It slows down a
417 * lot (since it triggers the beam syncing) and things seem to work
423 _gdk_windowing_before_process_all_updates (void)
425 in_process_all_updates = TRUE;
427 NSDisableScreenUpdates ();
431 _gdk_windowing_after_process_all_updates (void)
433 GSList *old_update_nswindows = update_nswindows;
434 GSList *tmp_list = update_nswindows;
436 update_nswindows = NULL;
440 NSWindow *nswindow = tmp_list->data;
442 [[nswindow contentView] displayIfNeeded];
444 _gdk_quartz_drawable_flush (NULL);
446 [nswindow enableFlushWindow];
447 [nswindow flushWindow];
450 tmp_list = tmp_list->next;
453 g_slist_free (old_update_nswindows);
455 in_process_all_updates = FALSE;
457 NSEnableScreenUpdates ();
461 gdk_window_impl_quartz_paintable_init (GdkPaintableIface *iface)
463 iface->begin_paint_region = gdk_window_impl_quartz_begin_paint_region;
464 iface->end_paint = gdk_window_impl_quartz_end_paint;
468 _gdk_window_impl_quartz_get_type (void)
470 static GType object_type = 0;
474 const GTypeInfo object_info =
476 sizeof (GdkWindowImplQuartzClass),
477 (GBaseInitFunc) NULL,
478 (GBaseFinalizeFunc) NULL,
479 (GClassInitFunc) gdk_window_impl_quartz_class_init,
480 NULL, /* class_finalize */
481 NULL, /* class_data */
482 sizeof (GdkWindowImplQuartz),
484 (GInstanceInitFunc) gdk_window_impl_quartz_init,
487 const GInterfaceInfo paintable_info =
489 (GInterfaceInitFunc) gdk_window_impl_quartz_paintable_init,
494 const GInterfaceInfo window_impl_info =
496 (GInterfaceInitFunc) gdk_window_impl_iface_init,
501 object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_QUARTZ,
502 "GdkWindowImplQuartz",
504 g_type_add_interface_static (object_type,
507 g_type_add_interface_static (object_type,
508 GDK_TYPE_WINDOW_IMPL,
516 _gdk_window_impl_get_type (void)
518 return _gdk_window_impl_quartz_get_type ();
522 get_default_title (void)
526 title = g_get_application_name ();
528 title = g_get_prgname ();
534 get_ancestor_coordinates_from_child (GdkWindow *child_window,
537 GdkWindow *ancestor_window,
541 GdkWindowObject *child_private = GDK_WINDOW_OBJECT (child_window);
542 GdkWindowObject *ancestor_private = GDK_WINDOW_OBJECT (ancestor_window);
544 while (child_private != ancestor_private)
546 child_x += child_private->x;
547 child_y += child_private->y;
549 child_private = child_private->parent;
552 *ancestor_x = child_x;
553 *ancestor_y = child_y;
557 _gdk_quartz_window_debug_highlight (GdkWindow *window, gint number)
559 GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
564 static NSWindow *debug_window[10];
565 static NSRect old_rect[10];
569 g_return_if_fail (number >= 0 && number <= 9);
571 if (window == _gdk_root)
576 if (debug_window[number])
577 [debug_window[number] close];
578 debug_window[number] = NULL;
583 toplevel = gdk_window_get_toplevel (window);
584 get_ancestor_coordinates_from_child (window, 0, 0, toplevel, &x, &y);
586 gdk_window_get_origin (toplevel, &tx, &ty);
590 _gdk_quartz_window_gdk_xy_to_xy (x, y + private->height,
593 rect = NSMakeRect (gx, gy, private->width, private->height);
595 if (debug_window[number] && NSEqualRects (rect, old_rect[number]))
598 old_rect[number] = rect;
600 if (debug_window[number])
601 [debug_window[number] close];
603 debug_window[number] = [[NSWindow alloc] initWithContentRect:rect
604 styleMask:NSBorderlessWindowMask
605 backing:NSBackingStoreBuffered
611 color = [NSColor redColor];
614 color = [NSColor blueColor];
617 color = [NSColor greenColor];
620 color = [NSColor yellowColor];
623 color = [NSColor brownColor];
626 color = [NSColor purpleColor];
629 color = [NSColor blackColor];
633 [debug_window[number] setBackgroundColor:color];
634 [debug_window[number] setAlphaValue:0.4];
635 [debug_window[number] setOpaque:NO];
636 [debug_window[number] setReleasedWhenClosed:YES];
637 [debug_window[number] setIgnoresMouseEvents:YES];
638 [debug_window[number] setLevel:NSFloatingWindowLevel];
640 [debug_window[number] orderFront:nil];
644 _gdk_quartz_window_is_ancestor (GdkWindow *ancestor,
647 if (ancestor == NULL || window == NULL)
650 return (gdk_window_get_parent (window) == ancestor ||
651 _gdk_quartz_window_is_ancestor (ancestor,
652 gdk_window_get_parent (window)));
656 /* See notes on top of gdkscreen-quartz.c */
658 _gdk_quartz_window_gdk_xy_to_xy (gint gdk_x,
663 GdkScreenQuartz *screen_quartz = GDK_SCREEN_QUARTZ (_gdk_screen);
666 *ns_y = screen_quartz->height - gdk_y + screen_quartz->min_y;
669 *ns_x = gdk_x + screen_quartz->min_x;
673 _gdk_quartz_window_xy_to_gdk_xy (gint ns_x,
678 GdkScreenQuartz *screen_quartz = GDK_SCREEN_QUARTZ (_gdk_screen);
681 *gdk_y = screen_quartz->height - ns_y + screen_quartz->min_y;
684 *gdk_x = ns_x - screen_quartz->min_x;
688 _gdk_quartz_window_nspoint_to_gdk_xy (NSPoint point,
692 _gdk_quartz_window_xy_to_gdk_xy (point.x, point.y,
697 find_child_window_helper (GdkWindow *window,
703 GdkWindowImplQuartz *impl;
706 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
708 if (window == _gdk_root)
709 update_toplevel_order ();
711 for (l = impl->sorted_children; l; l = l->next)
713 GdkWindowObject *child_private = l->data;
714 GdkWindowImplQuartz *child_impl = GDK_WINDOW_IMPL_QUARTZ (child_private->impl);
717 if (!GDK_WINDOW_IS_MAPPED (child_private))
720 temp_x = x_offset + child_private->x;
721 temp_y = y_offset + child_private->y;
723 /* Special-case the root window. We have to include the title
724 * bar in the checks, otherwise the window below the title bar
725 * will be found i.e. events punch through. (If we can find a
726 * better way to deal with the events in gdkevents-quartz, this
727 * might not be needed.)
729 if (window == _gdk_root)
731 NSRect frame = NSMakeRect (0, 0, 100, 100);
736 mask = [child_impl->toplevel styleMask];
738 /* Get the title bar height. */
739 content = [NSWindow contentRectForFrameRect:frame
741 titlebar_height = frame.size.height - content.size.height;
743 if (titlebar_height > 0 &&
744 x >= temp_x && y >= temp_y - titlebar_height &&
745 x < temp_x + child_private->width && y < temp_y)
747 /* The root means "unknown" i.e. a window not managed by
750 return (GdkWindow *)_gdk_root;
754 if (x >= temp_x && y >= temp_y &&
755 x < temp_x + child_private->width && y < temp_y + child_private->height)
757 /* Look for child windows. */
758 return find_child_window_helper (l->data,
767 /* Given a GdkWindow and coordinates relative to it, returns the
768 * innermost subwindow that contains the point. If the coordinates are
769 * outside the passed in window, NULL is returned.
772 _gdk_quartz_window_find_child (GdkWindow *window,
776 GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
778 if (x >= 0 && y >= 0 && x < private->width && y < private->height)
779 return find_child_window_helper (window, x, y, 0, 0);
786 generate_motion_event (GdkWindow *window)
789 NSPoint screen_point;
792 GdkWindowObject *private;
794 gint x, y, x_root, y_root;
797 GdkWindow *pointer_window;
799 event = gdk_event_new (GDK_MOTION_NOTIFY);
800 event->any.window = NULL;
801 event->any.send_event = TRUE;
803 private = (GdkWindowObject *)window;
804 nswindow = ((GdkWindowImplQuartz *)private->impl)->toplevel;
805 view = (GdkQuartzView *)[nswindow contentView];
807 screen_point = [NSEvent mouseLocation];
809 _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, &x_root, &y_root);
811 point = [nswindow convertScreenToBase:screen_point];
814 y = private->height - point.y;
816 pointer_window = _gdk_window_find_descendant_at (window, x, y,
819 event->any.type = GDK_MOTION_NOTIFY;
820 event->motion.window = window;
821 event->motion.time = GDK_CURRENT_TIME;
824 event->motion.x_root = x_root;
825 event->motion.y_root = y_root;
826 /* FIXME event->axes */
827 event->motion.state = 0;
828 event->motion.is_hint = FALSE;
829 event->motion.device = _gdk_display->core_pointer;
831 if (event->any.window)
832 g_object_ref (event->any.window);
834 node = _gdk_event_queue_append (gdk_display_get_default (), event);
835 _gdk_windowing_got_event (gdk_display_get_default (), node, event, 0);
839 _gdk_quartz_window_did_become_main (GdkWindow *window)
841 main_window_stack = g_slist_remove (main_window_stack, window);
843 if (GDK_WINDOW_OBJECT (window)->window_type != GDK_WINDOW_TEMP)
845 main_window_stack = g_slist_prepend (main_window_stack, window);
847 /* We just became the active window, send a motion-notify
848 * event so things like highlights get set up correctly.
849 * This motion-notify is sent to the key window.
851 generate_motion_event (window);
854 clear_toplevel_order ();
858 _gdk_quartz_window_did_resign_main (GdkWindow *window)
860 GdkWindow *new_window = NULL;
862 if (main_window_stack)
863 new_window = main_window_stack->data;
868 toplevels = gdk_window_get_toplevels ();
870 new_window = toplevels->data;
871 g_list_free (toplevels);
875 new_window != window &&
876 GDK_WINDOW_IS_MAPPED (new_window) &&
877 GDK_WINDOW_OBJECT (new_window)->window_type != GDK_WINDOW_TEMP)
879 GdkWindowObject *private = (GdkWindowObject *) new_window;
880 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
882 [impl->toplevel makeKeyAndOrderFront:impl->toplevel];
885 clear_toplevel_order ();
889 get_nsscreen_for_point (gint x, gint y)
893 NSScreen *screen = NULL;
895 GDK_QUARTZ_ALLOC_POOL;
897 screens = [NSScreen screens];
899 for (i = 0; i < [screens count]; i++)
901 NSRect rect = [[screens objectAtIndex:i] frame];
903 if (x >= rect.origin.x && x <= rect.origin.x + rect.size.width &&
904 y >= rect.origin.y && y <= rect.origin.y + rect.size.height)
906 screen = [screens objectAtIndex:i];
911 GDK_QUARTZ_RELEASE_POOL;
917 _gdk_window_impl_new (GdkWindow *window,
918 GdkWindow *real_parent,
921 GdkEventMask event_mask,
922 GdkWindowAttr *attributes,
923 gint attributes_mask)
925 GdkWindowObject *private;
926 GdkWindowImplQuartz *impl;
927 GdkDrawableImplQuartz *draw_impl;
928 GdkWindowImplQuartz *parent_impl;
930 GDK_QUARTZ_ALLOC_POOL;
932 private = (GdkWindowObject *)window;
934 impl = g_object_new (_gdk_window_impl_get_type (), NULL);
935 private->impl = (GdkDrawable *)impl;
936 draw_impl = GDK_DRAWABLE_IMPL_QUARTZ (impl);
937 draw_impl->wrapper = GDK_DRAWABLE (window);
939 parent_impl = GDK_WINDOW_IMPL_QUARTZ (private->parent->impl);
941 switch (private->window_type)
943 case GDK_WINDOW_TOPLEVEL:
944 case GDK_WINDOW_DIALOG:
945 case GDK_WINDOW_TEMP:
946 if (GDK_WINDOW_TYPE (private->parent) != GDK_WINDOW_ROOT)
948 /* The common code warns for this case */
949 parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (_gdk_root)->impl);
953 if (!private->input_only)
955 if (attributes_mask & GDK_WA_COLORMAP)
957 draw_impl->colormap = attributes->colormap;
958 g_object_ref (attributes->colormap);
962 if (visual == gdk_screen_get_system_visual (_gdk_screen))
964 draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
965 g_object_ref (draw_impl->colormap);
967 else if (visual == gdk_screen_get_rgba_visual (_gdk_screen))
969 draw_impl->colormap = gdk_screen_get_rgba_colormap (_gdk_screen);
970 g_object_ref (draw_impl->colormap);
974 draw_impl->colormap = gdk_colormap_new (visual, FALSE);
980 draw_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
981 g_object_ref (draw_impl->colormap);
984 /* Maintain the z-ordered list of children. */
985 if (private->parent != (GdkWindowObject *)_gdk_root)
986 parent_impl->sorted_children = g_list_prepend (parent_impl->sorted_children, window);
988 clear_toplevel_order ();
990 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
991 (attributes->cursor) :
994 switch (attributes->window_type)
996 case GDK_WINDOW_TOPLEVEL:
997 case GDK_WINDOW_DIALOG:
998 case GDK_WINDOW_TEMP:
1002 NSRect content_rect;
1003 NSUInteger style_mask;
1007 /* initWithContentRect will place on the mainScreen by default.
1008 * We want to select the screen to place on ourselves. We need
1009 * to find the screen the window will be on and correct the
1010 * content_rect coordinates to be relative to that screen.
1012 _gdk_quartz_window_gdk_xy_to_xy (private->x, private->y, &nx, &ny);
1014 screen = get_nsscreen_for_point (nx, ny);
1015 screen_rect = [screen frame];
1016 nx -= screen_rect.origin.x;
1017 ny -= screen_rect.origin.y;
1019 content_rect = NSMakeRect (nx, ny - private->height,
1023 if (attributes->window_type == GDK_WINDOW_TEMP ||
1024 attributes->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN)
1026 style_mask = NSBorderlessWindowMask;
1030 style_mask = (NSTitledWindowMask |
1031 NSClosableWindowMask |
1032 NSMiniaturizableWindowMask |
1033 NSResizableWindowMask);
1036 impl->toplevel = [[GdkQuartzWindow alloc] initWithContentRect:content_rect
1037 styleMask:style_mask
1038 backing:NSBackingStoreBuffered
1042 if (attributes_mask & GDK_WA_TITLE)
1043 title = attributes->title;
1045 title = get_default_title ();
1047 gdk_window_set_title (window, title);
1049 if (draw_impl->colormap == gdk_screen_get_rgba_colormap (_gdk_screen))
1051 [impl->toplevel setOpaque:NO];
1052 [impl->toplevel setBackgroundColor:[NSColor clearColor]];
1055 content_rect.origin.x = 0;
1056 content_rect.origin.y = 0;
1058 impl->view = [[GdkQuartzView alloc] initWithFrame:content_rect];
1059 [impl->view setGdkWindow:window];
1060 [impl->toplevel setContentView:impl->view];
1061 [impl->view release];
1065 case GDK_WINDOW_CHILD:
1067 GdkWindowImplQuartz *parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (private->parent)->impl);
1069 if (!private->input_only)
1071 NSRect frame_rect = NSMakeRect (private->x + private->parent->abs_x,
1072 private->y + private->parent->abs_y,
1076 impl->view = [[GdkQuartzView alloc] initWithFrame:frame_rect];
1078 [impl->view setGdkWindow:window];
1080 /* GdkWindows should be hidden by default */
1081 [impl->view setHidden:YES];
1082 [parent_impl->view addSubview:impl->view];
1083 [impl->view release];
1089 g_assert_not_reached ();
1092 GDK_QUARTZ_RELEASE_POOL;
1094 if (attributes_mask & GDK_WA_TYPE_HINT)
1095 gdk_window_set_type_hint (window, attributes->type_hint);
1099 _gdk_quartz_window_update_position (GdkWindow *window)
1102 NSRect content_rect;
1103 GdkWindowObject *private = (GdkWindowObject *)window;
1104 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1106 GDK_QUARTZ_ALLOC_POOL;
1108 frame_rect = [impl->toplevel frame];
1109 content_rect = [impl->toplevel contentRectForFrameRect:frame_rect];
1111 _gdk_quartz_window_xy_to_gdk_xy (content_rect.origin.x,
1112 content_rect.origin.y + content_rect.size.height,
1113 &private->x, &private->y);
1116 GDK_QUARTZ_RELEASE_POOL;
1120 _gdk_windowing_update_window_sizes (GdkScreen *screen)
1122 GList *windows, *list;
1123 GdkWindowObject *private = (GdkWindowObject *)_gdk_root;
1125 /* The size of the root window is so that it can contain all
1126 * monitors attached to this machine. The monitors are laid out
1127 * within this root window. We calculate the size of the root window
1128 * and the positions of the different monitors in gdkscreen-quartz.c.
1130 * This data is updated when the monitor configuration is changed.
1136 private->width = gdk_screen_get_width (screen);
1137 private->height = gdk_screen_get_height (screen);
1139 windows = gdk_screen_get_toplevel_windows (screen);
1141 for (list = windows; list; list = list->next)
1142 _gdk_quartz_window_update_position (list->data);
1144 g_list_free (windows);
1148 _gdk_windowing_window_init (void)
1150 GdkWindowObject *private;
1151 GdkWindowImplQuartz *impl;
1152 GdkDrawableImplQuartz *drawable_impl;
1154 g_assert (_gdk_root == NULL);
1156 _gdk_root = g_object_new (GDK_TYPE_WINDOW, NULL);
1158 private = (GdkWindowObject *)_gdk_root;
1159 private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
1160 private->impl_window = private;
1162 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (_gdk_root)->impl);
1164 _gdk_windowing_update_window_sizes (_gdk_screen);
1166 private->state = 0; /* We don't want GDK_WINDOW_STATE_WITHDRAWN here */
1167 private->window_type = GDK_WINDOW_ROOT;
1168 private->depth = 24;
1169 private->viewable = TRUE;
1171 drawable_impl = GDK_DRAWABLE_IMPL_QUARTZ (private->impl);
1173 drawable_impl->wrapper = GDK_DRAWABLE (private);
1174 drawable_impl->colormap = gdk_screen_get_system_colormap (_gdk_screen);
1175 g_object_ref (drawable_impl->colormap);
1179 _gdk_quartz_window_destroy (GdkWindow *window,
1181 gboolean foreign_destroy)
1183 GdkWindowObject *private;
1184 GdkWindowImplQuartz *impl;
1185 GdkWindowObject *parent;
1187 private = GDK_WINDOW_OBJECT (window);
1188 impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1190 main_window_stack = g_slist_remove (main_window_stack, window);
1192 g_list_free (impl->sorted_children);
1193 impl->sorted_children = NULL;
1195 parent = private->parent;
1198 GdkWindowImplQuartz *parent_impl = GDK_WINDOW_IMPL_QUARTZ (parent->impl);
1200 parent_impl->sorted_children = g_list_remove (parent_impl->sorted_children, window);
1203 _gdk_quartz_drawable_finish (GDK_DRAWABLE (impl));
1205 if (!recursing && !foreign_destroy)
1207 GDK_QUARTZ_ALLOC_POOL;
1210 [impl->toplevel close];
1211 else if (impl->view)
1212 [impl->view removeFromSuperview];
1214 GDK_QUARTZ_RELEASE_POOL;
1219 _gdk_windowing_window_destroy_foreign (GdkWindow *window)
1221 /* Foreign windows aren't supported in OSX. */
1224 /* FIXME: This might be possible to simplify with client-side windows. Also
1225 * note that already_mapped is not used yet, see the x11 backend.
1228 gdk_window_quartz_show (GdkWindow *window, gboolean already_mapped)
1230 GdkWindowObject *private = (GdkWindowObject *)window;
1231 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1232 gboolean focus_on_map;
1234 GDK_QUARTZ_ALLOC_POOL;
1236 if (!GDK_WINDOW_IS_MAPPED (window))
1237 focus_on_map = private->focus_on_map;
1239 focus_on_map = TRUE;
1245 make_key = (private->accept_focus && focus_on_map &&
1246 private->window_type != GDK_WINDOW_TEMP);
1248 [(GdkQuartzWindow*)impl->toplevel showAndMakeKey:make_key];
1249 clear_toplevel_order ();
1251 _gdk_quartz_events_send_map_event (window);
1255 [impl->view setHidden:NO];
1258 [impl->view setNeedsDisplay:YES];
1260 gdk_synthesize_window_state (window, GDK_WINDOW_STATE_WITHDRAWN, 0);
1262 if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
1263 gdk_window_maximize (window);
1265 if (private->state & GDK_WINDOW_STATE_ICONIFIED)
1266 gdk_window_iconify (window);
1268 if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
1269 _gdk_quartz_window_attach_to_parent (window);
1271 GDK_QUARTZ_RELEASE_POOL;
1274 /* Temporarily unsets the parent window, if the window is a
1278 _gdk_quartz_window_detach_from_parent (GdkWindow *window)
1280 GdkWindowImplQuartz *impl;
1282 g_return_if_fail (GDK_IS_WINDOW (window));
1284 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1286 g_return_if_fail (impl->toplevel != NULL);
1288 if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
1290 GdkWindowImplQuartz *parent_impl;
1292 parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (impl->transient_for)->impl);
1293 [parent_impl->toplevel removeChildWindow:impl->toplevel];
1294 clear_toplevel_order ();
1298 /* Re-sets the parent window, if the window is a transient. */
1300 _gdk_quartz_window_attach_to_parent (GdkWindow *window)
1302 GdkWindowImplQuartz *impl;
1304 g_return_if_fail (GDK_IS_WINDOW (window));
1306 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1308 g_return_if_fail (impl->toplevel != NULL);
1310 if (impl->transient_for && !GDK_WINDOW_DESTROYED (impl->transient_for))
1312 GdkWindowImplQuartz *parent_impl;
1314 parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (impl->transient_for)->impl);
1315 [parent_impl->toplevel addChildWindow:impl->toplevel ordered:NSWindowAbove];
1316 clear_toplevel_order ();
1321 gdk_window_quartz_hide (GdkWindow *window)
1323 GdkWindowObject *private = (GdkWindowObject *)window;
1324 GdkWindowImplQuartz *impl;
1326 /* Make sure we're not stuck in fullscreen mode. */
1327 if (get_fullscreen_geometry (window))
1328 SetSystemUIMode (kUIModeNormal, 0);
1330 check_grab_unmap (window);
1332 _gdk_window_clear_update_area (window);
1334 impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1338 /* Update main window. */
1339 main_window_stack = g_slist_remove (main_window_stack, window);
1340 if ([NSApp mainWindow] == impl->toplevel)
1341 _gdk_quartz_window_did_resign_main (window);
1343 if (impl->transient_for)
1344 _gdk_quartz_window_detach_from_parent (window);
1346 [(GdkQuartzWindow*)impl->toplevel hide];
1348 else if (impl->view)
1350 [impl->view setHidden:YES];
1355 gdk_window_quartz_withdraw (GdkWindow *window)
1357 gdk_window_hide (window);
1361 move_resize_window_internal (GdkWindow *window,
1367 GdkWindowObject *private = (GdkWindowObject *)window;
1368 GdkWindowImplQuartz *impl;
1369 GdkRectangle old_visible;
1370 GdkRectangle new_visible;
1371 GdkRectangle scroll_rect;
1372 GdkRegion *old_region;
1373 GdkRegion *expose_region;
1376 if (GDK_WINDOW_DESTROYED (window))
1379 impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1381 if ((x == -1 || (x == private->x)) &&
1382 (y == -1 || (y == private->y)) &&
1383 (width == -1 || (width == private->width)) &&
1384 (height == -1 || (height == private->height)))
1389 if (!impl->toplevel)
1391 /* The previously visible area of this window in a coordinate
1392 * system rooted at the origin of this window.
1394 old_visible.x = -private->x;
1395 old_visible.y = -private->y;
1397 gdk_window_get_size (GDK_DRAWABLE (private->parent),
1399 &old_visible.height);
1404 delta.width = x - private->x;
1414 delta.height = y - private->y;
1423 private->width = width;
1426 private->height = height;
1428 GDK_QUARTZ_ALLOC_POOL;
1432 NSRect content_rect;
1436 _gdk_quartz_window_gdk_xy_to_xy (private->x, private->y + private->height,
1439 content_rect = NSMakeRect (gx, gy, private->width, private->height);
1441 frame_rect = [impl->toplevel frameRectForContentRect:content_rect];
1442 [impl->toplevel setFrame:frame_rect display:YES];
1446 if (!private->input_only)
1450 nsrect = NSMakeRect (private->x, private->y, private->width, private->height);
1452 /* The newly visible area of this window in a coordinate
1453 * system rooted at the origin of this window.
1455 new_visible.x = -private->x;
1456 new_visible.y = -private->y;
1457 new_visible.width = old_visible.width; /* parent has not changed size */
1458 new_visible.height = old_visible.height; /* parent has not changed size */
1460 expose_region = gdk_region_rectangle (&new_visible);
1461 old_region = gdk_region_rectangle (&old_visible);
1462 gdk_region_subtract (expose_region, old_region);
1464 /* Determine what (if any) part of the previously visible
1465 * part of the window can be copied without a redraw
1467 scroll_rect = old_visible;
1468 scroll_rect.x -= delta.width;
1469 scroll_rect.y -= delta.height;
1470 gdk_rectangle_intersect (&scroll_rect, &old_visible, &scroll_rect);
1472 if (!gdk_region_empty (expose_region))
1474 GdkRectangle* rects;
1478 if (scroll_rect.width != 0 && scroll_rect.height != 0)
1480 [impl->view scrollRect:NSMakeRect (scroll_rect.x,
1487 [impl->view setFrame:nsrect];
1489 gdk_region_get_rectangles (expose_region, &rects, &n_rects);
1491 for (n = 0; n < n_rects; ++n)
1492 _gdk_quartz_window_set_needs_display_in_rect (window, &rects[n]);
1498 [impl->view setFrame:nsrect];
1499 [impl->view setNeedsDisplay:YES];
1502 gdk_region_destroy (expose_region);
1503 gdk_region_destroy (old_region);
1507 GDK_QUARTZ_RELEASE_POOL;
1511 window_quartz_move (GdkWindow *window,
1515 g_return_if_fail (GDK_IS_WINDOW (window));
1517 if (((GdkWindowObject *)window)->state & GDK_WINDOW_STATE_FULLSCREEN)
1520 move_resize_window_internal (window, x, y, -1, -1);
1524 window_quartz_resize (GdkWindow *window,
1528 g_return_if_fail (GDK_IS_WINDOW (window));
1530 if (((GdkWindowObject *)window)->state & GDK_WINDOW_STATE_FULLSCREEN)
1538 move_resize_window_internal (window, -1, -1, width, height);
1542 window_quartz_move_resize (GdkWindow *window,
1553 move_resize_window_internal (window, x, y, width, height);
1557 gdk_window_quartz_move_resize (GdkWindow *window,
1564 if (with_move && (width < 0 && height < 0))
1565 window_quartz_move (window, x, y);
1569 window_quartz_move_resize (window, x, y, width, height);
1571 window_quartz_resize (window, width, height);
1575 /* FIXME: This might need fixing (reparenting didn't work before client-side
1579 gdk_window_quartz_reparent (GdkWindow *window,
1580 GdkWindow *new_parent,
1584 GdkWindowObject *private, *old_parent_private, *new_parent_private;
1585 GdkWindowImplQuartz *impl, *old_parent_impl, *new_parent_impl;
1586 NSView *view, *new_parent_view;
1588 if (new_parent == _gdk_root)
1590 /* Could be added, just needs implementing. */
1591 g_warning ("Reparenting to root window is not supported yet in the Mac OS X backend");
1595 private = GDK_WINDOW_OBJECT (window);
1596 impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
1599 new_parent_private = GDK_WINDOW_OBJECT (new_parent);
1600 new_parent_impl = GDK_WINDOW_IMPL_QUARTZ (new_parent_private->impl);
1601 new_parent_view = new_parent_impl->view;
1603 old_parent_private = GDK_WINDOW_OBJECT (private->parent);
1604 old_parent_impl = GDK_WINDOW_IMPL_QUARTZ (old_parent_private->impl);
1608 [view removeFromSuperview];
1609 [new_parent_view addSubview:view];
1613 private->parent = new_parent_private;
1615 if (old_parent_private)
1617 old_parent_impl->sorted_children = g_list_remove (old_parent_impl->sorted_children, window);
1620 new_parent_impl->sorted_children = g_list_prepend (new_parent_impl->sorted_children, window);
1625 /* Get the toplevel ordering from NSApp and update our own list. We do
1626 * this on demand since the NSApp's list is not up to date directly
1627 * after we get windowDidBecomeMain.
1630 update_toplevel_order (void)
1632 GdkWindowObject *root;
1633 GdkWindowImplQuartz *root_impl;
1634 NSEnumerator *enumerator;
1636 GList *toplevels = NULL;
1638 root = GDK_WINDOW_OBJECT (_gdk_root);
1639 root_impl = GDK_WINDOW_IMPL_QUARTZ (root->impl);
1641 if (root_impl->sorted_children)
1644 GDK_QUARTZ_ALLOC_POOL;
1646 enumerator = [[NSApp orderedWindows] objectEnumerator];
1647 while ((nswindow = [enumerator nextObject]))
1651 if (![[nswindow contentView] isKindOfClass:[GdkQuartzView class]])
1654 window = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
1655 toplevels = g_list_prepend (toplevels, window);
1658 GDK_QUARTZ_RELEASE_POOL;
1660 root_impl->sorted_children = g_list_reverse (toplevels);
1664 clear_toplevel_order (void)
1666 GdkWindowObject *root;
1667 GdkWindowImplQuartz *root_impl;
1669 root = GDK_WINDOW_OBJECT (_gdk_root);
1670 root_impl = GDK_WINDOW_IMPL_QUARTZ (root->impl);
1672 g_list_free (root_impl->sorted_children);
1673 root_impl->sorted_children = NULL;
1677 gdk_window_quartz_raise (GdkWindow *window)
1679 if (GDK_WINDOW_DESTROYED (window))
1682 if (WINDOW_IS_TOPLEVEL (window))
1684 GdkWindowImplQuartz *impl;
1686 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1687 [impl->toplevel orderFront:impl->toplevel];
1689 clear_toplevel_order ();
1693 GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
1697 GdkWindowImplQuartz *impl;
1699 impl = (GdkWindowImplQuartz *)parent->impl;
1701 impl->sorted_children = g_list_remove (impl->sorted_children, window);
1702 impl->sorted_children = g_list_prepend (impl->sorted_children, window);
1708 gdk_window_quartz_lower (GdkWindow *window)
1710 if (GDK_WINDOW_DESTROYED (window))
1713 if (WINDOW_IS_TOPLEVEL (window))
1715 GdkWindowImplQuartz *impl;
1717 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1718 [impl->toplevel orderBack:impl->toplevel];
1720 clear_toplevel_order ();
1724 GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
1728 GdkWindowImplQuartz *impl;
1730 impl = (GdkWindowImplQuartz *)parent->impl;
1732 impl->sorted_children = g_list_remove (impl->sorted_children, window);
1733 impl->sorted_children = g_list_append (impl->sorted_children, window);
1739 gdk_window_quartz_restack_toplevel (GdkWindow *window,
1743 /* FIXME: Implement this */
1747 gdk_window_quartz_set_background (GdkWindow *window,
1748 const GdkColor *color)
1750 /* FIXME: We could theoretically set the background color for toplevels
1751 * here. (Currently we draw the background before emitting expose events)
1756 gdk_window_quartz_set_back_pixmap (GdkWindow *window,
1759 /* FIXME: Could theoretically set some background image here. (Currently
1760 * the back pixmap is drawn before emitting expose events.
1765 gdk_window_quartz_set_cursor (GdkWindow *window,
1768 GdkCursorPrivate *cursor_private;
1771 cursor_private = (GdkCursorPrivate *)cursor;
1773 if (GDK_WINDOW_DESTROYED (window))
1777 nscursor = [NSCursor arrowCursor];
1779 nscursor = cursor_private->nscursor;
1785 gdk_window_quartz_get_geometry (GdkWindow *window,
1792 GdkWindowImplQuartz *impl;
1793 GdkWindowObject *private;
1796 if (GDK_WINDOW_DESTROYED (window))
1799 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
1800 private = GDK_WINDOW_OBJECT (window);
1801 if (window == _gdk_root)
1809 *width = private->width;
1811 *height = private->height;
1813 else if (WINDOW_IS_TOPLEVEL (window))
1815 ns_rect = [impl->toplevel contentRectForFrameRect:[impl->toplevel frame]];
1817 /* This doesn't work exactly as in X. There doesn't seem to be a
1818 * way to get the coords relative to the parent window (usually
1819 * the window frame), but that seems useless except for
1820 * borderless windows where it's relative to the root window. So
1821 * we return (0, 0) (should be something like (0, 22)) for
1822 * windows with borders and the root relative coordinates
1825 if ([impl->toplevel styleMask] == NSBorderlessWindowMask)
1827 _gdk_quartz_window_xy_to_gdk_xy (ns_rect.origin.x,
1828 ns_rect.origin.y + ns_rect.size.height,
1840 *width = ns_rect.size.width;
1842 *height = ns_rect.size.height;
1846 ns_rect = [impl->view frame];
1849 *x = ns_rect.origin.x;
1851 *y = ns_rect.origin.y;
1853 *width = ns_rect.size.width;
1855 *height = ns_rect.size.height;
1859 *depth = gdk_drawable_get_depth (window);
1863 gdk_window_quartz_get_root_coords (GdkWindow *window,
1869 GdkWindowObject *private;
1870 int tmp_x = 0, tmp_y = 0;
1871 GdkWindow *toplevel;
1872 NSRect content_rect;
1873 GdkWindowImplQuartz *impl;
1875 if (GDK_WINDOW_DESTROYED (window))
1885 if (window == _gdk_root)
1895 private = GDK_WINDOW_OBJECT (window);
1897 toplevel = gdk_window_get_toplevel (window);
1898 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
1900 content_rect = [impl->toplevel contentRectForFrameRect:[impl->toplevel frame]];
1902 _gdk_quartz_window_xy_to_gdk_xy (content_rect.origin.x,
1903 content_rect.origin.y + content_rect.size.height,
1909 while (private != GDK_WINDOW_OBJECT (toplevel))
1911 if (_gdk_window_has_impl ((GdkWindow *)private))
1913 tmp_x += private->x;
1914 tmp_y += private->y;
1917 private = private->parent;
1929 gdk_window_quartz_get_deskrelative_origin (GdkWindow *window,
1933 return gdk_window_get_origin (window, x, y);
1937 gdk_window_get_root_origin (GdkWindow *window,
1946 gdk_window_get_frame_extents (window, &rect);
1955 /* Returns coordinates relative to the passed in window. */
1957 gdk_window_quartz_get_pointer_helper (GdkWindow *window,
1960 GdkModifierType *mask)
1962 GdkWindowObject *toplevel;
1963 GdkWindowObject *private;
1966 GdkWindow *found_window;
1968 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
1970 if (GDK_WINDOW_DESTROYED (window))
1978 toplevel = GDK_WINDOW_OBJECT (gdk_window_get_toplevel (window));
1980 *mask = _gdk_quartz_events_get_current_event_mask ();
1982 /* Get the y coordinate, needs to be flipped. */
1983 if (window == _gdk_root)
1985 point = [NSEvent mouseLocation];
1986 _gdk_quartz_window_nspoint_to_gdk_xy (point, &x_tmp, &y_tmp);
1990 GdkWindowImplQuartz *impl;
1993 impl = GDK_WINDOW_IMPL_QUARTZ (toplevel->impl);
1994 private = GDK_WINDOW_OBJECT (toplevel);
1995 nswindow = impl->toplevel;
1997 point = [nswindow mouseLocationOutsideOfEventStream];
2000 y_tmp = private->height - point.y;
2002 window = (GdkWindow *)toplevel;
2005 found_window = _gdk_quartz_window_find_child (window, x_tmp, y_tmp);
2007 /* We never return the root window. */
2008 if (found_window == _gdk_root)
2009 found_window = NULL;
2014 return found_window;
2018 gdk_window_quartz_get_pointer (GdkWindow *window,
2021 GdkModifierType *mask)
2023 return gdk_window_quartz_get_pointer_helper (window, x, y, mask) != NULL;
2026 /* Returns coordinates relative to the root. */
2028 _gdk_windowing_get_pointer (GdkDisplay *display,
2032 GdkModifierType *mask)
2034 g_return_if_fail (display == _gdk_display);
2036 *screen = _gdk_screen;
2037 gdk_window_quartz_get_pointer_helper (_gdk_root, x, y, mask);
2041 gdk_display_warp_pointer (GdkDisplay *display,
2046 CGDisplayMoveCursorToPoint (CGMainDisplayID (), CGPointMake (x, y));
2049 /* Returns coordinates relative to the found window. */
2051 _gdk_windowing_window_at_pointer (GdkDisplay *display,
2054 GdkModifierType *mask,
2055 gboolean get_toplevel)
2057 GdkWindow *found_window;
2059 GdkModifierType tmp_mask = 0;
2061 found_window = gdk_window_quartz_get_pointer_helper (_gdk_root,
2066 GdkWindowObject *private;
2068 /* The coordinates returned above are relative the root, we want
2069 * coordinates relative the window here.
2071 private = GDK_WINDOW_OBJECT (found_window);
2072 while (private != GDK_WINDOW_OBJECT (_gdk_root))
2077 private = private->parent;
2085 /* Mimic the X backend here, -1,-1 for unknown windows. */
2095 GdkWindowObject *w = (GdkWindowObject *)found_window;
2096 /* Requested toplevel, find it. */
2097 /* TODO: This can be implemented more efficient by never
2098 recursing into children in the first place */
2101 /* Convert to toplevel */
2102 while (w->parent != NULL &&
2103 w->parent->window_type != GDK_WINDOW_ROOT)
2109 found_window = (GdkWindow *)w;
2113 return found_window;
2117 gdk_window_quartz_get_events (GdkWindow *window)
2119 if (GDK_WINDOW_DESTROYED (window))
2122 return GDK_WINDOW_OBJECT (window)->event_mask;
2126 gdk_window_quartz_set_events (GdkWindow *window,
2127 GdkEventMask event_mask)
2129 /* The mask is set in the common code. */
2133 gdk_window_set_urgency_hint (GdkWindow *window,
2136 if (GDK_WINDOW_DESTROYED (window) ||
2137 !WINDOW_IS_TOPLEVEL (window))
2140 /* FIXME: Implement */
2144 gdk_window_set_geometry_hints (GdkWindow *window,
2145 const GdkGeometry *geometry,
2146 GdkWindowHints geom_mask)
2148 GdkWindowImplQuartz *impl;
2150 g_return_if_fail (geometry != NULL);
2152 if (GDK_WINDOW_DESTROYED (window) ||
2153 !WINDOW_IS_TOPLEVEL (window))
2156 impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl);
2157 if (!impl->toplevel)
2160 if (geom_mask & GDK_HINT_POS)
2162 /* FIXME: Implement */
2165 if (geom_mask & GDK_HINT_USER_POS)
2167 /* FIXME: Implement */
2170 if (geom_mask & GDK_HINT_USER_SIZE)
2172 /* FIXME: Implement */
2175 if (geom_mask & GDK_HINT_MIN_SIZE)
2179 size.width = geometry->min_width;
2180 size.height = geometry->min_height;
2182 [impl->toplevel setContentMinSize:size];
2185 if (geom_mask & GDK_HINT_MAX_SIZE)
2189 size.width = geometry->max_width;
2190 size.height = geometry->max_height;
2192 [impl->toplevel setContentMaxSize:size];
2195 if (geom_mask & GDK_HINT_BASE_SIZE)
2197 /* FIXME: Implement */
2200 if (geom_mask & GDK_HINT_RESIZE_INC)
2204 size.width = geometry->width_inc;
2205 size.height = geometry->height_inc;
2207 [impl->toplevel setContentResizeIncrements:size];
2210 if (geom_mask & GDK_HINT_ASPECT)
2212 /* FIXME: Implement */
2215 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2217 /* FIXME: Implement */
2222 gdk_window_set_title (GdkWindow *window,
2225 GdkWindowImplQuartz *impl;
2227 g_return_if_fail (title != NULL);
2229 if (GDK_WINDOW_DESTROYED (window) ||
2230 !WINDOW_IS_TOPLEVEL (window))
2233 impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *)window)->impl);
2237 GDK_QUARTZ_ALLOC_POOL;
2238 [impl->toplevel setTitle:[NSString stringWithUTF8String:title]];
2239 GDK_QUARTZ_RELEASE_POOL;
2244 gdk_window_set_role (GdkWindow *window,
2247 if (GDK_WINDOW_DESTROYED (window) ||
2248 WINDOW_IS_TOPLEVEL (window))
2251 /* FIXME: Implement */
2255 gdk_window_set_transient_for (GdkWindow *window,
2258 GdkWindowImplQuartz *window_impl;
2259 GdkWindowImplQuartz *parent_impl;
2261 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (parent) ||
2262 !WINDOW_IS_TOPLEVEL (window))
2265 window_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2266 if (!window_impl->toplevel)
2269 GDK_QUARTZ_ALLOC_POOL;
2271 if (window_impl->transient_for)
2273 _gdk_quartz_window_detach_from_parent (window);
2275 g_object_unref (window_impl->transient_for);
2276 window_impl->transient_for = NULL;
2279 parent_impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (parent)->impl);
2280 if (parent_impl->toplevel)
2282 /* We save the parent because it needs to be unset/reset when
2283 * hiding and showing the window.
2286 /* We don't set transients for tooltips, they are already
2287 * handled by the window level being the top one. If we do, then
2288 * the parent window will be brought to the top just because the
2289 * tooltip is, which is not what we want.
2291 if (gdk_window_get_type_hint (window) != GDK_WINDOW_TYPE_HINT_TOOLTIP)
2293 window_impl->transient_for = g_object_ref (parent);
2295 /* We only add the window if it is shown, otherwise it will
2296 * be shown unconditionally here. If it is not shown, the
2297 * window will be added in show() instead.
2299 if (!(GDK_WINDOW_OBJECT (window)->state & GDK_WINDOW_STATE_WITHDRAWN))
2300 _gdk_quartz_window_attach_to_parent (window);
2304 GDK_QUARTZ_RELEASE_POOL;
2308 gdk_window_quartz_shape_combine_region (GdkWindow *window,
2309 const GdkRegion *shape,
2313 /* FIXME: Implement */
2317 gdk_window_quartz_input_shape_combine_region (GdkWindow *window,
2318 const GdkRegion *shape_region,
2322 /* FIXME: Implement */
2326 gdk_window_set_override_redirect (GdkWindow *window,
2327 gboolean override_redirect)
2329 /* FIXME: Implement */
2333 gdk_window_set_accept_focus (GdkWindow *window,
2334 gboolean accept_focus)
2336 GdkWindowObject *private;
2338 private = (GdkWindowObject *)window;
2340 private->accept_focus = accept_focus != FALSE;
2344 gdk_window_quartz_set_static_gravities (GdkWindow *window,
2345 gboolean use_static)
2347 if (GDK_WINDOW_DESTROYED (window) ||
2348 !WINDOW_IS_TOPLEVEL (window))
2351 /* FIXME: Implement */
2356 gdk_window_set_focus_on_map (GdkWindow *window,
2357 gboolean focus_on_map)
2359 GdkWindowObject *private;
2361 private = (GdkWindowObject *)window;
2363 private->focus_on_map = focus_on_map != FALSE;
2367 gdk_window_set_icon (GdkWindow *window,
2368 GdkWindow *icon_window,
2372 /* FIXME: Implement */
2376 gdk_window_set_icon_name (GdkWindow *window,
2379 /* FIXME: Implement */
2383 gdk_window_focus (GdkWindow *window,
2386 GdkWindowObject *private;
2387 GdkWindowImplQuartz *impl;
2389 private = (GdkWindowObject*) window;
2390 impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
2392 if (GDK_WINDOW_DESTROYED (window) ||
2393 !WINDOW_IS_TOPLEVEL (window))
2396 if (private->accept_focus && private->window_type != GDK_WINDOW_TEMP)
2398 GDK_QUARTZ_ALLOC_POOL;
2399 [impl->toplevel makeKeyAndOrderFront:impl->toplevel];
2400 clear_toplevel_order ();
2401 GDK_QUARTZ_RELEASE_POOL;
2406 gdk_window_set_hints (GdkWindow *window,
2415 /* FIXME: Implement */
2419 gint window_type_hint_to_level (GdkWindowTypeHint hint)
2423 case GDK_WINDOW_TYPE_HINT_DOCK:
2424 case GDK_WINDOW_TYPE_HINT_UTILITY:
2425 return NSFloatingWindowLevel;
2427 case GDK_WINDOW_TYPE_HINT_MENU: /* Torn-off menu */
2428 case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU: /* Menu from menubar */
2429 return NSTornOffMenuWindowLevel;
2431 case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
2432 case GDK_WINDOW_TYPE_HINT_TOOLTIP:
2433 return NSStatusWindowLevel;
2435 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
2436 case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
2437 case GDK_WINDOW_TYPE_HINT_COMBO:
2438 case GDK_WINDOW_TYPE_HINT_DND:
2439 return NSPopUpMenuWindowLevel;
2441 case GDK_WINDOW_TYPE_HINT_NORMAL: /* Normal toplevel window */
2442 case GDK_WINDOW_TYPE_HINT_DIALOG: /* Dialog window */
2443 case GDK_WINDOW_TYPE_HINT_TOOLBAR: /* Window used to implement toolbars */
2444 case GDK_WINDOW_TYPE_HINT_DESKTOP: /* N/A */
2451 return NSNormalWindowLevel;
2455 window_type_hint_to_shadow (GdkWindowTypeHint hint)
2459 case GDK_WINDOW_TYPE_HINT_NORMAL: /* Normal toplevel window */
2460 case GDK_WINDOW_TYPE_HINT_DIALOG: /* Dialog window */
2461 case GDK_WINDOW_TYPE_HINT_DOCK:
2462 case GDK_WINDOW_TYPE_HINT_UTILITY:
2463 case GDK_WINDOW_TYPE_HINT_MENU: /* Torn-off menu */
2464 case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU: /* Menu from menubar */
2465 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
2466 case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
2467 case GDK_WINDOW_TYPE_HINT_COMBO:
2468 case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
2469 case GDK_WINDOW_TYPE_HINT_TOOLTIP:
2472 case GDK_WINDOW_TYPE_HINT_TOOLBAR: /* Window used to implement toolbars */
2473 case GDK_WINDOW_TYPE_HINT_DESKTOP: /* N/A */
2474 case GDK_WINDOW_TYPE_HINT_DND:
2486 gdk_window_set_type_hint (GdkWindow *window,
2487 GdkWindowTypeHint hint)
2489 GdkWindowImplQuartz *impl;
2491 if (GDK_WINDOW_DESTROYED (window) ||
2492 !WINDOW_IS_TOPLEVEL (window))
2495 impl = GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl);
2497 impl->type_hint = hint;
2499 /* Match the documentation, only do something if we're not mapped yet. */
2500 if (GDK_WINDOW_IS_MAPPED (window))
2503 [impl->toplevel setHasShadow: window_type_hint_to_shadow (hint)];
2504 [impl->toplevel setLevel: window_type_hint_to_level (hint)];
2508 gdk_window_get_type_hint (GdkWindow *window)
2510 if (GDK_WINDOW_DESTROYED (window) ||
2511 !WINDOW_IS_TOPLEVEL (window))
2512 return GDK_WINDOW_TYPE_HINT_NORMAL;
2514 return GDK_WINDOW_IMPL_QUARTZ (((GdkWindowObject *) window)->impl)->type_hint;
2518 gdk_window_set_modal_hint (GdkWindow *window,
2521 if (GDK_WINDOW_DESTROYED (window) ||
2522 !WINDOW_IS_TOPLEVEL (window))
2525 /* FIXME: Implement */
2529 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
2530 gboolean skips_taskbar)
2532 if (GDK_WINDOW_DESTROYED (window) ||
2533 !WINDOW_IS_TOPLEVEL (window))
2536 /* FIXME: Implement */
2540 gdk_window_set_skip_pager_hint (GdkWindow *window,
2541 gboolean skips_pager)
2543 if (GDK_WINDOW_DESTROYED (window) ||
2544 !WINDOW_IS_TOPLEVEL (window))
2547 /* FIXME: Implement */
2551 gdk_window_begin_resize_drag (GdkWindow *window,
2558 GdkWindowObject *private;
2559 GdkWindowImplQuartz *impl;
2561 g_return_if_fail (GDK_IS_WINDOW (window));
2563 if (edge != GDK_WINDOW_EDGE_SOUTH_EAST)
2565 g_warning ("Resizing is only implemented for GDK_WINDOW_EDGE_SOUTH_EAST on Mac OS");
2569 if (GDK_WINDOW_DESTROYED (window))
2572 private = GDK_WINDOW_OBJECT (window);
2573 impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
2575 if (!impl->toplevel)
2577 g_warning ("Can't call gdk_window_begin_resize_drag on non-toplevel window");
2581 [(GdkQuartzWindow *)impl->toplevel beginManualResize];
2585 gdk_window_begin_move_drag (GdkWindow *window,
2591 GdkWindowObject *private;
2592 GdkWindowImplQuartz *impl;
2594 if (GDK_WINDOW_DESTROYED (window) ||
2595 !WINDOW_IS_TOPLEVEL (window))
2598 private = GDK_WINDOW_OBJECT (window);
2599 impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
2601 if (!impl->toplevel)
2603 g_warning ("Can't call gdk_window_begin_move_drag on non-toplevel window");
2607 [(GdkQuartzWindow *)impl->toplevel beginManualMove];
2611 gdk_window_set_icon_list (GdkWindow *window,
2614 /* FIXME: Implement */
2618 gdk_window_get_frame_extents (GdkWindow *window,
2621 GdkWindowObject *private;
2622 GdkWindow *toplevel;
2623 GdkWindowImplQuartz *impl;
2626 g_return_if_fail (rect != NULL);
2628 private = GDK_WINDOW_OBJECT (window);
2635 toplevel = gdk_window_get_toplevel (window);
2636 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
2638 ns_rect = [impl->toplevel frame];
2640 _gdk_quartz_window_xy_to_gdk_xy (ns_rect.origin.x,
2641 ns_rect.origin.y + ns_rect.size.height,
2642 &rect->x, &rect->y);
2644 rect->width = ns_rect.size.width;
2645 rect->height = ns_rect.size.height;
2649 gdk_window_set_decorations (GdkWindow *window,
2650 GdkWMDecoration decorations)
2652 GdkWindowImplQuartz *impl;
2653 NSUInteger old_mask, new_mask;
2656 if (GDK_WINDOW_DESTROYED (window) ||
2657 !WINDOW_IS_TOPLEVEL (window))
2660 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2662 if (decorations == 0 || GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP ||
2663 impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN )
2665 new_mask = NSBorderlessWindowMask;
2669 /* FIXME: Honor other GDK_DECOR_* flags. */
2670 new_mask = (NSTitledWindowMask | NSClosableWindowMask |
2671 NSMiniaturizableWindowMask | NSResizableWindowMask);
2674 GDK_QUARTZ_ALLOC_POOL;
2676 old_mask = [impl->toplevel styleMask];
2678 /* Note, there doesn't seem to be a way to change this without
2679 * recreating the toplevel. There might be bad side-effects of doing
2680 * that, but it seems alright.
2682 if (old_mask != new_mask)
2686 old_view = [impl->toplevel contentView];
2688 rect = [impl->toplevel frame];
2690 /* Properly update the size of the window when the titlebar is
2693 if (old_mask == NSBorderlessWindowMask &&
2694 new_mask != NSBorderlessWindowMask)
2696 rect = [NSWindow frameRectForContentRect:rect styleMask:new_mask];
2699 else if (old_mask != NSBorderlessWindowMask &&
2700 new_mask == NSBorderlessWindowMask)
2702 rect = [NSWindow contentRectForFrameRect:rect styleMask:old_mask];
2705 impl->toplevel = [impl->toplevel initWithContentRect:rect
2707 backing:NSBackingStoreBuffered
2710 [impl->toplevel setHasShadow: window_type_hint_to_shadow (impl->type_hint)];
2711 [impl->toplevel setLevel: window_type_hint_to_level (impl->type_hint)];
2713 [impl->toplevel setContentView:old_view];
2714 [impl->toplevel setFrame:rect display:YES];
2716 /* Invalidate the window shadow for non-opaque views that have shadow
2717 * enabled, to get the shadow shape updated.
2719 if (![old_view isOpaque] && [impl->toplevel hasShadow])
2720 [(GdkQuartzView*)old_view setNeedsInvalidateShadow:YES];
2723 GDK_QUARTZ_RELEASE_POOL;
2727 gdk_window_get_decorations (GdkWindow *window,
2728 GdkWMDecoration *decorations)
2730 GdkWindowImplQuartz *impl;
2732 if (GDK_WINDOW_DESTROYED (window) ||
2733 !WINDOW_IS_TOPLEVEL (window))
2736 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2740 /* Borderless is 0, so we can't check it as a bit being set. */
2741 if ([impl->toplevel styleMask] == NSBorderlessWindowMask)
2747 /* FIXME: Honor the other GDK_DECOR_* flags. */
2748 *decorations = GDK_DECOR_ALL;
2756 gdk_window_set_functions (GdkWindow *window,
2757 GdkWMFunction functions)
2759 g_return_if_fail (GDK_IS_WINDOW (window));
2761 /* FIXME: Implement */
2765 _gdk_windowing_window_queue_antiexpose (GdkWindow *window,
2772 gdk_window_stick (GdkWindow *window)
2774 if (GDK_WINDOW_DESTROYED (window) ||
2775 !WINDOW_IS_TOPLEVEL (window))
2780 gdk_window_unstick (GdkWindow *window)
2782 if (GDK_WINDOW_DESTROYED (window) ||
2783 !WINDOW_IS_TOPLEVEL (window))
2788 gdk_window_maximize (GdkWindow *window)
2790 GdkWindowImplQuartz *impl;
2792 if (GDK_WINDOW_DESTROYED (window) ||
2793 !WINDOW_IS_TOPLEVEL (window))
2796 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2798 if (GDK_WINDOW_IS_MAPPED (window))
2800 GDK_QUARTZ_ALLOC_POOL;
2802 if (impl->toplevel && ![impl->toplevel isZoomed])
2803 [impl->toplevel zoom:nil];
2805 GDK_QUARTZ_RELEASE_POOL;
2809 gdk_synthesize_window_state (window,
2811 GDK_WINDOW_STATE_MAXIMIZED);
2816 gdk_window_unmaximize (GdkWindow *window)
2818 GdkWindowImplQuartz *impl;
2820 if (GDK_WINDOW_DESTROYED (window) ||
2821 !WINDOW_IS_TOPLEVEL (window))
2824 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2826 if (GDK_WINDOW_IS_MAPPED (window))
2828 GDK_QUARTZ_ALLOC_POOL;
2830 if (impl->toplevel && [impl->toplevel isZoomed])
2831 [impl->toplevel zoom:nil];
2833 GDK_QUARTZ_RELEASE_POOL;
2837 gdk_synthesize_window_state (window,
2838 GDK_WINDOW_STATE_MAXIMIZED,
2844 gdk_window_iconify (GdkWindow *window)
2846 GdkWindowImplQuartz *impl;
2848 if (GDK_WINDOW_DESTROYED (window) ||
2849 !WINDOW_IS_TOPLEVEL (window))
2852 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2854 if (GDK_WINDOW_IS_MAPPED (window))
2856 GDK_QUARTZ_ALLOC_POOL;
2859 [impl->toplevel miniaturize:nil];
2861 GDK_QUARTZ_RELEASE_POOL;
2865 gdk_synthesize_window_state (window,
2867 GDK_WINDOW_STATE_ICONIFIED);
2872 gdk_window_deiconify (GdkWindow *window)
2874 GdkWindowImplQuartz *impl;
2876 if (GDK_WINDOW_DESTROYED (window) ||
2877 !WINDOW_IS_TOPLEVEL (window))
2880 impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (window)->impl);
2882 if (GDK_WINDOW_IS_MAPPED (window))
2884 GDK_QUARTZ_ALLOC_POOL;
2887 [impl->toplevel deminiaturize:nil];
2889 GDK_QUARTZ_RELEASE_POOL;
2893 gdk_synthesize_window_state (window,
2894 GDK_WINDOW_STATE_ICONIFIED,
2899 static FullscreenSavedGeometry *
2900 get_fullscreen_geometry (GdkWindow *window)
2902 return g_object_get_data (G_OBJECT (window), FULLSCREEN_DATA);
2906 gdk_window_fullscreen (GdkWindow *window)
2908 FullscreenSavedGeometry *geometry;
2909 GdkWindowObject *private = (GdkWindowObject *) window;
2912 if (GDK_WINDOW_DESTROYED (window) ||
2913 !WINDOW_IS_TOPLEVEL (window))
2916 geometry = get_fullscreen_geometry (window);
2919 geometry = g_new (FullscreenSavedGeometry, 1);
2921 geometry->x = private->x;
2922 geometry->y = private->y;
2923 geometry->width = private->width;
2924 geometry->height = private->height;
2926 if (!gdk_window_get_decorations (window, &geometry->decor))
2927 geometry->decor = GDK_DECOR_ALL;
2929 g_object_set_data_full (G_OBJECT (window),
2930 FULLSCREEN_DATA, geometry,
2933 gdk_window_set_decorations (window, 0);
2935 frame = [[NSScreen mainScreen] frame];
2936 move_resize_window_internal (window,
2938 frame.size.width, frame.size.height);
2941 SetSystemUIMode (kUIModeAllHidden, kUIOptionAutoShowMenuBar);
2943 gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FULLSCREEN);
2947 gdk_window_unfullscreen (GdkWindow *window)
2949 FullscreenSavedGeometry *geometry;
2951 if (GDK_WINDOW_DESTROYED (window) ||
2952 !WINDOW_IS_TOPLEVEL (window))
2955 geometry = get_fullscreen_geometry (window);
2958 SetSystemUIMode (kUIModeNormal, 0);
2960 move_resize_window_internal (window,
2966 gdk_window_set_decorations (window, geometry->decor);
2968 g_object_set_data (G_OBJECT (window), FULLSCREEN_DATA, NULL);
2970 gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FULLSCREEN, 0);
2975 gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
2977 GdkWindowObject *private = (GdkWindowObject *) window;
2978 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
2981 g_return_if_fail (GDK_IS_WINDOW (window));
2983 if (GDK_WINDOW_DESTROYED (window) ||
2984 !WINDOW_IS_TOPLEVEL (window))
2987 level = window_type_hint_to_level (gdk_window_get_type_hint (window));
2989 /* Adjust normal window level by one if necessary. */
2990 [impl->toplevel setLevel: level + (setting ? 1 : 0)];
2994 gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
2996 GdkWindowObject *private = (GdkWindowObject *) window;
2997 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
3000 g_return_if_fail (GDK_IS_WINDOW (window));
3002 if (GDK_WINDOW_DESTROYED (window) ||
3003 !WINDOW_IS_TOPLEVEL (window))
3006 level = window_type_hint_to_level (gdk_window_get_type_hint (window));
3008 /* Adjust normal window level by one if necessary. */
3009 [impl->toplevel setLevel: level - (setting ? 1 : 0)];
3013 gdk_window_get_group (GdkWindow *window)
3015 g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
3017 if (GDK_WINDOW_DESTROYED (window) ||
3018 !WINDOW_IS_TOPLEVEL (window))
3021 /* FIXME: Implement */
3027 gdk_window_set_group (GdkWindow *window,
3030 /* FIXME: Implement */
3034 gdk_window_foreign_new_for_display (GdkDisplay *display,
3035 GdkNativeWindow anid)
3037 /* Foreign windows aren't supported in Mac OS X */
3042 gdk_window_lookup (GdkNativeWindow anid)
3044 /* Foreign windows aren't supported in Mac OS X */
3049 gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
3051 /* Foreign windows aren't supported in Mac OS X */
3056 gdk_window_enable_synchronized_configure (GdkWindow *window)
3061 gdk_window_configure_finished (GdkWindow *window)
3066 gdk_window_destroy_notify (GdkWindow *window)
3068 check_grab_destroy (window);
3072 _gdk_windowing_window_beep (GdkWindow *window)
3074 g_return_if_fail (GDK_IS_WINDOW (window));
3076 gdk_display_beep (_gdk_display);
3080 gdk_window_set_opacity (GdkWindow *window,
3083 GdkWindowObject *private = (GdkWindowObject *) window;
3084 GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
3086 g_return_if_fail (GDK_IS_WINDOW (window));
3087 g_return_if_fail (WINDOW_IS_TOPLEVEL (window));
3089 if (GDK_WINDOW_DESTROYED (window) ||
3090 !WINDOW_IS_TOPLEVEL (window))
3095 else if (opacity > 1)
3098 [impl->toplevel setAlphaValue: opacity];
3102 _gdk_windowing_window_set_composited (GdkWindow *window, gboolean composited)
3107 _gdk_windowing_get_shape_for_mask (GdkBitmap *mask)
3109 /* FIXME: implement */
3114 _gdk_windowing_window_get_shape (GdkWindow *window)
3116 /* FIXME: implement */
3121 _gdk_windowing_window_get_input_shape (GdkWindow *window)
3123 /* FIXME: implement */
3128 gdk_window_impl_iface_init (GdkWindowImplIface *iface)
3130 iface->show = gdk_window_quartz_show;
3131 iface->hide = gdk_window_quartz_hide;
3132 iface->withdraw = gdk_window_quartz_withdraw;
3133 iface->set_events = gdk_window_quartz_set_events;
3134 iface->get_events = gdk_window_quartz_get_events;
3135 iface->raise = gdk_window_quartz_raise;
3136 iface->lower = gdk_window_quartz_lower;
3137 iface->restack_toplevel = gdk_window_quartz_restack_toplevel;
3138 iface->move_resize = gdk_window_quartz_move_resize;
3139 iface->set_background = gdk_window_quartz_set_background;
3140 iface->set_back_pixmap = gdk_window_quartz_set_back_pixmap;
3141 iface->reparent = gdk_window_quartz_reparent;
3142 iface->set_cursor = gdk_window_quartz_set_cursor;
3143 iface->get_geometry = gdk_window_quartz_get_geometry;
3144 iface->get_root_coords = gdk_window_quartz_get_root_coords;
3145 iface->get_pointer = gdk_window_quartz_get_pointer;
3146 iface->get_deskrelative_origin = gdk_window_quartz_get_deskrelative_origin;
3147 iface->shape_combine_region = gdk_window_quartz_shape_combine_region;
3148 iface->input_shape_combine_region = gdk_window_quartz_input_shape_combine_region;
3149 iface->set_static_gravities = gdk_window_quartz_set_static_gravities;
3150 iface->queue_antiexpose = _gdk_quartz_window_queue_antiexpose;
3151 iface->queue_translation = _gdk_quartz_window_queue_translation;
3152 iface->destroy = _gdk_quartz_window_destroy;
3153 iface->input_window_destroy = _gdk_input_window_destroy;
3154 iface->input_window_crossing = _gdk_input_window_crossing;