mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-24 09:18:08 +02:00
Implement the extended keyboard protocol
This commit is contained in:
@@ -259,6 +259,7 @@ class Boss(Thread):
|
||||
is_key_pressed[key] = action == GLFW_PRESS
|
||||
self.start_cursor_blink()
|
||||
self.cursor_blink_zero_time = monotonic()
|
||||
func = None
|
||||
if action == GLFW_PRESS or action == GLFW_REPEAT:
|
||||
func = get_shortcut(self.opts.keymap, mods, key, scancode)
|
||||
if func is not None:
|
||||
@@ -267,24 +268,24 @@ class Boss(Thread):
|
||||
passthrough = f()
|
||||
if not passthrough:
|
||||
return
|
||||
tab = self.active_tab
|
||||
if tab is None:
|
||||
return
|
||||
window = self.active_window
|
||||
if window is not None:
|
||||
yield window
|
||||
if func is not None:
|
||||
f = getattr(tab, func, getattr(window, func, None))
|
||||
if f is not None:
|
||||
passthrough = f()
|
||||
if not passthrough:
|
||||
return
|
||||
if window.screen.auto_repeat_enabled or action == GLFW_PRESS:
|
||||
if window.char_grid.scrolled_by and key not in MODIFIER_KEYS:
|
||||
window.scroll_end()
|
||||
data = interpret_key_event(key, scancode, mods, window)
|
||||
if data:
|
||||
window.write_to_child(data)
|
||||
tab = self.active_tab
|
||||
if tab is None:
|
||||
return
|
||||
window = self.active_window
|
||||
if window is None:
|
||||
return
|
||||
yield window
|
||||
if func is not None:
|
||||
f = getattr(tab, func, getattr(window, func, None))
|
||||
if f is not None:
|
||||
passthrough = f()
|
||||
if not passthrough:
|
||||
return
|
||||
if window.char_grid.scrolled_by and key not in MODIFIER_KEYS:
|
||||
window.scroll_end()
|
||||
data = interpret_key_event(key, scancode, mods, window, action)
|
||||
if data:
|
||||
window.write_to_child(data)
|
||||
|
||||
@callback
|
||||
def on_focus(self, window, focused):
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import kitty.fast_data_types as defines
|
||||
import string
|
||||
|
||||
from . import fast_data_types as defines
|
||||
from .terminfo import key_as_bytes
|
||||
|
||||
smkx_key_map = {
|
||||
@@ -80,22 +82,60 @@ def get_localized_key(key, scancode):
|
||||
return valid_localized_key_names.get((name or '').upper(), key)
|
||||
|
||||
|
||||
def interpret_key_event(key, scancode, mods, window):
|
||||
action_map = {defines.GLFW_PRESS: b'p', defines.GLFW_RELEASE: b'r', defines.GLFW_REPEAT: b't'}
|
||||
|
||||
|
||||
def base64_encode(integer, chars=string.ascii_uppercase + string.ascii_lowercase + string.digits + '+/'):
|
||||
ans = ''
|
||||
while integer > 0:
|
||||
integer, remainder = divmod(integer, 36)
|
||||
ans = chars[remainder] + ans
|
||||
return ans
|
||||
|
||||
|
||||
def key_extended_map():
|
||||
ans = {}
|
||||
for k in dir(defines):
|
||||
if k.startswith('GLFW_KEY_'):
|
||||
val = getattr(defines, k)
|
||||
if val < defines.GLFW_KEY_LAST and val != defines.GLFW_KEY_UNKNOWN:
|
||||
ans[k[9:]] = base64_encode(val)
|
||||
return ans
|
||||
|
||||
|
||||
key_extended_map = key_extended_map()
|
||||
|
||||
|
||||
def extended_key_event(key, scancode, mods, action):
|
||||
if key >= defines.GLFW_KEY_LAST or key == defines.GLFW_KEY_UNKNOWN or (
|
||||
# Shifted printable key should be handled by interpret_text_event()
|
||||
mods == defines.GLFW_MOD_SHIFT and 32 <= key <= 126):
|
||||
return b''
|
||||
if mods == 0 and key in (defines.GLFW_KEY_BACKSPACE, defines.GLFW_KEY_ENTER):
|
||||
return smkx_key_map[key]
|
||||
return '\033_K{}{:x}:{}\033\\'.format(action_map[action], mods, key_extended_map[key]).encode('ascii')
|
||||
|
||||
|
||||
def interpret_key_event(key, scancode, mods, window, action):
|
||||
screen = window.screen
|
||||
if screen.extended_keyboard:
|
||||
return extended_key_event(key, scancode, mods, action)
|
||||
data = bytearray()
|
||||
key = get_localized_key(key, scancode)
|
||||
if mods == defines.GLFW_MOD_CONTROL and key in control_codes:
|
||||
# Map Ctrl-key to ascii control code
|
||||
data.extend(control_codes[key])
|
||||
elif mods == defines.GLFW_MOD_ALT and key in alt_codes:
|
||||
# Map Alt+key to Esc-key
|
||||
data.extend(alt_codes[key])
|
||||
else:
|
||||
key_map = get_key_map(window.screen)
|
||||
x = key_map.get(key)
|
||||
if x is not None:
|
||||
if mods == defines.GLFW_MOD_SHIFT:
|
||||
x = SHIFTED_KEYS.get(key, x)
|
||||
data.extend(x)
|
||||
if action == defines.GLFW_PRESS or (action == defines.GLFW_REPEAT and screen.auto_repeat_enabled):
|
||||
key = get_localized_key(key, scancode)
|
||||
if mods == defines.GLFW_MOD_CONTROL and key in control_codes:
|
||||
# Map Ctrl-key to ascii control code
|
||||
data.extend(control_codes[key])
|
||||
elif mods == defines.GLFW_MOD_ALT and key in alt_codes:
|
||||
# Map Alt+key to Esc-key
|
||||
data.extend(alt_codes[key])
|
||||
else:
|
||||
key_map = get_key_map(screen)
|
||||
x = key_map.get(key)
|
||||
if x is not None:
|
||||
if mods == defines.GLFW_MOD_SHIFT:
|
||||
x = SHIFTED_KEYS.get(key, x)
|
||||
data.extend(x)
|
||||
return bytes(data)
|
||||
|
||||
|
||||
@@ -109,13 +149,3 @@ def interpret_text_event(codepoint, mods):
|
||||
def get_shortcut(keymap, mods, key, scancode):
|
||||
key = get_localized_key(key, scancode)
|
||||
return keymap.get((mods & 0b1111, key))
|
||||
|
||||
|
||||
def key_integer_map():
|
||||
ans = {}
|
||||
for k in dir(defines):
|
||||
if k.startswith('GLFW_KEY_'):
|
||||
val = getattr(defines, k)
|
||||
if val < defines.GLFW_KEY_LAST and val != defines.GLFW_KEY_UNKNOWN:
|
||||
ans[k[9:]] = val
|
||||
return ans
|
||||
|
||||
Reference in New Issue
Block a user