Module: wine Branch: master Commit: eba417a47721975a475a01367e3e21dd5fb3356b URL: http://source.winehq.org/git/wine.git/?a=commit;h=eba417a47721975a475a01367e...
Author: Ken Thomases ken@codeweavers.com Date: Sun Oct 23 13:03:34 2016 -0500
winemac: Detect loss of ownership of the Mac pasteboard and update the clipboard manager status.
Signed-off-by: Ken Thomases ken@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/winemac.drv/clipboard.c | 17 +++++++++++++++-- dlls/winemac.drv/cocoa_clipboard.m | 20 ++++++++++++++++---- dlls/winemac.drv/cocoa_window.m | 7 +++++++ dlls/winemac.drv/event.c | 5 +++++ dlls/winemac.drv/macdrv.h | 1 + dlls/winemac.drv/macdrv_cocoa.h | 5 +++-- 6 files changed, 47 insertions(+), 8 deletions(-)
diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index 358794d..fc0d60c 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -1551,7 +1551,7 @@ static void set_mac_pasteboard_types_from_win32_clipboard(void)
if (!(formats = get_clipboard_formats(&count))) return;
- macdrv_clear_pasteboard(); + macdrv_clear_pasteboard(clipboard_cocoa_window);
for (i = 0; i < count; i++) { @@ -1657,7 +1657,7 @@ static BOOL update_clipboard(void) if (GetTickCount64() - last_clipboard_update > CLIPBOARD_UPDATE_DELAY) ret = grab_win32_clipboard(); } - else if (!macdrv_is_pasteboard_owner()) + else if (!macdrv_is_pasteboard_owner(clipboard_cocoa_window)) ret = grab_win32_clipboard();
updating = FALSE; @@ -2080,6 +2080,19 @@ BOOL query_pasteboard_data(HWND hwnd, CFStringRef type)
/************************************************************************** + * macdrv_lost_pasteboard_ownership + * + * Handler for the LOST_PASTEBOARD_OWNERSHIP event. + */ +void macdrv_lost_pasteboard_ownership(HWND hwnd) +{ + TRACE("win %p\n", hwnd); + if (!macdrv_is_pasteboard_owner(clipboard_cocoa_window)) + grab_win32_clipboard(); +} + + +/************************************************************************** * macdrv_init_clipboard */ void macdrv_init_clipboard(void) diff --git a/dlls/winemac.drv/cocoa_clipboard.m b/dlls/winemac.drv/cocoa_clipboard.m index 1d1cb88..3b6ec41 100644 --- a/dlls/winemac.drv/cocoa_clipboard.m +++ b/dlls/winemac.drv/cocoa_clipboard.m @@ -21,6 +21,7 @@ #include "macdrv_cocoa.h" #import "cocoa_app.h" #import "cocoa_event.h" +#import "cocoa_window.h"
static int owned_change_count = -1; @@ -29,17 +30,23 @@ static NSArray* BitmapOutputTypes; static NSDictionary* BitmapOutputTypeMap; static dispatch_once_t BitmapOutputTypesInitOnce;
+static NSString* const OwnershipSentinel = @"org.winehq.wine.winemac.pasteboard-ownership-sentinel"; +
/*********************************************************************** * macdrv_is_pasteboard_owner */ -int macdrv_is_pasteboard_owner(void) +int macdrv_is_pasteboard_owner(macdrv_window w) { __block int ret; + WineWindow* window = (WineWindow*)w;
OnMainThread(^{ NSPasteboard* pb = [NSPasteboard generalPasteboard]; ret = ([pb changeCount] == owned_change_count); + + [window.queue discardEventsMatchingMask:event_mask_for_type(LOST_PASTEBOARD_OWNERSHIP) + forWindow:window]; });
return ret; @@ -157,13 +164,18 @@ CFDataRef macdrv_copy_pasteboard_data(CFTypeRef pasteboard, CFStringRef type) * * Takes ownership of the Mac pasteboard and clears it of all data types. */ -void macdrv_clear_pasteboard(void) +void macdrv_clear_pasteboard(macdrv_window w) { - OnMainThreadAsync(^{ + WineWindow* window = (WineWindow*)w; + + OnMainThread(^{ @try { NSPasteboard* pb = [NSPasteboard generalPasteboard]; - owned_change_count = [pb declareTypes:[NSArray array] owner:nil]; + owned_change_count = [pb declareTypes:[NSArray arrayWithObject:OwnershipSentinel] + owner:window]; + [window.queue discardEventsMatchingMask:event_mask_for_type(LOST_PASTEBOARD_OWNERSHIP) + forWindow:window]; } @catch (id e) { diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index e638991..a68ba03 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -2824,6 +2824,13 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi macdrv_release_query(query); }
+ - (void) pasteboardChangedOwner:(NSPasteboard*)sender + { + macdrv_event* event = macdrv_create_event(LOST_PASTEBOARD_OWNERSHIP, self); + [queue postEvent:event]; + macdrv_release_event(event); + } +
/* * ---------- NSDraggingDestination methods ---------- diff --git a/dlls/winemac.drv/event.c b/dlls/winemac.drv/event.c index 2b3d6ce..7d3aab3 100644 --- a/dlls/winemac.drv/event.c +++ b/dlls/winemac.drv/event.c @@ -40,6 +40,7 @@ static const char *dbgstr_event(int type) "KEY_PRESS", "KEY_RELEASE", "KEYBOARD_CHANGED", + "LOST_PASTEBOARD_OWNERSHIP", "MOUSE_BUTTON", "MOUSE_MOVED", "MOUSE_MOVED_ABSOLUTE", @@ -107,6 +108,7 @@ static macdrv_event_mask get_event_mask(DWORD mask) event_mask |= event_mask_for_type(APP_QUIT_REQUESTED); event_mask |= event_mask_for_type(DISPLAYS_CHANGED); event_mask |= event_mask_for_type(IM_SET_TEXT); + event_mask |= event_mask_for_type(LOST_PASTEBOARD_OWNERSHIP); event_mask |= event_mask_for_type(STATUS_ITEM_MOUSE_BUTTON); event_mask |= event_mask_for_type(STATUS_ITEM_MOUSE_MOVE); event_mask |= event_mask_for_type(WINDOW_DID_UNMINIMIZE); @@ -230,6 +232,9 @@ void macdrv_handle_event(const macdrv_event *event) case KEYBOARD_CHANGED: macdrv_keyboard_changed(event); break; + case LOST_PASTEBOARD_OWNERSHIP: + macdrv_lost_pasteboard_ownership(hwnd); + break; case MOUSE_BUTTON: macdrv_mouse_button(hwnd, event); break; diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 8afd064..a3ded73 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -196,6 +196,7 @@ extern void macdrv_displays_changed(const macdrv_event *event) DECLSPEC_HIDDEN;
extern void macdrv_init_clipboard(void) DECLSPEC_HIDDEN; extern BOOL query_pasteboard_data(HWND hwnd, CFStringRef type) DECLSPEC_HIDDEN; +extern void macdrv_lost_pasteboard_ownership(HWND hwnd) DECLSPEC_HIDDEN; extern const char *debugstr_format(UINT id) DECLSPEC_HIDDEN; extern HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format) DECLSPEC_HIDDEN; extern BOOL macdrv_pasteboard_has_format(CFTypeRef pasteboard, UINT desired_format) DECLSPEC_HIDDEN; diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index b3e9106..21e9565 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -267,6 +267,7 @@ enum { KEY_PRESS, KEY_RELEASE, KEYBOARD_CHANGED, + LOST_PASTEBOARD_OWNERSHIP, MOUSE_BUTTON, MOUSE_MOVED, MOUSE_MOVED_ABSOLUTE, @@ -539,8 +540,8 @@ extern int macdrv_layout_list_needs_update DECLSPEC_HIDDEN; /* clipboard */ extern CFArrayRef macdrv_copy_pasteboard_types(CFTypeRef pasteboard) DECLSPEC_HIDDEN; extern CFDataRef macdrv_copy_pasteboard_data(CFTypeRef pasteboard, CFStringRef type) DECLSPEC_HIDDEN; -extern int macdrv_is_pasteboard_owner(void) DECLSPEC_HIDDEN; -extern void macdrv_clear_pasteboard(void) DECLSPEC_HIDDEN; +extern int macdrv_is_pasteboard_owner(macdrv_window w) DECLSPEC_HIDDEN; +extern void macdrv_clear_pasteboard(macdrv_window w) DECLSPEC_HIDDEN; extern int macdrv_set_pasteboard_data(CFStringRef type, CFDataRef data, macdrv_window w) DECLSPEC_HIDDEN;