Merge pull request #77993 from bruvzg/key_lbl_from_p

Implement DisplayServer.keyboard_get_label_from_physical method.
This commit is contained in:
Yuri Sizov 2023-07-12 21:02:37 +02:00
commit ff689003a5
9 changed files with 84 additions and 0 deletions

View file

@ -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>

View file

@ -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;

View file

@ -502,6 +502,7 @@ public:
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;

View file

@ -433,6 +433,7 @@ public:
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;

View file

@ -3499,6 +3499,17 @@ Key DisplayServerMacOS::keyboard_get_keycode_from_physical(Key p_keycode) const
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_

View file

@ -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;

View file

@ -623,6 +623,7 @@ public:
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;

View file

@ -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() {
}
@ -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);

View file

@ -499,6 +499,7 @@ public:
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"; };