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.
This commit is contained in:
parent
b3cc34e5b0
commit
f068e329c1
|
@ -1882,11 +1882,24 @@ - (BOOL) handleEvent:(NSEvent*)anEvent
|
|||
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 @@ static inline RECT rect_from_cgrect(CGRect cgrect)
|
|||
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 @@ static inline RECT rect_from_cgrect(CGRect cgrect)
|
|||
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 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display,
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue