Use pixel mode for mouse tracking in kittens

This commit is contained in:
Kovid Goyal 2021-09-28 12:46:41 +05:30
parent 9a3d99515f
commit 3c742a0037
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 21 additions and 8 deletions

View File

@ -25,10 +25,12 @@ from kitty.key_encoding import (
enter_key
)
from kitty.typing import ImageManagerType, KeyEventType, Protocol
from kitty.utils import ScreenSizeGetter, screen_size_function, write_all
from kitty.utils import (
ScreenSize, ScreenSizeGetter, screen_size_function, write_all
)
from .handler import Handler
from .operations import init_state, reset_state, MouseTracking
from .operations import MouseTracking, init_state, reset_state
class BinaryWrite(Protocol):
@ -116,14 +118,21 @@ CTRL_INDICATOR = 1 << 4
class MouseEvent(NamedTuple):
x: int
y: int
cell_x: int
cell_y: int
pixel_x: int
pixel_y: int
type: int
buttons: int
mods: int
def decode_sgr_mouse(text: str) -> MouseEvent:
def pixel_to_cell(px: int, length: int, cell_length: int) -> int:
px = max(0, min(px, length - 1))
return px // cell_length
def decode_sgr_mouse(text: str, screen_size: ScreenSize) -> MouseEvent:
cb_, x_, y_ = text.split(';')
m, y_ = y_[-1], y_[:-1]
cb, x, y = map(int, (cb_, x_, y_))
@ -142,7 +151,10 @@ def decode_sgr_mouse(text: str) -> MouseEvent:
mods |= ALT
if cb & CTRL_INDICATOR:
mods |= CTRL
return MouseEvent(x, y, typ, buttons, mods)
return MouseEvent(
pixel_to_cell(x, screen_size.width, screen_size.cell_width), pixel_to_cell(y, screen_size.height, screen_size.cell_height),
x, y, typ, buttons, mods
)
class UnhandledException(Handler):
@ -285,7 +297,7 @@ class Loop:
if csi.startswith('<'):
# SGR mouse event
try:
ev = decode_sgr_mouse(csi[1:])
ev = decode_sgr_mouse(csi[1:], self.handler.screen_size)
except Exception:
pass
else:

View File

@ -43,6 +43,7 @@ class Mode(Enum):
MOUSE_UTF8_MODE = 1005, '?'
MOUSE_SGR_MODE = 1006, '?'
MOUSE_URXVT_MODE = 1015, '?'
MOUSE_SGR_PIXEL_MODE = 1016, '?'
ALTERNATE_SCREEN = 1049, '?'
BRACKETED_PASTE = 2004, '?'
PENDING_UPDATE = 2026, '?'
@ -304,7 +305,7 @@ def init_state(alternate_screen: bool = True, mouse_tracking: MouseTracking = Mo
ans += set_mode(Mode.ALTERNATE_SCREEN) + reset_mode(Mode.DECOM)
ans += clear_screen()
if mouse_tracking is not MouseTracking.none:
ans += set_mode(Mode.MOUSE_SGR_MODE)
ans += set_mode(Mode.MOUSE_SGR_PIXEL_MODE)
if mouse_tracking is MouseTracking.buttons_only:
ans += set_mode(Mode.MOUSE_BUTTON_TRACKING)
elif mouse_tracking is MouseTracking.buttons_and_drag: