Commit f068e329 authored by Ken Thomases's avatar Ken Thomases Committed by Alexandre Julliard

winemac: Send WM_{ENTER, EXIT}SIZEMOVE before/after window dragging and run an…

winemac: Send WM_{ENTER, EXIT}SIZEMOVE before/after window dragging and run an internal event loop during. This simulates some of what would happen if user32 were managing the drag. The click in the caption would cause WM_SYSCOMMAND/SC_MOVE. The processing of that message is synchronous and doesn't return until the move is complete. Some games require that "blocking" in the internal event loop to prevent them from misbehaving during the drag.
parent b3cc34e5
......@@ -1882,11 +1882,24 @@ int macdrv_err_on;
WineWindow* window = (WineWindow*)[anEvent window];
if ([window isKindOfClass:[WineWindow class]])
{
macdrv_event* event;
int eventType;
if (subtype == 20)
{
[windowsBeingDragged addObject:window];
eventType = WINDOW_DRAG_BEGIN;
}
else
{
[windowsBeingDragged removeObject:window];
eventType = WINDOW_DRAG_END;
}
[self updateCursorClippingState];
event = macdrv_create_event(eventType, window);
[window.queue postEvent:event];
macdrv_release_event(event);
}
}
}
......
......@@ -51,6 +51,8 @@ static const char *dbgstr_event(int type)
"WINDOW_BROUGHT_FORWARD",
"WINDOW_CLOSE_REQUESTED",
"WINDOW_DID_UNMINIMIZE",
"WINDOW_DRAG_BEGIN",
"WINDOW_DRAG_END",
"WINDOW_FRAME_CHANGED",
"WINDOW_GOT_FOCUS",
"WINDOW_LOST_FOCUS",
......@@ -114,6 +116,8 @@ static macdrv_event_mask get_event_mask(DWORD mask)
event_mask |= event_mask_for_type(QUERY_EVENT);
event_mask |= event_mask_for_type(RELEASE_CAPTURE);
event_mask |= event_mask_for_type(WINDOW_BROUGHT_FORWARD);
event_mask |= event_mask_for_type(WINDOW_DRAG_BEGIN);
event_mask |= event_mask_for_type(WINDOW_DRAG_END);
event_mask |= event_mask_for_type(WINDOW_MINIMIZE_REQUESTED);
event_mask |= event_mask_for_type(WINDOW_RESIZE_ENDED);
}
......@@ -243,6 +247,12 @@ void macdrv_handle_event(const macdrv_event *event)
case WINDOW_DID_UNMINIMIZE:
macdrv_window_did_unminimize(hwnd);
break;
case WINDOW_DRAG_BEGIN:
macdrv_window_drag_begin(hwnd);
break;
case WINDOW_DRAG_END:
macdrv_window_drag_end(hwnd);
break;
case WINDOW_FRAME_CHANGED:
macdrv_window_frame_changed(hwnd, event);
break;
......@@ -307,7 +317,8 @@ DWORD CDECL macdrv_MsgWaitForMultipleObjectsEx(DWORD count, const HANDLE *handle
}
if (data->current_event && data->current_event->type != QUERY_EVENT &&
data->current_event->type != APP_QUIT_REQUESTED)
data->current_event->type != APP_QUIT_REQUESTED &&
data->current_event->type != WINDOW_DRAG_BEGIN)
event_mask = 0; /* don't process nested events */
if (process_events(data->queue, event_mask)) ret = count - 1;
......
......@@ -140,6 +140,7 @@ struct macdrv_win_data
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? */
struct window_surface *surface;
struct window_surface *unminimized_surface;
};
......@@ -167,6 +168,8 @@ extern void macdrv_window_minimize_requested(HWND hwnd) DECLSPEC_HIDDEN;
extern void macdrv_window_did_unminimize(HWND hwnd) DECLSPEC_HIDDEN;
extern void macdrv_window_brought_forward(HWND hwnd) DECLSPEC_HIDDEN;
extern void macdrv_window_resize_ended(HWND hwnd) DECLSPEC_HIDDEN;
extern void macdrv_window_drag_begin(HWND hwnd) DECLSPEC_HIDDEN;
extern void macdrv_window_drag_end(HWND hwnd) DECLSPEC_HIDDEN;
extern BOOL query_resize_start(HWND hwnd) DECLSPEC_HIDDEN;
extern BOOL query_min_max_info(HWND hwnd) DECLSPEC_HIDDEN;
......
......@@ -191,6 +191,8 @@ enum {
WINDOW_BROUGHT_FORWARD,
WINDOW_CLOSE_REQUESTED,
WINDOW_DID_UNMINIMIZE,
WINDOW_DRAG_BEGIN,
WINDOW_DRAG_END,
WINDOW_FRAME_CHANGED,
WINDOW_GOT_FOCUS,
WINDOW_LOST_FOCUS,
......
......@@ -1681,6 +1681,7 @@ void macdrv_window_frame_changed(HWND hwnd, const macdrv_event *event)
HWND parent;
UINT flags = SWP_NOACTIVATE | SWP_NOZORDER;
int width, height;
BOOL being_dragged;
if (!hwnd) return;
if (!(data = get_win_data(hwnd))) return;
......@@ -1719,16 +1720,17 @@ 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;
release_win_data(data);
if (event->window_frame_changed.fullscreen)
flags |= SWP_NOSENDCHANGING;
if (!(flags & SWP_NOSIZE) || !(flags & SWP_NOMOVE))
{
if (!event->window_frame_changed.in_resize)
if (!event->window_frame_changed.in_resize && !being_dragged)
SendMessageW(hwnd, WM_ENTERSIZEMOVE, 0, 0);
SetWindowPos(hwnd, 0, rect.left, rect.top, width, height, flags);
if (!event->window_frame_changed.in_resize)
if (!event->window_frame_changed.in_resize && !being_dragged)
SendMessageW(hwnd, WM_EXITSIZEMOVE, 0, 0);
}
}
......@@ -1916,6 +1918,73 @@ void macdrv_window_resize_ended(HWND hwnd)
}
/***********************************************************************
* macdrv_window_drag_begin
*
* Handler for WINDOW_DRAG_BEGIN events.
*/
void macdrv_window_drag_begin(HWND hwnd)
{
struct macdrv_win_data *data;
MSG msg;
TRACE("win %p\n", hwnd);
if (!(data = get_win_data(hwnd))) return;
if (data->being_dragged) goto done;
data->being_dragged = 1;
release_win_data(data);
SendMessageW(hwnd, WM_ENTERSIZEMOVE, 0, 0);
while (GetMessageW(&msg, 0, 0, 0))
{
if (!CallMsgFilterW(&msg, MSGF_SIZE) && msg.message != WM_KEYDOWN &&
msg.message != WM_MOUSEMOVE && msg.message != WM_LBUTTONDOWN && msg.message != WM_LBUTTONUP)
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
if (msg.message == WM_EXITSIZEMOVE) break;
}
TRACE("done\n");
if ((data = get_win_data(hwnd)))
data->being_dragged = 0;
done:
release_win_data(data);
}
/***********************************************************************
* macdrv_window_drag_end
*
* Handler for WINDOW_DRAG_END events.
*/
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;
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);
}
}
struct quit_info {
HWND *wins;
UINT capacity;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment