GDK W32: Optimize clipboard handling a bit

Delay as long as possible before calling OpenClipboard(),
call CloseClipboard() as quickly as possible after that.
Don't call OpenClipboard() when we don't need to (for example,
we don't need to open clipboard to call GetClipboardOwner()).

Also, print out actual W32 error code in some cases where it
was not printed before.

https://bugzilla.gnome.org/show_bug.cgi?id=763907
This commit is contained in:
Руслан Ижбулатов 2016-03-19 09:49:56 +00:00
parent 692c3b11ff
commit b9b67e05e1
3 changed files with 35 additions and 28 deletions

View File

@ -380,38 +380,46 @@ inner_clipboard_window_procedure (HWND hwnd,
case WM_CLIPBOARDUPDATE:
case WM_DRAWCLIPBOARD:
{
int success;
HWND hwndOwner;
#ifdef G_ENABLE_DEBUG
UINT nFormat = 0;
#endif
HWND hwnd_owner;
HWND hwnd_opener;
GdkEvent *event;
GdkWindow *owner;
success = OpenClipboard (hwnd);
if (!success)
{
g_warning ("Failed to OpenClipboard on window handle %p", hwnd);
return 0;
}
hwnd_owner = GetClipboardOwner ();
hwndOwner = GetClipboardOwner ();
owner = gdk_win32_window_lookup_for_display (_gdk_display, hwndOwner);
if (owner == NULL)
owner = gdk_win32_window_foreign_new_for_display (_gdk_display, hwndOwner);
if ((hwnd_owner == NULL) &&
(GetLastError () != ERROR_SUCCESS))
WIN32_API_FAILED ("GetClipboardOwner");
GDK_NOTE (DND, g_print (" drawclipboard owner: %p", hwndOwner));
hwnd_opener = GetOpenClipboardWindow ();
GDK_NOTE (DND, g_print (" drawclipboard owner: %p; opener %p ", hwnd_owner, hwnd_opener));
#ifdef G_ENABLE_DEBUG
if (_gdk_debug_flags & GDK_DEBUG_DND)
{
while ((nFormat = EnumClipboardFormats (nFormat)) != 0)
g_print ("%s ", _gdk_win32_cf_to_string (nFormat));
if (OpenClipboard (hwnd))
{
UINT nFormat = 0;
while ((nFormat = EnumClipboardFormats (nFormat)) != 0)
g_print ("%s ", _gdk_win32_cf_to_string (nFormat));
CloseClipboard ();
}
else
{
WIN32_API_FAILED ("OpenClipboard");
}
}
#endif
GDK_NOTE (DND, g_print (" \n"));
owner = gdk_win32_window_lookup_for_display (_gdk_display, hwnd_owner);
if (owner == NULL)
owner = gdk_win32_window_foreign_new_for_display (_gdk_display, hwnd_owner);
event = gdk_event_new (GDK_OWNER_CHANGE);
event->owner_change.window = gdk_get_default_root_window ();
event->owner_change.owner = owner;
@ -421,8 +429,6 @@ inner_clipboard_window_procedure (HWND hwnd,
event->owner_change.selection_time = GDK_CURRENT_TIME;
_gdk_win32_append_event (event);
CloseClipboard ();
if (_hwnd_next_viewer != NULL)
return SendMessage (_hwnd_next_viewer, message, wparam, lparam);

View File

@ -194,12 +194,6 @@ _gdk_win32_window_change_property (GdkWindow *window,
if (type == _utf8_string)
{
if (!OpenClipboard (GDK_WINDOW_HWND (window)))
{
WIN32_API_FAILED ("OpenClipboard");
return;
}
wcptr = g_utf8_to_utf16 ((char *) data, nelements, NULL, &wclen, &err);
if (err != NULL)
{
@ -208,6 +202,13 @@ _gdk_win32_window_change_property (GdkWindow *window,
return;
}
if (!OpenClipboard (GDK_WINDOW_HWND (window)))
{
WIN32_API_FAILED ("OpenClipboard");
g_free (wcptr);
return;
}
wclen++; /* Terminating 0 */
size = wclen * 2;
for (i = 0; i < wclen; i++)

View File

@ -492,6 +492,8 @@ _gdk_win32_display_convert_selection (GdkDisplay *display,
}
}
API_CALL (CloseClipboard, ());
GDK_NOTE (DND, {
int i;
@ -514,8 +516,6 @@ _gdk_win32_display_convert_selection (GdkDisplay *display,
ntargets * sizeof (GdkAtom));
else
property = GDK_NONE;
API_CALL (CloseClipboard, ());
}
else if (selection == GDK_SELECTION_CLIPBOARD && target == _utf8_string)
{