fixup! JBR-5980: Pasting from clipboard not working reliably in Windows.

(also fixes JBR-6267: Image retreived from the Clipboard is not the same image that was set to the Clipboard)

- Sets the system property awt.windows.clipboard.cache.disabled to false by default ;
- Adds memory barriers around the native flag AwtClipboard::isOwner ;
- Allows back WM_ACTIVATEAPP messages to reach ::DefWindowProc .
This commit is contained in:
Nikita Provotorov
2023-11-10 21:14:47 +01:00
parent 845c60f3bb
commit 60d09c6597
4 changed files with 15 additions and 7 deletions

View File

@@ -160,8 +160,9 @@ final class WClipboard extends SunClipboard {
// ====================== JBR-5980 Pasting from clipboard not working reliably in Windows ======================
boolean flagInitializer = false; // let's fall back in the default behavior
try {
// is "false" by default due to JBR-6267
flagInitializer =
"true".equalsIgnoreCase(System.getProperty("awt.windows.clipboard.cache.disabled", "true"));
"true".equalsIgnoreCase(System.getProperty("awt.windows.clipboard.cache.disabled", "false"));
} catch (Throwable ignored) {
}
isContentsCacheDisabled = flagInitializer;

View File

@@ -49,7 +49,7 @@ volatile BOOL AwtClipboard::isClipboardViewerRegistered = FALSE;
*/
void AwtClipboard::LostOwnership(JNIEnv *env) {
isOwner = FALSE;
(void)::InterlockedExchange(&AwtClipboard::isOwner, FALSE); // isOwner = FALSE;
if (theCurrentClipboard != NULL) {
env->CallVoidMethod(theCurrentClipboard, lostSelectionOwnershipMID);
@@ -96,7 +96,7 @@ void AwtClipboard::UnregisterClipboardViewer(JNIEnv *env) {
// ======================== JBR-5980 Pasting from clipboard not working reliably in Windows ===========================
volatile BOOL AwtClipboard::areOwnershipExtraChecksEnabled = FALSE;
volatile BOOL AwtClipboard::isOwner = FALSE;
volatile LONG /* BOOL */ AwtClipboard::isOwner = FALSE;
jmethodID AwtClipboard::ensureNoOwnedDataMID = nullptr;
void AwtClipboard::SetOwnershipExtraChecksEnabled(BOOL enabled) {
@@ -113,7 +113,10 @@ void AwtClipboard::ExtraCheckOfOwnership() {
return;
}
if (isOwner == TRUE) {
const bool isOwner =
// Checks the actual value of AwtClipboard::isOwner without altering it
(::InterlockedCompareExchange(&AwtClipboard::isOwner, TRUE, TRUE) != LONG{FALSE});
if (isOwner) {
const HWND toolkitHwnd = AwtToolkit::GetInstance().GetHWnd();
if (::OpenClipboard(toolkitHwnd) == 0) {

View File

@@ -54,7 +54,7 @@ public:
(void)::InterlockedExchange(&isGettingOwnership, TRUE); // isGettingOwnership = TRUE
VERIFY(EmptyClipboard());
(void)::InterlockedExchange(&isGettingOwnership, FALSE); // isGettingOwnership = FALSE
AwtClipboard::isOwner = TRUE;
(void)::InterlockedExchange(&isOwner, TRUE); // isOwner = TRUE;
}
INLINE static BOOL IsGettingOwnership() {
@@ -78,7 +78,12 @@ public:
private:
static volatile BOOL areOwnershipExtraChecksEnabled;
static volatile BOOL isOwner;
// Although the variable's type is LONG, it's supposed to be treated as BOOL,
// with the only possible values TRUE and FALSE.
// Also, all accesses to the variable (both reading and writing) MUST be performed using
// Windows Interlocked Variable Access API.
// LONG is only used to make sure it's safe to pass the variable to ::Interlocked*** functions.
static volatile LONG /* BOOL */ isOwner;
// ================================================================================================================
};

View File

@@ -1609,7 +1609,6 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
// the window is being activated, let's check if we still own the clipboard
AwtClipboard::ExtraCheckOfOwnership();
}
mr = mrConsume;
break;
case WM_MOUSEACTIVATE: {
AwtWindow *window = GetContainer();