JDK-8218416 : Cannot switch focus between 3 Java Frames using macOS system shortcut Cmd+`
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 8u131,11.0.1
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: os_x
  • CPU: x86
  • Submitted: 2019-01-16
  • Updated: 2019-02-05
  • Resolved: 2019-02-05
Related Reports
Duplicate :  
Description
ADDITIONAL SYSTEM INFORMATION :
macOS (10.14 Mojave)
Oracle JDK 8u191 (build 1.8.0_191-b12 / HotSpot build 25.191-b12)
Oracle JDK 11.0.1 (build 11.0.1+13-LTS / HotSpot build 11.0.1+13-LTS)

A DESCRIPTION OF THE PROBLEM :
MacOS default system shortcut 'Move focus to next window' (Cmd+`) cannot switch focus between three Java Frames. Pressing Cmd+` only switches focus between two last open Java Frames.

It seems that the issue appeared on jdk8u131 and it is reproducible on jdk8u131 - jdk8u191, jdk11.0.1.
The issue is NOT reproducible on jdk8u121 and on current releases jdk8u202, jdk11.0.2.

Possible regression of JDK-8169589.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Open three java.awt.Frames
2. Press Cmd+` three times

Or please run MoveFocusShortcutTest using Java:
    <JAVA_HOME>/bin/javac  MoveFocusShortcutTest.java
    <JAVA_HOME>/bin/java  MoveFocusShortcutTest

Or please run MoveFocusShortcutTest using JTReg:
    <JTREG_HOME>/bin/jtreg -testjdk:<JAVA_HOME> MoveFocusShortcutTest.java

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Focus successively switches between all three Java Frames.

Please see the MoveFocusShortcutTest output on jdk8u121:

<jdk1.8.0_121.jdk>/Contents/Home/bin/java -showversion  MoveFocusShortcutTest
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

Open test frames
Window gained focus: TestFrame1
Window gained focus: TestFrame2
Window gained focus: TestFrame3
All frames were opened
Move focus to the next window
Window gained focus: TestFrame2
Move focus to the next window
Window gained focus: TestFrame1
Move focus to the next window
Window gained focus: TestFrame3
Test PASSED

Please see the MoveFocusShortcutTest output on jdk11.0.2:

<jdk-11.0.2.jdk>/Contents/Home/bin/java -showversion  MoveFocusShortcutTest
java version "11.0.2" 2018-10-16 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.2+7-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.2+7-LTS, mixed mode)
Open test frames
Window gained focus: TestFrame1
Window gained focus: TestFrame2
Window gained focus: TestFrame3
All frames were opened
Move focus to the next window
Window gained focus: TestFrame2
Move focus to the next window
Window gained focus: TestFrame1
Move focus to the next window
Window gained focus: TestFrame3
Test PASSED
ACTUAL -
Focus only switches between two last open Frames.

Please see the MoveFocusShortcutTest output on jdk8u191:

<jdk1.8.0_191.jdk>/Contents/Home/bin/java -showversion  MoveFocusShortcutTest
java version "1.8.0_191"
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)

Open test frames
Window gained focus: TestFrame1
Window gained focus: TestFrame2
Window gained focus: TestFrame3
All frames were opened
Move focus to the next window
Window gained focus: TestFrame2
Move focus to the next window
Window gained focus: TestFrame3
Move focus to the next window
Window gained focus: TestFrame2
Exception in thread "main" java.lang.RuntimeException: Test FAILED: Command+` shortcut cannot move focus to the TestFrame(s): 1
	at MoveFocusShortcutTest.main(MoveFocusShortcutTest.java:138)

Please see the MoveFocusShortcutTest output on jdk11.0.1:

<jdk-11.0.1.jdk>/Contents/Home/bin/java -showversion  MoveFocusShortcutTest
java version "11.0.1" 2018-10-16 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.1+13-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.1+13-LTS, mixed mode)
Open test frames
Window gained focus: TestFrame1
Window gained focus: TestFrame2
Window gained focus: TestFrame3
All frames were opened
Move focus to the next window
Window gained focus: TestFrame2
Move focus to the next window
Window gained focus: TestFrame3
Move focus to the next window
Window gained focus: TestFrame2
Exception in thread "main" java.lang.RuntimeException: Test FAILED: Command+` shortcut cannot move focus to the TestFrame(s): 1
	at MoveFocusShortcutTest.main(MoveFocusShortcutTest.java:138)

