Skip to content

Commit

Permalink
Merge pull request #77993 from bruvzg/key_lbl_from_p
Browse files Browse the repository at this point in the history
Implement DisplayServer.keyboard_get_label_from_physical method.
  • Loading branch information
YuriSizov committed Jul 12, 2023
2 parents a927b22 + 08e8ff3 commit ff68900
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 0 deletions.
8 changes: 8 additions & 0 deletions doc/classes/DisplayServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,14 @@
[b]Note:[/b] This method is implemented on Linux (X11), macOS and Windows.
</description>
</method>
<method name="keyboard_get_label_from_physical" qualifiers="const">
<return type="int" enum="Key" />
<param index="0" name="keycode" type="int" enum="Key" />
<description>
Converts a physical (US QWERTY) [param keycode] to localized label printed on the key in the active keyboard layout.
[b]Note:[/b] This method is implemented on Linux (X11), macOS and Windows.
</description>
</method>
<method name="keyboard_get_layout_count" qualifiers="const">
<return type="int" />
<description>
Expand Down
24 changes: 24 additions & 0 deletions platform/linuxbsd/x11/display_server_x11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2980,6 +2980,30 @@ Key DisplayServerX11::keyboard_get_keycode_from_physical(Key p_keycode) const {
return (Key)(key | modifiers);
}

