Skip to content

Commit ba987c9

Browse files
committed
Implement keyboard_get_label_from_physical method.
1 parent b6c0dd2 commit ba987c9

9 files changed

Lines changed: 84 additions & 0 deletions

File tree

doc/classes/DisplayServer.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,14 @@
775775
[b]Note:[/b] This method is implemented on Linux (X11), macOS and Windows.
776776
</description>
777777
</method>
778+
<method name="keyboard_get_label_from_physical" qualifiers="const">
779+
<return type="int" enum="Key" />
780+
<param index="0" name="keycode" type="int" enum="Key" />
781+
<description>
782+
Converts a physical (US QWERTY) [param keycode] to localized label printed on the key in the active keyboard layout.
783+
[b]Note:[/b] This method is implemented on Linux (X11), macOS and Windows.
784+
</description>
785+
</method>
778786
<method name="keyboard_get_layout_count" qualifiers="const">
779787
<return type="int" />
780788
<description>

platform/linuxbsd/x11/display_server_x11.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2970,6 +2970,30 @@ Key DisplayServerX11::keyboard_get_keycode_from_physical(Key p_keycode) const {
29702970
return (Key)(key | modifiers);
29712971
}
29722972

2973+
Key DisplayServerX11::keyboard_get_label_from_physical(Key p_keycode) const {
2974+
Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK;
2975+
Key keycode_no_mod = p_keycode & KeyModifierMask::CODE_MASK;
2976+
unsigned int xkeycode = KeyMappingX11::get_xlibcode(keycode_no_mod);
2977+
KeySym xkeysym = XkbKeycodeToKeysym(x11_display, xkeycode, keyboard_get_current_layout(), 0);
2978+
if (is_ascii_lower_case(xkeysym)) {
2979+
xkeysym -= ('a' - 'A');
2980+
}
2981+
2982+
Key key = KeyMappingX11::get_keycode(xkeysym);
2983+
#ifdef XKB_ENABLED
2984+
if (xkb_loaded_v08p) {
2985+
String keysym = String::chr(xkb_keysym_to_utf32(xkb_keysym_to_upper(xkeysym)));
2986+
key = fix_key_label(keysym[0], KeyMappingX11::get_keycode(xkeysym));
2987+
}
2988+
#endif
2989+
2990+
// If not found, fallback to QWERTY.
2991+
// This should match the behavior of the event pump
2992+
if (key == Key::NONE) {
2993+
return p_keycode;
2994+
}
2995+
return (Key)(key | modifiers);
2996+
}
29732997
DisplayServerX11::Property DisplayServerX11::_read_property(Display *p_display, Window p_window, Atom p_property) {
29742998
Atom actual_type = None;
29752999
int actual_format = 0;

platform/linuxbsd/x11/display_server_x11.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,7 @@ class DisplayServerX11 : public DisplayServer {
500500
virtual String keyboard_get_layout_language(int p_index) const override;
501501
virtual String keyboard_get_layout_name(int p_index) const override;
502502
virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override;
503+
virtual Key keyboard_get_label_from_physical(Key p_keycode) const override;
503504

504505
virtual void process_events() override;
505506

platform/macos/display_server_macos.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ class DisplayServerMacOS : public DisplayServer {
430430
virtual String keyboard_get_layout_language(int p_index) const override;
431431
virtual String keyboard_get_layout_name(int p_index) const override;
432432
virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override;
433+
virtual Key keyboard_get_label_from_physical(Key p_keycode) const override;
433434

434435
virtual void process_events() override;
435436
virtual void force_process_and_drop_events() override;

platform/macos/display_server_macos.mm

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3491,6 +3491,17 @@
34913491
return (Key)(KeyMappingMacOS::remap_key(macos_keycode, 0, false) | modifiers);
34923492
}
34933493

3494+
Key DisplayServerMacOS::keyboard_get_label_from_physical(Key p_keycode) const {
3495+
if (p_keycode == Key::PAUSE || p_keycode == Key::NONE) {
3496+
return p_keycode;
3497+
}
3498+
3499+
Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK;
3500+
Key keycode_no_mod = p_keycode & KeyModifierMask::CODE_MASK;
3501+
unsigned int macos_keycode = KeyMappingMacOS::unmap_key(keycode_no_mod);
3502+
return (Key)(KeyMappingMacOS::remap_key(macos_keycode, 0, true) | modifiers);
3503+
}
3504+
34943505
void DisplayServerMacOS::process_events() {
34953506
_THREAD_SAFE_METHOD_
34963507

platform/windows/display_server_windows.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1998,6 +1998,38 @@ Key DisplayServerWindows::keyboard_get_keycode_from_physical(Key p_keycode) cons
19981998
return (Key)(KeyMappingWindows::get_keysym(vk) | modifiers);
19991999
}
20002000

2001+
Key DisplayServerWindows::keyboard_get_label_from_physical(Key p_keycode) const {
2002+
Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK;
2003+
Key keycode_no_mod = (Key)(p_keycode & KeyModifierMask::CODE_MASK);
2004+
2005+
if (keycode_no_mod == Key::PRINT ||
2006+
keycode_no_mod == Key::KP_ADD ||
2007+
keycode_no_mod == Key::KP_5 ||
2008+
(keycode_no_mod >= Key::KEY_0 && keycode_no_mod <= Key::KEY_9)) {
2009+
return p_keycode;
2010+
}
2011+
2012+
unsigned int scancode = KeyMappingWindows::get_scancode(keycode_no_mod);
2013+
if (scancode == 0) {
2014+
return p_keycode;
2015+
}
2016+
2017+
Key keycode = KeyMappingWindows::get_keysym(MapVirtualKey(scancode, MAPVK_VSC_TO_VK));
2018+
2019+
HKL current_layout = GetKeyboardLayout(0);
2020+
static BYTE keyboard_state[256];
2021+
memset(keyboard_state, 0, 256);
2022+
wchar_t chars[256] = {};
2023+
UINT extended_code = MapVirtualKey(scancode, MAPVK_VSC_TO_VK_EX);
2024+
if (ToUnicodeEx(extended_code, scancode, keyboard_state, chars, 255, 4, current_layout) > 0) {
2025+
String keysym = String::utf16((char16_t *)chars, 255);
2026+
if (!keysym.is_empty()) {
2027+
return fix_key_label(keysym[0], keycode) | modifiers;
2028+
}
2029+
}
2030+
return p_keycode;
2031+
}
2032+
20012033
String _get_full_layout_name_from_registry(HKL p_layout) {
20022034
String id = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\" + String::num_int64((int64_t)p_layout, 16, false).lpad(8, "0");
20032035
String ret;

platform/windows/display_server_windows.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,7 @@ class DisplayServerWindows : public DisplayServer {
621621
virtual String keyboard_get_layout_language(int p_index) const override;
622622
virtual String keyboard_get_layout_name(int p_index) const override;
623623
virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override;
624+
virtual Key keyboard_get_label_from_physical(Key p_keycode) const override;
624625

625626
virtual int tablet_get_driver_count() const override;
626627
virtual String tablet_get_driver_name(int p_driver) const override;

servers/display_server.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,10 @@ Key DisplayServer::keyboard_get_keycode_from_physical(Key p_keycode) const {
520520
ERR_FAIL_V_MSG(p_keycode, "Not supported by this display server.");
521521
}
522522

523+
Key DisplayServer::keyboard_get_label_from_physical(Key p_keycode) const {
524+
ERR_FAIL_V_MSG(p_keycode, "Not supported by this display server.");
525+
}
526+
523527
void DisplayServer::force_process_and_drop_events() {
524528
}
525529

@@ -756,6 +760,7 @@ void DisplayServer::_bind_methods() {
756760
ClassDB::bind_method(D_METHOD("keyboard_get_layout_language", "index"), &DisplayServer::keyboard_get_layout_language);
757761
ClassDB::bind_method(D_METHOD("keyboard_get_layout_name", "index"), &DisplayServer::keyboard_get_layout_name);
758762
ClassDB::bind_method(D_METHOD("keyboard_get_keycode_from_physical", "keycode"), &DisplayServer::keyboard_get_keycode_from_physical);
763+
ClassDB::bind_method(D_METHOD("keyboard_get_label_from_physical", "keycode"), &DisplayServer::keyboard_get_label_from_physical);
759764

760765
ClassDB::bind_method(D_METHOD("process_events"), &DisplayServer::process_events);
761766
ClassDB::bind_method(D_METHOD("force_process_and_drop_events"), &DisplayServer::force_process_and_drop_events);

servers/display_server.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,7 @@ class DisplayServer : public Object {
498498
virtual String keyboard_get_layout_language(int p_index) const;
499499
virtual String keyboard_get_layout_name(int p_index) const;
500500
virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const;
501+
virtual Key keyboard_get_label_from_physical(Key p_keycode) const;
501502

502503
virtual int tablet_get_driver_count() const { return 1; };
503504
virtual String tablet_get_driver_name(int p_driver) const { return "default"; };

0 commit comments

Comments
 (0)