diff --git a/dlls/winemac.drv/cocoa_app.h b/dlls/winemac.drv/cocoa_app.h index e76a47c377a..c88b894b5cf 100644 --- a/dlls/winemac.drv/cocoa_app.h +++ b/dlls/winemac.drv/cocoa_app.h @@ -121,6 +121,7 @@ - (BOOL) waitUntilQueryDone:(int*)done timeout:(NSDate*)timeout processEvents:(B - (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 77be0956c85..2cf67f17ffc 100644 --- a/dlls/winemac.drv/cocoa_app.m +++ b/dlls/winemac.drv/cocoa_app.m @@ -1553,6 +1553,18 @@ - (void) window:(WineWindow*)window isBeingDragged:(BOOL)dragged [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 2333c1ffd45..65dc3924081 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -1653,6 +1653,9 @@ - (void) doOrderOut 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 53dcd879e45..bb0e8ed13f2 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -136,13 +136,13 @@ static inline RECT rect_from_cgrect(CGRect cgrect) 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 e2de40d9dd7..bdd623d2f98 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); - } }