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 import_window;
|
||||
static Atom current_selection;
|
||||
static UINT rendered_formats;
|
||||
static ULONG64 last_clipboard_update;
|
||||
static struct clipboard_format **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
|
||||
*/
|
||||
static void render_format( UINT id )
|
||||
static HANDLE render_format( UINT id )
|
||||
{
|
||||
Display *display = thread_display();
|
||||
unsigned int i;
|
||||
HANDLE handle = 0;
|
||||
|
||||
if (!current_selection) return;
|
||||
if (!current_selection) return 0;
|
||||
|
||||
for (i = 0; i < nb_current_x11_formats; i++)
|
||||
{
|
||||
|
@ -1040,6 +1041,7 @@ static void render_format( UINT id )
|
|||
if (handle) SetClipboardData( id, handle );
|
||||
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.
|
||||
*/
|
||||
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 *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( string );
|
||||
|
||||
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;
|
||||
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);
|
||||
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;
|
||||
TRACE( "selection changed, importing\n" );
|
||||
EmptyClipboard();
|
||||
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();
|
||||
request_selection_contents( display );
|
||||
CloseClipboard();
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1832,7 +1866,7 @@ BOOL update_clipboard( HWND hwnd )
|
|||
if (hwnd != clipboard_hwnd) return TRUE;
|
||||
if (!is_clipboard_owner) 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() );
|
||||
break;
|
||||
case WM_RENDERFORMAT:
|
||||
render_format( wp );
|
||||
if (render_format( wp )) rendered_formats++;
|
||||
break;
|
||||
case WM_DESTROYCLIPBOARD:
|
||||
TRACE( "WM_DESTROYCLIPBOARD: lost ownership\n" );
|
||||
|
@ -1935,7 +1969,7 @@ static DWORD WINAPI clipboard_thread( void *arg )
|
|||
clipboard_thread_id = GetCurrentThreadId();
|
||||
AddClipboardFormatListener( clipboard_hwnd );
|
||||
register_builtin_formats();
|
||||
grab_win32_clipboard( clipboard_display );
|
||||
request_selection_contents( clipboard_display, TRUE );
|
||||
|
||||
TRACE( "clipboard thread %04x running\n", GetCurrentThreadId() );
|
||||
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;
|
||||
|
||||
release_selection( event->display, event->time );
|
||||
grab_win32_clipboard( event->display );
|
||||
request_selection_contents( event->display, TRUE );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue