winemac: Forcibly release mouse capture for clicks in Mac menu bar or app deactivation.
This commit is contained in:
parent
1d10457aee
commit
153f3e27c4
|
@ -1719,6 +1719,7 @@ - (void) setupObservations
|
||||||
{
|
{
|
||||||
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 @@ - (void) setupObservations
|
||||||
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 @@ - (BOOL) inputSourceIsInputMethod
|
||||||
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 @@ - (void)applicationDidResignActive:(NSNotification *)notification
|
||||||
[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)
|
||||||
"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)
|
||||||
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)
|
||||||
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 @@ extern int macdrv_set_display_mode(const struct macdrv_display* display,
|
||||||
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)
|
||||||
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue