Revamp the macOS implementation of scancodes

- Describe keys in separate words when applicable on macOS
- Use "Option" instead of "Alt" to describe keys on macOS
- Filter key up events like key down events
- Use localize to generate keyboard events
  That is better than translating to text because several keys can
  generate the same text.
- Add fallback mapping for NumpadEnter
- Handle swapped virtual key codes with ISO keyboard
This commit is contained in:
kimci86 2022-09-21 20:46:30 +02:00 committed by Lukas Dürrenberger
parent 89ea3af65e
commit 1cbd6e9d12
3 changed files with 996 additions and 949 deletions

View File

@ -89,7 +89,7 @@ public:
static CFDictionaryRef copyDevicesMask(UInt32 page, UInt32 usage);
////////////////////////////////////////////////////////////
/// Try to convert a character into a SFML key code.
/// \brief Try to convert a character into a SFML key code
///
/// Return sf::Keyboard::Unknown if it doesn't match any 'localized' keys.
///
@ -102,7 +102,7 @@ public:
static Keyboard::Key localizedKey(UniChar ch);
////////////////////////////////////////////////////////////
/// Opposite transformation as localizedKeys
/// \brief Opposite transformation as localizedKeys
///
/// Return 0x00 (NULL) for non-convertible keys/numpad numbers.
/// For letters, uppercase codes are returned.
@ -112,7 +112,7 @@ public:
static UniChar toUnicode(Keyboard::Key key);
////////////////////////////////////////////////////////////
/// Try to convert a virtual keycode (HID level) into a
/// \brief Try to convert a virtual keycode (HID level) into a
/// SFML scancode.
///
/// Return sf::Keyboard::Scan::Unknown if the keycode is unknown.
@ -152,14 +152,6 @@ public:
////////////////////////////////////////////////////////////
String getDescription(Keyboard::Scancode code);
////////////////////////////////////////////////////////////
/// Regenerate the mappings from/to Key and Scancode.
///
/// This function is public to allow regular update calls
/// from the manager in case there's a keyboard layout change.
///
////////////////////////////////////////////////////////////
void buildMappings();
private:
////////////////////////////////////////////////////////////
@ -213,6 +205,19 @@ private:
////////////////////////////////////////////////////////////
void loadKey(IOHIDElementRef key);
////////////////////////////////////////////////////////////
/// \brief Regenerate the mappings from/to Key and Scancode
///
////////////////////////////////////////////////////////////
void buildMappings();
////////////////////////////////////////////////////////////
/// \brief Callback to regenerate mappings from/to Key and
/// Scancode when there's a keyboard layout change
///
////////////////////////////////////////////////////////////
static void keyboardChanged(CFNotificationCenterRef, void* observer, CFStringRef, const void*, CFDictionaryRef);
////////////////////////////////////////////////////////////
/// \brief Release all resources
///
@ -275,9 +280,9 @@ private:
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
IOHIDManagerRef m_manager; ///< Underlying HID Manager
IOHIDManagerRef m_manager; ///< Underlying HID Manager
IOHIDElements m_keys[Keyboard::Scan::ScancodeCount]; ///< All the keys on any connected keyboard
Keyboard::Scancode m_keyToScancodeMapping[Keyboard::KeyCount]; ///< Mapping from Key to Scancode
Keyboard::Scancode m_keyToScancodeMapping[Keyboard::KeyCount]; ///< Mapping from Key to Scancode
Keyboard::Key m_scancodeToKeyMapping[Keyboard::Scan::ScancodeCount]; ///< Mapping from Scancode to Key
////////////////////////////////////////////////////////////
@ -288,7 +293,7 @@ private:
/// HID keys.
///
/// The mappings (both directions) get invalidated when the
/// keyboard layout changes. They both default to (s)Unknown.
/// keyboard layout changes. They both default to (Scan::)Unknown.
///
////////////////////////////////////////////////////////////
};

File diff suppressed because it is too large Load Diff

View File

@ -166,7 +166,7 @@
sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
if (key.code != sf::Keyboard::Unknown) // The key is recognized.
if ((key.code != sf::Keyboard::Unknown) || (key.scancode != sf::Keyboard::Scan::Unknown))
m_requester->keyUp(key);
}
@ -188,16 +188,12 @@
////////////////////////////////////////////////////////
+(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent*)event
{
// We look for the key in a list of characters that depend on keyboard localization,
// if the key is not "dead".
NSString* string = [event charactersIgnoringModifiers];
sf::Keyboard::Key key = ([string length] > 0)
? sf::priv::HIDInputManager::localizedKey([string characterAtIndex:0])
: sf::Keyboard::Unknown;
// The scancode always depends on the hardware keyboard, not some OS setting.
sf::Keyboard::Scancode code = sf::priv::HIDInputManager::nonLocalizedKey([event keyCode]);
// Get the corresponding key under the current keyboard layout.
sf::Keyboard::Key key = sf::Keyboard::localize(code);
return keyEventWithModifiers([event modifierFlags], key, code);
}