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>
This commit is contained in:
Ken Thomases 2017-06-21 10:15:50 -05:00 committed by Alexandre Julliard
parent 63205bf01d
commit 6250eb54fe
5 changed files with 45 additions and 18 deletions

View File

@ -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;

View File

@ -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;

View File

@ -1653,6 +1653,9 @@ - (void) doOrderOut
BOOL wasVisible = [self isVisible];
BOOL wasOnActiveSpace = [self isOnActiveSpace];
[self endWindowDragging];
[controller windowWillOrderOut:self];
if (enteringFullScreen || exitingFullScreen)
{
pendingOrderOut = TRUE;

View File

@ -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;

View File

@ -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);
}
}