Commit 153f3e27 authored by Ken Thomases's avatar Ken Thomases Committed by Alexandre Julliard

winemac: Forcibly release mouse capture for clicks in Mac menu bar or app deactivation.

parent 1d10457a
...@@ -1719,6 +1719,7 @@ int macdrv_err_on; ...@@ -1719,6 +1719,7 @@ int macdrv_err_on;
{ {
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
NSNotificationCenter* wsnc = [[NSWorkspace sharedWorkspace] notificationCenter]; NSNotificationCenter* wsnc = [[NSWorkspace sharedWorkspace] notificationCenter];
NSDistributedNotificationCenter* dnc = [NSDistributedNotificationCenter defaultCenter];
[nc addObserverForName:NSWindowDidBecomeKeyNotification [nc addObserverForName:NSWindowDidBecomeKeyNotification
object:nil object:nil
...@@ -1760,6 +1761,17 @@ int macdrv_err_on; ...@@ -1760,6 +1761,17 @@ int macdrv_err_on;
selector:@selector(activeSpaceDidChange) selector:@selector(activeSpaceDidChange)
name:NSWorkspaceActiveSpaceDidChangeNotification name:NSWorkspaceActiveSpaceDidChangeNotification
object:nil]; object:nil];
[nc addObserver:self
selector:@selector(releaseMouseCapture)
name:NSMenuDidBeginTrackingNotification
object:nil];
[dnc addObserver:self
selector:@selector(releaseMouseCapture)
name:@"com.apple.HIToolbox.beginMenuTrackingNotification"
object:nil
suspensionBehavior:NSNotificationSuspensionBehaviorDrop];
} }
- (BOOL) inputSourceIsInputMethod - (BOOL) inputSourceIsInputMethod
...@@ -1781,6 +1793,26 @@ int macdrv_err_on; ...@@ -1781,6 +1793,26 @@ int macdrv_err_on;
return inputSourceIsInputMethod; return inputSourceIsInputMethod;
} }
- (void) releaseMouseCapture
{
// This might be invoked on a background thread by the distributed
// notification center. Shunt it to the main thread.
if (![NSThread isMainThread])
{
dispatch_async(dispatch_get_main_queue(), ^{ [self releaseMouseCapture]; });
return;
}
if (mouseCaptureWindow)
{
macdrv_event* event;
event = macdrv_create_event(RELEASE_CAPTURE, mouseCaptureWindow);
[mouseCaptureWindow.queue postEvent:event];
macdrv_release_event(event);
}
}
/* /*
* ---------- NSApplicationDelegate methods ---------- * ---------- NSApplicationDelegate methods ----------
...@@ -1850,6 +1882,8 @@ int macdrv_err_on; ...@@ -1850,6 +1882,8 @@ int macdrv_err_on;
[eventQueuesLock unlock]; [eventQueuesLock unlock];
macdrv_release_event(event); macdrv_release_event(event);
[self releaseMouseCapture];
} }
- (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *)sender - (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *)sender
......
...@@ -44,6 +44,7 @@ static const char *dbgstr_event(int type) ...@@ -44,6 +44,7 @@ static const char *dbgstr_event(int type)
"MOUSE_MOVED_ABSOLUTE", "MOUSE_MOVED_ABSOLUTE",
"MOUSE_SCROLL", "MOUSE_SCROLL",
"QUERY_EVENT", "QUERY_EVENT",
"RELEASE_CAPTURE",
"STATUS_ITEM_CLICKED", "STATUS_ITEM_CLICKED",
"WINDOW_CLOSE_REQUESTED", "WINDOW_CLOSE_REQUESTED",
"WINDOW_DID_MINIMIZE", "WINDOW_DID_MINIMIZE",
...@@ -104,6 +105,7 @@ static macdrv_event_mask get_event_mask(DWORD mask) ...@@ -104,6 +105,7 @@ static macdrv_event_mask get_event_mask(DWORD mask)
if (mask & QS_SENDMESSAGE) if (mask & QS_SENDMESSAGE)
{ {
event_mask |= event_mask_for_type(QUERY_EVENT); event_mask |= event_mask_for_type(QUERY_EVENT);
event_mask |= event_mask_for_type(RELEASE_CAPTURE);
} }
return event_mask; return event_mask;
...@@ -202,6 +204,9 @@ void macdrv_handle_event(const macdrv_event *event) ...@@ -202,6 +204,9 @@ void macdrv_handle_event(const macdrv_event *event)
case QUERY_EVENT: case QUERY_EVENT:
macdrv_query_event(hwnd, event); macdrv_query_event(hwnd, event);
break; break;
case RELEASE_CAPTURE:
macdrv_release_capture(hwnd, event);
break;
case STATUS_ITEM_CLICKED: case STATUS_ITEM_CLICKED:
macdrv_status_item_clicked(event); macdrv_status_item_clicked(event);
break; break;
......
...@@ -175,6 +175,7 @@ enum { ...@@ -175,6 +175,7 @@ enum {
MOUSE_MOVED_ABSOLUTE, MOUSE_MOVED_ABSOLUTE,
MOUSE_SCROLL, MOUSE_SCROLL,
QUERY_EVENT, QUERY_EVENT,
RELEASE_CAPTURE,
STATUS_ITEM_CLICKED, STATUS_ITEM_CLICKED,
WINDOW_CLOSE_REQUESTED, WINDOW_CLOSE_REQUESTED,
WINDOW_DID_MINIMIZE, WINDOW_DID_MINIMIZE,
......
...@@ -918,3 +918,26 @@ void macdrv_mouse_scroll(HWND hwnd, const macdrv_event *event) ...@@ -918,3 +918,26 @@ void macdrv_mouse_scroll(HWND hwnd, const macdrv_event *event)
event->mouse_scroll.x, event->mouse_scroll.y, event->mouse_scroll.x, event->mouse_scroll.y,
event->mouse_scroll.x_scroll, FALSE, event->mouse_scroll.time_ms); event->mouse_scroll.x_scroll, FALSE, event->mouse_scroll.time_ms);
} }
/***********************************************************************
* macdrv_release_capture
*
* Handler for RELEASE_CAPTURE events.
*/
void macdrv_release_capture(HWND hwnd, const macdrv_event *event)
{
struct macdrv_thread_data *thread_data = macdrv_thread_data();
HWND capture = GetCapture();
HWND capture_top = GetAncestor(capture, GA_ROOT);
TRACE("win %p/%p thread_data->capture_window %p GetCapture() %p in %p\n", hwnd,
event->window, thread_data->capture_window, capture, capture_top);
if (event->window == thread_data->capture_window && hwnd == capture_top)
{
ReleaseCapture();
if (!PostMessageW(capture, WM_CANCELMODE, 0, 0))
WARN("failed to post WM_CANCELMODE; error 0x%08x\n", GetLastError());
}
}
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