winex11: Don't update the clipboard if the X11 selection hasn't changed.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e4cc5bf1b9
commit
1137e3502d
|
@ -191,6 +191,7 @@ static BOOL is_clipboard_owner;
|
||||||
static Window selection_window;
|
static Window selection_window;
|
||||||
static Window import_window;
|
static Window import_window;
|
||||||
static Atom current_selection;
|
static Atom current_selection;
|
||||||
|
static UINT rendered_formats;
|
||||||
static ULONG64 last_clipboard_update;
|
static ULONG64 last_clipboard_update;
|
||||||
static struct clipboard_format **current_x11_formats;
|
static struct clipboard_format **current_x11_formats;
|
||||||
static unsigned int nb_current_x11_formats;
|
static unsigned int nb_current_x11_formats;
|
||||||
|
@ -1025,13 +1026,13 @@ void X11DRV_CLIPBOARD_ImportSelection( Display *display, Window win, Atom select
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* render_format
|
* render_format
|
||||||
*/
|
*/
|
||||||
static void render_format( UINT id )
|
static HANDLE render_format( UINT id )
|
||||||
{
|
{
|
||||||
Display *display = thread_display();
|
Display *display = thread_display();
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
HANDLE handle = 0;
|
HANDLE handle = 0;
|
||||||
|
|
||||||
if (!current_selection) return;
|
if (!current_selection) return 0;
|
||||||
|
|
||||||
for (i = 0; i < nb_current_x11_formats; i++)
|
for (i = 0; i < nb_current_x11_formats; i++)
|
||||||
{
|
{
|
||||||
|
@ -1040,6 +1041,7 @@ static void render_format( UINT id )
|
||||||
if (handle) SetClipboardData( id, handle );
|
if (handle) SetClipboardData( id, handle );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1778,45 +1780,77 @@ static void release_selection( Display *display, Time time )
|
||||||
*
|
*
|
||||||
* Retrieve the contents of the X11 selection when it's owned by an X11 app.
|
* Retrieve the contents of the X11 selection when it's owned by an X11 app.
|
||||||
*/
|
*/
|
||||||
static void request_selection_contents( Display *display )
|
static BOOL request_selection_contents( Display *display, BOOL changed )
|
||||||
{
|
{
|
||||||
struct clipboard_format *targets = find_x11_format( x11drv_atom(TARGETS) );
|
struct clipboard_format *targets = find_x11_format( x11drv_atom(TARGETS) );
|
||||||
struct clipboard_format *string = find_x11_format( XA_STRING );
|
struct clipboard_format *string = find_x11_format( XA_STRING );
|
||||||
|
struct clipboard_format *format = NULL;
|
||||||
|
Window owner = 0;
|
||||||
|
unsigned char *data = NULL;
|
||||||
|
unsigned long size = 0;
|
||||||
|
Atom type = 0;
|
||||||
|
|
||||||
|
static Atom last_selection;
|
||||||
|
static Window last_owner;
|
||||||
|
static struct clipboard_format *last_format;
|
||||||
|
static Atom last_type;
|
||||||
|
static unsigned char *last_data;
|
||||||
|
static unsigned long last_size;
|
||||||
|
|
||||||
assert( targets );
|
assert( targets );
|
||||||
assert( string );
|
assert( string );
|
||||||
|
|
||||||
current_selection = 0;
|
current_selection = 0;
|
||||||
if (use_primary_selection && XGetSelectionOwner( display, XA_PRIMARY ))
|
if (use_primary_selection)
|
||||||
{
|
{
|
||||||
if (import_selection( display, import_window, XA_PRIMARY, targets ))
|
if ((owner = XGetSelectionOwner( display, XA_PRIMARY )))
|
||||||
current_selection = XA_PRIMARY;
|
current_selection = XA_PRIMARY;
|
||||||
else
|
|
||||||
import_selection( display, import_window, XA_PRIMARY, string );
|
|
||||||
}
|
}
|
||||||
else if (XGetSelectionOwner( display, x11drv_atom(CLIPBOARD) ))
|
if (!current_selection)
|
||||||
{
|
{
|
||||||
if (import_selection( display, import_window, x11drv_atom(CLIPBOARD), targets ))
|
if ((owner = XGetSelectionOwner( display, x11drv_atom(CLIPBOARD) )))
|
||||||
current_selection = x11drv_atom(CLIPBOARD);
|
current_selection = x11drv_atom(CLIPBOARD);
|
||||||
else
|
|
||||||
import_selection( display, import_window, x11drv_atom(CLIPBOARD), string );
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if (current_selection)
|
||||||
|
{
|
||||||
|
if (convert_selection( display, import_window, current_selection, targets, &type, &data, &size ))
|
||||||
|
format = targets;
|
||||||
|
else if (convert_selection( display, import_window, current_selection, string, &type, &data, &size ))
|
||||||
|
format = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
changed = (changed ||
|
||||||
|
rendered_formats ||
|
||||||
|
last_selection != current_selection ||
|
||||||
|
last_owner != owner ||
|
||||||
|
last_format != format ||
|
||||||
|
last_type != type ||
|
||||||
|
last_size != size ||
|
||||||
|
memcmp( last_data, data, size ));
|
||||||
|
|
||||||
|
if (!changed)
|
||||||
|
{
|
||||||
|
HeapFree( GetProcessHeap(), 0, data );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
* grab_win32_clipboard
|
|
||||||
*
|
|
||||||
* Grab the Win32 clipboard when an X11 app has grabbed the X11 selection,
|
|
||||||
* and fill it with the selection contents.
|
|
||||||
*/
|
|
||||||
static BOOL grab_win32_clipboard( Display *display )
|
|
||||||
{
|
|
||||||
if (!OpenClipboard( clipboard_hwnd )) return FALSE;
|
if (!OpenClipboard( clipboard_hwnd )) return FALSE;
|
||||||
|
TRACE( "selection changed, importing\n" );
|
||||||
EmptyClipboard();
|
EmptyClipboard();
|
||||||
is_clipboard_owner = TRUE;
|
is_clipboard_owner = TRUE;
|
||||||
|
rendered_formats = 0;
|
||||||
|
|
||||||
|
if (format) format->import( type, data, size );
|
||||||
|
|
||||||
|
HeapFree( GetProcessHeap(), 0, last_data );
|
||||||
|
last_selection = current_selection;
|
||||||
|
last_owner = owner;
|
||||||
|
last_format = format;
|
||||||
|
last_type = type;
|
||||||
|
last_data = data;
|
||||||
|
last_size = size;
|
||||||
last_clipboard_update = GetTickCount64();
|
last_clipboard_update = GetTickCount64();
|
||||||
request_selection_contents( display );
|
|
||||||
CloseClipboard();
|
CloseClipboard();
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1832,7 +1866,7 @@ BOOL update_clipboard( HWND hwnd )
|
||||||
if (hwnd != clipboard_hwnd) return TRUE;
|
if (hwnd != clipboard_hwnd) return TRUE;
|
||||||
if (!is_clipboard_owner) return TRUE;
|
if (!is_clipboard_owner) return TRUE;
|
||||||
if (GetTickCount64() - last_clipboard_update <= SELECTION_UPDATE_DELAY) return TRUE;
|
if (GetTickCount64() - last_clipboard_update <= SELECTION_UPDATE_DELAY) return TRUE;
|
||||||
return grab_win32_clipboard( thread_display() );
|
return request_selection_contents( thread_display(), FALSE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1852,7 +1886,7 @@ static LRESULT CALLBACK clipboard_wndproc( HWND hwnd, UINT msg, WPARAM wp, LPARA
|
||||||
acquire_selection( thread_init_display() );
|
acquire_selection( thread_init_display() );
|
||||||
break;
|
break;
|
||||||
case WM_RENDERFORMAT:
|
case WM_RENDERFORMAT:
|
||||||
render_format( wp );
|
if (render_format( wp )) rendered_formats++;
|
||||||
break;
|
break;
|
||||||
case WM_DESTROYCLIPBOARD:
|
case WM_DESTROYCLIPBOARD:
|
||||||
TRACE( "WM_DESTROYCLIPBOARD: lost ownership\n" );
|
TRACE( "WM_DESTROYCLIPBOARD: lost ownership\n" );
|
||||||
|
@ -1935,7 +1969,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( clipboard_display );
|
request_selection_contents( clipboard_display, TRUE );
|
||||||
|
|
||||||
TRACE( "clipboard thread %04x running\n", GetCurrentThreadId() );
|
TRACE( "clipboard thread %04x running\n", GetCurrentThreadId() );
|
||||||
while (GetMessageW( &msg, 0, 0, 0 )) DispatchMessageW( &msg );
|
while (GetMessageW( &msg, 0, 0, 0 )) DispatchMessageW( &msg );
|
||||||
|
@ -2014,7 +2048,7 @@ BOOL X11DRV_SelectionClear( HWND hwnd, XEvent *xev )
|
||||||
if (event->selection != x11drv_atom(CLIPBOARD)) return FALSE;
|
if (event->selection != x11drv_atom(CLIPBOARD)) return FALSE;
|
||||||
|
|
||||||
release_selection( event->display, event->time );
|
release_selection( event->display, event->time );
|
||||||
grab_win32_clipboard( event->display );
|
request_selection_contents( event->display, TRUE );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue