# HG changeset patch # User Daniel Kozar # Date 1596141309 -7200 # Thu Jul 30 22:35:09 2020 +0200 # Node ID f8c781fe18c84a3af4e8f15113d1535bafb62634 # Parent 447366afcf86292bd16c1a9021ac8d88004356ba Use new APIs on Windows for monitoring available clipboard formats This change replaces the usage of SetClipboardViewer with Add/RemoveClipboardFormatListener, introduced in Windows Vista. This makes OpenJDK immune to external applications failing to process clipboard messages properly. diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Clipboard.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Clipboard.cpp --- a/src/java.desktop/windows/native/libawt/windows/awt_Clipboard.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Clipboard.cpp @@ -42,9 +42,7 @@ BOOL AwtClipboard::isGettingOwnership = FALSE; volatile jmethodID AwtClipboard::handleContentsChangedMID; -volatile BOOL AwtClipboard::skipInitialWmDrawClipboardMsg = TRUE; volatile BOOL AwtClipboard::isClipboardViewerRegistered = FALSE; -volatile HWND AwtClipboard::hwndNextViewer = NULL; #define GALLOCFLG (GMEM_DDESHARE | GMEM_MOVEABLE | GMEM_ZEROINIT) @@ -59,27 +57,11 @@ } } -void AwtClipboard::WmChangeCbChain(WPARAM wParam, LPARAM lParam) { - if ((HWND)wParam == hwndNextViewer) { - hwndNextViewer = (HWND)lParam; - } else if (hwndNextViewer != NULL) { - ::SendMessage(hwndNextViewer, WM_CHANGECBCHAIN, wParam, lParam); - } -} - -void AwtClipboard::WmDrawClipboard(JNIEnv *env, WPARAM wParam, LPARAM lParam) { - if (skipInitialWmDrawClipboardMsg) { - // skipping the first contents change notification as it comes - // immediately after registering the clipboard viewer window - // and it is not caused by an actual contents change. - skipInitialWmDrawClipboardMsg = FALSE; - return; - } +void AwtClipboard::WmClipboardUpdate(JNIEnv *env) { if (theCurrentClipboard != NULL) { env->CallVoidMethod(theCurrentClipboard, handleContentsChangedMID); DASSERT(!safe_ExceptionOccurred(env)); } - ::SendMessage(hwndNextViewer, WM_DRAWCLIPBOARD, wParam, lParam); } void AwtClipboard::RegisterClipboardViewer(JNIEnv *env, jobject jclipboard) { @@ -96,7 +78,7 @@ env->GetMethodID(cls, "handleContentsChanged", "()V"); DASSERT(AwtClipboard::handleContentsChangedMID != NULL); - hwndNextViewer = ::SetClipboardViewer(AwtToolkit::GetInstance().GetHWnd()); + ::AddClipboardFormatListener(AwtToolkit::GetInstance().GetHWnd()); isClipboardViewerRegistered = TRUE; } @@ -104,10 +86,8 @@ TRY; if (isClipboardViewerRegistered) { - ::ChangeClipboardChain(AwtToolkit::GetInstance().GetHWnd(), AwtClipboard::hwndNextViewer); - AwtClipboard::hwndNextViewer = NULL; + ::RemoveClipboardFormatListener(AwtToolkit::GetInstance().GetHWnd()); isClipboardViewerRegistered = FALSE; - skipInitialWmDrawClipboardMsg = TRUE; } CATCH_BAD_ALLOC; diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Clipboard.h b/src/java.desktop/windows/native/libawt/windows/awt_Clipboard.h --- a/src/java.desktop/windows/native/libawt/windows/awt_Clipboard.h +++ b/src/java.desktop/windows/native/libawt/windows/awt_Clipboard.h @@ -36,10 +36,7 @@ class AwtClipboard { private: static BOOL isGettingOwnership; - // handle to the next window in the clipboard viewer chain - static volatile HWND hwndNextViewer; static volatile BOOL isClipboardViewerRegistered; - static volatile BOOL skipInitialWmDrawClipboardMsg; static volatile jmethodID handleContentsChangedMID; public: @@ -57,8 +54,7 @@ } static void LostOwnership(JNIEnv *env); - static void WmChangeCbChain(WPARAM wparam, LPARAM lparam); - static void WmDrawClipboard(JNIEnv *env, WPARAM wparam, LPARAM lparam); + static void WmClipboardUpdate(JNIEnv *env); static void RegisterClipboardViewer(JNIEnv *env, jobject jclipboard); static void UnregisterClipboardViewer(JNIEnv *env); }; diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp --- a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp @@ -1065,12 +1065,8 @@ AwtClipboard::LostOwnership((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2)); return 0; } - case WM_CHANGECBCHAIN: { - AwtClipboard::WmChangeCbChain(wParam, lParam); - return 0; - } - case WM_DRAWCLIPBOARD: { - AwtClipboard::WmDrawClipboard((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2), wParam, lParam); + case WM_CLIPBOARDUPDATE: { + AwtClipboard::WmClipboardUpdate((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2)); return 0; } case WM_AWT_LIST_SETMULTISELECT: { diff --git a/test/jdk/java/awt/datatransfer/ClipboardInterVMTest/ClipboardInterVMTest.java b/test/jdk/java/awt/datatransfer/ClipboardInterVMTest/ClipboardInterVMTest.java --- a/test/jdk/java/awt/datatransfer/ClipboardInterVMTest/ClipboardInterVMTest.java +++ b/test/jdk/java/awt/datatransfer/ClipboardInterVMTest/ClipboardInterVMTest.java @@ -83,7 +83,7 @@ } }); - System.out.println("Starting external clipborad modifier..."); + System.out.println("Starting external clipboard modifier..."); new Thread(() -> runTest(ClipboardInterVMTest.class.getCanonicalName(), "pong")).start(); String content = ""; @@ -106,7 +106,7 @@ }; if (!flavorChangedMonitor.await(10, TimeUnit.SECONDS)) { - throw new RuntimeException("No LostOwnership event received."); + throw new RuntimeException("No FlavorsChanged event received."); }; if (!content.equals("pong")) {