winemac: Break out of the window-dragging message loop if the window is hidden or destroyed.
Ken Thomases
ken at codeweavers.com
Wed Jun 21 10:15:50 CDT 2017
Signed-off-by: Ken Thomases <ken at codeweavers.com>
---
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 @@ - (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 77be095..2cf67f1 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 2333c1f..65dc392 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 53dcd87..bb0e8ed 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 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);
- }
}
--
2.10.2
More information about the wine-patches
mailing list