[PATCH 2/3] winemac: Don't update the clipboard if the Mac pasteboard hasn't changed.

Ken Thomases ken at codeweavers.com
Wed Jan 11 11:06:21 CST 2017


Signed-off-by: Ken Thomases <ken at codeweavers.com>
---
 dlls/winemac.drv/clipboard.c | 87 ++++++++++++++++++++++++++++++--------------
 1 file changed, 60 insertions(+), 27 deletions(-)

diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c
index ff79a1e..7d9ae0a 100644
--- a/dlls/winemac.drv/clipboard.c
+++ b/dlls/winemac.drv/clipboard.c
@@ -194,6 +194,7 @@ static DWORD clipboard_thread_id;
 static HWND clipboard_hwnd;
 static BOOL is_clipboard_owner;
 static macdrv_window clipboard_cocoa_window;
+static UINT rendered_formats;
 static ULONG64 last_clipboard_update;
 static WINE_CLIPFORMAT **current_mac_formats;
 static unsigned int nb_current_mac_formats;
@@ -1358,39 +1359,25 @@ BOOL macdrv_pasteboard_has_format(CFTypeRef pasteboard, UINT desired_format)
 
 
 /**************************************************************************
- *              get_formats_for_pasteboard
+ *              get_formats_for_pasteboard_types
  */
-static WINE_CLIPFORMAT** get_formats_for_pasteboard(CFTypeRef pasteboard, UINT *num_formats)
+static WINE_CLIPFORMAT** get_formats_for_pasteboard_types(CFArrayRef types, UINT *num_formats)
 {
-    CFArrayRef types;
     CFIndex count, i;
     CFMutableSetRef seen_formats;
     WINE_CLIPFORMAT** formats;
     UINT pos;
 
-    TRACE("pasteboard %s\n", debugstr_cf(pasteboard));
-
-    types = macdrv_copy_pasteboard_types(pasteboard);
-    if (!types)
-    {
-        WARN("Failed to copy pasteboard types\n");
-        return NULL;
-    }
-
     count = CFArrayGetCount(types);
     TRACE("got %ld types\n", count);
 
     if (!count)
-    {
-        CFRelease(types);
         return NULL;
-    }
 
     seen_formats = CFSetCreateMutable(NULL, count, NULL);
     if (!seen_formats)
     {
         WARN("Failed to allocate seen formats set\n");
-        CFRelease(types);
         return NULL;
     }
 
@@ -1398,7 +1385,6 @@ static WINE_CLIPFORMAT** get_formats_for_pasteboard(CFTypeRef pasteboard, UINT *
     if (!formats)
     {
         WARN("Failed to allocate formats array\n");
-        CFRelease(types);
         CFRelease(seen_formats);
         return NULL;
     }
@@ -1457,7 +1443,6 @@ static WINE_CLIPFORMAT** get_formats_for_pasteboard(CFTypeRef pasteboard, UINT *
         formats[pos++] = format;
     }
 
-    CFRelease(types);
     CFRelease(seen_formats);
 
     if (!pos)
@@ -1472,6 +1457,29 @@ static WINE_CLIPFORMAT** get_formats_for_pasteboard(CFTypeRef pasteboard, UINT *
 
 
 /**************************************************************************
+ *              get_formats_for_pasteboard
+ */
+static WINE_CLIPFORMAT** get_formats_for_pasteboard(CFTypeRef pasteboard, UINT *num_formats)
+{
+    CFArrayRef types;
+    WINE_CLIPFORMAT** formats;
+
+    TRACE("pasteboard %s\n", debugstr_cf(pasteboard));
+
+    types = macdrv_copy_pasteboard_types(pasteboard);
+    if (!types)
+    {
+        WARN("Failed to copy pasteboard types\n");
+        return NULL;
+    }
+
+    formats = get_formats_for_pasteboard_types(types, num_formats);
+    CFRelease(types);
+    return formats;
+}
+
+
+/**************************************************************************
  *              macdrv_get_pasteboard_formats
  */
 UINT* macdrv_get_pasteboard_formats(CFTypeRef pasteboard, UINT* num_formats)
@@ -1571,12 +1579,12 @@ static void set_mac_pasteboard_types_from_win32_clipboard(void)
 /**************************************************************************
  *              set_win32_clipboard_formats_from_mac_pasteboard
  */
-static void set_win32_clipboard_formats_from_mac_pasteboard(void)
+static void set_win32_clipboard_formats_from_mac_pasteboard(CFArrayRef types)
 {
     WINE_CLIPFORMAT** formats;
     UINT count, i;
 
-    formats = get_formats_for_pasteboard(NULL, &count);
+    formats = get_formats_for_pasteboard_types(types, &count);
     if (!formats)
         return;
 
@@ -1610,7 +1618,11 @@ static void render_format(UINT id)
         {
             HANDLE handle = current_mac_formats[i]->import_func(pasteboard_data);
             CFRelease(pasteboard_data);
-            if (handle) SetClipboardData(id, handle);
+            if (handle)
+            {
+                SetClipboardData(id, handle);
+                rendered_formats++;
+            }
             break;
         }
     }
@@ -1623,13 +1635,34 @@ static void render_format(UINT id)
  * Grab the Win32 clipboard when a Mac app has taken ownership of the
  * pasteboard, and fill it with the pasteboard data types.
  */
-static void grab_win32_clipboard(void)
+static void grab_win32_clipboard(BOOL changed)
 {
+    static CFArrayRef last_types;
+    CFArrayRef types;
+
+    types = macdrv_copy_pasteboard_types(NULL);
+    if (!types)
+    {
+        WARN("Failed to copy pasteboard types\n");
+        return;
+    }
+
+    changed = (changed || rendered_formats || !last_types || !CFEqual(types, last_types));
+    if (!changed)
+    {
+        CFRelease(types);
+        return;
+    }
+
+    if (last_types) CFRelease(last_types);
+    last_types = types; /* takes ownership */
+
     if (!OpenClipboard(clipboard_hwnd)) return;
     EmptyClipboard();
     is_clipboard_owner = TRUE;
+    rendered_formats = 0;
     last_clipboard_update = GetTickCount64();
-    set_win32_clipboard_formats_from_mac_pasteboard();
+    set_win32_clipboard_formats_from_mac_pasteboard(types);
     CloseClipboard();
 }
 
@@ -1653,10 +1686,10 @@ static void update_clipboard(void)
     if (is_clipboard_owner)
     {
         if (GetTickCount64() - last_clipboard_update > CLIPBOARD_UPDATE_DELAY)
-            grab_win32_clipboard();
+            grab_win32_clipboard(FALSE);
     }
     else if (!macdrv_is_pasteboard_owner(clipboard_cocoa_window))
-        grab_win32_clipboard();
+        grab_win32_clipboard(TRUE);
 
     updating = FALSE;
 }
@@ -1823,7 +1856,7 @@ static DWORD WINAPI clipboard_thread(void *arg)
     clipboard_thread_id = GetCurrentThreadId();
     AddClipboardFormatListener(clipboard_hwnd);
     register_builtin_formats();
-    grab_win32_clipboard();
+    grab_win32_clipboard(TRUE);
 
     TRACE("clipboard thread %04x running\n", GetCurrentThreadId());
     while (1)
@@ -2085,7 +2118,7 @@ void macdrv_lost_pasteboard_ownership(HWND hwnd)
 {
     TRACE("win %p\n", hwnd);
     if (!macdrv_is_pasteboard_owner(clipboard_cocoa_window))
-        grab_win32_clipboard();
+        grab_win32_clipboard(TRUE);
 }
 
 
-- 
2.10.2




More information about the wine-patches mailing list