Skip to content

Commit 5815d3a

Browse files
committed
Merge branch 'main' into fix-border-fix-flipped-title-colors-in-panel-border
2 parents 66051d8 + 369feef commit 5815d3a

File tree

5 files changed

+53
-16
lines changed

5 files changed

+53
-16
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1111

1212
- Fixed smooth scrolling broken on iTerm over SSH https://github.com/Textualize/textual/pull/5551
1313
- Fixed height of auto container which contains auto height children https://github.com/Textualize/textual/pull/5552
14+
- Fixed `Content.from_markup` not stripping control codes https://github.com/Textualize/textual/pull/5557
15+
- Fixed `delta_x` and `delta_y` in mouse events when smooth scrolling is enabled https://github.com/Textualize/textual/pull/5556
1416
- Fixed flipped title colors in panel border https://github.com/Textualize/textual/issues/5548
1517

18+
### Added
19+
20+
- Added `pointer_x`, `pointer_y`, `pointer_screen_x`, and `pointer_screen_y` attributes to mouse events https://github.com/Textualize/textual/pull/5556
21+
1622
## [2.0.4] - 2025-02-17
1723

1824
### Fixed

src/textual/_xterm_parser.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,15 @@ def parse_mouse_code(self, code: str) -> Message | None:
8383
and self.terminal_pixel_size is not None
8484
and self.terminal_size is not None
8585
):
86-
x_ratio = self.terminal_pixel_size[0] / self.terminal_size[0]
87-
y_ratio = self.terminal_pixel_size[1] / self.terminal_size[1]
86+
pixel_width, pixel_height = self.terminal_pixel_size
87+
width, height = self.terminal_size
88+
x_ratio = pixel_width / width
89+
y_ratio = pixel_height / height
8890
x /= x_ratio
8991
y /= y_ratio
9092

91-
delta_x = x - self.last_x
92-
delta_y = y - self.last_y
93+
delta_x = int(x) - int(self.last_x)
94+
delta_y = int(y) - int(self.last_y)
9395
self.last_x = x
9496
self.last_y = y
9597
event_class: type[events.MouseEvent]

src/textual/content.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ def from_markup(cls, markup: str | Content, **variables: object) -> Content:
193193
if variables:
194194
raise ValueError("A literal string is require to substitute variables.")
195195
return markup
196+
markup = _strip_control_codes(markup)
196197
from textual.markup import to_content
197198

198199
content = to_content(markup, template_variables=variables or None)

src/textual/events.py

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,8 @@ def __init__(
362362
widget: Widget | None,
363363
x: float,
364364
y: float,
365-
delta_x: float,
366-
delta_y: float,
365+
delta_x: int,
366+
delta_y: int,
367367
button: int,
368368
shift: bool,
369369
meta: bool,
@@ -399,34 +399,54 @@ def __init__(
399399

400400
@property
401401
def x(self) -> int:
402-
"""The relative X coordinate."""
402+
"""The relative X coordinate of the cell under the mouse."""
403403
return int(self._x)
404404

405405
@property
406406
def y(self) -> int:
407-
"""The relative Y coordinate."""
407+
"""The relative Y coordinate of the cell under the mouse."""
408408
return int(self._y)
409409

410410
@property
411411
def delta_x(self) -> int:
412412
"""Change in `x` since last message."""
413-
return int(self._delta_x)
413+
return self._delta_x
414414

415415
@property
416416
def delta_y(self) -> int:
417417
"""Change in `y` since the last message."""
418-
return int(self._delta_y)
418+
return self._delta_y
419419

420420
@property
421421
def screen_x(self) -> int:
422-
"""X coordinate relative to top left of screen."""
422+
"""X coordinate of the cell relative to top left of screen."""
423423
return int(self._screen_x)
424424

425425
@property
426426
def screen_y(self) -> int:
427-
"""Y coordinate relative to top left of screen."""
427+
"""Y coordinate of the cell relative to top left of screen."""
428428
return int(self._screen_y)
429429

430+
@property
431+
def pointer_x(self) -> float:
432+
"""The relative X coordinate of the pointer."""
433+
return self._x
434+
435+
@property
436+
def pointer_y(self) -> float:
437+
"""The relative Y coordinate of the pointer."""
438+
return self._y
439+
440+
@property
441+
def pointer_screen_x(self) -> float:
442+
"""The X coordinate of the pointer relative to the screen."""
443+
return self._screen_x
444+
445+
@property
446+
def pointer_screen_y(self) -> float:
447+
"""The Y coordinate of the pointer relative to the screen."""
448+
return self._screen_y
449+
430450
@classmethod
431451
def from_event(
432452
cls: Type[MouseEventT], widget: Widget, event: MouseEvent
@@ -449,10 +469,12 @@ def from_event(
449469

450470
def __rich_repr__(self) -> rich.repr.Result:
451471
yield self.widget
452-
yield "x", self._x
453-
yield "y", self._y
454-
yield "delta_x", self._delta_x, 0
455-
yield "delta_y", self._delta_y, 0
472+
yield "x", self.x
473+
yield "y", self.y
474+
yield "pointer_x", self.pointer_x
475+
yield "pointer_y", self.pointer_y
476+
yield "delta_x", self.delta_x, 0
477+
yield "delta_y", self.delta_y, 0
456478
if self.screen_x != self.x:
457479
yield "screen_x", self._screen_x
458480
if self.screen_y != self.y:

tests/test_content.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,3 +223,9 @@ def test_escape():
223223
content = Content.from_markup("\\[bold]Not really bold")
224224
assert content.plain == "[bold]Not really bold"
225225
assert content.spans == []
226+
227+
228+
def test_strip_control_codes():
229+
"""Test that control codes are removed from content."""
230+
assert Content("foo\r\nbar").plain == "foo\nbar"
231+
assert Content.from_markup("foo\r\nbar").plain == "foo\nbar"

0 commit comments

Comments
 (0)