From 668357c12525e799fdc6b2f547bfc5967a3795d5 Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Mon, 13 Feb 2012 18:10:57 +0000 Subject: [PATCH] Empty Windows clipboard when X loses focus At the moment, we only notice selection updates when the selection owner changes. So, unfortunately, applications which already own a selection can change that selection without us noticing. For example, gitk (and probably all applications using Tk) only claim the selection when it moves between controls, one can adjust the selection within a control without any notice. This simple fix assumes that whenever X gains focus, the selection will be adjusted, so when we lose focus, we should clear the Windows clipboard. This ensures Windows will ask for the contents to be rendered again if Windows application asks for the content, ensuring they get the updated content. (This is almost, but not quite right. If the selection isn't altered while we have the focus, then we've destroyed what was on the clipboard previously.) Signed-off-by: Jon TURNEY --- hw/xwin/win.h | 3 +++ hw/xwin/winclipboard.h | 1 + hw/xwin/winclipboardinit.c | 7 +++++++ hw/xwin/winclipboardwndproc.c | 26 ++++++++++++++++++++++++++ hw/xwin/winwndproc.c | 6 ++++++ 5 files changed, 43 insertions(+), 0 deletions(-) diff --git a/hw/xwin/win.h b/hw/xwin/win.h index 3522ee4..1ffef27 100644 --- a/hw/xwin/win.h +++ b/hw/xwin/win.h @@ -825,6 +825,9 @@ winInitClipboard (void); void winFixClipboardChain (void); + +void +winUpdateClipboard (void); #endif diff --git a/hw/xwin/winclipboard.h b/hw/xwin/winclipboard.h index 6f16163..c51988b 100644 --- a/hw/xwin/winclipboard.h +++ b/hw/xwin/winclipboard.h @@ -74,6 +74,7 @@ #define WIN_CLIPBOARD_DELAY 1 #define WM_WM_REINIT (WM_USER + 1) +#define WM_WM_DEINIT (WM_USER + 2) /* * References to external symbols diff --git a/hw/xwin/winclipboardinit.c b/hw/xwin/winclipboardinit.c index 1cbc27a..da8a9b7 100644 --- a/hw/xwin/winclipboardinit.c +++ b/hw/xwin/winclipboardinit.c @@ -143,3 +143,10 @@ winFixClipboardChain (void) PostMessage (g_hwndClipboard, WM_WM_REINIT, 0, 0); } } + +void +winUpdateClipboard (void) +{ + if (g_fClipboard && g_hwndClipboard) + PostMessage (g_hwndClipboard, WM_WM_DEINIT, 0, 0); +} diff --git a/hw/xwin/winclipboardwndproc.c b/hw/xwin/winclipboardwndproc.c index 02347ff..40bdaa9 100755 --- a/hw/xwin/winclipboardwndproc.c +++ b/hw/xwin/winclipboardwndproc.c @@ -246,6 +246,32 @@ winClipboardWindowProc (HWND hwnd, UINT message, winDebug ("winClipboardWindowProc - WM_WM_REINIT: Exit\n"); return 0; + case WM_WM_DEINIT: + { + /* + Assume the user has changed the selection since we gained + focus, so empty the Windows clipboard, to tell Windows that + it needs to ask us to render the contents again if anyone asks + for it + */ + + /* Set up for another delayed rendering callback */ + OpenClipboard (hwnd); + + /* Take ownership of the Windows clipboard */ + EmptyClipboard (); + + /* Advertise Unicode if we support it */ + if (g_fUnicodeSupport) + SetClipboardData (CF_UNICODETEXT, NULL); + + /* Always advertise regular text */ + SetClipboardData (CF_TEXT, NULL); + + /* Release the clipboard */ + CloseClipboard (); + } + return 0; case WM_DRAWCLIPBOARD: { diff --git a/hw/xwin/winwndproc.c b/hw/xwin/winwndproc.c index e99697d..23d5454 100644 --- a/hw/xwin/winwndproc.c +++ b/hw/xwin/winwndproc.c @@ -1217,6 +1217,12 @@ winWindowProc (HWND hwnd, UINT message, #ifdef XWIN_CLIPBOARD /* Make sure the clipboard chain is ok. */ winFixClipboardChain (); + + if (!wParam) + { + /* Make sure clipboard is updated if needed */ + winUpdateClipboard (); + } #endif /* Call engine specific screen activation/deactivation function */ -- 1.7.5.1