---------- BEGIN SOURCE ----------
import java.awt.AWTException;
import java.awt.Frame;
import java.awt.GraphicsEnvironment;
import java.awt.Robot;
import java.awt.Window;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * @test
 * @summary Cmd+` doesn't work
 * @requires (jdk.version.major >= 8 & os.family == "mac")
 * @run main MoveFocusShortcutTest
 */

/*
 * Description: Test checks that Command+` macOS system shortcut successively switches focus between three Java Frames.
 *
 * Note: Please check that Command+` macOS system shortcut is enabled before launching this test
 * (use system Preferences -> Keyboard -> Shortcuts tab -> Keyboard -> mark 'Move focus to next window' checkbox)
 * MacOS accessibility permission should also be granted on macOS > for the application launching this test, so
 * Java Robot is able to access the keyboard (use System Preferences -> Security&Privacy -> Accessibility -> Privacy).
 */

public class MoveFocusShortcutTest {

    private static final int PAUSE = 2000;

    private static TestFrame frame1;
    private static TestFrame frame2;
    private static TestFrame frame3;

    private static WindowAdapter frameFocusListener;

    private static Robot robot;

    private static class TestFrame extends Frame {

        private final CountDownLatch frameGainedFocus;

        private TestFrame(String title) {
            super(title);
            frameGainedFocus = new CountDownLatch(2);
        }

        private CountDownLatch getLatch() {
            return frameGainedFocus;
        }
    }

    /*
     * Checks that pressing Command+` successively switches focus between three Java Frames
     */
    public static void main(String[] args) throws AWTException, InterruptedException {

        if (GraphicsEnvironment.isHeadless()) {
            throw new RuntimeException("ERROR: Cannot execute the test in headless environment");
        }

        frame1 = new TestFrame("TestFrame1");
        frame2 = new TestFrame("TestFrame2");
        frame3 = new TestFrame("TestFrame3");

        frameFocusListener = new WindowAdapter() {
            @Override
            public void windowGainedFocus(WindowEvent windowEvent) {
                Window window = windowEvent.getWindow();
                try {
                    TestFrame frame = (TestFrame) windowEvent.getWindow();
                    frame.getLatch().countDown();
                    System.out.println("Window gained focus: " + frame.getTitle());
                } catch (ClassCastException e) {
                    throw new RuntimeException("Unexpected window: " + window);
                }
            }
        };

        try {
            robot = new Robot();
            robot.setAutoDelay(50);

            System.out.println("Open test frames");
            showGUI();

            Thread.sleep(PAUSE);
            robot.waitForIdle();

            boolean check1 = (frame1.getLatch().getCount() == 1);
            boolean check2 = (frame2.getLatch().getCount() == 1);
            boolean check3 = (frame3.getLatch().getCount() == 1);

            if (check1 && check2 && check3) {
                System.out.println("All frames were opened");
            } else {
                throw new RuntimeException("Test ERROR: Cannot focus the TestFrame(s): "
                        + getFailedChecksString(check1, check2, check3));
            }

            moveFocusToNextWindow();
            Thread.sleep(PAUSE);
            robot.waitForIdle();

            moveFocusToNextWindow();
            Thread.sleep(PAUSE);
            robot.waitForIdle();

            moveFocusToNextWindow();
            Thread.sleep(PAUSE);
            robot.waitForIdle();

            boolean result1 = frame1.getLatch().await(PAUSE, TimeUnit.MILLISECONDS);
            boolean result2 = frame2.getLatch().await(PAUSE, TimeUnit.MILLISECONDS);
            boolean result3 = frame3.getLatch().await(PAUSE, TimeUnit.MILLISECONDS);

            if(result1 && result2 && result3) {
                System.out.println("Test PASSED");
            } else {
                throw new RuntimeException("Test FAILED: Command+` shortcut cannot move focus to the TestFrame(s): "
                        + getFailedChecksString(result1 , result2 , result3));
            }
        } finally {
            destroyGUI();
            /* Waiting for EDT auto-shutdown */
            Thread.sleep(PAUSE);
        }
    }

    /*
     * Opens test frames
     */
    private static void showGUI() {
        frame1.setSize(400, 200);
        frame2.setSize(400, 200);
        frame3.setSize(400, 200);
        frame1.setLocation(50, 50);
        frame2.setLocation(100, 100);
        frame3.setLocation(150, 150);
        frame1.addWindowFocusListener(frameFocusListener);
        frame2.addWindowFocusListener(frameFocusListener);
        frame3.addWindowFocusListener(frameFocusListener);
        frame1.setVisible(true);
        frame2.setVisible(true);
        frame3.setVisible(true);
    }

    /*
     * Presses Command+` on macOS keyboard
     */
    private static void moveFocusToNextWindow() {
        System.out.println("Move focus to the next window");
        robot.keyPress(KeyEvent.VK_META);
        robot.keyPress(KeyEvent.VK_BACK_QUOTE);
        robot.keyRelease(KeyEvent.VK_BACK_QUOTE);
        robot.keyRelease(KeyEvent.VK_META);
    }

    /*
     * Returns string containing positions of the false values
     */
    private static String getFailedChecksString(boolean ... values) {
        int i = 0;
        String result = "";
        for (boolean value : values) {
            i++;
            if(!value) {
                result += result.isEmpty() ? i : (", " + i);
            }
        }
        return result;
    }

    /*
     * Disposes test frames
     */
    private static void destroyGUI() {
        frame1.removeWindowFocusListener(frameFocusListener);
        frame2.removeWindowFocusListener(frameFocusListener);
        frame3.removeWindowFocusListener(frameFocusListener);
        frame1.dispose();
        frame2.dispose();
        frame3.dispose();
    }
}

---------- END SOURCE ----------

FREQUENCY : always



Comments
Reported with macOS Mojave (10.14) as regression in JDK 8u131, MacOS default system shortcut 'Move focus to next window' (Cmd+`) cannot switch focus between three Java Frames. Results: ======== 8u122: Pass 8u131: Fail 8u201: Fail 8u202: Pass 11.0.1: Fail 11.0.2: Pass 12 ea b30: Pass 13 ea b06: Pass To verify, run the attached test case with respective JDK versions. This was a regression introduced in JDK 8u131, but seems fixed in 8u202 and 11.0.2 through JDK-8206392.
05-02-2019