Skip to content

Commit 560c5c7

Browse files
committed
Merge pull request godotengine#77993 from bruvzg/key_lbl_from_p
Implement DisplayServer.keyboard_get_label_from_physical method.
2 parents 1bd0a0c + ba987c9 commit 560c5c7

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
@@ -2980,6 +2980,30 @@ Key DisplayServerX11::keyboard_get_keycode_from_physical(Key p_keycode) const {
29802980
return (Key)(key | modifiers);
29812981
}
29822982

2983+
Key DisplayServerX11::keyboard_get_label_from_physical(Key p_keycode) const {
2984+
Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK;
2985+
Key keycode_no_mod = p_keycode & KeyModifierMask::CODE_MASK;
2986+
unsigned int xkeycode = KeyMappingX11::get_xlibcode(keycode_no_mod);
2987+
KeySym xkeysym = XkbKeycodeToKeysym(x11_display, xkeycode, keyboard_get_current_layout(), 0);
2988+
if (is_ascii_lower_case(xkeysym)) {
2989+
xkeysym -= ('a' - 'A');
2990+
}
2991+
2992+
Key key = KeyMappingX11::get_keycode(xkeysym);
2993+
#ifdef XKB_ENABLED
2994+
if (xkb_loaded_v08p) {
2995+
String keysym = String::chr(xkb_keysym_to_utf32(xkb_keysym_to_upper(xkeysym)));
2996+
key = fix_key_label(keysym[0], KeyMappingX11::get_keycode(xkeysym));
2997+
}
2998+
#endif
2999+
3000+
// If not found, fallback to QWERTY.
3001+
// This should match the behavior of the event pump
3002+
if (key == Key::NONE) {
3003+
return p_keycode;
3004+
}
3005+
return (Key)(key | modifiers);
3006+
}
29833007
DisplayServerX11::Property DisplayServerX11::_read_property(Display *p_display, Window p_window, Atom p_property) {
29843008
Atom actual_type = None;
29853009
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
@@ -502,6 +502,7 @@ class DisplayServerX11 : public DisplayServer {
502502
virtual String keyboard_get_layout_language(int p_index) const override;
503503
virtual String keyboard_get_layout_name(int p_index) const override;
504504
virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override;
505+
virtual Key keyboard_get_label_from_physical(Key p_keycode) const override;
505506

506507
virtual void process_events() override;
507508

platform/macos/display_server_macos.h

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

437438
virtual void process_events() override;
438439
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
@@ -3499,6 +3499,17 @@
34993499
return (Key)(KeyMappingMacOS::remap_key(macos_keycode, 0, false) | modifiers);
35003500
}
35013501

3502+
Key DisplayServerMacOS::keyboard_get_label_from_physical(Key p_keycode) const {
3503+
if (p_keycode == Key::PAUSE || p_keycode == Key::NONE) {
3504+
return p_keycode;
3505+
}
3506+
3507+
Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK;
3508+
Key keycode_no_mod = p_keycode & KeyModifierMask::CODE_MASK;
3509+
unsigned int macos_keycode = KeyMappingMacOS::unmap_key(keycode_no_mod);
3510+
return (Key)(KeyMappingMacOS::remap_key(macos_keycode, 0, true) | modifiers);
3511+
}
3512+
35023513
void DisplayServerMacOS::process_events() {
35033514
_THREAD_SAFE_METHOD_
35043515

platform/windows/display_server_windows.cpp

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

2013+
Key DisplayServerWindows::keyboard_get_label_from_physical(Key p_keycode) const {
2014+
Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK;
2015+
Key keycode_no_mod = (Key)(p_keycode & KeyModifierMask::CODE_MASK);
2016+
2017+
if (keycode_no_mod == Key::PRINT ||
2018+
keycode_no_mod == Key::KP_ADD ||
2019+
keycode_no_mod == Key::KP_5 ||
2020+
(keycode_no_mod >= Key::KEY_0 && keycode_no_mod <= Key::KEY_9)) {
2021+
return p_keycode;
2022+
}
2023+
2024+
unsigned int scancode = KeyMappingWindows::get_scancode(keycode_no_mod);
2025+
if (scancode == 0) {
2026+
return p_keycode;
2027+
}
2028+
2029+
Key keycode = KeyMappingWindows::get_keysym(MapVirtualKey(scancode, MAPVK_VSC_TO_VK));
2030+
2031+
HKL current_layout = GetKeyboardLayout(0);
2032+
static BYTE keyboard_state[256];
2033+
memset(keyboard_state, 0, 256);
2034+
wchar_t chars[256] = {};
2035+
UINT extended_code = MapVirtualKey(scancode, MAPVK_VSC_TO_VK_EX);
2036+
if (ToUnicodeEx(extended_code, scancode, keyboard_state, chars, 255, 4, current_layout) > 0) {
2037+
String keysym = String::utf16((char16_t *)chars, 255);
2038+
if (!keysym.is_empty()) {
2039+
return fix_key_label(keysym[0], keycode) | modifiers;
2040+
}
2041+
}
2042+
return p_keycode;
2043+
}
2044+
20132045
String _get_full_layout_name_from_registry(HKL p_layout) {
20142046
String id = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\" + String::num_int64((int64_t)p_layout, 16, false).lpad(8, "0");
20152047
String ret;

platform/windows/display_server_windows.h

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

627628
virtual int tablet_get_driver_count() const override;
628629
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

@@ -757,6 +761,7 @@ void DisplayServer::_bind_methods() {
757761
ClassDB::bind_method(D_METHOD("keyboard_get_layout_language", "index"), &DisplayServer::keyboard_get_layout_language);
758762
ClassDB::bind_method(D_METHOD("keyboard_get_layout_name", "index"), &DisplayServer::keyboard_get_layout_name);
759763
ClassDB::bind_method(D_METHOD("keyboard_get_keycode_from_physical", "keycode"), &DisplayServer::keyboard_get_keycode_from_physical);
764+
ClassDB::bind_method(D_METHOD("keyboard_get_label_from_physical", "keycode"), &DisplayServer::keyboard_get_label_from_physical);
760765

761766
ClassDB::bind_method(D_METHOD("process_events"), &DisplayServer::process_events);
762767
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
@@ -499,6 +499,7 @@ class DisplayServer : public Object {
499499
virtual String keyboard_get_layout_language(int p_index) const;
500500
virtual String keyboard_get_layout_name(int p_index) const;
501501
virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const;
502+
virtual Key keyboard_get_label_from_physical(Key p_keycode) const;
502503

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

0 commit comments

Comments
 (0)