Compare commits

..

2 Commits

Author SHA1 Message Date
bourgesl
7dd1877b07 JBR-9351 jb/java/awt/Counters/UpdateWindowsCounter.java fails by time out
Fixed Timers to be daemon
2025-09-15 07:56:34 +02:00
bourgesl
8e83713851 JBR-9350 javax/swing/JOptionPane/8081019/bug8081019.java: Cannot invoke "sun.lwawt.LWWindowPeer.getTarget()" because "this.peer" is null
Added peer null checks + use perfCountersEnabled flag
2025-09-15 07:56:34 +02:00
8 changed files with 52 additions and 254 deletions

View File

@@ -4319,43 +4319,38 @@ public class BasicTreeUI extends TreeUI
updateSize();
}
else if (treeState.isExpanded(parentPath)) {
boolean isShowing = tree.isShowing();
TreePath minPath = null;
Rectangle minBounds = null;
if (isShowing) {
// Changed nodes are visible
// Find the minimum index, we only need paint from there
// down.
int minIndex = indices[0];
for (int i = indices.length - 1; i > 0; i--) {
minIndex = Math.min(indices[i], minIndex);
}
Object minChild = treeModel.getChild(
parentPath.getLastPathComponent(), minIndex);
minPath = parentPath.pathByAddingChild(minChild);
minBounds = getPathBounds(tree, minPath);
// Changed nodes are visible
// Find the minimum index, we only need paint from there
// down.
int minIndex = indices[0];
for (int i = indices.length - 1; i > 0; i--) {
minIndex = Math.min(indices[i], minIndex);
}
Object minChild = treeModel.getChild(
parentPath.getLastPathComponent(), minIndex);
TreePath minPath = parentPath.pathByAddingChild(minChild);
Rectangle minBounds = getPathBounds(tree, minPath);
// Forward to the treestate
treeState.treeNodesChanged(e);
// Mark preferred size as bogus.
updateSize0();
if (isShowing) {
// And repaint
Rectangle newMinBounds = getPathBounds(tree, minPath);
if (minBounds == null || newMinBounds == null) {
return;
}
// And repaint
Rectangle newMinBounds = getPathBounds(tree, minPath);
if (minBounds == null || newMinBounds == null) {
return;
}
if (indices.length == 1 &&
newMinBounds.height == minBounds.height) {
tree.repaint(0, minBounds.y, tree.getWidth(),
minBounds.height);
} else {
tree.repaint(0, minBounds.y, tree.getWidth(),
tree.getHeight() - minBounds.y);
}
if (indices.length == 1 &&
newMinBounds.height == minBounds.height) {
tree.repaint(0, minBounds.y, tree.getWidth(),
minBounds.height);
}
else {
tree.repaint(0, minBounds.y, tree.getWidth(),
tree.getHeight() - minBounds.y);
}
}
else {

View File

@@ -87,7 +87,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.concurrent.Semaphore;
@@ -151,10 +150,7 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
VKEnv.init(display);
initIDs(display);
}
@SuppressWarnings("removal")
String desktop = AccessController.doPrivileged((PrivilegedAction<String>) ()
-> System.getenv("XDG_CURRENT_DESKTOP"));
String desktop = System.getenv("XDG_CURRENT_DESKTOP");
isKDE = desktop != null && desktop.toLowerCase().contains("kde");
initialized = true;
}
@@ -443,7 +439,6 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
final WLInputState newInputState = inputState.updatedFromKeyboardLeaveEvent(serial, surfacePtr);
final WLWindowPeer peer = peerFromSurface(surfacePtr);
if (peer != null && peer.getTarget() instanceof Window window) {
((WLToolkit) Toolkit.getDefaultToolkit()).ungrab(window);
final WindowEvent winLostFocusEvent = new WindowEvent(window, WindowEvent.WINDOW_LOST_FOCUS);
WLKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow(null);
WLKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
@@ -966,25 +961,15 @@ public class WLToolkit extends UNIXToolkit implements Runnable {
@Override
public void grab(Window w) {
// There is no input grab in Wayland for client applications, only
// the compositor can control grabs. But we need UngrabEvent
// for popup/tooltip management, so we do input grab accounting here
// and in ungrab() below.
Objects.requireNonNull(w);
var peer = AWTAccessor.getComponentAccessor().getPeer(w);
if (peer instanceof WLWindowPeer windowPeer) {
windowPeer.grab();
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Not implemented: WLToolkit.grab()");
}
}
@Override
public void ungrab(Window w) {
Objects.requireNonNull(w);
var peer = AWTAccessor.getComponentAccessor().getPeer(w);
if (peer instanceof WLWindowPeer windowPeer) {
windowPeer.ungrab();
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Not implemented: WLToolkit.ungrab()");
}
}
/**

View File

@@ -26,7 +26,6 @@ package sun.awt.wl;
import sun.awt.AWTAccessor;
import sun.awt.SurfacePixelGrabber;
import sun.awt.UngrabEvent;
import sun.java2d.SunGraphics2D;
import sun.java2d.vulkan.VKSurfaceData;
import sun.java2d.wl.WLSMSurfaceData;
@@ -53,7 +52,6 @@ import java.lang.ref.WeakReference;
public class WLWindowPeer extends WLComponentPeer implements WindowPeer, SurfacePixelGrabber {
private static Font defaultFont;
private Dialog blocker;
private static WLWindowPeer grabbingWindow; // fake, kept for UngrabEvent only
// If this window gets focus from Wayland, we need to transfer focus synthFocusOwner, if any
private WeakReference<Component> synthFocusOwner = new WeakReference<>(null);
@@ -100,8 +98,6 @@ public class WLWindowPeer extends WLComponentPeer implements WindowPeer, Surface
@Override
protected void wlSetVisible(boolean v) {
if (!v) ungrab();
if (v && targetIsWlPopup() && shouldBeFocusedOnShowing()) {
requestWindowFocus();
}
@@ -204,7 +200,6 @@ public class WLWindowPeer extends WLComponentPeer implements WindowPeer, Surface
@Override
public void dispose() {
ungrab();
resetCornerMasks();
super.dispose();
}
@@ -244,24 +239,6 @@ public class WLWindowPeer extends WLComponentPeer implements WindowPeer, Surface
synthFocusOwner = new WeakReference<>(c);
}
public void grab() {
if (grabbingWindow != null && !isGrabbing()) {
grabbingWindow.ungrab();
}
grabbingWindow = this;
}
public void ungrab() {
if (isGrabbing()) {
grabbingWindow = null;
WLToolkit.postEvent(new UngrabEvent(getTarget()));
}
}
private boolean isGrabbing() {
return this == grabbingWindow;
}
@Override
public BufferedImage getClientAreaSnapshot(int x, int y, int width, int height) {
// Move the coordinate system to the client area

View File

@@ -22,72 +22,25 @@
*/
#include "AccessibleCaret.h"
#include "debug_assert.h" // DASSERT
#include "sun_awt_windows_AccessibleCaretLocationNotifier.h"
#include <atomic> // std::atomic
/**
* This class implements Win32 IAccessible interface in a similar way to the system text caret.
*/
static std::atomic<AccessibleCaret *> GLOBAL_INSTANCE{nullptr};
AccessibleCaret* AccessibleCaret::getInstanceIfPresent() noexcept {
return GLOBAL_INSTANCE.load();
}
AccessibleCaret* AccessibleCaret::getOrCreateInstance() {
bool unused;
return AccessibleCaret::getOrCreateInstance(unused);
}
AccessibleCaret* AccessibleCaret::getOrCreateInstance(bool& instanceIsNew) {
instanceIsNew = false;
AccessibleCaret* result = GLOBAL_INSTANCE.load();
if (result == nullptr) {
AccessibleCaret* newInstance = new AccessibleCaret();
if (GLOBAL_INSTANCE.compare_exchange_strong(result, newInstance)) {
result = newInstance;
instanceIsNew = true;
} else {
DASSERT(result != nullptr);
delete newInstance;
}
}
DASSERT(result != nullptr);
return result;
}
bool AccessibleCaret::releaseInstanceIfPresent() {
AccessibleCaret* instance = GLOBAL_INSTANCE.exchange(nullptr);
if (instance != nullptr) {
instance->Release();
return true;
}
return false;
}
*/
AccessibleCaret::AccessibleCaret()
: m_refCount(1), m_x(0), m_y(0), m_width(0), m_height(0) {
InitializeCriticalSection(&m_caretLocationLock);
}
AccessibleCaret* AccessibleCaret::createInstance() {
return new AccessibleCaret();
}
AccessibleCaret::~AccessibleCaret() {
DeleteCriticalSection(&m_caretLocationLock);
// If the destroyed object is being referred by the singleton variable, the latter should be cleared.
// This case should never happen, but if it does, it's better not to leave a dangling pointer.
AccessibleCaret* self = this;
(void)GLOBAL_INSTANCE.compare_exchange_strong(self, nullptr);
}
std::atomic<AccessibleCaret *> AccessibleCaret::instance{nullptr};
// IUnknown methods
IFACEMETHODIMP_(ULONG) AccessibleCaret::AddRef() {
@@ -287,10 +240,10 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_AccessibleCaretLocationNotifier_upda
JNIEnv *env, jclass jClass,
jlong jHwnd, jint x, jint y, jint width, jint height) {
HWND hwnd = reinterpret_cast<HWND>(jHwnd);
bool caretIsNew = false;
AccessibleCaret* caret = AccessibleCaret::getOrCreateInstance(caretIsNew);
if (caretIsNew) {
AccessibleCaret *caret = AccessibleCaret::instance.load(std::memory_order_acquire);
if (caret == nullptr) {
caret = AccessibleCaret::createInstance();
AccessibleCaret::instance.store(caret, std::memory_order_release);
// Notify with Object ID "OBJID_CARET".
// After that, an assistive tool will send a WM_GETOBJECT message with this ID,
// and we can return the caret instance.
@@ -308,7 +261,9 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_AccessibleCaretLocationNotifier_upda
*/
JNIEXPORT void JNICALL Java_sun_awt_windows_AccessibleCaretLocationNotifier_releaseNativeCaret(
JNIEnv *env, jclass jClass, jlong jHwnd) {
if (AccessibleCaret::releaseInstanceIfPresent()) {
AccessibleCaret *caret = AccessibleCaret::instance.exchange(nullptr, std::memory_order_acq_rel);
if (caret != nullptr) {
caret->Release();
HWND hwnd = reinterpret_cast<HWND>(jHwnd);
NotifyWinEvent(EVENT_OBJECT_HIDE, hwnd, OBJID_CARET, CHILDID_SELF);
NotifyWinEvent(EVENT_OBJECT_DESTROY, hwnd, OBJID_CARET, CHILDID_SELF);

View File

@@ -23,16 +23,14 @@
#ifndef ACCESSIBLECARET_H
#define ACCESSIBLECARET_H
#include "jni.h"
#include <oleacc.h>
#include <windows.h> // ULONG, CRITICAL_SECTION
#include <atomic>
class AccessibleCaret : public IAccessible {
public:
static AccessibleCaret* getInstanceIfPresent() noexcept;
static AccessibleCaret* getOrCreateInstance();
static AccessibleCaret* getOrCreateInstance(bool& instanceIsNew);
static bool releaseInstanceIfPresent();
static AccessibleCaret *createInstance();
static std::atomic<AccessibleCaret *> instance;
// IUnknown methods.
IFACEMETHODIMP_(ULONG) AddRef();

View File

@@ -48,8 +48,8 @@
#include "awt_Win32GraphicsDevice.h"
#include "Hashtable.h"
#include "ComCtl32Util.h"
#include "AccessibleCaret.h"
#include "math.h"
#include "AccessibleCaret.h"
#include <Region.h>
@@ -2091,7 +2091,7 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
}
}
} else if (objId == OBJID_CARET) {
AccessibleCaret *caret = AccessibleCaret::getInstanceIfPresent();
AccessibleCaret *caret = AccessibleCaret::instance.load(std::memory_order_acquire);
if (caret != nullptr) {
retValue = LresultFromObject(IID_IAccessible, wParam, caret);
mr = mrConsume;

View File

@@ -1,112 +0,0 @@
/*
* Copyright 2025 JetBrains s.r.o.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;
import java.util.concurrent.CompletableFuture;
/**
* @test
* @summary Verifies popups and tooltips are disposed of when switching to a different window
* @requires os.family == "linux"
* @key headful
* @run main/manual WLUngrab
*/
public class WLUngrab {
static final CompletableFuture<RuntimeException> swingError = new CompletableFuture<>();
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(WLUngrab::showUI);
swingError.get();
}
private static void showUI() {
JFrame frame = new JFrame("Ungrab test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMenuBar menuBar = new JMenuBar();
JMenu menu1 = new JMenu("Test menu");
menu1.add(new JMenuItem("item 1"));
menu1.add(new JMenuItem("item 2"));
menu1.addSeparator();
JMenu submenu = new JMenu("submenu...");
submenu.add(new JMenuItem("subitem1"));
submenu.add(new JMenuItem("subitem2"));
submenu.add(new JMenuItem("subitem3"));
menu1.add(submenu);
menuBar.add(menu1);
JMenu menu2 = new JMenu("Another");
menu2.add(new JMenuItem("test"));
menuBar.add(menu2);
frame.setJMenuBar(menuBar);
JLabel label = new JLabel("Right-click here for a popup-menu.");
final JPopupMenu popup = new JPopupMenu();
popup.add(new JMenuItem("popup menu item"));
popup.add(new JMenuItem("popup menu item 2"));
popup.add(new JMenuItem("popup menu item 3"));
label.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if (e.isPopupTrigger()) {
popup.show(e.getComponent(),
e.getX(), e.getY());
}
}
});
JPanel content = new JPanel();
var layout = new GridLayout(3, 2, 10, 10);
content.setLayout(layout);
content.add(label);
JButton button = new JButton("Hover here for a tooltip");
button.setToolTipText("<html><h1>TOOLTIP</h2><p>tooltip text</p></html>");
content.add(button);
JButton passButton = new JButton("Pass");
passButton.addActionListener(e -> {swingError.complete(null);});
JButton failButton = new JButton("Fail");
failButton.addActionListener(e -> {swingError.completeExceptionally(new RuntimeException("The tester has pressed FAILED"));});
content.add(failButton);
content.add(passButton);
content.add(new JLabel("<html><h1>INSTRUCTIONS</h1>" +
"<p>Make a tooltip, popup, or pulldown menu appear.</p>" +
"<p>Switch to a different application window.</p>" +
"<p>Switch back to this window.</p>" +
"<p>Press Pass iff the tooltip/popup/menu was closed upon switching back.</p>" +
"<p>Otherwise press Fail.</p></html>"));
frame.setContentPane(content);
frame.pack();
frame.setVisible(true);
}
}

View File

@@ -116,7 +116,7 @@
java/awt/AlphaComposite/WindowAlphaCompositeTest.java JBR-6553 macosx-all
java/awt/Button/DisabledButtonPress.java JBR-5799 windows-aarch64
java/awt/Desktop/8064934/bug8064934.java JBR-5764,JBR-5799 windows-all
java/awt/Debug/DumpOnKey/DumpOnKey.java JBR-5225,JBR-9350 windows-all,macosx-all
java/awt/Debug/DumpOnKey/DumpOnKey.java JBR-5225 windows-all
java/awt/event/HierarchyEvent/SpecTest.java JBR-7589 windows-all
java/awt/event/KeyEvent/CorrectTime/CorrectTime.java JBR-6665 linux-all,windows-all
java/awt/event/KeyEvent/SwallowKeyEvents/SwallowKeyEvents.java 8224055,JBR-5906 macosx-all,linux-all
@@ -764,7 +764,7 @@ java/awt/MenuBar/TestNoScreenMenuBar.java 8265987 macosx-all
java/awt/Dialog/DialogAboveFrame/DialogAboveFrameTest.java JBR-5210 windows-all
java/awt/Dialog/MakeWindowAlwaysOnTop/MakeWindowAlwaysOnTop.java 8266243,JBR-6632 macosx-all,linux-all
java/awt/Dialog/ModalDialogPermission/ModalDialogPermission.java JBR-5225,JBR-9350 windows-all,macosx-all
java/awt/Dialog/ModalDialogPermission/ModalDialogPermission.java JBR-5225 windows-all
java/awt/Dialog/SiblingChildOrder/SiblingChildOrderTest.java JBR-5082 linux-all
java/awt/Window/GetScreenLocation/GetScreenLocationTest.java 8225787,8253184 linux-all,windows-all
java/awt/dnd/DragSourceMotionListenerTest.java 8225131 windows-all
@@ -1064,7 +1064,7 @@ javax/swing/JMenuItem/8158566/CloseOnMouseClickPropertyTest.java JBR-5545,JBR-65
javax/swing/JMenuItem/bug4839464.java JBR-5911 windows-all
javax/swing/JMenuItem/6249972/bug6249972.java 8197552 windows-all
javax/swing/JOptionPane/7138665/bug7138665.java JBR-5799 windows-all
javax/swing/JOptionPane/8081019/bug8081019.java JBR-5767,JBR-9350 windows-all,macosx-all
javax/swing/JOptionPane/8081019/bug8081019.java JBR-5767 windows-all
javax/swing/JPasswordField/TestSelectedTextBackgroundColor.java JBR-8665 linux-6.8.0-1017-raspi
javax/swing/JProgressBar/8015748/JProgressBarOrientationRobotTest.java JBR-8571 linux-all
javax/swing/JProgressBar/8161664/ProgressBarMemoryLeakTest.java JBR-8926 macosx-x64