winemac: Don't update clipboard if its content didn't change.

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Piotr Caban 2017-05-30 09:56:25 +02:00 committed by Alexandre Julliard
parent 98860707bc
commit 1cd883fcb5
3 changed files with 27 additions and 15 deletions

View File

@ -198,7 +198,6 @@ static DWORD clipboard_thread_id;
static HWND clipboard_hwnd; static HWND clipboard_hwnd;
static BOOL is_clipboard_owner; static BOOL is_clipboard_owner;
static macdrv_window clipboard_cocoa_window; static macdrv_window clipboard_cocoa_window;
static UINT rendered_formats;
static ULONG64 last_clipboard_update; static ULONG64 last_clipboard_update;
static DWORD last_get_seqno; static DWORD last_get_seqno;
static WINE_CLIPFORMAT **current_mac_formats; static WINE_CLIPFORMAT **current_mac_formats;
@ -1729,11 +1728,7 @@ static void render_format(UINT id)
{ {
HANDLE handle = current_mac_formats[i]->import_func(pasteboard_data); HANDLE handle = current_mac_formats[i]->import_func(pasteboard_data);
CFRelease(pasteboard_data); CFRelease(pasteboard_data);
if (handle) if (handle) SetClipboardData(id, handle);
{
SetClipboardData(id, handle);
rendered_formats++;
}
break; break;
} }
} }
@ -1746,7 +1741,7 @@ static void render_format(UINT id)
* Grab the Win32 clipboard when a Mac app has taken ownership of the * Grab the Win32 clipboard when a Mac app has taken ownership of the
* pasteboard, and fill it with the pasteboard data types. * pasteboard, and fill it with the pasteboard data types.
*/ */
static void grab_win32_clipboard(BOOL changed) static void grab_win32_clipboard(void)
{ {
static CFArrayRef last_types; static CFArrayRef last_types;
CFArrayRef types; CFArrayRef types;
@ -1758,8 +1753,7 @@ static void grab_win32_clipboard(BOOL changed)
return; return;
} }
changed = (changed || rendered_formats || !last_types || !CFEqual(types, last_types)); if (!macdrv_has_pasteboard_changed() && last_types && CFEqual(types, last_types))
if (!changed)
{ {
CFRelease(types); CFRelease(types);
return; return;
@ -1771,7 +1765,6 @@ static void grab_win32_clipboard(BOOL changed)
if (!OpenClipboard(clipboard_hwnd)) return; if (!OpenClipboard(clipboard_hwnd)) return;
EmptyClipboard(); EmptyClipboard();
is_clipboard_owner = TRUE; is_clipboard_owner = TRUE;
rendered_formats = 0;
last_clipboard_update = GetTickCount64(); last_clipboard_update = GetTickCount64();
set_win32_clipboard_formats_from_mac_pasteboard(types); set_win32_clipboard_formats_from_mac_pasteboard(types);
CloseClipboard(); CloseClipboard();
@ -1798,10 +1791,10 @@ static void update_clipboard(void)
if (is_clipboard_owner) if (is_clipboard_owner)
{ {
if (GetTickCount64() - last_clipboard_update > CLIPBOARD_UPDATE_DELAY) if (GetTickCount64() - last_clipboard_update > CLIPBOARD_UPDATE_DELAY)
grab_win32_clipboard(FALSE); grab_win32_clipboard();
} }
else if (!macdrv_is_pasteboard_owner(clipboard_cocoa_window)) else if (!macdrv_is_pasteboard_owner(clipboard_cocoa_window))
grab_win32_clipboard(TRUE); grab_win32_clipboard();
updating = FALSE; updating = FALSE;
} }
@ -1828,7 +1821,7 @@ static LRESULT CALLBACK clipboard_wndproc(HWND hwnd, UINT msg, WPARAM wp, LPARAM
break; break;
case WM_TIMER: case WM_TIMER:
if (!is_clipboard_owner) break; if (!is_clipboard_owner) break;
grab_win32_clipboard(FALSE); grab_win32_clipboard();
break; break;
case WM_DESTROYCLIPBOARD: case WM_DESTROYCLIPBOARD:
TRACE("WM_DESTROYCLIPBOARD: lost ownership\n"); TRACE("WM_DESTROYCLIPBOARD: lost ownership\n");
@ -1974,7 +1967,7 @@ static DWORD WINAPI clipboard_thread(void *arg)
clipboard_thread_id = GetCurrentThreadId(); clipboard_thread_id = GetCurrentThreadId();
AddClipboardFormatListener(clipboard_hwnd); AddClipboardFormatListener(clipboard_hwnd);
register_builtin_formats(); register_builtin_formats();
grab_win32_clipboard(TRUE); grab_win32_clipboard();
TRACE("clipboard thread %04x running\n", GetCurrentThreadId()); TRACE("clipboard thread %04x running\n", GetCurrentThreadId());
while (1) while (1)
@ -2239,7 +2232,7 @@ void macdrv_lost_pasteboard_ownership(HWND hwnd)
{ {
TRACE("win %p\n", hwnd); TRACE("win %p\n", hwnd);
if (!macdrv_is_pasteboard_owner(clipboard_cocoa_window)) if (!macdrv_is_pasteboard_owner(clipboard_cocoa_window))
grab_win32_clipboard(TRUE); grab_win32_clipboard();
} }

View File

@ -25,6 +25,7 @@
static int owned_change_count = -1; static int owned_change_count = -1;
static int change_count = -1;
static NSArray* BitmapOutputTypes; static NSArray* BitmapOutputTypes;
static NSDictionary* BitmapOutputTypeMap; static NSDictionary* BitmapOutputTypeMap;
@ -52,6 +53,23 @@ int macdrv_is_pasteboard_owner(macdrv_window w)
return ret; return ret;
} }
/***********************************************************************
* macdrv_has_pasteboard_changed
*/
int macdrv_has_pasteboard_changed(void)
{
__block int new_change_count;
int ret;
OnMainThread(^{
NSPasteboard* pb = [NSPasteboard generalPasteboard];
new_change_count = [pb changeCount];
});
ret = (change_count != new_change_count);
change_count = new_change_count;
return ret;
}
/*********************************************************************** /***********************************************************************
* macdrv_copy_pasteboard_types * macdrv_copy_pasteboard_types

View File

@ -549,6 +549,7 @@ extern void macdrv_get_input_source_info(CFDataRef* uchr,CGEventSourceKeyboardTy
extern CFArrayRef macdrv_copy_pasteboard_types(CFTypeRef pasteboard) DECLSPEC_HIDDEN; extern CFArrayRef macdrv_copy_pasteboard_types(CFTypeRef pasteboard) DECLSPEC_HIDDEN;
extern CFDataRef macdrv_copy_pasteboard_data(CFTypeRef pasteboard, CFStringRef type) DECLSPEC_HIDDEN; extern CFDataRef macdrv_copy_pasteboard_data(CFTypeRef pasteboard, CFStringRef type) DECLSPEC_HIDDEN;
extern int macdrv_is_pasteboard_owner(macdrv_window w) DECLSPEC_HIDDEN; extern int macdrv_is_pasteboard_owner(macdrv_window w) DECLSPEC_HIDDEN;
extern int macdrv_has_pasteboard_changed(void) DECLSPEC_HIDDEN;
extern void macdrv_clear_pasteboard(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; extern int macdrv_set_pasteboard_data(CFStringRef type, CFDataRef data, macdrv_window w) DECLSPEC_HIDDEN;