Allow mapping shortcuts using the raw key code from the OS

Fixes #848
This commit is contained in:
Kovid Goyal 2018-09-02 18:46:10 +05:30
parent 96cbfe946c
commit 6ec58f58ce
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 42 additions and 16 deletions

View File

@ -3,6 +3,15 @@ Changelog
|kitty| is a feature full, cross-platform, *fast*, GPU based terminal emulator. |kitty| is a feature full, cross-platform, *fast*, GPU based terminal emulator.
0.12.1 [future]
------------------------------
- Allow mapping shortcuts using the raw key code from the OS (:iss:`848`)
- Allow mapping of individual keypresses without modifiers as shortcuts
- Fix legacy invocation of icat as `kitty icat` not working (:iss:`850`)
0.12.0 [2018-09-01] 0.12.0 [2018-09-01]
------------------------------ ------------------------------

View File

@ -35,14 +35,22 @@ named_keys = {
def parse_shortcut(sc): def parse_shortcut(sc):
parts = sc.split('+') parts = sc.split('+')
mods = parse_mods(parts[:-1], sc) mods = 0
if mods is None: if len(parts) > 1:
return None, None, None mods = parse_mods(parts[:-1], sc)
if mods is None:
return None, None, None
key = parts[-1].upper() key = parts[-1].upper()
key = getattr(defines, 'GLFW_KEY_' + named_keys.get(key, key), None) key = getattr(defines, 'GLFW_KEY_' + named_keys.get(key, key), None)
is_native = False is_native = False
if key is None: if key is None:
key = defines.key_for_native_key_name(parts[-1]) if parts[-1].startswith('0x'):
try:
key = int(parts[-1], 16)
except Exception:
pass
else:
key = defines.key_for_native_key_name(parts[-1])
is_native = key is not None is_native = key is not None
return mods, is_native, key return mods, is_native, key

View File

@ -95,6 +95,21 @@ for a list of key names. The name to use is the part after the :code:`XKB_KEY_`
prefix. Note that you should only use an XKB key name for keys that are not present prefix. Note that you should only use an XKB key name for keys that are not present
in the list of GLFW keys. in the list of GLFW keys.
Finally, you can use raw system key codes to map keys. To see the system key code
for a key, start kitty with the :option:`kitty --debug-keyboard` option. Then kitty will
output some debug text for every key event. In that text look for ``native_code``
the value of that becomes the key name in the shortcut. For example:
.. code-block:: none
on_key_input: glfw key: 65 native_code: 0x61 action: PRESS mods: 0x0 text: 'a'
Here, the key name for the :kbd:`A` key is :kbd:`0x61` and you can use it with::
map ctrl+0x61 something
to map :kbd:`ctrl+a` to something.
You can use the special action :code:`no_op` to unmap a keyboard shortcut that is You can use the special action :code:`no_op` to unmap a keyboard shortcut that is
assigned in the default configuration. assigned in the default configuration.

View File

@ -103,13 +103,9 @@ check_if_special(int key, int mods, int scancode) {
qkey = SPECIAL_INDEX(qkey); qkey = SPECIAL_INDEX(qkey);
special = needs_special_handling[qkey]; special = needs_special_handling[qkey];
} }
#ifdef __APPLE__ for (size_t i = 0; !special && i < native_special_keys_count; i++) {
(void)scancode; if (scancode == native_special_keys[i].scancode && mods == native_special_keys[i].mods) special = true;
#else }
for (size_t i = 0; !special && i < native_special_keys_count; i++) {
if (scancode == native_special_keys[i].scancode && mods == native_special_keys[i].mods) special = true;
}
#endif
return special; return special;
} }
@ -127,7 +123,7 @@ update_ime_position(OSWindow *os_window, Window* w, Screen *screen) {
void void
on_key_input(int key, int scancode, int action, int mods, const char* text, int state) { on_key_input(int key, int scancode, int action, int mods, const char* text, int state) {
Window *w = active_window(); Window *w = active_window();
debug("on_key_input: glfw key: %d native_code: %d action: %s mods: 0x%x text: '%s' state: %d ", debug("on_key_input: glfw key: %d native_code: 0x%x action: %s mods: 0x%x text: '%s' state: %d ",
key, scancode, key, scancode,
(action == GLFW_RELEASE ? "RELEASE" : (action == GLFW_PRESS ? "PRESS" : "REPEAT")), (action == GLFW_RELEASE ? "RELEASE" : (action == GLFW_PRESS ? "PRESS" : "REPEAT")),
mods, text, state); mods, text, state);
@ -222,15 +218,13 @@ PYWRAP1(key_for_native_key_name) {
const char *name; const char *name;
int case_sensitive = 0; int case_sensitive = 0;
PA("s|p", &name, case_sensitive); PA("s|p", &name, case_sensitive);
#ifdef __APPLE__ #ifndef __APPLE__
Py_RETURN_NONE;
#else
if (glfwGetXKBScancode) { // if this function is called before GLFW is initialized glfwGetXKBScancode will be NULL if (glfwGetXKBScancode) { // if this function is called before GLFW is initialized glfwGetXKBScancode will be NULL
int scancode = glfwGetXKBScancode(name, case_sensitive); int scancode = glfwGetXKBScancode(name, case_sensitive);
if (scancode) return Py_BuildValue("i", scancode); if (scancode) return Py_BuildValue("i", scancode);
} }
Py_RETURN_NONE;
#endif #endif
Py_RETURN_NONE;
} }
static PyMethodDef module_methods[] = { static PyMethodDef module_methods[] = {