ecore_cocoa: fix live resize of windows 04/82904/3
authorJean Guyomarc'h <jean.guyomarch@openwide.fr>
Fri, 16 Oct 2015 08:19:57 +0000 (10:19 +0200)
committerHermet Park <chuneon.park@samsung.com>
Fri, 2 Sep 2016 03:04:43 +0000 (20:04 -0700)
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

Change-Id: I926f619cb0cb14533d968456db6861db759331df
Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
src/lib/ecore_cocoa/ecore_cocoa_app.h
src/lib/ecore_cocoa/ecore_cocoa_app.m
src/lib/ecore_cocoa/ecore_cocoa_window.m

index 3e20639..0cc0161 100644 (file)
@@ -18,6 +18,9 @@
 - (id)init;
 - (void)internalUpdate;
 
+- (void) pauseNSRunLoopMonitoring;
+- (void) resumeNSRunLoopMonitoring;
+
 @end
 
 
index e7598ab..066d29f 100644 (file)
@@ -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
 
index e4c904e..25a7c58 100644 (file)
@@ -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;