From 77b703c2fc392645d52c7762a3b5f041d995021f Mon Sep 17 00:00:00 2001 From: Kristian Rietveld Date: Sun, 15 Aug 2010 13:24:58 +0200 Subject: [PATCH] quartz: stop offscreen windows code from crashing. This is an adapted version of commit bde0f9a8f68b626aac364690e8658b28decb3ee1 on master. Mainly fixes to properly differentiate bewteen toplevel and offscreen windows, since these sometimes need different treatment. Furthermore, usage of gdk_window_get_effective_foo() instead of gdk_window_get_foo() where applicable. There is an drawing issue left when scrolling e.g. tree views in offscreen windows. I think this is likely an issue with gdk_quartz_draw_drawable() which is used for the copy area code in offscreen windows. It works fine in master, since this was converted to Cairo. --- gdk/quartz/gdkevents-quartz.c | 18 ++++++++++++------ gdk/quartz/gdkwindow-quartz.c | 29 +++++++++++++++++------------ 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/gdk/quartz/gdkevents-quartz.c b/gdk/quartz/gdkevents-quartz.c index 1a0b67846..1334d83ed 100644 --- a/gdk/quartz/gdkevents-quartz.c +++ b/gdk/quartz/gdkevents-quartz.c @@ -36,6 +36,11 @@ #define GRIP_WIDTH 15 #define GRIP_HEIGHT 15 +#define WINDOW_IS_TOPLEVEL(window) \ + (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN) + /* This is the window corresponding to the key window */ static GdkWindow *current_keyboard_window; @@ -87,7 +92,7 @@ gdk_keyboard_grab (GdkWindow *window, g_return_val_if_fail (GDK_IS_WINDOW (window), 0); display = gdk_drawable_get_display (window); - toplevel = gdk_window_get_toplevel (window); + toplevel = gdk_window_get_effective_toplevel (window); _gdk_display_set_has_keyboard_grab (display, window, @@ -520,7 +525,7 @@ find_toplevel_under_pointer (GdkDisplay *display, GdkWindow *toplevel; toplevel = display->pointer_info.toplevel_under_pointer; - if (toplevel) + if (toplevel && WINDOW_IS_TOPLEVEL (toplevel)) { GdkWindowObject *private; NSWindow *nswindow; @@ -599,7 +604,7 @@ find_window_for_ns_event (NSEvent *nsevent, * events are discarded. */ grab = _gdk_display_get_last_pointer_grab (display); - if (grab) + if (WINDOW_IS_TOPLEVEL (toplevel) && grab) { /* Implicit grabs do not go through XGrabPointer and thus the * event mask should not be checked. @@ -637,7 +642,7 @@ find_window_for_ns_event (NSEvent *nsevent, GdkWindowObject *grab_private; NSWindow *grab_nswindow; - grab_toplevel = gdk_window_get_toplevel (grab->window); + grab_toplevel = gdk_window_get_effective_toplevel (grab->window); grab_private = (GdkWindowObject *)grab_toplevel; grab_nswindow = ((GdkWindowImplQuartz *)grab_private->impl)->toplevel; @@ -673,7 +678,8 @@ find_window_for_ns_event (NSEvent *nsevent, toplevel_under_pointer = find_toplevel_under_pointer (display, screen_point, &x_tmp, &y_tmp); - if (toplevel_under_pointer) + if (toplevel_under_pointer + && WINDOW_IS_TOPLEVEL (toplevel_under_pointer)) { GdkWindowObject *toplevel_private; GdkWindowImplQuartz *toplevel_impl; @@ -730,7 +736,7 @@ find_window_for_ns_event (NSEvent *nsevent, case NSKeyUp: case NSFlagsChanged: if (_gdk_display->keyboard_grab.window && !_gdk_display->keyboard_grab.owner_events) - return gdk_window_get_toplevel (_gdk_display->keyboard_grab.window); + return gdk_window_get_effective_toplevel (_gdk_display->keyboard_grab.window); return toplevel; diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c index a1424ce54..b28d9b717 100644 --- a/gdk/quartz/gdkwindow-quartz.c +++ b/gdk/quartz/gdkwindow-quartz.c @@ -386,8 +386,8 @@ _gdk_windowing_window_process_updates_recurse (GdkWindow *window, { GdkWindow *toplevel; - toplevel = gdk_window_get_toplevel (window); - if (toplevel) + toplevel = gdk_window_get_effective_toplevel (window); + if (toplevel && WINDOW_IS_TOPLEVEL (toplevel)) { GdkWindowObject *toplevel_private; GdkWindowImplQuartz *toplevel_impl; @@ -409,12 +409,17 @@ _gdk_windowing_window_process_updates_recurse (GdkWindow *window, } } - gdk_region_get_rectangles (region, &rects, &n_rects); + if (WINDOW_IS_TOPLEVEL (window)) + { + gdk_region_get_rectangles (region, &rects, &n_rects); - for (i = 0; i < n_rects; i++) - _gdk_quartz_window_set_needs_display_in_rect (window, &rects[i]); + for (i = 0; i < n_rects; i++) + _gdk_quartz_window_set_needs_display_in_rect (window, &rects[i]); - g_free (rects); + g_free (rects); + } + else + _gdk_window_process_updates_recurse (window, region); /* NOTE: I'm not sure if we should displayIfNeeded here. It slows down a * lot (since it triggers the beam syncing) and things seem to work @@ -583,7 +588,7 @@ _gdk_quartz_window_debug_highlight (GdkWindow *window, gint number) return; } - toplevel = gdk_window_get_toplevel (window); + toplevel = gdk_window_get_effective_toplevel (window); get_ancestor_coordinates_from_child (window, 0, 0, toplevel, &x, &y); gdk_window_get_origin (toplevel, &tx, &ty); @@ -816,7 +821,7 @@ _gdk_quartz_window_did_resign_main (GdkWindow *window) if (new_window && new_window != window && GDK_WINDOW_IS_MAPPED (new_window) && - GDK_WINDOW_OBJECT (new_window)->window_type != GDK_WINDOW_TEMP) + WINDOW_IS_TOPLEVEL (new_window)) { GdkWindowObject *private = (GdkWindowObject *) new_window; GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); @@ -1180,7 +1185,7 @@ gdk_window_quartz_show (GdkWindow *window, gboolean already_mapped) else focus_on_map = TRUE; - if (impl->toplevel) + if (impl->toplevel && WINDOW_IS_TOPLEVEL (window)) { gboolean make_key; @@ -1275,7 +1280,7 @@ gdk_window_quartz_hide (GdkWindow *window) impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); - if (impl->toplevel) + if (window && WINDOW_IS_TOPLEVEL (window)) { /* Update main window. */ main_window_stack = g_slist_remove (main_window_stack, window); @@ -1917,7 +1922,7 @@ gdk_window_quartz_get_pointer_helper (GdkWindow *window, return NULL; } - toplevel = GDK_WINDOW_OBJECT (gdk_window_get_toplevel (window)); + toplevel = GDK_WINDOW_OBJECT (gdk_window_get_effective_toplevel (window)); *mask = _gdk_quartz_events_get_current_event_mask (); @@ -2574,7 +2579,7 @@ gdk_window_get_frame_extents (GdkWindow *window, rect->width = 1; rect->height = 1; - toplevel = gdk_window_get_toplevel (window); + toplevel = gdk_window_get_effective_toplevel (window); impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl); ns_rect = [impl->toplevel frame];