From a2a85a194c9a1fd3bf27e1087589e0d6c6ee9d48 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sat, 13 Aug 2011 14:11:29 -0700 Subject: [PATCH] Bug 655122: Lion crashes during resize. Move resizing detection to a separate function and detect resizes so that they don't result in grabs (which was causing the crash). --- gdk/quartz/gdkevents-quartz.c | 85 +++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 24 deletions(-) diff --git a/gdk/quartz/gdkevents-quartz.c b/gdk/quartz/gdkevents-quartz.c index 1334d83edc..9e273296a2 100644 --- a/gdk/quartz/gdkevents-quartz.c +++ b/gdk/quartz/gdkevents-quartz.c @@ -35,6 +35,7 @@ #define GRIP_WIDTH 15 #define GRIP_HEIGHT 15 +#define GDK_LION_RESIZE 5 #define WINDOW_IS_TOPLEVEL(window) \ (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \ @@ -689,30 +690,6 @@ find_window_for_ns_event (NSEvent *nsevent, toplevel_private = (GdkWindowObject *)toplevel; toplevel_impl = (GdkWindowImplQuartz *)toplevel_private->impl; - if ([toplevel_impl->toplevel showsResizeIndicator]) - { - NSRect frame; - - /* If the resize indicator is visible and the event - * is in the lower right 15x15 corner, we leave these - * events to Cocoa as to be handled as resize events. - * Applications may have widgets in this area. These - * will most likely be larger than 15x15 and for - * scroll bars there are also other means to move - * the scroll bar. Since the resize indicator is - * the only way of resizing windows on Mac OS, it - * is too important to not make functional. - */ - frame = [toplevel_impl->view bounds]; - if (x_tmp > frame.size.width - GRIP_WIDTH - && x_tmp < frame.size.width - && y_tmp > frame.size.height - GRIP_HEIGHT - && y_tmp < frame.size.height) - { - return NULL; - } - } - *x = x_tmp; *y = y_tmp; } @@ -1065,6 +1042,63 @@ _gdk_quartz_events_get_current_event_mask (void) return current_event_mask; } +/* Detect window resizing */ + +static gboolean +test_resize (NSEvent *event, GdkWindow *toplevel, gint x, gint y) +{ + GdkWindowObject *toplevel_private; + GdkWindowImplQuartz *toplevel_impl; + gboolean lion; + /* Resizing only begins if an NSLeftMouseButton event is received in + * the resizing area. Handle anything else. + */ + if ([event type] != NSLeftMouseDown) + return FALSE; + + toplevel_private = (GdkWindowObject *)toplevel; + toplevel_impl = (GdkWindowImplQuartz *)toplevel_private->impl; + if ([toplevel_impl->toplevel showsResizeIndicator]) + { + NSRect frame; + + /* If the resize indicator is visible and the event + * is in the lower right 15x15 corner, we leave these + * events to Cocoa as to be handled as resize events. + * Applications may have widgets in this area. These + * will most likely be larger than 15x15 and for + * scroll bars there are also other means to move + * the scroll bar. Since the resize indicator is + * the only way of resizing windows on Mac OS, it + * is too important to not make functional. + */ + frame = [toplevel_impl->view bounds]; + if (x > frame.size.width - GRIP_WIDTH + && x < frame.size.width + && y > frame.size.height - GRIP_HEIGHT + && y < frame.size.height) + { + return TRUE; + } + } + /* If we're on Lion and within 5 pixels of an edge, + * then assume that the user wants to resize, and + * return NULL to let Quartz get on with it. We check + * the selector isRestorable to see if we're on 10.7. + * This extra check is in case the user starts + * dragging before GDK recognizes the grab. + */ + + lion = gdk_quartz_osx_version() >= GDK_OSX_LION; + if (lion && (x < GDK_LION_RESIZE || + x > toplevel_private->width - GDK_LION_RESIZE || + y > toplevel_private->height - GDK_LION_RESIZE)) + { + return TRUE; + } + return FALSE; +} + static gboolean gdk_event_translate (GdkEvent *event, NSEvent *nsevent) @@ -1148,6 +1182,9 @@ gdk_event_translate (GdkEvent *event, window = find_window_for_ns_event (nsevent, &x, &y, &x_root, &y_root); if (!window) return FALSE; + /* Quartz handles resizing on its own, so we want to stay out of the way. */ + if (test_resize(nsevent, window, x, y)) + return FALSE; /* Apply any window filters. */ if (GDK_IS_WINDOW (window))