Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/prompt_toolkit/key_binding/bindings/mouse.py: 35%
96 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 06:07 +0000
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 06:07 +0000
1from __future__ import annotations
3import sys
4from typing import TYPE_CHECKING, FrozenSet
6from prompt_toolkit.data_structures import Point
7from prompt_toolkit.key_binding.key_processor import KeyPress, KeyPressEvent
8from prompt_toolkit.keys import Keys
9from prompt_toolkit.mouse_events import (
10 MouseButton,
11 MouseEvent,
12 MouseEventType,
13 MouseModifier,
14)
16from ..key_bindings import KeyBindings
18if TYPE_CHECKING:
19 from prompt_toolkit.key_binding.key_bindings import NotImplementedOrNone
21__all__ = [
22 "load_mouse_bindings",
23]
25E = KeyPressEvent
27# fmt: off
28# flake8: noqa E201
29SCROLL_UP = MouseEventType.SCROLL_UP
30SCROLL_DOWN = MouseEventType.SCROLL_DOWN
31MOUSE_DOWN = MouseEventType.MOUSE_DOWN
32MOUSE_MOVE = MouseEventType.MOUSE_MOVE
33MOUSE_UP = MouseEventType.MOUSE_UP
35NO_MODIFIER : frozenset[MouseModifier] = frozenset()
36SHIFT : frozenset[MouseModifier] = frozenset({MouseModifier.SHIFT})
37ALT : frozenset[MouseModifier] = frozenset({MouseModifier.ALT})
38SHIFT_ALT : frozenset[MouseModifier] = frozenset({MouseModifier.SHIFT, MouseModifier.ALT})
39CONTROL : frozenset[MouseModifier] = frozenset({MouseModifier.CONTROL})
40SHIFT_CONTROL : frozenset[MouseModifier] = frozenset({MouseModifier.SHIFT, MouseModifier.CONTROL})
41ALT_CONTROL : frozenset[MouseModifier] = frozenset({MouseModifier.ALT, MouseModifier.CONTROL})
42SHIFT_ALT_CONTROL: frozenset[MouseModifier] = frozenset({MouseModifier.SHIFT, MouseModifier.ALT, MouseModifier.CONTROL})
43UNKNOWN_MODIFIER : frozenset[MouseModifier] = frozenset()
45LEFT = MouseButton.LEFT
46MIDDLE = MouseButton.MIDDLE
47RIGHT = MouseButton.RIGHT
48NO_BUTTON = MouseButton.NONE
49UNKNOWN_BUTTON = MouseButton.UNKNOWN
51xterm_sgr_mouse_events = {
52 ( 0, 'm') : (LEFT, MOUSE_UP, NO_MODIFIER), # left_up 0+ + + =0
53 ( 4, 'm') : (LEFT, MOUSE_UP, SHIFT), # left_up Shift 0+4+ + =4
54 ( 8, 'm') : (LEFT, MOUSE_UP, ALT), # left_up Alt 0+ +8+ =8
55 (12, 'm') : (LEFT, MOUSE_UP, SHIFT_ALT), # left_up Shift Alt 0+4+8+ =12
56 (16, 'm') : (LEFT, MOUSE_UP, CONTROL), # left_up Control 0+ + +16=16
57 (20, 'm') : (LEFT, MOUSE_UP, SHIFT_CONTROL), # left_up Shift Control 0+4+ +16=20
58 (24, 'm') : (LEFT, MOUSE_UP, ALT_CONTROL), # left_up Alt Control 0+ +8+16=24
59 (28, 'm') : (LEFT, MOUSE_UP, SHIFT_ALT_CONTROL), # left_up Shift Alt Control 0+4+8+16=28
61 ( 1, 'm') : (MIDDLE, MOUSE_UP, NO_MODIFIER), # middle_up 1+ + + =1
62 ( 5, 'm') : (MIDDLE, MOUSE_UP, SHIFT), # middle_up Shift 1+4+ + =5
63 ( 9, 'm') : (MIDDLE, MOUSE_UP, ALT), # middle_up Alt 1+ +8+ =9
64 (13, 'm') : (MIDDLE, MOUSE_UP, SHIFT_ALT), # middle_up Shift Alt 1+4+8+ =13
65 (17, 'm') : (MIDDLE, MOUSE_UP, CONTROL), # middle_up Control 1+ + +16=17
66 (21, 'm') : (MIDDLE, MOUSE_UP, SHIFT_CONTROL), # middle_up Shift Control 1+4+ +16=21
67 (25, 'm') : (MIDDLE, MOUSE_UP, ALT_CONTROL), # middle_up Alt Control 1+ +8+16=25
68 (29, 'm') : (MIDDLE, MOUSE_UP, SHIFT_ALT_CONTROL), # middle_up Shift Alt Control 1+4+8+16=29
70 ( 2, 'm') : (RIGHT, MOUSE_UP, NO_MODIFIER), # right_up 2+ + + =2
71 ( 6, 'm') : (RIGHT, MOUSE_UP, SHIFT), # right_up Shift 2+4+ + =6
72 (10, 'm') : (RIGHT, MOUSE_UP, ALT), # right_up Alt 2+ +8+ =10
73 (14, 'm') : (RIGHT, MOUSE_UP, SHIFT_ALT), # right_up Shift Alt 2+4+8+ =14
74 (18, 'm') : (RIGHT, MOUSE_UP, CONTROL), # right_up Control 2+ + +16=18
75 (22, 'm') : (RIGHT, MOUSE_UP, SHIFT_CONTROL), # right_up Shift Control 2+4+ +16=22
76 (26, 'm') : (RIGHT, MOUSE_UP, ALT_CONTROL), # right_up Alt Control 2+ +8+16=26
77 (30, 'm') : (RIGHT, MOUSE_UP, SHIFT_ALT_CONTROL), # right_up Shift Alt Control 2+4+8+16=30
79 ( 0, 'M') : (LEFT, MOUSE_DOWN, NO_MODIFIER), # left_down 0+ + + =0
80 ( 4, 'M') : (LEFT, MOUSE_DOWN, SHIFT), # left_down Shift 0+4+ + =4
81 ( 8, 'M') : (LEFT, MOUSE_DOWN, ALT), # left_down Alt 0+ +8+ =8
82 (12, 'M') : (LEFT, MOUSE_DOWN, SHIFT_ALT), # left_down Shift Alt 0+4+8+ =12
83 (16, 'M') : (LEFT, MOUSE_DOWN, CONTROL), # left_down Control 0+ + +16=16
84 (20, 'M') : (LEFT, MOUSE_DOWN, SHIFT_CONTROL), # left_down Shift Control 0+4+ +16=20
85 (24, 'M') : (LEFT, MOUSE_DOWN, ALT_CONTROL), # left_down Alt Control 0+ +8+16=24
86 (28, 'M') : (LEFT, MOUSE_DOWN, SHIFT_ALT_CONTROL), # left_down Shift Alt Control 0+4+8+16=28
88 ( 1, 'M') : (MIDDLE, MOUSE_DOWN, NO_MODIFIER), # middle_down 1+ + + =1
89 ( 5, 'M') : (MIDDLE, MOUSE_DOWN, SHIFT), # middle_down Shift 1+4+ + =5
90 ( 9, 'M') : (MIDDLE, MOUSE_DOWN, ALT), # middle_down Alt 1+ +8+ =9
91 (13, 'M') : (MIDDLE, MOUSE_DOWN, SHIFT_ALT), # middle_down Shift Alt 1+4+8+ =13
92 (17, 'M') : (MIDDLE, MOUSE_DOWN, CONTROL), # middle_down Control 1+ + +16=17
93 (21, 'M') : (MIDDLE, MOUSE_DOWN, SHIFT_CONTROL), # middle_down Shift Control 1+4+ +16=21
94 (25, 'M') : (MIDDLE, MOUSE_DOWN, ALT_CONTROL), # middle_down Alt Control 1+ +8+16=25
95 (29, 'M') : (MIDDLE, MOUSE_DOWN, SHIFT_ALT_CONTROL), # middle_down Shift Alt Control 1+4+8+16=29
97 ( 2, 'M') : (RIGHT, MOUSE_DOWN, NO_MODIFIER), # right_down 2+ + + =2
98 ( 6, 'M') : (RIGHT, MOUSE_DOWN, SHIFT), # right_down Shift 2+4+ + =6
99 (10, 'M') : (RIGHT, MOUSE_DOWN, ALT), # right_down Alt 2+ +8+ =10
100 (14, 'M') : (RIGHT, MOUSE_DOWN, SHIFT_ALT), # right_down Shift Alt 2+4+8+ =14
101 (18, 'M') : (RIGHT, MOUSE_DOWN, CONTROL), # right_down Control 2+ + +16=18
102 (22, 'M') : (RIGHT, MOUSE_DOWN, SHIFT_CONTROL), # right_down Shift Control 2+4+ +16=22
103 (26, 'M') : (RIGHT, MOUSE_DOWN, ALT_CONTROL), # right_down Alt Control 2+ +8+16=26
104 (30, 'M') : (RIGHT, MOUSE_DOWN, SHIFT_ALT_CONTROL), # right_down Shift Alt Control 2+4+8+16=30
106 (32, 'M') : (LEFT, MOUSE_MOVE, NO_MODIFIER), # left_drag 32+ + + =32
107 (36, 'M') : (LEFT, MOUSE_MOVE, SHIFT), # left_drag Shift 32+4+ + =36
108 (40, 'M') : (LEFT, MOUSE_MOVE, ALT), # left_drag Alt 32+ +8+ =40
109 (44, 'M') : (LEFT, MOUSE_MOVE, SHIFT_ALT), # left_drag Shift Alt 32+4+8+ =44
110 (48, 'M') : (LEFT, MOUSE_MOVE, CONTROL), # left_drag Control 32+ + +16=48
111 (52, 'M') : (LEFT, MOUSE_MOVE, SHIFT_CONTROL), # left_drag Shift Control 32+4+ +16=52
112 (56, 'M') : (LEFT, MOUSE_MOVE, ALT_CONTROL), # left_drag Alt Control 32+ +8+16=56
113 (60, 'M') : (LEFT, MOUSE_MOVE, SHIFT_ALT_CONTROL), # left_drag Shift Alt Control 32+4+8+16=60
115 (33, 'M') : (MIDDLE, MOUSE_MOVE, NO_MODIFIER), # middle_drag 33+ + + =33
116 (37, 'M') : (MIDDLE, MOUSE_MOVE, SHIFT), # middle_drag Shift 33+4+ + =37
117 (41, 'M') : (MIDDLE, MOUSE_MOVE, ALT), # middle_drag Alt 33+ +8+ =41
118 (45, 'M') : (MIDDLE, MOUSE_MOVE, SHIFT_ALT), # middle_drag Shift Alt 33+4+8+ =45
119 (49, 'M') : (MIDDLE, MOUSE_MOVE, CONTROL), # middle_drag Control 33+ + +16=49
120 (53, 'M') : (MIDDLE, MOUSE_MOVE, SHIFT_CONTROL), # middle_drag Shift Control 33+4+ +16=53
121 (57, 'M') : (MIDDLE, MOUSE_MOVE, ALT_CONTROL), # middle_drag Alt Control 33+ +8+16=57
122 (61, 'M') : (MIDDLE, MOUSE_MOVE, SHIFT_ALT_CONTROL), # middle_drag Shift Alt Control 33+4+8+16=61
124 (34, 'M') : (RIGHT, MOUSE_MOVE, NO_MODIFIER), # right_drag 34+ + + =34
125 (38, 'M') : (RIGHT, MOUSE_MOVE, SHIFT), # right_drag Shift 34+4+ + =38
126 (42, 'M') : (RIGHT, MOUSE_MOVE, ALT), # right_drag Alt 34+ +8+ =42
127 (46, 'M') : (RIGHT, MOUSE_MOVE, SHIFT_ALT), # right_drag Shift Alt 34+4+8+ =46
128 (50, 'M') : (RIGHT, MOUSE_MOVE, CONTROL), # right_drag Control 34+ + +16=50
129 (54, 'M') : (RIGHT, MOUSE_MOVE, SHIFT_CONTROL), # right_drag Shift Control 34+4+ +16=54
130 (58, 'M') : (RIGHT, MOUSE_MOVE, ALT_CONTROL), # right_drag Alt Control 34+ +8+16=58
131 (62, 'M') : (RIGHT, MOUSE_MOVE, SHIFT_ALT_CONTROL), # right_drag Shift Alt Control 34+4+8+16=62
133 (35, 'M') : (NO_BUTTON, MOUSE_MOVE, NO_MODIFIER), # none_drag 35+ + + =35
134 (39, 'M') : (NO_BUTTON, MOUSE_MOVE, SHIFT), # none_drag Shift 35+4+ + =39
135 (43, 'M') : (NO_BUTTON, MOUSE_MOVE, ALT), # none_drag Alt 35+ +8+ =43
136 (47, 'M') : (NO_BUTTON, MOUSE_MOVE, SHIFT_ALT), # none_drag Shift Alt 35+4+8+ =47
137 (51, 'M') : (NO_BUTTON, MOUSE_MOVE, CONTROL), # none_drag Control 35+ + +16=51
138 (55, 'M') : (NO_BUTTON, MOUSE_MOVE, SHIFT_CONTROL), # none_drag Shift Control 35+4+ +16=55
139 (59, 'M') : (NO_BUTTON, MOUSE_MOVE, ALT_CONTROL), # none_drag Alt Control 35+ +8+16=59
140 (63, 'M') : (NO_BUTTON, MOUSE_MOVE, SHIFT_ALT_CONTROL), # none_drag Shift Alt Control 35+4+8+16=63
142 (64, 'M') : (NO_BUTTON, SCROLL_UP, NO_MODIFIER), # scroll_up 64+ + + =64
143 (68, 'M') : (NO_BUTTON, SCROLL_UP, SHIFT), # scroll_up Shift 64+4+ + =68
144 (72, 'M') : (NO_BUTTON, SCROLL_UP, ALT), # scroll_up Alt 64+ +8+ =72
145 (76, 'M') : (NO_BUTTON, SCROLL_UP, SHIFT_ALT), # scroll_up Shift Alt 64+4+8+ =76
146 (80, 'M') : (NO_BUTTON, SCROLL_UP, CONTROL), # scroll_up Control 64+ + +16=80
147 (84, 'M') : (NO_BUTTON, SCROLL_UP, SHIFT_CONTROL), # scroll_up Shift Control 64+4+ +16=84
148 (88, 'M') : (NO_BUTTON, SCROLL_UP, ALT_CONTROL), # scroll_up Alt Control 64+ +8+16=88
149 (92, 'M') : (NO_BUTTON, SCROLL_UP, SHIFT_ALT_CONTROL), # scroll_up Shift Alt Control 64+4+8+16=92
151 (65, 'M') : (NO_BUTTON, SCROLL_DOWN, NO_MODIFIER), # scroll_down 64+ + + =65
152 (69, 'M') : (NO_BUTTON, SCROLL_DOWN, SHIFT), # scroll_down Shift 64+4+ + =69
153 (73, 'M') : (NO_BUTTON, SCROLL_DOWN, ALT), # scroll_down Alt 64+ +8+ =73
154 (77, 'M') : (NO_BUTTON, SCROLL_DOWN, SHIFT_ALT), # scroll_down Shift Alt 64+4+8+ =77
155 (81, 'M') : (NO_BUTTON, SCROLL_DOWN, CONTROL), # scroll_down Control 64+ + +16=81
156 (85, 'M') : (NO_BUTTON, SCROLL_DOWN, SHIFT_CONTROL), # scroll_down Shift Control 64+4+ +16=85
157 (89, 'M') : (NO_BUTTON, SCROLL_DOWN, ALT_CONTROL), # scroll_down Alt Control 64+ +8+16=89
158 (93, 'M') : (NO_BUTTON, SCROLL_DOWN, SHIFT_ALT_CONTROL), # scroll_down Shift Alt Control 64+4+8+16=93
159}
161typical_mouse_events = {
162 32: (LEFT , MOUSE_DOWN , UNKNOWN_MODIFIER),
163 33: (MIDDLE , MOUSE_DOWN , UNKNOWN_MODIFIER),
164 34: (RIGHT , MOUSE_DOWN , UNKNOWN_MODIFIER),
165 35: (UNKNOWN_BUTTON , MOUSE_UP , UNKNOWN_MODIFIER),
167 64: (LEFT , MOUSE_MOVE , UNKNOWN_MODIFIER),
168 65: (MIDDLE , MOUSE_MOVE , UNKNOWN_MODIFIER),
169 66: (RIGHT , MOUSE_MOVE , UNKNOWN_MODIFIER),
170 67: (NO_BUTTON , MOUSE_MOVE , UNKNOWN_MODIFIER),
172 96: (NO_BUTTON , SCROLL_UP , UNKNOWN_MODIFIER),
173 97: (NO_BUTTON , SCROLL_DOWN, UNKNOWN_MODIFIER),
174}
176urxvt_mouse_events={
177 32: (UNKNOWN_BUTTON, MOUSE_DOWN , UNKNOWN_MODIFIER),
178 35: (UNKNOWN_BUTTON, MOUSE_UP , UNKNOWN_MODIFIER),
179 96: (NO_BUTTON , SCROLL_UP , UNKNOWN_MODIFIER),
180 97: (NO_BUTTON , SCROLL_DOWN, UNKNOWN_MODIFIER),
181}
182# fmt:on
185def load_mouse_bindings() -> KeyBindings:
186 """
187 Key bindings, required for mouse support.
188 (Mouse events enter through the key binding system.)
189 """
190 key_bindings = KeyBindings()
192 @key_bindings.add(Keys.Vt100MouseEvent)
193 def _(event: E) -> NotImplementedOrNone:
194 """
195 Handling of incoming mouse event.
196 """
197 # TypicaL: "eSC[MaB*"
198 # Urxvt: "Esc[96;14;13M"
199 # Xterm SGR: "Esc[<64;85;12M"
201 # Parse incoming packet.
202 if event.data[2] == "M":
203 # Typical.
204 mouse_event, x, y = map(ord, event.data[3:])
206 # TODO: Is it possible to add modifiers here?
207 mouse_button, mouse_event_type, mouse_modifiers = typical_mouse_events[
208 mouse_event
209 ]
211 # Handle situations where `PosixStdinReader` used surrogateescapes.
212 if x >= 0xDC00:
213 x -= 0xDC00
214 if y >= 0xDC00:
215 y -= 0xDC00
217 x -= 32
218 y -= 32
219 else:
220 # Urxvt and Xterm SGR.
221 # When the '<' is not present, we are not using the Xterm SGR mode,
222 # but Urxvt instead.
223 data = event.data[2:]
224 if data[:1] == "<":
225 sgr = True
226 data = data[1:]
227 else:
228 sgr = False
230 # Extract coordinates.
231 mouse_event, x, y = map(int, data[:-1].split(";"))
232 m = data[-1]
234 # Parse event type.
235 if sgr:
236 try:
237 (
238 mouse_button,
239 mouse_event_type,
240 mouse_modifiers,
241 ) = xterm_sgr_mouse_events[mouse_event, m]
242 except KeyError:
243 return NotImplemented
245 else:
246 # Some other terminals, like urxvt, Hyper terminal, ...
247 (
248 mouse_button,
249 mouse_event_type,
250 mouse_modifiers,
251 ) = urxvt_mouse_events.get(
252 mouse_event, (UNKNOWN_BUTTON, MOUSE_MOVE, UNKNOWN_MODIFIER)
253 )
255 x -= 1
256 y -= 1
258 # Only handle mouse events when we know the window height.
259 if event.app.renderer.height_is_known and mouse_event_type is not None:
260 # Take region above the layout into account. The reported
261 # coordinates are absolute to the visible part of the terminal.
262 from prompt_toolkit.renderer import HeightIsUnknownError
264 try:
265 y -= event.app.renderer.rows_above_layout
266 except HeightIsUnknownError:
267 return NotImplemented
269 # Call the mouse handler from the renderer.
271 # Note: This can return `NotImplemented` if no mouse handler was
272 # found for this position, or if no repainting needs to
273 # happen. this way, we avoid excessive repaints during mouse
274 # movements.
275 handler = event.app.renderer.mouse_handlers.mouse_handlers[y][x]
276 return handler(
277 MouseEvent(
278 position=Point(x=x, y=y),
279 event_type=mouse_event_type,
280 button=mouse_button,
281 modifiers=mouse_modifiers,
282 )
283 )
285 return NotImplemented
287 @key_bindings.add(Keys.ScrollUp)
288 def _scroll_up(event: E) -> None:
289 """
290 Scroll up event without cursor position.
291 """
292 # We don't receive a cursor position, so we don't know which window to
293 # scroll. Just send an 'up' key press instead.
294 event.key_processor.feed(KeyPress(Keys.Up), first=True)
296 @key_bindings.add(Keys.ScrollDown)
297 def _scroll_down(event: E) -> None:
298 """
299 Scroll down event without cursor position.
300 """
301 event.key_processor.feed(KeyPress(Keys.Down), first=True)
303 @key_bindings.add(Keys.WindowsMouseEvent)
304 def _mouse(event: E) -> NotImplementedOrNone:
305 """
306 Handling of mouse events for Windows.
307 """
308 # This key binding should only exist for Windows.
309 if sys.platform == "win32":
310 # Parse data.
311 pieces = event.data.split(";")
313 button = MouseButton(pieces[0])
314 event_type = MouseEventType(pieces[1])
315 x = int(pieces[2])
316 y = int(pieces[3])
318 # Make coordinates absolute to the visible part of the terminal.
319 output = event.app.renderer.output
321 from prompt_toolkit.output.win32 import Win32Output
322 from prompt_toolkit.output.windows10 import Windows10_Output
324 if isinstance(output, (Win32Output, Windows10_Output)):
325 screen_buffer_info = output.get_win32_screen_buffer_info()
326 rows_above_cursor = (
327 screen_buffer_info.dwCursorPosition.Y
328 - event.app.renderer._cursor_pos.y
329 )
330 y -= rows_above_cursor
332 # Call the mouse event handler.
333 # (Can return `NotImplemented`.)
334 handler = event.app.renderer.mouse_handlers.mouse_handlers[y][x]
336 return handler(
337 MouseEvent(
338 position=Point(x=x, y=y),
339 event_type=event_type,
340 button=button,
341 modifiers=UNKNOWN_MODIFIER,
342 )
343 )
345 # No mouse handler found. Return `NotImplemented` so that we don't
346 # invalidate the UI.
347 return NotImplemented
349 return key_bindings