Also transmit key events when broadcasting

This commit is contained in:
Kovid Goyal 2020-12-01 14:11:50 +05:30
parent 457c292d3c
commit 34db18ea0a
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 55 additions and 6 deletions

View File

@ -9,7 +9,7 @@ from typing import Any, Dict, List, Optional, Tuple
from kitty.cli import parse_args
from kitty.cli_stub import BroadcastCLIOptions
from kitty.key_encoding import RELEASE, key_defs as K
from kitty.key_encoding import RELEASE, encode_key_event, key_defs as K
from kitty.rc.base import MATCH_TAB_OPTION, MATCH_WINDOW_OPTION
from kitty.remote_control import create_basic_command, encode_send
from kitty.typing import KeyEventType
@ -48,12 +48,17 @@ class Broadcast(Handler):
if key_event.key is K['TAB']:
self.write_broadcast_text('\t')
self.write('\t')
return
elif key_event.key is K['BACKSPACE']:
self.write_broadcast_text('\177')
self.write('\x08\x1b[X')
return
elif key_event.key is K['ENTER']:
self.write_broadcast_text('\r')
self.print('')
return
ek = encode_key_event(key_event)
self.write_broadcast_data('kitty-key:' + ek)
def write_broadcast_text(self, text: str) -> None:
self.write_broadcast_data('base64:' + standard_b64encode(text.encode('utf-8')).decode('ascii'))

View File

@ -302,7 +302,7 @@ class Loop:
def _on_apc(self, apc: str) -> None:
if apc.startswith('K'):
try:
k = decode_key_event(apc)
k = decode_key_event(apc[1:])
except Exception:
pass
else:

39
kitty/key_encoding.py generated
View File

@ -417,6 +417,10 @@ def symbolic_name(glfw_name: str) -> str:
return glfw_name[9:].replace('_', ' ')
def glfw_key_name(symbolic_name: str) -> str:
return 'GLFW_KEY_' + symbolic_name.replace(' ', '_')
def update_encoding() -> None:
import re
import subprocess
@ -492,9 +496,9 @@ del key_name, enc
def decode_key_event(text: str) -> KeyEvent:
typ = type_map[text[1]]
mods = mod_map[text[2]]
key = key_rmap[text[3:5]]
typ = type_map[text[0]]
mods = mod_map[text[1]]
key = key_rmap[text[2:4]]
return KeyEvent(typ, mods, key)
@ -503,3 +507,32 @@ def encode_key_event(key_event: KeyEvent) -> str:
mods = rmod_map[key_event.mods]
key = ENCODING[key_event.key.replace('_', ' ')]
return typ + mods + key
class WindowSystemKeyEvent(NamedTuple):
code: int
mods: int
action: int
def decode_key_event_as_window_system_key(text: str) -> Optional[WindowSystemKeyEvent]:
k = decode_key_event(text)
glfw_name = glfw_key_name(k.key)
glfw_code = getattr(defines, glfw_name, None)
if glfw_code is None:
return None
action = defines.GLFW_PRESS
if k.type is RELEASE:
action = defines.GLFW_RELEASE
elif k.type is REPEAT:
action = defines.GLFW_REPEAT
mods = 0
if k.mods & CTRL:
mods |= defines.GLFW_MOD_CONTROL
if k.mods & ALT:
mods |= defines.GLFW_MOD_ALT
if k.mods & SUPER:
mods |= defines.GLFW_MOD_SUPER
if k.mods & SHIFT:
mods |= defines.GLFW_MOD_SHIFT
return WindowSystemKeyEvent(glfw_code, mods, action)

View File

@ -8,6 +8,10 @@ import sys
from typing import TYPE_CHECKING, Dict, Generator, List, Optional
from kitty.config import parse_send_text_bytes
from kitty.key_encoding import (
WindowSystemKeyEvent, decode_key_event_as_window_system_key
)
from kitty.keys import interpret_key_event
from .base import (
MATCH_TAB_OPTION, MATCH_WINDOW_OPTION, ArgsType, Boss, MatchError,
@ -142,13 +146,20 @@ Do not send text to the active window, even if it is one of the matched windows.
data = q.encode('utf-8')
elif encoding == 'base64':
data = base64.standard_b64decode(q)
elif encoding == 'kitty-key':
data = decode_key_event_as_window_system_key(q)
else:
raise TypeError(f'Invalid encoding for send-text data: {encoding}')
exclude_active = payload_get('exclude_active')
for window in windows:
if window is not None:
if not exclude_active or window is not boss.active_window:
window.write_to_child(data)
if isinstance(data, WindowSystemKeyEvent):
kdata = interpret_key_event(data.code, 0, data.mods, window, data.action)
if kdata:
window.write_to_child(kdata)
else:
window.write_to_child(data)
send_text = SendText()