diff options
author | Jean Guyomarc'h <jean.guyomarch@openwide.fr> | 2015-10-16 10:19:57 +0200 |
---|---|---|
committer | Nicolas Aguirre <aguirre.nicolas@gmail.com> | 2015-11-10 08:27:25 +0100 |
commit | 629feee0eca95550f0b85c957bf8959caa8ade11 (patch) | |
tree | f318f5d6cafe761b9bb97344f213bd9abd918df1 | |
parent | 114dedd65b2119a13b2e1eda86b620b4092d020b (diff) | |
download | efl-629feee0eca95550f0b85c957bf8959caa8ade11.tar.gz |
ecore_cocoa: fix live resize of windows
This was a tricky little bastard!
When a window is live resized, the NSWindow which is the target of
the live resize will wait for a kevent from the window manager,
until live resizing is done. So... live resizing is synchronous
and blocks the main thread... hence ecore_main_loop.
- When live resize starts, the Ecore_Timer which polls NSRunLoop
is paused.
- When the window is resized, the ecore_main_loop is run manually
with ecore_main_loop_iterate() to process Ecore events (mostly
Ecore_Evas)
- When live resize finished, the Ecore_Timer which polls NSRunLoop
is resumed.
@fix
-rw-r--r-- | src/lib/ecore_cocoa/ecore_cocoa_app.h | 3 | ||||
-rw-r--r-- | src/lib/ecore_cocoa/ecore_cocoa_app.m | 15 | ||||
-rw-r--r-- | src/lib/ecore_cocoa/ecore_cocoa_window.m | 22 |
3 files changed, 40 insertions, 0 deletions
diff --git a/src/lib/ecore_cocoa/ecore_cocoa_app.h b/src/lib/ecore_cocoa/ecore_cocoa_app.h index 3e206395c3..0cc01615af 100644 --- a/src/lib/ecore_cocoa/ecore_cocoa_app.h +++ b/src/lib/ecore_cocoa/ecore_cocoa_app.h @@ -18,6 +18,9 @@ - (id)init; - (void)internalUpdate; +- (void) pauseNSRunLoopMonitoring; +- (void) resumeNSRunLoopMonitoring; + @end diff --git a/src/lib/ecore_cocoa/ecore_cocoa_app.m b/src/lib/ecore_cocoa/ecore_cocoa_app.m index e7598abd25..066d29f12e 100644 --- a/src/lib/ecore_cocoa/ecore_cocoa_app.m +++ b/src/lib/ecore_cocoa/ecore_cocoa_app.m @@ -95,6 +95,21 @@ _ecore_cocoa_run_loop_cb(void *data EINA_UNUSED) [super sendEvent:anEvent]; } +- (void) pauseNSRunLoopMonitoring +{ + /* + * After calling this method, we will run an iteration of + * the main loop. We don't want this timer to be fired while + * calling manually the ecore loop, because it will query the + * NSRunLoop, which blocks during live resize. + */ + ecore_timer_freeze(_timer); +} + +- (void) resumeNSRunLoopMonitoring +{ + ecore_timer_thaw(_timer); +} @end diff --git a/src/lib/ecore_cocoa/ecore_cocoa_window.m b/src/lib/ecore_cocoa/ecore_cocoa_window.m index 50319f4fdd..368df83051 100644 --- a/src/lib/ecore_cocoa/ecore_cocoa_window.m +++ b/src/lib/ecore_cocoa/ecore_cocoa_window.m @@ -8,6 +8,7 @@ #include <Ecore_Cocoa.h> #include <Ecore_Cocoa_Cursor.h> #import "ecore_cocoa_window.h" +#import "ecore_cocoa_app.h" #include "ecore_cocoa_private.h" static NSCursor *_cursors[__ECORE_COCOA_CURSOR_LAST]; @@ -83,6 +84,17 @@ static NSCursor *_cursors[__ECORE_COCOA_CURSOR_LAST]; (([self isFullScreen] == YES) ? 0 : ecore_cocoa_titlebar_height_get()); event->wid = [notif object]; ecore_event_add(ECORE_COCOA_EVENT_RESIZE, 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 @@ -99,6 +111,16 @@ static NSCursor *_cursors[__ECORE_COCOA_CURSOR_LAST]; ecore_event_add(ECORE_COCOA_EVENT_GOT_FOCUS, e, NULL, NULL); } +- (void) windowWillStartLiveResize:(NSNotification *) EINA_UNUSED notification +{ + [NSApp pauseNSRunLoopMonitoring]; +} + +- (void) windowDidEndLiveResize:(NSNotification *) EINA_UNUSED notification +{ + [NSApp resumeNSRunLoopMonitoring]; +} + - (void)windowDidResignKey:(NSNotification *)notification { Ecore_Cocoa_Event_Window *e; |