[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