From 94d6344b439efa1b72c52e2ce236c639199c8545 Mon Sep 17 00:00:00 2001 From: Nikita Tsarev Date: Thu, 24 Aug 2023 20:06:00 +0200 Subject: JBR-5963: Fix RobotKeyboard test and implement getLockingKeyState --- .../unix/classes/sun/awt/wl/WLInputState.java | 23 ++++++++++++++-------- .../unix/classes/sun/awt/wl/WLToolkit.java | 23 ++++++++++++++++++---- .../unix/native/libawt_wlawt/WLToolkit.c | 16 +++++++++++++-- test/jdk/java/awt/wakefield/RobotKeyboard.java | 13 +++++++++++- 4 files changed, 60 insertions(+), 15 deletions(-) diff --git a/src/java.desktop/unix/classes/sun/awt/wl/WLInputState.java b/src/java.desktop/unix/classes/sun/awt/wl/WLInputState.java index b9c65e5eb23..d5fb773e6c6 100644 --- a/src/java.desktop/unix/classes/sun/awt/wl/WLInputState.java +++ b/src/java.desktop/unix/classes/sun/awt/wl/WLInputState.java @@ -38,6 +38,7 @@ package sun.awt.wl; * @param pointerButtonPressedEvent null or the latest PointerButtonEvent such that getIsButtonPressed() == true * @param modifiers a bit set of modifiers reflecting currently pressed keys (@see WLInputState.getNewModifiers()) * @param surfaceForKeyboardInput represents 'struct wl_surface*' that keyboards events should go to + * @param lockingKeyState a bit set of locking modifiers currently active */ record WLInputState(WLPointerEvent eventWithSurface, WLPointerEvent eventWithSerial, @@ -46,7 +47,8 @@ record WLInputState(WLPointerEvent eventWithSurface, PointerButtonEvent pointerButtonPressedEvent, int modifiers, long surfaceForKeyboardInput, - boolean isPointerOverSurface) { + boolean isPointerOverSurface, + int lockingKeyState) { /** * Groups together information about a mouse pointer button event. * @param surface 'struct wl_surface*' the button was pressed over @@ -60,7 +62,7 @@ record WLInputState(WLPointerEvent eventWithSurface, static WLInputState initialState() { return new WLInputState(null, null, null, null, - null, 0, 0, false); + null, 0, 0, false, 0); } /** @@ -92,7 +94,8 @@ record WLInputState(WLPointerEvent eventWithSurface, newPointerButtonEvent, newModifiers, surfaceForKeyboardInput, - newPointerOverSurface); + newPointerOverSurface, + lockingKeyState); } public WLInputState updatedFromKeyboardEnterEvent(long serial, long surfacePtr) { @@ -105,10 +108,11 @@ record WLInputState(WLPointerEvent eventWithSurface, pointerButtonPressedEvent, modifiers, surfacePtr, - isPointerOverSurface); + isPointerOverSurface, + lockingKeyState); } - public WLInputState updatedFromKeyboardModifiersEvent(long serial, int keyboardModifiers) { + public WLInputState updatedFromKeyboardModifiersEvent(long serial, int keyboardModifiers, int newLockingKeyState) { // "The compositor must send the wl_keyboard.modifiers event after this event". final int oldPointerModifiers = modifiers & WLPointerEvent.PointerButtonCodes.combinedMask(); final int newModifiers = oldPointerModifiers | keyboardModifiers; @@ -120,7 +124,8 @@ record WLInputState(WLPointerEvent eventWithSurface, pointerButtonPressedEvent, newModifiers, surfaceForKeyboardInput, - isPointerOverSurface); + isPointerOverSurface, + newLockingKeyState); } public WLInputState updatedFromKeyboardLeaveEvent(long serial, long surfacePtr) { @@ -135,7 +140,8 @@ record WLInputState(WLPointerEvent eventWithSurface, pointerButtonPressedEvent, newModifiers, 0, - isPointerOverSurface); + isPointerOverSurface, + lockingKeyState); } public WLInputState resetPointerState() { @@ -147,7 +153,8 @@ record WLInputState(WLPointerEvent eventWithSurface, pointerButtonPressedEvent, 0, surfaceForKeyboardInput, - false); + false, + lockingKeyState); } private PointerButtonEvent getNewPointerButtonEvent(WLPointerEvent pointerEvent, diff --git a/src/java.desktop/unix/classes/sun/awt/wl/WLToolkit.java b/src/java.desktop/unix/classes/sun/awt/wl/WLToolkit.java index 28783e42373..a89464502a8 100644 --- a/src/java.desktop/unix/classes/sun/awt/wl/WLToolkit.java +++ b/src/java.desktop/unix/classes/sun/awt/wl/WLToolkit.java @@ -133,6 +133,9 @@ public class WLToolkit extends UNIXToolkit implements Runnable { private static final int MOUSE_BUTTONS_COUNT = 3; private static final int AWT_MULTICLICK_DEFAULT_TIME_MS = 500; + private static final int CAPS_LOCK_MASK = 0x01; + private static final int NUM_LOCK_MASK = 0x02; + private static boolean initialized = false; private static native void initIDs(); @@ -451,7 +454,9 @@ public class WLToolkit extends UNIXToolkit implements Runnable { boolean isShiftActive, boolean isAltActive, boolean isCtrlActive, - boolean isMetaActive) { + boolean isMetaActive, + boolean isCapsActive, + boolean isNumActive) { // Invoked from the native code assert EventQueue.isDispatchThread(); @@ -460,12 +465,17 @@ public class WLToolkit extends UNIXToolkit implements Runnable { | (isAltActive ? InputEvent.ALT_DOWN_MASK : 0) | (isCtrlActive ? InputEvent.CTRL_DOWN_MASK : 0) | (isMetaActive ? InputEvent.META_DOWN_MASK : 0); + + final int newLockingKeyState = + (isCapsActive ? CAPS_LOCK_MASK : 0) + | (isNumActive ? NUM_LOCK_MASK : 0); + if (logKeys.isLoggable(PlatformLogger.Level.FINE)) { logKeys.fine("dispatchKeyboardModifiersEvent: new modifiers 0x" + Integer.toHexString(newModifiers)); } - inputState = inputState.updatedFromKeyboardModifiersEvent(serial, newModifiers); + inputState = inputState.updatedFromKeyboardModifiersEvent(serial, newModifiers, newLockingKeyState); } private static void dispatchKeyboardEnterEvent(long serial, long surfacePtr) { @@ -760,8 +770,13 @@ public class WLToolkit extends UNIXToolkit implements Runnable { } @Override public boolean getLockingKeyState(int key) { - log.info("Not implemented: WLToolkit.getLockingKeyState()"); - return false; + return switch (key) { + case KeyEvent.VK_CAPS_LOCK -> (inputState.lockingKeyState() & CAPS_LOCK_MASK) != 0; + case KeyEvent.VK_NUM_LOCK -> (inputState.lockingKeyState() & NUM_LOCK_MASK) != 0; + case KeyEvent.VK_SCROLL_LOCK, KeyEvent.VK_KANA_LOCK -> + throw new UnsupportedOperationException("getting locking key state is not supported for this key"); + default -> throw new IllegalArgumentException("invalid key for Toolkit.getLockingKeyState"); + }; } @Override diff --git a/src/java.desktop/unix/native/libawt_wlawt/WLToolkit.c b/src/java.desktop/unix/native/libawt_wlawt/WLToolkit.c index aebbe6d8c8d..a32bfac8e10 100644 --- a/src/java.desktop/unix/native/libawt_wlawt/WLToolkit.c +++ b/src/java.desktop/unix/native/libawt_wlawt/WLToolkit.c @@ -546,6 +546,16 @@ wl_keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, XKB_MOD_NAME_LOGO, XKB_STATE_MODS_EFFECTIVE); + const bool is_caps_active + = xkb_ifs.xkb_state_mod_name_is_active(xkb_state, + XKB_MOD_NAME_CAPS, + XKB_STATE_MODS_EFFECTIVE); + + const bool is_num_active + = xkb_ifs.xkb_state_mod_name_is_active(xkb_state, + XKB_MOD_NAME_NUM, + XKB_STATE_MODS_EFFECTIVE); + (*env)->CallStaticVoidMethod(env, tkClass, dispatchKeyboardModifiersEventMID, @@ -553,7 +563,9 @@ wl_keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, is_shift_active, is_alt_active, is_ctrl_active, - is_meta_active); + is_meta_active, + is_caps_active, + is_num_active); JNU_CHECK_EXCEPTION(env); } @@ -776,7 +788,7 @@ initJavaRefs(JNIEnv *env, jclass clazz) JNI_FALSE); CHECK_NULL_RETURN(dispatchKeyboardModifiersEventMID = (*env)->GetStaticMethodID(env, tkClass, "dispatchKeyboardModifiersEvent", - "(JZZZZ)V"), + "(JZZZZZZ)V"), JNI_FALSE); CHECK_NULL_RETURN(keyRepeatRateFID = (*env)->GetStaticFieldID(env, tkClass, diff --git a/test/jdk/java/awt/wakefield/RobotKeyboard.java b/test/jdk/java/awt/wakefield/RobotKeyboard.java index 3af23e94d37..2b9b0cbe1b1 100644 --- a/test/jdk/java/awt/wakefield/RobotKeyboard.java +++ b/test/jdk/java/awt/wakefield/RobotKeyboard.java @@ -67,7 +67,6 @@ public class RobotKeyboard { "VK_CONTROL", "VK_D", "VK_DECIMAL", - "VK_DECIMAL", "VK_DELETE", "VK_DIVIDE", "VK_DOWN", @@ -206,6 +205,18 @@ public class RobotKeyboard { robot.setAutoDelay(50); robot.delay(500); + if (Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK)) { + // Disable caps lock + robot.keyPress(KeyEvent.VK_CAPS_LOCK); + robot.keyRelease(KeyEvent.VK_CAPS_LOCK); + } + + if (!Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_NUM_LOCK)) { + // Enable num lock + robot.keyPress(KeyEvent.VK_NUM_LOCK); + robot.keyRelease(KeyEvent.VK_NUM_LOCK); + } + boolean ok = true; for (String key : ordinaryKeyNames) { -- cgit v1.2.3