From b9b67e05e1f1f036322addafcd1479aebbc0fde5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1?= =?UTF-8?q?=D1=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= Date: Sat, 19 Mar 2016 09:49:56 +0000 Subject: [PATCH] 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 --- gdk/win32/gdkdisplay-win32.c | 46 +++++++++++++++++++--------------- gdk/win32/gdkproperty-win32.c | 13 +++++----- gdk/win32/gdkselection-win32.c | 4 +-- 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c index c739e73812..ce1c5bcced 100644 --- a/gdk/win32/gdkdisplay-win32.c +++ b/gdk/win32/gdkdisplay-win32.c @@ -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); diff --git a/gdk/win32/gdkproperty-win32.c b/gdk/win32/gdkproperty-win32.c index a3936998d5..65850c3054 100644 --- a/gdk/win32/gdkproperty-win32.c +++ b/gdk/win32/gdkproperty-win32.c @@ -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++) diff --git a/gdk/win32/gdkselection-win32.c b/gdk/win32/gdkselection-win32.c index 6d7b7c7ec9..131c0bf436 100644 --- a/gdk/win32/gdkselection-win32.c +++ b/gdk/win32/gdkselection-win32.c @@ -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) {