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
This commit is contained in:
Jean Guyomarc'h 2016-06-05 11:29:25 +02:00
parent 7bb32abf33
commit 266396b1eb
2 changed files with 36 additions and 21 deletions

View File

@ -2,7 +2,8 @@
@interface EcoreCocoaWindow: NSWindow <NSWindowDelegate>
{
void *ecore_window_data;
void *ecore_window_data;
int _live_resize;
}
@property (nonatomic, assign) void *ecore_window_data;

View File

@ -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];
}