Skip to content

Commit

Permalink
8297554: Remove Scene.KeyHandler
Browse files Browse the repository at this point in the history
Reviewed-by: arapte, kcr
  • Loading branch information
Michael Strauß committed Dec 21, 2022
1 parent 9c52605 commit ac3f60c
Showing 1 changed file with 101 additions and 106 deletions.
207 changes: 101 additions & 106 deletions modules/javafx.graphics/src/main/java/javafx/scene/Scene.java
Expand Up @@ -366,7 +366,7 @@ private Scene(Parent root, double width, double height, Paint fill,
EventHandler<InputEvent> pressedHandler = event -> {
Node focusOwner = getFocusOwner();
if (focusOwner != null) {
getKeyHandler().setFocusVisible(focusOwner, false);
setFocusOwner(focusOwner, false);
}
};

Expand Down Expand Up @@ -777,7 +777,7 @@ private ReadOnlyObjectWrapper<Window> windowPropertyImpl() {

@Override protected void invalidated() {
final Window newWindow = get();
getKeyHandler().windowForSceneChanged(oldWindow, newWindow);
windowForSceneChanged(oldWindow, newWindow);
if (oldWindow != null) {
disposePeer();
}
Expand Down Expand Up @@ -2090,19 +2090,41 @@ null, new Point3D(
* *
**************************************************************************/

/*
* We cannot initialize keyHandler in init because some of the triggers
* access it before the init block.
* No clue why def keyHandler = bind lazy {KeyHandler{scene:this};}
* does not compile.
private void windowForSceneChanged(Window oldWindow, Window newWindow) {
if (oldWindow != null) {
oldWindow.focusedProperty().removeListener(sceneWindowFocusedListener);
}

if (newWindow != null) {
newWindow.focusedProperty().addListener(sceneWindowFocusedListener);
setWindowFocused(newWindow.isFocused());
} else {
setWindowFocused(false);
}
}

private final InvalidationListener sceneWindowFocusedListener =
valueModel -> setWindowFocused(((ReadOnlyBooleanProperty)valueModel).get());

/**
* Stores whether the window associated with this scene is currently focused.
*/
private KeyHandler keyHandler = null;
private KeyHandler getKeyHandler() {
if (keyHandler == null) {
keyHandler = new KeyHandler();
private boolean windowFocused;

private void setWindowFocused(boolean value) {
windowFocused = value;

Node node = getFocusOwner();
if (node != null) {
node.setFocusQuietly(windowFocused, focusOwner.focusVisible);
node.notifyFocusListeners();
}

if (windowFocused && accessible != null) {
accessible.sendNotification(AccessibleAttribute.FOCUS_NODE);
}
return keyHandler;
}

/**
* Set to true if something has happened to the focused node that makes
* it no longer eligible to have the focus.
Expand Down Expand Up @@ -2159,22 +2181,50 @@ void processKeyEvent(KeyEvent e) {
}
}

getKeyHandler().process(e);
final Node sceneFocusOwner = getFocusOwner();
final EventTarget eventTarget =
(sceneFocusOwner != null && sceneFocusOwner.getScene() == Scene.this) ? sceneFocusOwner : Scene.this;

// send the key event to the current focus owner or to scene if
// the focus owner is not set
Event.fireEvent(eventTarget, e);
}

void requestFocus(Node node, boolean focusVisible) {
getKeyHandler().requestFocus(node, focusVisible);
if (node == null) {
setFocusOwner(null, false);
} else if (node.isCanReceiveFocus()) {
setFocusOwner(node, focusVisible);
}
}

private Node oldFocusOwner;

/**
* The scene's current focus owner node. This node's "focused"
* variable might be false if this scene has no window, or if the
* window is inactive (window.focused == false).
* @since JavaFX 2.2
*/
private ReadOnlyObjectWrapper<Node> focusOwner = new ReadOnlyObjectWrapper<>(this, "focusOwner") {
private FocusOwnerProperty focusOwner = new FocusOwnerProperty();

private class FocusOwnerProperty extends ReadOnlyObjectWrapper<Node> {
Node oldFocusOwner;

/**
* Stores whether the current focus owner visibly indicates focus.
* This value is used to restore visible focus when a window loses
* and re-gains focus.
*/
boolean focusVisible;

@Override
public Object getBean() {
return Scene.this;
}

@Override
public String getName() {
return "focusOwner";
}

@Override
protected void invalidated() {
Expand All @@ -2183,7 +2233,7 @@ protected void invalidated() {
}
Node value = get();
if (value != null) {
value.setFocusQuietly(keyHandler.windowFocused, keyHandler.focusVisible);
value.setFocusQuietly(windowFocused, focusVisible);
if (value != oldFocusOwner) {
value.getScene().enableInputMethodEvents(
value.getInputMethodRequests() != null
Expand Down Expand Up @@ -2218,12 +2268,43 @@ protected void invalidated() {
}
};

public final ReadOnlyObjectProperty<Node> focusOwnerProperty() {
return focusOwner.getReadOnlyProperty();
}

public final Node getFocusOwner() {
return focusOwner.get();
}

public final ReadOnlyObjectProperty<Node> focusOwnerProperty() {
return focusOwner.getReadOnlyProperty();
private void setFocusOwner(Node node, boolean focusVisible) {
// Cancel IM composition if there is one in progress.
// This needs to be done before the focus owner is switched as it
// generates event that needs to be delivered to the old focus owner.
if (focusOwner.oldFocusOwner != null) {
final Scene s = focusOwner.oldFocusOwner.getScene();
if (s != null) {
final TKScene peer = s.getPeer();
if (peer != null) {
peer.finishInputMethodComposition();
}
}
}

// Store the current focusVisible state of the focus owner in case it needs to be
// restored when a window loses and re-gains focus.
focusOwner.focusVisible = focusVisible;

if (focusOwner.get() != node) {
// If the focus owner has changed, FocusOwnerProperty::invalidated will update
// the node's focusVisible flag.
focusOwner.set(node);
} else if (node != null) {
// If the focus owner has not changed (i.e. only focusVisible has changed),
// FocusOwnerProperty::invalidated will not be called, therefore we need to
// update the node's focusVisible flag manually.
node.focusVisible.set(focusVisible);
node.focusVisible.notifyListeners();
}
}

// For testing.
Expand Down Expand Up @@ -4044,92 +4125,6 @@ private PickResult pickNode(PickRay pickRay) {
}
}

/* *****************************************************************************
* *
* Key Event Handling *
* *
******************************************************************************/

class KeyHandler {
boolean focusVisible;

private void setFocusOwner(Node value, boolean focusVisible) {
this.focusVisible = focusVisible;

// Cancel IM composition if there is one in progress.
// This needs to be done before the focus owner is switched as it
// generates event that needs to be delivered to the old focus owner.
if (oldFocusOwner != null) {
final Scene s = oldFocusOwner.getScene();
if (s != null) {
final TKScene peer = s.getPeer();
if (peer != null) {
peer.finishInputMethodComposition();
}
}
}
focusOwner.set(value);
}

private void setFocusVisible(Node node, boolean focusVisible) {
this.focusVisible = focusVisible;
node.focusVisible.set(focusVisible);
node.focusVisible.notifyListeners();
}

private boolean windowFocused;
protected boolean isWindowFocused() { return windowFocused; }
protected void setWindowFocused(boolean value) {
windowFocused = value;
if (getFocusOwner() != null) {
getFocusOwner().setFocusQuietly(windowFocused, focusVisible);
getFocusOwner().notifyFocusListeners();
}
if (windowFocused) {
if (accessible != null) {
accessible.sendNotification(AccessibleAttribute.FOCUS_NODE);
}
}
}

private void windowForSceneChanged(Window oldWindow, Window window) {
if (oldWindow != null) {
oldWindow.focusedProperty().removeListener(sceneWindowFocusedListener);
}

if (window != null) {
window.focusedProperty().addListener(sceneWindowFocusedListener);
setWindowFocused(window.isFocused());
} else {
setWindowFocused(false);
}
}

private final InvalidationListener sceneWindowFocusedListener = valueModel -> setWindowFocused(((ReadOnlyBooleanProperty)valueModel).get());

private void process(KeyEvent e) {
final Node sceneFocusOwner = getFocusOwner();
final EventTarget eventTarget =
(sceneFocusOwner != null && sceneFocusOwner.getScene() == Scene.this) ? sceneFocusOwner
: Scene.this;

// send the key event to the current focus owner or to scene if
// the focus owner is not set
Event.fireEvent(eventTarget, e);
}

private void requestFocus(Node node, boolean focusVisible) {
if (node == null) {
setFocusOwner(null, false);
} else if (node.isCanReceiveFocus()) {
if (node != getFocusOwner()) {
setFocusOwner(node, focusVisible);
} else {
setFocusVisible(node, focusVisible);
}
}
}
}
/* *************************************************************************
* *
* Event Dispatch *
Expand Down

1 comment on commit ac3f60c

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.