From b8fd2a5e1f7bbd86fa32f48c14378eef2f83ec19 Mon Sep 17 00:00:00 2001 From: mstr2 <43553916+mstr2@users.noreply.github.com> Date: Wed, 21 Apr 2021 20:06:51 +0200 Subject: [PATCH 01/21] Added :focus-visible CSS pseudoclass --- .../scene/control/DatePickerContent.java | 3 +- .../control/behavior/ButtonBehavior.java | 2 +- .../behavior/FocusTraversalInputMap.java | 17 +- .../control/behavior/SliderBehavior.java | 5 +- .../behavior/TwoLevelFocusBehavior.java | 13 +- .../behavior/TwoLevelFocusComboBehavior.java | 13 +- .../behavior/TwoLevelFocusListBehavior.java | 13 +- .../behavior/TwoLevelFocusPopupBehavior.java | 21 +-- .../scene/KeyboardShortcutsHandler.java | 3 +- .../java/com/sun/javafx/scene/NodeHelper.java | 12 +- .../traversal/TopMostTraversalEngine.java | 19 +- .../scene/traversal/TraversalMethod.java | 41 +++++ .../src/main/java/javafx/scene/Node.java | 170 ++++++++++++------ .../src/main/java/javafx/scene/Scene.java | 36 ++-- .../src/main/java/javafx/scene/SubScene.java | 5 +- .../traversal/TopMostTraversalEngineTest.java | 35 ++-- .../javafx/scene/traversal/TraversalTest.java | 7 +- .../traversal/TraverseInvisibleTest.java | 3 +- .../sun/javafx/webkit/WebPageClientImpl.java | 3 +- 19 files changed, 278 insertions(+), 143 deletions(-) create mode 100644 modules/javafx.graphics/src/main/java/com/sun/javafx/scene/traversal/TraversalMethod.java diff --git a/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/DatePickerContent.java b/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/DatePickerContent.java index 761887a16de..83c432ed0af 100644 --- a/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/DatePickerContent.java +++ b/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/DatePickerContent.java @@ -66,6 +66,7 @@ import com.sun.javafx.scene.control.skin.resources.ControlResources; import com.sun.javafx.scene.traversal.Direction; +import com.sun.javafx.scene.traversal.TraversalMethod; import static com.sun.javafx.PlatformUtil.*; import com.sun.javafx.scene.NodeHelper; @@ -170,7 +171,7 @@ public DatePickerContent(final DatePicker datePicker) { if (newFocusOwner == gridPane) { if (oldFocusOwner instanceof DateCell) { // Backwards traversal, skip gridPane. - NodeHelper.traverse(gridPane, Direction.PREVIOUS); + NodeHelper.traverse(gridPane, Direction.PREVIOUS, TraversalMethod.DEFAULT); } else { // Forwards traversal, pass focus to day cell. if (lastFocusedDayCell != null) { diff --git a/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/ButtonBehavior.java b/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/ButtonBehavior.java index e485c83e539..d5777a13a03 100644 --- a/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/ButtonBehavior.java +++ b/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/ButtonBehavior.java @@ -179,7 +179,7 @@ protected void keyReleased(KeyEvent e) { */ protected void mousePressed(MouseEvent e) { // if the button is not already focused, then request the focus - if (! getNode().isFocused() && getNode().isFocusTraversable()) { + if (getNode().isFocusTraversable()) { getNode().requestFocus(); } diff --git a/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/FocusTraversalInputMap.java b/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/FocusTraversalInputMap.java index d18821f4ba6..d1df5c65a46 100644 --- a/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/FocusTraversalInputMap.java +++ b/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/FocusTraversalInputMap.java @@ -26,6 +26,7 @@ import com.sun.javafx.scene.NodeHelper; import com.sun.javafx.scene.traversal.Direction; +import com.sun.javafx.scene.traversal.TraversalMethod; import javafx.event.EventTarget; import javafx.scene.Node; import com.sun.javafx.scene.control.inputmap.InputMap; @@ -90,12 +91,12 @@ public static InputMap createInputMap(N node) { * @param node The node to traverse on * @param dir The direction to traverse */ - public static void traverse(final Node node, final Direction dir) { + public static void traverse(final Node node, final Direction dir, TraversalMethod method) { if (node == null) { throw new IllegalArgumentException("Attempting to traverse on a null Node. " + "Most probably a KeyEvent has been fired with a null target specified."); } - NodeHelper.traverse(node, dir); + NodeHelper.traverse(node, dir, method); } /** @@ -103,7 +104,7 @@ public static void traverse(final Node node, final Direction dir) { * go the next focusTraversable Node above the current one. */ public static final void traverseUp(KeyEvent e) { - traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.UP); + traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.UP, TraversalMethod.KEY); } /** @@ -111,7 +112,7 @@ public static final void traverseUp(KeyEvent e) { * go the next focusTraversable Node below the current one. */ public static final void traverseDown(KeyEvent e) { - traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.DOWN); + traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.DOWN, TraversalMethod.KEY); } /** @@ -119,7 +120,7 @@ public static final void traverseDown(KeyEvent e) { * go the next focusTraversable Node left of the current one. */ public static final void traverseLeft(KeyEvent e) { - traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.LEFT); + traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.LEFT, TraversalMethod.KEY); } /** @@ -127,7 +128,7 @@ public static final void traverseLeft(KeyEvent e) { * go the next focusTraversable Node right of the current one. */ public static final void traverseRight(KeyEvent e) { - traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.RIGHT); + traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.RIGHT, TraversalMethod.KEY); } /** @@ -135,7 +136,7 @@ public static final void traverseRight(KeyEvent e) { * go the next focusTraversable Node in the focus traversal cycle. */ public static final void traverseNext(KeyEvent e) { - traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.NEXT); + traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.NEXT, TraversalMethod.KEY); } /** @@ -143,7 +144,7 @@ public static final void traverseNext(KeyEvent e) { * go the previous focusTraversable Node in the focus traversal cycle. */ public static final void traversePrevious(KeyEvent e) { - traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.PREVIOUS); + traverse(getNode(e), com.sun.javafx.scene.traversal.Direction.PREVIOUS, TraversalMethod.KEY); } private static Node getNode(KeyEvent e) { diff --git a/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/SliderBehavior.java b/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/SliderBehavior.java index 3d0ea3087fc..d2a9040634a 100644 --- a/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/SliderBehavior.java +++ b/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/SliderBehavior.java @@ -109,8 +109,7 @@ public void trackPress(MouseEvent e, double position) { // determine the percentage of the way between min and max // represented by this mouse event final Slider slider = getNode(); - // If not already focused, request focus - if (!slider.isFocused()) slider.requestFocus(); + slider.requestFocus(); if (slider.getOrientation().equals(Orientation.HORIZONTAL)) { slider.adjustValue(position * (slider.getMax() - slider.getMin()) + slider.getMin()); } else { @@ -125,7 +124,7 @@ public void trackPress(MouseEvent e, double position) { public void thumbPressed(MouseEvent e, double position) { // If not already focused, request focus final Slider slider = getNode(); - if (!slider.isFocused()) slider.requestFocus(); + slider.requestFocus(); slider.setValueChanging(true); } diff --git a/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TwoLevelFocusBehavior.java b/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TwoLevelFocusBehavior.java index 89fa52b46f7..e1007d9250c 100644 --- a/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TwoLevelFocusBehavior.java +++ b/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TwoLevelFocusBehavior.java @@ -26,6 +26,7 @@ package com.sun.javafx.scene.control.behavior; import com.sun.javafx.scene.NodeHelper; +import com.sun.javafx.scene.traversal.TraversalMethod; import javafx.css.PseudoClass; import javafx.scene.Node; import javafx.scene.control.Control; @@ -104,27 +105,27 @@ public void dispose() { switch (((KeyEvent)event).getCode()) { case TAB : if (((KeyEvent)event).isShiftDown()) { - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.PREVIOUS); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.PREVIOUS, TraversalMethod.KEY); } else { - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.NEXT); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.NEXT, TraversalMethod.KEY); } event.consume(); break; case UP : - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.UP); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.UP, TraversalMethod.KEY); event.consume(); break; case DOWN : - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.DOWN); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.DOWN, TraversalMethod.KEY); event.consume(); break; case LEFT : - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.LEFT); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.LEFT, TraversalMethod.KEY); event.consume(); break; case RIGHT : - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.RIGHT); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.RIGHT, TraversalMethod.KEY); event.consume(); break; case ENTER : diff --git a/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TwoLevelFocusComboBehavior.java b/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TwoLevelFocusComboBehavior.java index fa489275156..c012789f168 100644 --- a/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TwoLevelFocusComboBehavior.java +++ b/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TwoLevelFocusComboBehavior.java @@ -26,6 +26,7 @@ package com.sun.javafx.scene.control.behavior; import com.sun.javafx.scene.NodeHelper; +import com.sun.javafx.scene.traversal.TraversalMethod; import javafx.scene.Node; import javafx.scene.Scene; @@ -84,27 +85,27 @@ public void dispose() { switch (((KeyEvent)event).getCode()) { case TAB : if (((KeyEvent)event).isShiftDown()) { - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.PREVIOUS); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.PREVIOUS, TraversalMethod.KEY); } else { - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.NEXT); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.NEXT, TraversalMethod.KEY); } event.consume(); break; case UP : - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.UP); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.UP, TraversalMethod.KEY); event.consume(); break; case DOWN : - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.DOWN); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.DOWN, TraversalMethod.KEY); event.consume(); break; case LEFT : - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.LEFT); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.LEFT, TraversalMethod.KEY); event.consume(); break; case RIGHT : - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.RIGHT); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.RIGHT, TraversalMethod.KEY); event.consume(); break; case ENTER : diff --git a/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TwoLevelFocusListBehavior.java b/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TwoLevelFocusListBehavior.java index 50c106a6dce..d842d45d643 100644 --- a/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TwoLevelFocusListBehavior.java +++ b/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TwoLevelFocusListBehavior.java @@ -27,6 +27,7 @@ import com.sun.javafx.scene.NodeHelper; import com.sun.javafx.scene.control.Properties; +import com.sun.javafx.scene.traversal.TraversalMethod; import javafx.scene.Node; import javafx.scene.Parent; @@ -86,27 +87,27 @@ public void dispose() { switch (((KeyEvent)event).getCode()) { case TAB : if (((KeyEvent)event).isShiftDown()) { - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.PREVIOUS); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.PREVIOUS, TraversalMethod.KEY); } else { - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.NEXT); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.NEXT, TraversalMethod.KEY); } event.consume(); break; case UP : - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.UP); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.UP, TraversalMethod.KEY); event.consume(); break; case DOWN : - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.DOWN); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.DOWN, TraversalMethod.KEY); event.consume(); break; case LEFT : - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.LEFT); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.LEFT, TraversalMethod.KEY); event.consume(); break; case RIGHT : - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.RIGHT); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.RIGHT, TraversalMethod.KEY); event.consume(); break; case ENTER : diff --git a/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TwoLevelFocusPopupBehavior.java b/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TwoLevelFocusPopupBehavior.java index 8b1b599036b..772a6dd1640 100644 --- a/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TwoLevelFocusPopupBehavior.java +++ b/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/behavior/TwoLevelFocusPopupBehavior.java @@ -26,6 +26,7 @@ package com.sun.javafx.scene.control.behavior; import com.sun.javafx.scene.NodeHelper; +import com.sun.javafx.scene.traversal.TraversalMethod; import javafx.scene.Node; import javafx.scene.control.PopupControl; @@ -105,27 +106,27 @@ public void dispose() { switch (((KeyEvent)event).getCode()) { case TAB : if (((KeyEvent)event).isShiftDown()) { - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.PREVIOUS); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.PREVIOUS, TraversalMethod.KEY); } else { - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.NEXT); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.NEXT, TraversalMethod.KEY); } event.consume(); break; case UP : - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.UP); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.UP, TraversalMethod.KEY); event.consume(); break; case DOWN : - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.DOWN); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.DOWN, TraversalMethod.KEY); event.consume(); break; case LEFT : - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.LEFT); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.LEFT, TraversalMethod.KEY); event.consume(); break; case RIGHT : - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.RIGHT); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.RIGHT, TraversalMethod.KEY); event.consume(); break; case ENTER : @@ -165,26 +166,26 @@ public void dispose() { break; case LEFT : if (obj instanceof Node) { - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.LEFT); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.LEFT, TraversalMethod.KEY); event.consume(); } else if (obj instanceof Scene) { Node node = ((Scene)obj).getFocusOwner(); if (node != null) { - NodeHelper.traverse(node, com.sun.javafx.scene.traversal.Direction.LEFT); + NodeHelper.traverse(node, com.sun.javafx.scene.traversal.Direction.LEFT, TraversalMethod.KEY); event.consume(); } } break; case RIGHT : if (obj instanceof Node) { - NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.RIGHT); + NodeHelper.traverse((Node) obj, com.sun.javafx.scene.traversal.Direction.RIGHT, TraversalMethod.KEY); event.consume(); } else if (obj instanceof Scene) { Node node = ((Scene)obj).getFocusOwner(); if (node != null) { - NodeHelper.traverse(node, com.sun.javafx.scene.traversal.Direction.RIGHT); + NodeHelper.traverse(node, com.sun.javafx.scene.traversal.Direction.RIGHT, TraversalMethod.KEY); event.consume(); } } diff --git a/modules/javafx.graphics/src/main/java/com/sun/javafx/scene/KeyboardShortcutsHandler.java b/modules/javafx.graphics/src/main/java/com/sun/javafx/scene/KeyboardShortcutsHandler.java index edaf393862c..9ab9a7cd92f 100644 --- a/modules/javafx.graphics/src/main/java/com/sun/javafx/scene/KeyboardShortcutsHandler.java +++ b/modules/javafx.graphics/src/main/java/com/sun/javafx/scene/KeyboardShortcutsHandler.java @@ -34,6 +34,7 @@ import java.util.Map; import java.util.Set; +import com.sun.javafx.scene.traversal.TraversalMethod; import javafx.collections.ObservableList; import javafx.collections.ObservableMap; import javafx.event.Event; @@ -99,7 +100,7 @@ public ObservableMap getAccelerators() { } private void traverse(Event event, Node node, Direction dir) { - if (NodeHelper.traverse(node, dir)) { + if (NodeHelper.traverse(node, dir, TraversalMethod.KEY)) { event.consume(); } } diff --git a/modules/javafx.graphics/src/main/java/com/sun/javafx/scene/NodeHelper.java b/modules/javafx.graphics/src/main/java/com/sun/javafx/scene/NodeHelper.java index dec9c54e3ec..617c98304b1 100644 --- a/modules/javafx.graphics/src/main/java/com/sun/javafx/scene/NodeHelper.java +++ b/modules/javafx.graphics/src/main/java/com/sun/javafx/scene/NodeHelper.java @@ -31,6 +31,7 @@ import com.sun.javafx.geom.transform.BaseTransform; import com.sun.javafx.scene.input.PickResultChooser; import com.sun.javafx.scene.traversal.Direction; +import com.sun.javafx.scene.traversal.TraversalMethod; import com.sun.javafx.sg.prism.NGNode; import com.sun.javafx.util.Utils; import java.util.List; @@ -233,8 +234,8 @@ public static BooleanProperty showMnemonicsProperty(Node node) { return nodeAccessor.showMnemonicsProperty(node); } - public static boolean traverse(Node node, Direction direction) { - return nodeAccessor.traverse(node, direction); + public static boolean traverse(Node node, Direction direction, TraversalMethod method) { + return nodeAccessor.traverse(node, direction, method); } public static double getPivotX(Node node) { @@ -307,6 +308,10 @@ public static Map,List