Key DisplayServerX11::keyboard_get_label_from_physical(Key p_keycode) const {
Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK;
Key keycode_no_mod = p_keycode & KeyModifierMask::CODE_MASK;
unsigned int xkeycode = KeyMappingX11::get_xlibcode(keycode_no_mod);
KeySym xkeysym = XkbKeycodeToKeysym(x11_display, xkeycode, keyboard_get_current_layout(), 0);
if (is_ascii_lower_case(xkeysym)) {
xkeysym -= ('a' - 'A');
}

Key key = KeyMappingX11::get_keycode(xkeysym);
#ifdef XKB_ENABLED
if (xkb_loaded_v08p) {
String keysym = String::chr(xkb_keysym_to_utf32(xkb_keysym_to_upper(xkeysym)));
key = fix_key_label(keysym[0], KeyMappingX11::get_keycode(xkeysym));
}
#endif

// If not found, fallback to QWERTY.
// This should match the behavior of the event pump
if (key == Key::NONE) {
return p_keycode;
}
return (Key)(key | modifiers);
}
DisplayServerX11::Property DisplayServerX11::_read_property(Display *p_display, Window p_window, Atom p_property) {
Atom actual_type = None;
int actual_format = 0;
Expand Down
1 change: 1 addition & 0 deletions platform/linuxbsd/x11/display_server_x11.h
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ class DisplayServerX11 : public DisplayServer {
virtual String keyboard_get_layout_language(int p_index) const override;
virtual String keyboard_get_layout_name(int p_index) const override;
virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override;
virtual Key keyboard_get_label_from_physical(Key p_keycode) const override;

virtual void process_events() override;

Expand Down
1 change: 1 addition & 0 deletions platform/macos/display_server_macos.h
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ class DisplayServerMacOS : public DisplayServer {
virtual String keyboard_get_layout_language(int p_index) const override;
virtual String keyboard_get_layout_name(int p_index) const override;
virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override;
virtual Key keyboard_get_label_from_physical(Key p_keycode) const override;

virtual void process_events() override;
virtual void force_process_and_drop_events() override;
Expand Down
11 changes: 11 additions & 0 deletions platform/macos/display_server_macos.mm
Original file line number Diff line number Diff line change
Expand Up @@ -3499,6 +3499,17 @@
return (Key)(KeyMappingMacOS::remap_key(macos_keycode, 0, false) | modifiers);
}

Key DisplayServerMacOS::keyboard_get_label_from_physical(Key p_keycode) const {
if (p_keycode == Key::PAUSE || p_keycode == Key::NONE) {
return p_keycode;
}

Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK;
Key keycode_no_mod = p_keycode & KeyModifierMask::CODE_MASK;
unsigned int macos_keycode = KeyMappingMacOS::unmap_key(keycode_no_mod);
return (Key)(KeyMappingMacOS::remap_key(macos_keycode, 0, true) | modifiers);
}

void DisplayServerMacOS::process_events() {
_THREAD_SAFE_METHOD_

Expand Down
32 changes: 32 additions & 0 deletions platform/windows/display_server_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2010,6 +2010,38 @@ Key DisplayServerWindows::keyboard_get_keycode_from_physical(Key p_keycode) cons
return (Key)(KeyMappingWindows::get_keysym(vk) | modifiers);
}

Key DisplayServerWindows::keyboard_get_label_from_physical(Key p_keycode) const {
Key modifiers = p_keycode & KeyModifierMask::MODIFIER_MASK;
Key keycode_no_mod = (Key)(p_keycode & KeyModifierMask::CODE_MASK);

if (keycode_no_mod == Key::PRINT ||
keycode_no_mod == Key::KP_ADD ||
keycode_no_mod == Key::KP_5 ||
(keycode_no_mod >= Key::KEY_0 && keycode_no_mod <= Key::KEY_9)) {
return p_keycode;
}

unsigned int scancode = KeyMappingWindows::get_scancode(keycode_no_mod);
if (scancode == 0) {
return p_keycode;
}

Key keycode = KeyMappingWindows::get_keysym(MapVirtualKey(scancode, MAPVK_VSC_TO_VK));

HKL current_layout = GetKeyboardLayout(0);
static BYTE keyboard_state[256];
memset(keyboard_state, 0, 256);
wchar_t chars[256] = {};
UINT extended_code = MapVirtualKey(scancode, MAPVK_VSC_TO_VK_EX);
if (ToUnicodeEx(extended_code, scancode, keyboard_state, chars, 255, 4, current_layout) > 0) {
String keysym = String::utf16((char16_t *)chars, 255);
if (!keysym.is_empty()) {
return fix_key_label(keysym[0], keycode) | modifiers;
}
}
return p_keycode;
}

String _get_full_layout_name_from_registry(HKL p_layout) {
String id = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\" + String::num_int64((int64_t)p_layout, 16, false).lpad(8, "0");
String ret;
Expand Down
1 change: 1 addition & 0 deletions platform/windows/display_server_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@ class DisplayServerWindows : public DisplayServer {
virtual String keyboard_get_layout_language(int p_index) const override;
virtual String keyboard_get_layout_name(int p_index) const override;
virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const override;
virtual Key keyboard_get_label_from_physical(Key p_keycode) const override;

virtual int tablet_get_driver_count() const override;
virtual String tablet_get_driver_name(int p_driver) const override;
Expand Down
5 changes: 5 additions & 0 deletions servers/display_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,10 @@ Key DisplayServer::keyboard_get_keycode_from_physical(Key p_keycode) const {
ERR_FAIL_V_MSG(p_keycode, "Not supported by this display server.");
}

Key DisplayServer::keyboard_get_label_from_physical(Key p_keycode) const {
ERR_FAIL_V_MSG(p_keycode, "Not supported by this display server.");
}

void DisplayServer::force_process_and_drop_events() {
}

Expand Down Expand Up @@ -757,6 +761,7 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("keyboard_get_layout_language", "index"), &DisplayServer::keyboard_get_layout_language);
ClassDB::bind_method(D_METHOD("keyboard_get_layout_name", "index"), &DisplayServer::keyboard_get_layout_name);
ClassDB::bind_method(D_METHOD("keyboard_get_keycode_from_physical", "keycode"), &DisplayServer::keyboard_get_keycode_from_physical);
ClassDB::bind_method(D_METHOD("keyboard_get_label_from_physical", "keycode"), &DisplayServer::keyboard_get_label_from_physical);

ClassDB::bind_method(D_METHOD("process_events"), &DisplayServer::process_events);
ClassDB::bind_method(D_METHOD("force_process_and_drop_events"), &DisplayServer::force_process_and_drop_events);
Expand Down
1 change: 1 addition & 0 deletions servers/display_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ class DisplayServer : public Object {
virtual String keyboard_get_layout_language(int p_index) const;
virtual String keyboard_get_layout_name(int p_index) const;
virtual Key keyboard_get_keycode_from_physical(Key p_keycode) const;
virtual Key keyboard_get_label_from_physical(Key p_keycode) const;

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

0 comments on commit ff68900

Please sign in to comment.