From 266396b1eb6d5ddca135caaaf596184afb9b4f03 Mon Sep 17 00:00:00 2001 From: Jean Guyomarc'h Date: Sun, 5 Jun 2016 11:29:25 +0200 Subject: [PATCH] ecore_cocoa: fix main loop handling Pffff... another tricky one... -windowDidResize is actually also called when the window is not resize by the user, leading to multiple event posting, and of course the infamous call of ecore_main_loop_iterate() when it was not paused at all, leading to messy events handling... the most visible being the initial resizing of the window going rogue. We now ensure with -windowWillStartLiveResize and -windowDidEndLiveResize that we only send an event when the user requested it. Since the main loop is paused at this point, calling ecore_main_loop_iterate() becomes safe. Fixes T3648 --- src/lib/ecore_cocoa/ecore_cocoa_window.h | 3 +- src/lib/ecore_cocoa/ecore_cocoa_window.m | 54 +++++++++++++++--------- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/lib/ecore_cocoa/ecore_cocoa_window.h b/src/lib/ecore_cocoa/ecore_cocoa_window.h index 911c729ab8..a30240fc69 100644 --- a/src/lib/ecore_cocoa/ecore_cocoa_window.h +++ b/src/lib/ecore_cocoa/ecore_cocoa_window.h @@ -2,7 +2,8 @@ @interface EcoreCocoaWindow: NSWindow { - void *ecore_window_data; + void *ecore_window_data; + int _live_resize; } @property (nonatomic, assign) void *ecore_window_data; diff --git a/src/lib/ecore_cocoa/ecore_cocoa_window.m b/src/lib/ecore_cocoa/ecore_cocoa_window.m index 941a12f705..5bd2e0fd5d 100644 --- a/src/lib/ecore_cocoa/ecore_cocoa_window.m +++ b/src/lib/ecore_cocoa/ecore_cocoa_window.m @@ -34,6 +34,8 @@ static NSCursor *_cursors[__ECORE_COCOA_CURSOR_LAST]; [self setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + _live_resize = 0; + return self; } @@ -72,28 +74,36 @@ static NSCursor *_cursors[__ECORE_COCOA_CURSOR_LAST]; Ecore_Cocoa_Event_Window_Resize_Request *event; NSSize size = self.frame.size; - event = malloc(sizeof(*event)); - if (EINA_UNLIKELY(event == NULL)) - { - CRI("Failed to allocate Ecore_Cocoa_Event_Window_Resize_Request"); - return; - } - event->w = size.width; - event->h = size.height - - (([self isFullScreen] == YES) ? 0 : ecore_cocoa_titlebar_height_get()); - event->cocoa_window = [notif object]; - ecore_event_add(ECORE_COCOA_EVENT_WINDOW_RESIZE_REQUEST, event, NULL, NULL); - /* - * During live resize, NSRunLoop blocks, and prevent the ecore_main_loop - * to be run. - * This, combined with the -pauseNSRunLoopMonitoring and - * -resumeNSRunLoopMonitoring methods invoked in - * -windowWillStartLiveResize and -windowDidEndLiveResize - * allow the ecore_main_loop to run withing NSRunLoop during the - * live resizing of a window. + * Only throw a resize event and manipulate the main loop when + * we are 100% sure we are in a live resize, and the main loop + * has already been paused!! */ - ecore_main_loop_iterate(); + if (_live_resize > 0) + { + event = malloc(sizeof(*event)); + if (EINA_UNLIKELY(event == NULL)) + { + CRI("Failed to allocate Ecore_Cocoa_Event_Window_Resize_Request"); + return; + } + event->w = size.width; + event->h = size.height - + (([self isFullScreen] == YES) ? 0 : ecore_cocoa_titlebar_height_get()); + event->cocoa_window = [notif object]; + ecore_event_add(ECORE_COCOA_EVENT_WINDOW_RESIZE_REQUEST, event, NULL, NULL); + + /* + * During live resize, NSRunLoop blocks, and prevent the ecore_main_loop + * to be run. + * This, combined with the -pauseNSRunLoopMonitoring and + * -resumeNSRunLoopMonitoring methods invoked in + * -windowWillStartLiveResize and -windowDidEndLiveResize + * allow the ecore_main_loop to run withing NSRunLoop during the + * live resizing of a window. + */ + ecore_main_loop_iterate(); + } } - (void)windowDidBecomeKey:(NSNotification *)notification @@ -112,11 +122,15 @@ static NSCursor *_cursors[__ECORE_COCOA_CURSOR_LAST]; - (void) windowWillStartLiveResize:(NSNotification *) EINA_UNUSED notification { + /* Live resize must be set AFTER pausing the main loop */ [NSApp pauseNSRunLoopMonitoring]; + _live_resize++; } - (void) windowDidEndLiveResize:(NSNotification *) EINA_UNUSED notification { + /* Live resize must be clear BEFORE resuming the main loop */ + _live_resize--; [NSApp resumeNSRunLoopMonitoring]; }