Module: wine Branch: master Commit: 525c0b17952425142e2a4fce5ca358b4f2f8a73e URL: http://source.winehq.org/git/wine.git/?a=commit;h=525c0b17952425142e2a4fce5c...
Author: Ken Thomases ken@codeweavers.com Date: Wed Jan 11 11:06:21 2017 -0600
winemac: Don't update the clipboard if the Mac pasteboard hasn't changed.
Signed-off-by: Ken Thomases ken@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
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); }