From 296f003e58e48ea8508994c289d1f5fde22acd1c Mon Sep 17 00:00:00 2001 From: teatov Date: Sat, 2 Aug 2025 06:01:31 +1000 Subject: [PATCH] add qmk keycode detection --- scripts/layouts/parser_kle.gd | 2 - scripts/layouts/parser_qmk.gd | 198 +++++++++++++++++++++++++++++++--- 2 files changed, 184 insertions(+), 16 deletions(-) diff --git a/scripts/layouts/parser_kle.gd b/scripts/layouts/parser_kle.gd index 2547aee..feb14f2 100644 --- a/scripts/layouts/parser_kle.gd +++ b/scripts/layouts/parser_kle.gd @@ -263,8 +263,6 @@ func _get_key_locations(key_pos_dicts: Dictionary[Key, Array]) -> void: key_pos_dict_right = key_pos_dict if key_pos_dict_left == key_pos_dict_right: - # or not key_pos_dict_left - # or not key_pos_dict_right continue if keycode == KEY_ENTER: diff --git a/scripts/layouts/parser_qmk.gd b/scripts/layouts/parser_qmk.gd index 49f8883..cdd2264 100644 --- a/scripts/layouts/parser_qmk.gd +++ b/scripts/layouts/parser_qmk.gd @@ -1,7 +1,152 @@ class_name ParserQMK extends AbstractParser const KEYCODE_MAP: Dictionary[String, Key] = { - "ENTER": KEY_ENTER, + "ENT": KEY_ENTER, + "ESC": KEY_ESCAPE, + "BSPC": KEY_BACKSPACE, + "SPC": KEY_SPACE, + "MINS": KEY_MINUS, + "EQL": KEY_EQUAL, + "LEFT_BRACKET": KEY_BRACKETLEFT, + "LBRC": KEY_BRACKETLEFT, + "RIGHT_BRACKET": KEY_BRACKETRIGHT, + "RBRC": KEY_BRACKETRIGHT, + "BSLS": KEY_BACKSLASH, + "NONUS_HASH": KEY_BACKSLASH, + "NUHS": KEY_BACKSLASH, + "SCLN": KEY_SEMICOLON, + "QUOTE": KEY_APOSTROPHE, + "QUOT": KEY_APOSTROPHE, + "GRAVE": KEY_QUOTELEFT, + "GRV": KEY_QUOTELEFT, + "COMM": KEY_COMMA, + "DOT": KEY_PERIOD, + "SLSH": KEY_SLASH, + "NONUS_BACKSLASH": KEY_SECTION, + "NUBS": KEY_SECTION, + "CAPS_LOCK": KEY_CAPSLOCK, + "CAPS": KEY_CAPSLOCK, + "SCROLL_LOCK": KEY_SCROLLLOCK, + "SCRL": KEY_SCROLLLOCK, + "BRMD": KEY_SCROLLLOCK, + "NUM_LOCK": KEY_NUMLOCK, + "NUM": KEY_NUMLOCK, + "PRINT_SCREEN": KEY_PRINT, + "PSCR": KEY_PRINT, + "PAUS": KEY_PAUSE, + "BRK": KEY_PAUSE, + "BRMU": KEY_PAUSE, + "INS": KEY_INSERT, + "PAGE_UP": KEY_PAGEUP, + "PGUP": KEY_PAGEUP, + "DEL": KEY_DELETE, + "PAGE_DOWN": KEY_PAGEDOWN, + "PGDN": KEY_PAGEDOWN, + "RGHT": KEY_RIGHT, + "APPLICATION": KEY_MENU, + "APP": KEY_MENU, + "SYSTEM_REQUEST": KEY_SYSREQ, + "SYRQ": KEY_SYSREQ, + "CLR": KEY_CLEAR, + "RETURN": KEY_ENTER, + "RETN": KEY_ENTER, + "AUDIO_MUTE": KEY_VOLUMEMUTE, + "MUTE": KEY_VOLUMEMUTE, + "AUDIO_VOL_UP": KEY_VOLUMEUP, + "VOLU": KEY_VOLUMEUP, + "AUDIO_VOL_DOWN": KEY_VOLUMEDOWN, + "VOLD": KEY_VOLUMEDOWN, + "MEDIA_NEXT_TRACK": KEY_MEDIANEXT, + "MNXT": KEY_MEDIANEXT, + "MEDIA_PREV_TRACK": KEY_MEDIAPREVIOUS, + "MPRV": KEY_MEDIAPREVIOUS, + "MEDIA_STOP": KEY_MEDIASTOP, + "MSTP": KEY_MEDIASTOP, + "MEDIA_PLAY_PAUSE": KEY_MEDIAPLAY, + "MPLY": KEY_MEDIAPLAY, + "MAIL": KEY_LAUNCHMAIL, + "WWW_SEARCH": KEY_SEARCH, + "WSCH": KEY_SEARCH, + "WWW_HOME": KEY_SEARCH, + "WHOM": KEY_SEARCH, + "WWW_BACK": KEY_BACK, + "WBAK": KEY_BACK, + "WWW_FORWARD": KEY_FORWARD, + "WFWD": KEY_FORWARD, + "WWW_STOP": KEY_STOP, + "WSTP": KEY_STOP, + "WWW_REFRESH": KEY_REFRESH, + "WREF": KEY_REFRESH, + "WWW_FAVORITES": KEY_FAVORITES, + "WFAV": KEY_FAVORITES, + "MEDIA_FAST_FORWARD": KEY_MEDIANEXT, + "MFFD": KEY_MEDIANEXT, + "MEDIA_REWIND": KEY_MEDIAPREVIOUS, + "MRWD": KEY_MEDIAPREVIOUS, + "INTERNATIONAL_1": KEY_BACKSLASH, + "INT1": KEY_BACKSLASH, + "INTERNATIONAL_3": KEY_YEN, + "INT3": KEY_YEN, + "KP_SLASH": KEY_KP_DIVIDE, + "PSLS": KEY_KP_DIVIDE, + "KP_ASTERISK": KEY_KP_MULTIPLY, + "PAST": KEY_KP_MULTIPLY, + "KP_MINUS": KEY_KP_SUBTRACT, + "PMNS": KEY_KP_SUBTRACT, + "KP_PLUS": KEY_KP_ADD, + "PPLS": KEY_KP_ADD, + "KP_ENTER": KEY_KP_ENTER, + "PENT": KEY_KP_ENTER, + "KP_1": KEY_KP_1, + "P1": KEY_KP_1, + "KP_2": KEY_KP_2, + "P2": KEY_KP_2, + "KP_3": KEY_KP_3, + "P3": KEY_KP_3, + "KP_4": KEY_KP_4, + "P4": KEY_KP_4, + "KP_5": KEY_KP_5, + "P5": KEY_KP_5, + "KP_6": KEY_KP_6, + "P6": KEY_KP_6, + "KP_7": KEY_KP_7, + "P7": KEY_KP_7, + "KP_8": KEY_KP_8, + "P8": KEY_KP_8, + "KP_9": KEY_KP_9, + "P9": KEY_KP_9, + "KP_0": KEY_KP_0, + "P0": KEY_KP_0, + "KP_DOT": KEY_KP_PERIOD, + "PDOT": KEY_KP_PERIOD, + "KP_COMMA": KEY_KP_PERIOD, + "PCMM": KEY_KP_PERIOD, +} + +const KEYCODE_MODIFIER_LEFT_MAP: Dictionary[String, Key] = { + "LEFT_CTRL": KEY_CTRL, + "LCTL": KEY_CTRL, + "LEFT_SHIFT": KEY_SHIFT, + "LSFT": KEY_SHIFT, + "LEFT_ALT": KEY_ALT, + "LOPT": KEY_ALT, + "LEFT_GUI": KEY_META, + "LGUI": KEY_META, + "LCMD": KEY_META, + "LWIN": KEY_META, +} + +const KEYCODE_MODIFIER_RIGHT_MAP: Dictionary[String, Key] = { + "RIGHT_CTRL": KEY_CTRL, + "RCTL": KEY_CTRL, + "RIGHT_SHIFT": KEY_SHIFT, + "RSFT": KEY_SHIFT, + "RIGHT_ALT": KEY_ALT, + "ROPT": KEY_ALT, + "RIGHT_GUI": KEY_META, + "RGUI": KEY_META, + "RCMD": KEY_META, + "RWIN": KEY_META, } const KEYBOARD_NAME := "keyboard_name" @@ -46,9 +191,7 @@ func _init(data: Dictionary, file_name: String) -> void: ): return - _rows = _deserialize_keys( - data[LAYOUTS][layout_name][LAYOUT] as Array, keymap_keys - ) + _rows = _deserialize_keys(data[LAYOUTS][layout_name][LAYOUT] as Array, keymap_keys) func get_name() -> String: @@ -59,9 +202,7 @@ func get_rows() -> Array[Array]: return _rows -func _deserialize_keys( - data_keys: Array, keymap_keys: Array[String] -) -> Array[Array]: +func _deserialize_keys(data_keys: Array, keymap_keys: Array[String]) -> Array[Array]: var layout_rows: Dictionary[float, Array] = {} var rows_max_xs: Dictionary[float, float] = {} var prev_pos_x: float = 0 @@ -71,7 +212,6 @@ func _deserialize_keys( if data_keys[i] is not Dictionary: continue var data_key := data_keys[i] as Dictionary - print(data_key) if ( not data_key.has(MATRIX) or not data_key.has(X) @@ -89,7 +229,7 @@ func _deserialize_keys( prev_pos_y = data_key[Y] var keycode := ( - _get_keycode_from_keymap_key(keymap_keys[i].substr(3)) + _get_keycode_from_keymap_key(keymap_keys[i]) if i < keymap_keys.size() else KEY_NONE ) @@ -101,6 +241,15 @@ func _deserialize_keys( data_key[Y] as float - prev_pos_y ) ) + + var location := ( + _get_key_location(keymap_keys[i]) + if i < keymap_keys.size() + else KEY_LOCATION_UNSPECIFIED + ) + if location != KEY_LOCATION_UNSPECIFIED: + key_dict[KeyProps.LOC] = location + layout_rows[data_key[Y]].append(key_dict) var width: float = data_key[W] if data_key.has(W) else 1.0 @@ -172,16 +321,37 @@ func _get_keymap_keys(json_file_name: String) -> Array[String]: return keymap_keys -func _get_keycode_from_keymap_key(keymap_key: String) -> Key: +func _get_keymap_key_unprefixed(keymap_key_prefixed: String) -> String: + return keymap_key_prefixed.substr(3) + + +func _get_keycode_from_keymap_key(keymap_key_prefixed: String) -> Key: + var keymap_key := _get_keymap_key_unprefixed(keymap_key_prefixed) var keycode := KEY_NONE - if KEYCODE_MAP.has(keymap_key): - keycode = KEYCODE_MAP[keymap_key] + keycode = OS.find_keycode_from_string(keymap_key) if keycode == KEY_NONE and KEYCODE_MAP.has(keymap_key): keycode = KEYCODE_MAP[keymap_key] - if keycode == KEY_NONE and keymap_key.length() == 1: - keycode = OS.find_keycode_from_string(keymap_key) + if keycode == KEY_NONE and KEYCODE_MODIFIER_LEFT_MAP.has(keymap_key): + keycode = KEYCODE_MODIFIER_LEFT_MAP[keymap_key] + + if keycode == KEY_NONE and KEYCODE_MODIFIER_RIGHT_MAP.has(keymap_key): + keycode = KEYCODE_MODIFIER_RIGHT_MAP[keymap_key] + + if keycode == KEY_NONE: + printerr( + "%s: could not recognize key label %s" % [_file_name, keymap_key_prefixed] + ) return keycode + + +func _get_key_location(keymap_key_prefixed: String) -> KeyLocation: + var keymap_key := _get_keymap_key_unprefixed(keymap_key_prefixed) + if KEYCODE_MODIFIER_LEFT_MAP.has(keymap_key): + return KEY_LOCATION_LEFT + if KEYCODE_MODIFIER_RIGHT_MAP.has(keymap_key): + return KEY_LOCATION_RIGHT + return KEY_LOCATION_UNSPECIFIED