MouseScrollUp/MouseScrollDown => plain MousEvent's

... which means they get passesd x, y, etc. In particular,
they are passed the keyboard modifiers. This allows widgets
to use e.g. ctrl-wheel to scroll right/left.
This commit is contained in:
Nitzan Shaked
2022-12-30 18:44:09 +02:00
parent a33d87d3d4
commit e13ea5e0bd
3 changed files with 43 additions and 48 deletions

View File

@@ -54,36 +54,35 @@ class XTermParser(Parser[events.Event]):
if sgr_match:
_buttons, _x, _y, state = sgr_match.groups()
buttons = int(_buttons)
button = (buttons + 1) & 3
x = int(_x) - 1
y = int(_y) - 1
delta_x = x - self.last_x
delta_y = y - self.last_y
self.last_x = x
self.last_y = y
event: events.Event
if buttons & 64:
event = (
events.MouseScrollUp if button == 1 else events.MouseScrollDown
)(sender, x, y)
else:
event = (
events.MouseMove
if buttons & 32
else (events.MouseDown if state == "M" else events.MouseUp)
)(
sender,
x,
y,
delta_x,
delta_y,
button,
bool(buttons & 4),
bool(buttons & 8),
bool(buttons & 16),
screen_x=x,
screen_y=y,
)
event_cls = (
(events.MouseScrollDown if buttons & 1 else events.MouseScrollUp)
if buttons & 64
else events.MouseMove
if buttons & 32
else (events.MouseDown if state == "M" else events.MouseUp)
)
if event_cls in (events.MouseScrollUp, events.MouseScrollDown):
buttons &= ~(64 | 3)
button = (buttons + 1) & 3
event = event_cls(
sender,
x,
y,
delta_x,
delta_y,
button,
bool(buttons & 4),
bool(buttons & 8),
bool(buttons & 16),
screen_x=x,
screen_y=y,
)
return event
return None

View File

@@ -419,22 +419,14 @@ class MouseUp(MouseEvent, bubble=True, verbose=True):
pass
class MouseScrollDown(InputEvent, bubble=True, verbose=True):
__slots__ = ["x", "y"]
def __init__(self, sender: MessageTarget, x: int, y: int) -> None:
super().__init__(sender)
self.x = x
self.y = y
@rich.repr.auto
class MouseScrollDown(MouseEvent, bubble=True):
pass
class MouseScrollUp(InputEvent, bubble=True, verbose=True):
__slots__ = ["x", "y"]
def __init__(self, sender: MessageTarget, x: int, y: int) -> None:
super().__init__(sender)
self.x = x
self.y = y
@rich.repr.auto
class MouseScrollUp(MouseEvent, bubble=True):
pass
class Click(MouseEvent, bubble=True):

View File

@@ -236,14 +236,14 @@ def test_mouse_move(parser, sequence, shift, meta, button):
@pytest.mark.parametrize(
"sequence",
"sequence, shift, meta",
[
"\x1b[<64;18;25M",
"\x1b[<68;18;25M",
"\x1b[<72;18;25M",
("\x1b[<64;18;25M", False, False),
("\x1b[<68;18;25M", True, False),
("\x1b[<72;18;25M", False, True),
],
)
def test_mouse_scroll_up(parser, sequence):
def test_mouse_scroll_up(parser, sequence, shift, meta):
"""Scrolling the mouse with and without modifiers held down.
We don't currently capture modifier keys in scroll events.
"""
@@ -256,17 +256,19 @@ def test_mouse_scroll_up(parser, sequence):
assert isinstance(event, MouseScrollUp)
assert event.x == 17
assert event.y == 24
assert event.shift is shift
assert event.meta is meta
@pytest.mark.parametrize(
"sequence",
"sequence, shift, meta",
[
"\x1b[<65;18;25M",
"\x1b[<69;18;25M",
"\x1b[<73;18;25M",
("\x1b[<65;18;25M", False, False),
("\x1b[<69;18;25M", True, False),
("\x1b[<73;18;25M", False, True),
],
)
def test_mouse_scroll_down(parser, sequence):
def test_mouse_scroll_down(parser, sequence, shift, meta):
events = list(parser.feed(sequence))
assert len(events) == 1
@@ -276,6 +278,8 @@ def test_mouse_scroll_down(parser, sequence):
assert isinstance(event, MouseScrollDown)
assert event.x == 17
assert event.y == 24
assert event.shift is shift
assert event.meta is meta
def test_mouse_event_detected_but_info_not_parsed(parser):