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