Ken Thomases : winemac: Break out of the window-dragging message loop if the window is hidden or destroyed.

Alexandre Julliard julliard at winehq.org
Wed Jun 21 16:43:44 CDT 2017


Module: wine
Branch: master
Commit: 6250eb54fe7d6d8091768cab535b46493c78da6f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6250eb54fe7d6d8091768cab535b46493c78da6f

Author: Ken Thomases <ken at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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);
-    }
 }
 
 




More information about the wine-cvs mailing list