8377191: Remove AppContext from KeyboardFocusManager

Reviewed-by: dnguyen, tr, serb
This commit is contained in:
Phil Race 2026-02-13 22:40:26 +00:00
parent a98d3a76a5
commit 1920983edb
6 changed files with 46 additions and 187 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2026, 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
@ -64,7 +64,6 @@ import javax.swing.JComponent;
import sun.awt.AWTAccessor;
import sun.awt.AWTAccessor.ComponentAccessor;
import sun.awt.AppContext;
import sun.awt.CGraphicsDevice;
import sun.awt.DisplayChangedListener;
import sun.awt.ExtendedKeyCodes;
@ -1236,9 +1235,7 @@ public class LWWindowPeer
return false;
}
AppContext targetAppContext = AWTAccessor.getComponentAccessor().getAppContext(getTarget());
KeyboardFocusManager kfm = AWTAccessor.getKeyboardFocusManagerAccessor()
.getCurrentKeyboardFocusManager(targetAppContext);
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
Window currentActive = kfm.getActiveWindow();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2026, 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
@ -7938,7 +7938,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
(this, temporary, focusedWindowChangeAllowed, time, cause);
if (!success) {
KeyboardFocusManager.getCurrentKeyboardFocusManager
(appContext).dequeueKeyEvents(time, this);
().dequeueKeyEvents(time, this);
if (focusLog.isLoggable(PlatformLogger.Level.FINEST)) {
focusLog.finest("Peer request failed");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2026, 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
@ -38,7 +38,6 @@ import java.util.ListIterator;
import java.util.Set;
import sun.awt.AWTAccessor;
import sun.awt.AppContext;
import sun.awt.SunToolkit;
import sun.awt.TimedWindowEvent;
import sun.util.logging.PlatformLogger;
@ -231,9 +230,8 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
@Serial
private static final long serialVersionUID = -2924743257508701758L;
public DefaultKeyboardFocusManagerSentEvent(AWTEvent nested,
AppContext toNotify) {
super(nested, toNotify);
public DefaultKeyboardFocusManagerSentEvent(AWTEvent nested) {
super(nested);
}
public final void dispatch() {
KeyboardFocusManager manager =
@ -260,76 +258,12 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
}
/**
* Sends a synthetic AWTEvent to a Component. If the Component is in
* the current AppContext, then the event is immediately dispatched.
* If the Component is in a different AppContext, then the event is
* posted to the other AppContext's EventQueue, and this method blocks
* until the event is handled or target AppContext is disposed.
* Returns true if successfully dispatched event, false if failed
* to dispatch.
* Sends a synthetic AWTEvent to a Component.
*/
static boolean sendMessage(Component target, AWTEvent e) {
e.isPosted = true;
AppContext myAppContext = AppContext.getAppContext();
final AppContext targetAppContext = target.appContext;
final SentEvent se =
new DefaultKeyboardFocusManagerSentEvent(e, myAppContext);
if (myAppContext == targetAppContext) {
se.dispatch();
} else {
if (targetAppContext.isDisposed()) {
return false;
}
SunToolkit.postEvent(targetAppContext, se);
if (EventQueue.isDispatchThread()) {
if (Thread.currentThread() instanceof EventDispatchThread) {
EventDispatchThread edt = (EventDispatchThread)
Thread.currentThread();
edt.pumpEvents(SentEvent.ID, new Conditional() {
public boolean evaluate() {
return !se.dispatched && !targetAppContext.isDisposed();
}
});
} else {
if (fxAppThreadIsDispatchThread) {
Thread fxCheckDispatchThread = new Thread() {
@Override
public void run() {
while (!se.dispatched && !targetAppContext.isDisposed()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
break;
}
}
}
};
fxCheckDispatchThread.start();
try {
// check if event is dispatched or disposed
// but since this user app thread is same as
// dispatch thread in fx when run with
// javafx.embed.singleThread=true
// we do not wait infinitely to avoid deadlock
// as dispatch will ultimately be done by this thread
fxCheckDispatchThread.join(500);
} catch (InterruptedException ex) {
}
}
}
} else {
synchronized (se) {
while (!se.dispatched && !targetAppContext.isDisposed()) {
try {
se.wait(1000);
} catch (InterruptedException ie) {
break;
}
}
}
}
}
final SentEvent se = new DefaultKeyboardFocusManagerSentEvent(e);
se.dispatch();
return se.dispatched;
}
@ -356,7 +290,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
// Check that the component awaiting focus belongs to
// the current focused window. See 8015454.
if (toplevel != null && toplevel.isFocused()) {
SunToolkit.postEvent(AppContext.getAppContext(), new SequencedEvent(e));
SunToolkit.postEvent(new SequencedEvent(e));
return true;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2026, 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
@ -50,7 +50,6 @@ import java.util.WeakHashMap;
import sun.util.logging.PlatformLogger;
import sun.awt.AppContext;
import sun.awt.SunToolkit;
import sun.awt.KeyboardFocusManagerPeerProvider;
import sun.awt.AWTAccessor;
@ -127,9 +126,6 @@ public abstract class KeyboardFocusManager
public void setMostRecentFocusOwner(Window window, Component component) {
KeyboardFocusManager.setMostRecentFocusOwner(window, component);
}
public KeyboardFocusManager getCurrentKeyboardFocusManager(AppContext ctx) {
return KeyboardFocusManager.getCurrentKeyboardFocusManager(ctx);
}
public Container getCurrentFocusCycleRoot() {
return KeyboardFocusManager.currentFocusCycleRoot;
}
@ -183,53 +179,40 @@ public abstract class KeyboardFocusManager
static final int TRAVERSAL_KEY_LENGTH = DOWN_CYCLE_TRAVERSAL_KEYS + 1;
private static KeyboardFocusManager manager;
/**
* Returns the current KeyboardFocusManager instance for the calling
* thread's context.
* Returns the current KeyboardFocusManager instance
*
* @return this thread's context's KeyboardFocusManager
* @return the current KeyboardFocusManager
* @see #setCurrentKeyboardFocusManager
*/
public static KeyboardFocusManager getCurrentKeyboardFocusManager() {
return getCurrentKeyboardFocusManager(AppContext.getAppContext());
}
static synchronized KeyboardFocusManager
getCurrentKeyboardFocusManager(AppContext appcontext)
{
KeyboardFocusManager manager = (KeyboardFocusManager)
appcontext.get(KeyboardFocusManager.class);
public static synchronized KeyboardFocusManager getCurrentKeyboardFocusManager() {
if (manager == null) {
manager = new DefaultKeyboardFocusManager();
appcontext.put(KeyboardFocusManager.class, manager);
}
return manager;
}
/**
* Sets the current KeyboardFocusManager instance for the calling thread's
* context. If null is specified, then the current KeyboardFocusManager
* Sets the current KeyboardFocusManager instance.
* If null is specified, then the current KeyboardFocusManager
* is replaced with a new instance of DefaultKeyboardFocusManager.
*
* @param newManager the new KeyboardFocusManager for this thread's context
* @param newManager the new KeyboardFocusManager
* @see #getCurrentKeyboardFocusManager
* @see DefaultKeyboardFocusManager
*/
public static void setCurrentKeyboardFocusManager(KeyboardFocusManager newManager) {
KeyboardFocusManager oldManager = null;
KeyboardFocusManager oldManager = manager;
if (newManager == null) {
newManager = new DefaultKeyboardFocusManager();
}
synchronized (KeyboardFocusManager.class) {
AppContext appcontext = AppContext.getAppContext();
if (newManager != null) {
oldManager = getCurrentKeyboardFocusManager(appcontext);
appcontext.put(KeyboardFocusManager.class, newManager);
} else {
oldManager = getCurrentKeyboardFocusManager(appcontext);
appcontext.remove(KeyboardFocusManager.class);
}
manager = newManager;
}
if (oldManager != null) {
@ -344,7 +327,7 @@ public abstract class KeyboardFocusManager
private static java.util.Map<Window, WeakReference<Component>> mostRecentFocusOwners = new WeakHashMap<>();
/*
* SequencedEvent which is currently dispatched in AppContext.
* SequencedEvent which is currently dispatched.
*/
transient SequencedEvent currentSequencedEvent = null;
@ -431,13 +414,7 @@ public abstract class KeyboardFocusManager
*/
public Component getFocusOwner() {
synchronized (KeyboardFocusManager.class) {
if (focusOwner == null) {
return null;
}
return (focusOwner.appContext == AppContext.getAppContext())
? focusOwner
: null;
return focusOwner;
}
}
@ -599,42 +576,32 @@ public abstract class KeyboardFocusManager
}
/**
* Returns the permanent focus owner, if the permanent focus owner is in
* the same context as the calling thread. The permanent focus owner is
* Returns the permanent focus owner. The permanent focus owner is
* defined as the last Component in an application to receive a permanent
* FOCUS_GAINED event. The focus owner and permanent focus owner are
* equivalent unless a temporary focus change is currently in effect. In
* such a situation, the permanent focus owner will again be the focus
* owner when the temporary focus change ends.
*
* @return the permanent focus owner, or null if the permanent focus owner
* is not a member of the calling thread's context
* @return the permanent focus owner, or null if there is none
* @see #getGlobalPermanentFocusOwner
* @see #setGlobalPermanentFocusOwner
*/
public Component getPermanentFocusOwner() {
synchronized (KeyboardFocusManager.class) {
if (permanentFocusOwner == null) {
return null;
}
return (permanentFocusOwner.appContext ==
AppContext.getAppContext())
? permanentFocusOwner
: null;
return permanentFocusOwner;
}
}
/**
* Returns the permanent focus owner, even if the calling thread is in a
* different context than the permanent focus owner. The permanent focus
* Returns the permanent focus owner. The permanent focus
* owner is defined as the last Component in an application to receive a
* permanent FOCUS_GAINED event. The focus owner and permanent focus owner
* are equivalent unless a temporary focus change is currently in effect.
* In such a situation, the permanent focus owner will again be the focus
* owner when the temporary focus change ends.
*
* @return the permanent focus owner
* @return the permanent focus owner, or null if there is none
* @see #getPermanentFocusOwner
* @see #setGlobalPermanentFocusOwner
*/
@ -701,24 +668,16 @@ public abstract class KeyboardFocusManager
}
/**
* Returns the focused Window, if the focused Window is in the same context
* as the calling thread. The focused Window is the Window that is or
* contains the focus owner.
* Returns the focused Window.
* The focused Window is the Window that is or contains the focus owner.
*
* @return the focused Window, or null if the focused Window is not a
* member of the calling thread's context
* @return the focused Window, or null if there is none
* @see #getGlobalFocusedWindow
* @see #setGlobalFocusedWindow
*/
public Window getFocusedWindow() {
synchronized (KeyboardFocusManager.class) {
if (focusedWindow == null) {
return null;
}
return (focusedWindow.appContext == AppContext.getAppContext())
? focusedWindow
: null;
return focusedWindow;
}
}
@ -785,27 +744,19 @@ public abstract class KeyboardFocusManager
}
/**
* Returns the active Window, if the active Window is in the same context
* as the calling thread. Only a Frame or a Dialog can be the active
* Returns the active Window. Only a Frame or a Dialog can be the active
* Window. The native windowing system may denote the active Window or its
* children with special decorations, such as a highlighted title bar.
* The active Window is always either the focused Window, or the first
* Frame or Dialog that is an owner of the focused Window.
*
* @return the active Window, or null if the active Window is not a member
* of the calling thread's context
* @return the active Window, or null if there is none
* @see #getGlobalActiveWindow
* @see #setGlobalActiveWindow
*/
public Window getActiveWindow() {
synchronized (KeyboardFocusManager.class) {
if (activeWindow == null) {
return null;
}
return (activeWindow.appContext == AppContext.getAppContext())
? activeWindow
: null;
return activeWindow;
}
}
@ -1100,14 +1051,7 @@ public abstract class KeyboardFocusManager
*/
public Container getCurrentFocusCycleRoot() {
synchronized (KeyboardFocusManager.class) {
if (currentFocusCycleRoot == null) {
return null;
}
return (currentFocusCycleRoot.appContext ==
AppContext.getAppContext())
? currentFocusCycleRoot
: null;
return currentFocusCycleRoot;
}
}
@ -2159,7 +2103,7 @@ public abstract class KeyboardFocusManager
descendant = heavyweight;
}
KeyboardFocusManager manager = getCurrentKeyboardFocusManager(SunToolkit.targetToAppContext(descendant));
KeyboardFocusManager manager = getCurrentKeyboardFocusManager();
FocusEvent currentFocusOwnerEvent = null;
FocusEvent newFocusOwnerEvent = null;
@ -2268,8 +2212,7 @@ public abstract class KeyboardFocusManager
descendant = heavyweight;
}
KeyboardFocusManager manager =
getCurrentKeyboardFocusManager(SunToolkit.targetToAppContext(descendant));
KeyboardFocusManager manager = getCurrentKeyboardFocusManager();
KeyboardFocusManager thisManager = getCurrentKeyboardFocusManager();
Component currentFocusOwner = thisManager.getGlobalFocusOwner();
Component nativeFocusOwner = thisManager.getNativeFocusOwner();
@ -2484,16 +2427,6 @@ public abstract class KeyboardFocusManager
KeyboardFocusManager manager = getCurrentKeyboardFocusManager();
LinkedList<LightweightFocusRequest> localLightweightRequests = null;
Component globalFocusOwner = manager.getGlobalFocusOwner();
if ((globalFocusOwner != null) &&
(globalFocusOwner.appContext != AppContext.getAppContext()))
{
// The current app context differs from the app context of a focus
// owner (and all pending lightweight requests), so we do nothing
// now and wait for a next event.
return;
}
synchronized(heavyweightRequests) {
if (currentLightweightRequests != null) {
clearingCurrentLightweightRequests = true;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2026, 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
@ -441,11 +441,6 @@ public final class AWTAccessor {
*/
void setMostRecentFocusOwner(Window window, Component component);
/**
* Returns current KFM of the specified AppContext.
*/
KeyboardFocusManager getCurrentKeyboardFocusManager(AppContext ctx);
/**
* Return the current focus cycle root
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2026, 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
@ -218,7 +218,7 @@ public abstract class EmbeddedFrame extends Frame
*/
public boolean dispatchKeyEvent(KeyEvent e) {
Container currentRoot = AWTAccessor.getKeyboardFocusManagerAccessor()
Container currentRoot = KeyboardFocusManager.getCurrentKeyboardFocusManager()
.getCurrentFocusCycleRoot();
// if we are not in EmbeddedFrame's cycle, we should not try to leave.