diff options
author | Jean Guyomarc'h <jean@guyomarch.bzh> | 2016-06-05 11:29:25 +0200 |
---|---|---|
committer | Jean Guyomarc'h <jean@guyomarch.bzh> | 2016-06-05 12:12:02 +0200 |
commit | 266396b1eb6d5ddca135caaaf596184afb9b4f03 (patch) | |
tree | a79dd573ee642941ebcda191cc575e7d4a82c4f6 | |
parent | 7bb32abf330c41981d2dae472ff313950ce73a9a (diff) |
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
-rw-r--r-- | src/lib/ecore_cocoa/ecore_cocoa_window.h | 3 | ||||
-rw-r--r-- | 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 @@ | |||
2 | 2 | ||
3 | @interface EcoreCocoaWindow: NSWindow <NSWindowDelegate> | 3 | @interface EcoreCocoaWindow: NSWindow <NSWindowDelegate> |
4 | { | 4 | { |
5 | void *ecore_window_data; | 5 | void *ecore_window_data; |
6 | int _live_resize; | ||
6 | } | 7 | } |
7 | 8 | ||
8 | @property (nonatomic, assign) void *ecore_window_data; | 9 | @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]; | |||
34 | 34 | ||
35 | [self setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; | 35 | [self setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; |
36 | 36 | ||
37 | _live_resize = 0; | ||
38 | |||
37 | return self; | 39 | return self; |
38 | } | 40 | } |
39 | 41 | ||
@@ -72,28 +74,36 @@ static NSCursor *_cursors[__ECORE_COCOA_CURSOR_LAST]; | |||
72 | Ecore_Cocoa_Event_Window_Resize_Request *event; | 74 | Ecore_Cocoa_Event_Window_Resize_Request *event; |
73 | NSSize size = self.frame.size; | 75 | NSSize size = self.frame.size; |
74 | 76 | ||
75 | event = malloc(sizeof(*event)); | ||
76 | if (EINA_UNLIKELY(event == NULL)) | ||
77 | { | ||
78 | CRI("Failed to allocate Ecore_Cocoa_Event_Window_Resize_Request"); | ||
79 | return; | ||
80 | } | ||
81 | event->w = size.width; | ||
82 | event->h = size.height - | ||
83 | (([self isFullScreen] == YES) ? 0 : ecore_cocoa_titlebar_height_get()); | ||
84 | event->cocoa_window = [notif object]; | ||
85 | ecore_event_add(ECORE_COCOA_EVENT_WINDOW_RESIZE_REQUEST, event, NULL, NULL); | ||
86 | |||
87 | /* | 77 | /* |
88 | * During live resize, NSRunLoop blocks, and prevent the ecore_main_loop | 78 | * Only throw a resize event and manipulate the main loop when |
89 | * to be run. | 79 | * we are 100% sure we are in a live resize, and the main loop |
90 | * This, combined with the -pauseNSRunLoopMonitoring and | 80 | * has already been paused!! |
91 | * -resumeNSRunLoopMonitoring methods invoked in | ||
92 | * -windowWillStartLiveResize and -windowDidEndLiveResize | ||
93 | * allow the ecore_main_loop to run withing NSRunLoop during the | ||
94 | * live resizing of a window. | ||
95 | */ | 81 | */ |
96 | ecore_main_loop_iterate(); | 82 | if (_live_resize > 0) |
83 | { | ||
84 | event = malloc(sizeof(*event)); | ||
85 | if (EINA_UNLIKELY(event == NULL)) | ||
86 | { | ||
87 | CRI("Failed to allocate Ecore_Cocoa_Event_Window_Resize_Request"); | ||
88 | return; | ||
89 | } | ||
90 | event->w = size.width; | ||
91 | event->h = size.height - | ||
92 | (([self isFullScreen] == YES) ? 0 : ecore_cocoa_titlebar_height_get()); | ||
93 | event->cocoa_window = [notif object]; | ||
94 | ecore_event_add(ECORE_COCOA_EVENT_WINDOW_RESIZE_REQUEST, event, NULL, NULL); | ||
95 | |||
96 | /* | ||
97 | * During live resize, NSRunLoop blocks, and prevent the ecore_main_loop | ||
98 | * to be run. | ||
99 | * This, combined with the -pauseNSRunLoopMonitoring and | ||
100 | * -resumeNSRunLoopMonitoring methods invoked in | ||
101 | * -windowWillStartLiveResize and -windowDidEndLiveResize | ||
102 | * allow the ecore_main_loop to run withing NSRunLoop during the | ||
103 | * live resizing of a window. | ||
104 | */ | ||
105 | ecore_main_loop_iterate(); | ||
106 | } | ||
97 | } | 107 | } |
98 | 108 | ||
99 | - (void)windowDidBecomeKey:(NSNotification *)notification | 109 | - (void)windowDidBecomeKey:(NSNotification *)notification |
@@ -112,11 +122,15 @@ static NSCursor *_cursors[__ECORE_COCOA_CURSOR_LAST]; | |||
112 | 122 | ||
113 | - (void) windowWillStartLiveResize:(NSNotification *) EINA_UNUSED notification | 123 | - (void) windowWillStartLiveResize:(NSNotification *) EINA_UNUSED notification |
114 | { | 124 | { |
125 | /* Live resize must be set AFTER pausing the main loop */ | ||
115 | [NSApp pauseNSRunLoopMonitoring]; | 126 | [NSApp pauseNSRunLoopMonitoring]; |
127 | _live_resize++; | ||
116 | } | 128 | } |
117 | 129 | ||
118 | - (void) windowDidEndLiveResize:(NSNotification *) EINA_UNUSED notification | 130 | - (void) windowDidEndLiveResize:(NSNotification *) EINA_UNUSED notification |
119 | { | 131 | { |
132 | /* Live resize must be clear BEFORE resuming the main loop */ | ||
133 | _live_resize--; | ||
120 | [NSApp resumeNSRunLoopMonitoring]; | 134 | [NSApp resumeNSRunLoopMonitoring]; |
121 | } | 135 | } |
122 | 136 | ||