From e2456574f9e2ecd677f43bcd429f4e1b4a9fae17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20D=C3=BCrrenberger?= Date: Thu, 19 Sep 2024 22:06:38 +0200 Subject: [PATCH] Add CapsLock, NumLock and ScrollLock support for Events --- include/SFML/Window/Event.hpp | 30 +++++++------ src/SFML/Window/Android/WindowImplAndroid.cpp | 10 +++-- src/SFML/Window/DRM/InputImpl.cpp | 27 +++++++++--- src/SFML/Window/Unix/WindowImplX11.cpp | 30 +++++++------ src/SFML/Window/Win32/WindowImplWin32.cpp | 30 +++++++------ .../Window/macOS/SFKeyboardModifiersHelper.mm | 42 +++++++++++++------ 6 files changed, 111 insertions(+), 58 deletions(-) diff --git a/include/SFML/Window/Event.hpp b/include/SFML/Window/Event.hpp index 94052982d..8dcfc3b14 100644 --- a/include/SFML/Window/Event.hpp +++ b/include/SFML/Window/Event.hpp @@ -94,12 +94,15 @@ public: //////////////////////////////////////////////////////////// struct KeyPressed { - Keyboard::Key code{}; //!< Code of the key that has been pressed - Keyboard::Scancode scancode{}; //!< Physical code of the key that has been pressed - bool alt{}; //!< Is the Alt key pressed? - bool control{}; //!< Is the Control key pressed? - bool shift{}; //!< Is the Shift key pressed? - bool system{}; //!< Is the System key pressed? + Keyboard::Key code{}; //!< Code of the key that has been pressed + Keyboard::Scancode scancode{}; //!< Physical code of the key that has been pressed + bool alt{}; //!< Is the Alt key pressed? + bool control{}; //!< Is the Control key pressed? + bool shift{}; //!< Is the Shift key pressed? + bool system{}; //!< Is the System key pressed? + bool capsLock{}; //!< Is the CapsLock key toggled? + bool numLock{}; //!< Is the NumLock key toggled? (Not supported on macOS) + bool scrollLock{}; //!< Is the ScrollLock key toggled? }; //////////////////////////////////////////////////////////// @@ -108,12 +111,15 @@ public: //////////////////////////////////////////////////////////// struct KeyReleased { - Keyboard::Key code{}; //!< Code of the key that has been released - Keyboard::Scancode scancode{}; //!< Physical code of the key that has been released - bool alt{}; //!< Is the Alt key pressed? - bool control{}; //!< Is the Control key pressed? - bool shift{}; //!< Is the Shift key pressed? - bool system{}; //!< Is the System key pressed? + Keyboard::Key code{}; //!< Code of the key that has been released + Keyboard::Scancode scancode{}; //!< Physical code of the key that has been released + bool alt{}; //!< Is the Alt key pressed? + bool control{}; //!< Is the Control key pressed? + bool shift{}; //!< Is the Shift key pressed? + bool system{}; //!< Is the System key pressed? + bool capsLock{}; //!< Is the CapsLock key toggled? + bool numLock{}; //!< Is the NumLock key toggled? (Not supported on macOS) + bool scrollLock{}; //!< Is the ScrollLock key toggled? }; //////////////////////////////////////////////////////////// diff --git a/src/SFML/Window/Android/WindowImplAndroid.cpp b/src/SFML/Window/Android/WindowImplAndroid.cpp index ab9d11f64..c96716cbd 100644 --- a/src/SFML/Window/Android/WindowImplAndroid.cpp +++ b/src/SFML/Window/Android/WindowImplAndroid.cpp @@ -416,9 +416,13 @@ int WindowImplAndroid::processKeyEvent(AInputEvent* inputEvent, ActivityStates& const auto forwardKeyEvent = [&](auto keyEvent) { - keyEvent.code = androidKeyToSF(key); - keyEvent.alt = metakey & AMETA_ALT_ON; - keyEvent.shift = metakey & AMETA_SHIFT_ON; + keyEvent.code = androidKeyToSF(key); + keyEvent.alt = metakey & AMETA_ALT_ON; + keyEvent.shift = metakey & AMETA_SHIFT_ON; + keyEvent.system = metakey & AMETA_SYM_ON; + keyEvent.capsLock = metakey & AMETA_CAPS_LOCK_ON; + keyEvent.numLock = metakey & AMETA_NUM_LOCK_ON; + keyEvent.scrollLock = metakey & AMETA_SCROLL_LOCK_ON; forwardEvent(keyEvent); }; diff --git a/src/SFML/Window/DRM/InputImpl.cpp b/src/SFML/Window/DRM/InputImpl.cpp index 20dbb6644..abfc227e8 100644 --- a/src/SFML/Window/DRM/InputImpl.cpp +++ b/src/SFML/Window/DRM/InputImpl.cpp @@ -90,6 +90,18 @@ bool systemDown() { return keyMap[sf::Keyboard::Key::LSystem] || keyMap[sf::Keyboard::Key::RSystem]; } +bool capsLockDown() +{ + return false; // TODO: To be implemented, potentially with scancode support +} +bool numLockDown() +{ + return false; // TODO: To be implemented, potentially with scancode support +} +bool scrollLockDown() +{ + return false; // TODO: To be implemented, potentially with scancode support +} void uninitFileDescriptors() { @@ -407,12 +419,15 @@ std::optional eventProcess() const auto makeKeyEvent = [&](auto keyEvent) { - keyEvent.code = kb; - keyEvent.scancode = sf::Keyboard::Scan::Unknown; // TODO: not implemented - keyEvent.alt = altDown(); - keyEvent.control = controlDown(); - keyEvent.shift = shiftDown(); - keyEvent.system = systemDown(); + keyEvent.code = kb; + keyEvent.scancode = sf::Keyboard::Scan::Unknown; // TODO: not implemented + keyEvent.alt = altDown(); + keyEvent.control = controlDown(); + keyEvent.shift = shiftDown(); + keyEvent.system = systemDown(); + keyEvent.capsLock = capsLockDown(); + keyEvent.numLock = numLockDown(); + keyEvent.scrollLock = scrollLockDown(); return keyEvent; }; diff --git a/src/SFML/Window/Unix/WindowImplX11.cpp b/src/SFML/Window/Unix/WindowImplX11.cpp index 05c587c21..e8444fa5f 100644 --- a/src/SFML/Window/Unix/WindowImplX11.cpp +++ b/src/SFML/Window/Unix/WindowImplX11.cpp @@ -1808,12 +1808,15 @@ bool WindowImplX11::processEvent(XEvent& windowEvent) // Fill the event parameters // TODO: if modifiers are wrong, use XGetModifierMapping to retrieve the actual modifiers mapping Event::KeyPressed event; - event.code = KeyboardImpl::getKeyFromEvent(windowEvent.xkey); - event.scancode = KeyboardImpl::getScancodeFromEvent(windowEvent.xkey); - event.alt = windowEvent.xkey.state & Mod1Mask; - event.control = windowEvent.xkey.state & ControlMask; - event.shift = windowEvent.xkey.state & ShiftMask; - event.system = windowEvent.xkey.state & Mod4Mask; + event.code = KeyboardImpl::getKeyFromEvent(windowEvent.xkey); + event.scancode = KeyboardImpl::getScancodeFromEvent(windowEvent.xkey); + event.alt = windowEvent.xkey.state & Mod1Mask; + event.control = windowEvent.xkey.state & ControlMask; + event.shift = windowEvent.xkey.state & ShiftMask; + event.system = windowEvent.xkey.state & Mod4Mask; + event.capsLock = windowEvent.xkey.state & LockMask; + event.numLock = windowEvent.xkey.state & Mod2Mask; + event.scrollLock = windowEvent.xkey.state & Mod3Mask; const bool filtered = XFilterEvent(&windowEvent, None); @@ -1889,12 +1892,15 @@ bool WindowImplX11::processEvent(XEvent& windowEvent) { // Fill the event parameters Event::KeyReleased event; - event.code = KeyboardImpl::getKeyFromEvent(windowEvent.xkey); - event.scancode = KeyboardImpl::getScancodeFromEvent(windowEvent.xkey); - event.alt = windowEvent.xkey.state & Mod1Mask; - event.control = windowEvent.xkey.state & ControlMask; - event.shift = windowEvent.xkey.state & ShiftMask; - event.system = windowEvent.xkey.state & Mod4Mask; + event.code = KeyboardImpl::getKeyFromEvent(windowEvent.xkey); + event.scancode = KeyboardImpl::getScancodeFromEvent(windowEvent.xkey); + event.alt = windowEvent.xkey.state & Mod1Mask; + event.control = windowEvent.xkey.state & ControlMask; + event.shift = windowEvent.xkey.state & ShiftMask; + event.system = windowEvent.xkey.state & Mod4Mask; + event.capsLock = windowEvent.xkey.state & LockMask; + event.numLock = windowEvent.xkey.state & Mod2Mask; + event.scrollLock = windowEvent.xkey.state & Mod3Mask; pushEvent(event); break; diff --git a/src/SFML/Window/Win32/WindowImplWin32.cpp b/src/SFML/Window/Win32/WindowImplWin32.cpp index f89945949..c917211cd 100644 --- a/src/SFML/Window/Win32/WindowImplWin32.cpp +++ b/src/SFML/Window/Win32/WindowImplWin32.cpp @@ -886,12 +886,15 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam) if (m_keyRepeatEnabled || ((HIWORD(lParam) & KF_REPEAT) == 0)) { Event::KeyPressed event; - event.alt = HIWORD(GetKeyState(VK_MENU)) != 0; - event.control = HIWORD(GetKeyState(VK_CONTROL)) != 0; - event.shift = HIWORD(GetKeyState(VK_SHIFT)) != 0; - event.system = HIWORD(GetKeyState(VK_LWIN)) || HIWORD(GetKeyState(VK_RWIN)); - event.code = virtualKeyCodeToSF(wParam, lParam); - event.scancode = toScancode(wParam, lParam); + event.alt = GetKeyState(VK_MENU) & 0x8000; + event.control = GetKeyState(VK_CONTROL) & 0x8000; + event.shift = GetKeyState(VK_SHIFT) & 0x8000; + event.system = GetKeyState(VK_LWIN) & 0x8000 || GetKeyState(VK_RWIN) & 0x8000; + event.capsLock = GetKeyState(VK_CAPITAL) & 0x0001; + event.numLock = GetKeyState(VK_NUMLOCK) & 0x0001; + event.scrollLock = GetKeyState(VK_SCROLL) & 0x0001; + event.code = virtualKeyCodeToSF(wParam, lParam); + event.scancode = toScancode(wParam, lParam); pushEvent(event); } break; @@ -902,12 +905,15 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam) case WM_SYSKEYUP: { Event::KeyReleased event; - event.alt = HIWORD(GetKeyState(VK_MENU)) != 0; - event.control = HIWORD(GetKeyState(VK_CONTROL)) != 0; - event.shift = HIWORD(GetKeyState(VK_SHIFT)) != 0; - event.system = HIWORD(GetKeyState(VK_LWIN)) || HIWORD(GetKeyState(VK_RWIN)); - event.code = virtualKeyCodeToSF(wParam, lParam); - event.scancode = toScancode(wParam, lParam); + event.alt = GetKeyState(VK_MENU) & 0x8000; + event.control = GetKeyState(VK_CONTROL) & 0x8000; + event.shift = GetKeyState(VK_SHIFT) & 0x8000; + event.system = GetKeyState(VK_LWIN) & 0x8000 || GetKeyState(VK_RWIN) & 0x8000; + event.capsLock = GetKeyState(VK_CAPITAL) & 0x0001; + event.numLock = GetKeyState(VK_NUMLOCK) & 0x0001; + event.scrollLock = GetKeyState(VK_SCROLL) & 0x0001; + event.code = virtualKeyCodeToSF(wParam, lParam); + event.scancode = toScancode(wParam, lParam); pushEvent(event); break; } diff --git a/src/SFML/Window/macOS/SFKeyboardModifiersHelper.mm b/src/SFML/Window/macOS/SFKeyboardModifiersHelper.mm index f44d72232..44b8c1220 100644 --- a/src/SFML/Window/macOS/SFKeyboardModifiersHelper.mm +++ b/src/SFML/Window/macOS/SFKeyboardModifiersHelper.mm @@ -63,6 +63,7 @@ struct ModifiersState BOOL leftControlWasDown{}; BOOL rightControlWasDown{}; BOOL capsLockWasOn{}; + BOOL numLockWasOn{}; }; @@ -151,7 +152,8 @@ void initialiseKeyboardHelper() state.rightAlternateWasDown = isKeyMaskActive(modifiers, NSRightAlternateKeyMask); state.leftControlWasDown = isKeyMaskActive(modifiers, NSLeftControlKeyMask); state.rightControlWasDown = isKeyMaskActive(modifiers, NSRightControlKeyMask); - state.capsLockWasOn = isKeyMaskActive(modifiers, NSEventModifierFlagCapsLock); + state.capsLockWasOn = isKeyMaskActive(modifiers, NSAlphaShiftKeyMask); + state.numLockWasOn = isKeyMaskActive(modifiers, NSNumericPadKeyMask); isStateInitialized = YES; } @@ -161,12 +163,15 @@ void initialiseKeyboardHelper() sf::Event::KeyPressed keyPressedEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key, sf::Keyboard::Scancode code) { sf::Event::KeyPressed event; - event.code = key; - event.scancode = code; - event.alt = modifiers & NSAlternateKeyMask; - event.control = modifiers & NSControlKeyMask; - event.shift = modifiers & NSShiftKeyMask; - event.system = modifiers & NSCommandKeyMask; + event.code = key; + event.scancode = code; + event.alt = modifiers & NSAlternateKeyMask; + event.control = modifiers & NSControlKeyMask; + event.shift = modifiers & NSShiftKeyMask; + event.system = modifiers & NSCommandKeyMask; + event.capsLock = modifiers & NSAlphaShiftKeyMask; + event.numLock = modifiers & NSNumericPadKeyMask; + event.scrollLock = false; // Doesn't exist on macOS return event; } @@ -175,12 +180,15 @@ sf::Event::KeyPressed keyPressedEventWithModifiers(NSUInteger modifiers, sf::Key sf::Event::KeyReleased keyReleasedEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key, sf::Keyboard::Scancode code) { sf::Event::KeyReleased event; - event.code = key; - event.scancode = code; - event.alt = modifiers & NSAlternateKeyMask; - event.control = modifiers & NSControlKeyMask; - event.shift = modifiers & NSShiftKeyMask; - event.system = modifiers & NSCommandKeyMask; + event.code = key; + event.scancode = code; + event.alt = modifiers & NSAlternateKeyMask; + event.control = modifiers & NSControlKeyMask; + event.shift = modifiers & NSShiftKeyMask; + event.system = modifiers & NSCommandKeyMask; + event.capsLock = modifiers & NSAlphaShiftKeyMask; + event.numLock = modifiers & NSNumericPadKeyMask; + event.scrollLock = false; // Doesn't exist on macOS return event; } @@ -243,4 +251,12 @@ void handleModifiersChanged(NSUInteger modifiers, sf::priv::WindowImplCocoa& req sf::Keyboard::Key::Unknown, sf::Keyboard::Scan::CapsLock, requester); + + // Handle num lock + processOneModifier(modifiers, + NSEventModifierFlagNumericPad, + state.numLockWasOn, + sf::Keyboard::Key::Unknown, + sf::Keyboard::Scan::NumLock, + requester); }