Module: wine Branch: master Commit: 6250eb54fe7d6d8091768cab535b46493c78da6f URL: http://source.winehq.org/git/wine.git/?a=commit;h=6250eb54fe7d6d8091768cab53...
Author: Ken Thomases ken@codeweavers.com Date: Wed Jun 21 10:15:50 2017 -0500
winemac: Break out of the window-dragging message loop if the window is hidden or destroyed.
Signed-off-by: Ken Thomases ken@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/winemac.drv/cocoa_app.h | 1 + dlls/winemac.drv/cocoa_app.m | 12 +++++++++++ dlls/winemac.drv/cocoa_window.m | 3 +++ dlls/winemac.drv/macdrv.h | 2 +- dlls/winemac.drv/window.c | 45 +++++++++++++++++++++++++---------------- 5 files changed, 45 insertions(+), 18 deletions(-)
diff --git a/dlls/winemac.drv/cocoa_app.h b/dlls/winemac.drv/cocoa_app.h index e76a47c..c88b894 100644 --- a/dlls/winemac.drv/cocoa_app.h +++ b/dlls/winemac.drv/cocoa_app.h @@ -121,6 +121,7 @@ enum { - (void) noteKey:(uint16_t)keyCode pressed:(BOOL)pressed;
- (void) window:(WineWindow*)window isBeingDragged:(BOOL)dragged; + - (void) windowWillOrderOut:(WineWindow*)window;
- (void) flipRect:(NSRect*)rect;
diff --git a/dlls/winemac.drv/cocoa_app.m b/dlls/winemac.drv/cocoa_app.m index 77be095..2cf67f1 100644 --- a/dlls/winemac.drv/cocoa_app.m +++ b/dlls/winemac.drv/cocoa_app.m @@ -1553,6 +1553,18 @@ static NSString* WineLocalizedString(unsigned int stringID) [self updateCursorClippingState]; }
+ - (void) windowWillOrderOut:(WineWindow*)window + { + if ([windowsBeingDragged containsObject:window]) + { + [self window:window isBeingDragged:NO]; + + macdrv_event* event = macdrv_create_event(WINDOW_DRAG_END, window); + [window.queue postEvent:event]; + macdrv_release_event(event); + } + } + - (void) handleMouseMove:(NSEvent*)anEvent { WineWindow* targetWindow; diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index 2333c1f..65dc392 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -1653,6 +1653,9 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi BOOL wasVisible = [self isVisible]; BOOL wasOnActiveSpace = [self isOnActiveSpace];
+ [self endWindowDragging]; + [controller windowWillOrderOut:self]; + if (enteringFullScreen || exitingFullScreen) { pendingOrderOut = TRUE; diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 53dcd87..bb0e8ed 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -136,13 +136,13 @@ struct macdrv_win_data RECT client_rect; /* client area relative to parent */ int pixel_format; /* pixel format for GL */ COLORREF color_key; /* color key for layered window; CLR_INVALID is not color keyed */ + HANDLE drag_event; /* event to signal that Cocoa-driven window dragging has ended */ unsigned int on_screen : 1; /* is window ordered in? (minimized or not) */ unsigned int shaped : 1; /* is window using a custom region shape? */ unsigned int layered : 1; /* is window layered and with valid attributes? */ unsigned int ulw_layered : 1; /* has UpdateLayeredWindow() been called for window? */ unsigned int per_pixel_alpha : 1; /* is window using per-pixel alpha? */ unsigned int minimized : 1; /* is window minimized? */ - unsigned int being_dragged : 1; /* is window being dragged under Cocoa's control? */ unsigned int swap_interval : 1; /* GL swap interval for window */ struct window_surface *surface; struct window_surface *unminimized_surface; diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index e2de40d..bdd623d 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1573,6 +1573,7 @@ void CDECL macdrv_DestroyWindow(HWND hwnd) if (!(data = get_win_data(hwnd))) return;
if (hwnd == GetCapture()) macdrv_SetCapture(0, 0); + if (data->drag_event) SetEvent(data->drag_event);
destroy_cocoa_window(data); destroy_cocoa_view(data); @@ -2268,7 +2269,7 @@ void macdrv_window_frame_changed(HWND hwnd, const macdrv_event *event) TRACE("%p resizing from (%dx%d) to (%dx%d)\n", hwnd, data->window_rect.right - data->window_rect.left, data->window_rect.bottom - data->window_rect.top, width, height);
- being_dragged = data->being_dragged; + being_dragged = data->drag_event != NULL; release_win_data(data);
if (event->window_frame_changed.fullscreen) @@ -2486,6 +2487,8 @@ void macdrv_window_drag_begin(HWND hwnd, const macdrv_event *event) { DWORD style = GetWindowLongW(hwnd, GWL_STYLE); struct macdrv_win_data *data; + HANDLE drag_event = NULL; + BOOL loop = TRUE; MSG msg;
TRACE("win %p\n", hwnd); @@ -2494,9 +2497,12 @@ void macdrv_window_drag_begin(HWND hwnd, const macdrv_event *event) if (!(style & WS_VISIBLE)) return;
if (!(data = get_win_data(hwnd))) return; - if (data->being_dragged) goto done; + if (data->drag_event) goto done;
- data->being_dragged = TRUE; + drag_event = CreateEventW(NULL, TRUE, FALSE, NULL); + if (!drag_event) goto done; + + data->drag_event = drag_event; release_win_data(data);
if (!event->window_drag_begin.no_activate && can_activate_window(hwnd) && GetForegroundWindow() != hwnd) @@ -2515,13 +2521,22 @@ void macdrv_window_drag_begin(HWND hwnd, const macdrv_event *event) SendMessageW(hwnd, WM_ENTERSIZEMOVE, 0, 0); ReleaseCapture();
- while (GetMessageW(&msg, 0, 0, 0)) + while (loop) { - if (msg.message == WM_EXITSIZEMOVE) + while (!PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) { - SendMessageW(hwnd, WM_EXITSIZEMOVE, 0, 0); - break; + DWORD result = MsgWaitForMultipleObjectsEx(1, &drag_event, INFINITE, QS_ALLINPUT, MWMO_INPUTAVAILABLE); + if (result == WAIT_OBJECT_0) + { + loop = FALSE; + break; + } } + if (!loop) + break; + + if (msg.message == WM_QUIT) + break;
if (!CallMsgFilterW(&msg, MSGF_SIZE) && msg.message != WM_KEYDOWN && msg.message != WM_MOUSEMOVE && msg.message != WM_LBUTTONDOWN && msg.message != WM_LBUTTONUP) @@ -2531,13 +2546,16 @@ void macdrv_window_drag_begin(HWND hwnd, const macdrv_event *event) } }
+ SendMessageW(hwnd, WM_EXITSIZEMOVE, 0, 0); + TRACE("done\n");
if ((data = get_win_data(hwnd))) - data->being_dragged = FALSE; + data->drag_event = NULL;
done: release_win_data(data); + if (drag_event) CloseHandle(drag_event); }
@@ -2549,20 +2567,13 @@ done: void macdrv_window_drag_end(HWND hwnd) { struct macdrv_win_data *data; - BOOL being_dragged;
TRACE("win %p\n", hwnd);
if (!(data = get_win_data(hwnd))) return; - being_dragged = data->being_dragged; + if (data->drag_event) + SetEvent(data->drag_event); release_win_data(data); - - if (being_dragged) - { - /* Post this rather than sending it, so that the message loop in - macdrv_window_drag_begin() will see it. */ - PostMessageW(hwnd, WM_EXITSIZEMOVE, 0, 0); - } }