Ken Thomases : winemac: Detect loss of ownership of the Mac pasteboard and update the clipboard manager status.
Alexandre Julliard
julliard at winehq.org
Mon Oct 24 15:57:54 CDT 2016
Module: wine
Branch: master
Commit: eba417a47721975a475a01367e3e21dd5fb3356b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=eba417a47721975a475a01367e3e21dd5fb3356b
Author: Ken Thomases <ken at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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;
More information about the wine-cvs
mailing list