8322750: Test "api/java_awt/interactive/SystemTrayTests.html" failed because A blue ball icon is added outside of the system tray

Reviewed-by: jdv, kizune, psadhukhan, prr
This commit is contained in:
Alexander Zvegintsev 2024-02-15 17:52:48 +00:00
parent a231706a06
commit 5a988a5087
2 changed files with 92 additions and 7 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -33,6 +33,7 @@ import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB;
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR;
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VRGB;
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.awt.color.ColorSpace;
@ -47,6 +48,9 @@ import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
@ -240,6 +244,72 @@ public abstract class UNIXToolkit extends SunToolkit
return img;
}
private static volatile Boolean shouldDisableSystemTray = null;
/**
* There is an issue displaying the xembed icons in appIndicators
* area with certain Gnome Shell versions.
* To avoid any loss of quality of service, we are disabling
* SystemTray support in such cases.
*
* @return true if system tray should be disabled
*/
public boolean shouldDisableSystemTray() {
Boolean result = shouldDisableSystemTray;
if (result == null) {
synchronized (GTK_LOCK) {
result = shouldDisableSystemTray;
if (result == null) {
if ("gnome".equals(getDesktop())) {
@SuppressWarnings("removal")
Integer gnomeShellMajorVersion =
AccessController
.doPrivileged((PrivilegedAction<Integer>)
this::getGnomeShellMajorVersion);
if (gnomeShellMajorVersion == null
|| gnomeShellMajorVersion < 45) {
return shouldDisableSystemTray = true;
}
}
shouldDisableSystemTray = result = false;
}
}
}
return result;
}
private Integer getGnomeShellMajorVersion() {
try {
Process process =
new ProcessBuilder("/usr/bin/gnome-shell", "--version")
.start();
try (InputStreamReader isr = new InputStreamReader(process.getInputStream());
BufferedReader reader = new BufferedReader(isr)) {
if (process.waitFor(2, SECONDS) && process.exitValue() == 0) {
String line = reader.readLine();
if (line != null) {
String[] versionComponents = line
.replaceAll("[^\\d.]", "")
.split("\\.");
if (versionComponents.length >= 1) {
return Integer.parseInt(versionComponents[0]);
}
}
}
}
} catch (IOException
| InterruptedException
| IllegalThreadStateException
| NumberFormatException ignored) {
}
return null;
}
/**
* Returns a BufferedImage which contains the Gtk icon requested. If no
* such icon exists or an error occurs loading the icon the result will

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -30,6 +30,7 @@ import java.awt.peer.SystemTrayPeer;
import sun.awt.SunToolkit;
import sun.awt.AppContext;
import sun.awt.AWTAccessor;
import sun.awt.UNIXToolkit;
import sun.util.logging.PlatformLogger;
public class XSystemTrayPeer implements SystemTrayPeer, XMSelectionListener {
@ -48,22 +49,32 @@ public class XSystemTrayPeer implements SystemTrayPeer, XMSelectionListener {
private static final XAtom _NET_SYSTEM_TRAY_OPCODE = XAtom.get("_NET_SYSTEM_TRAY_OPCODE");
private static final XAtom _NET_WM_ICON = XAtom.get("_NET_WM_ICON");
private static final long SYSTEM_TRAY_REQUEST_DOCK = 0;
private final boolean shouldDisableSystemTray;
XSystemTrayPeer(SystemTray target) {
this.target = target;
peerInstance = this;
selection.addSelectionListener(this);
UNIXToolkit tk = (UNIXToolkit)Toolkit.getDefaultToolkit();
shouldDisableSystemTray = tk.shouldDisableSystemTray();
long selection_owner = selection.getOwner(SCREEN);
available = (selection_owner != XConstants.None);
if (!shouldDisableSystemTray) {
selection.addSelectionListener(this);
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine(" check if system tray is available. selection owner: " + selection_owner);
long selection_owner = selection.getOwner(SCREEN);
available = (selection_owner != XConstants.None);
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine(" check if system tray is available. selection owner: " + selection_owner);
}
}
}
public void ownerChanged(int screen, XMSelection sel, long newOwner, long data, long timestamp) {
if (shouldDisableSystemTray) {
return;
}
if (screen != SCREEN) {
return;
}
@ -77,6 +88,10 @@ public class XSystemTrayPeer implements SystemTrayPeer, XMSelectionListener {
}
public void ownerDeath(int screen, XMSelection sel, long deadOwner) {
if (shouldDisableSystemTray) {
return;
}
if (screen != SCREEN) {
return;
}