Skip to content

Commit c0cda89

Browse files
authored
Merge pull request #5812 from TomJGooding/fix-input-fix-invalid-cursor-position-after-updating-value
fix(input): fix invalid cursor position after updating value
2 parents e9be189 + b148ab2 commit c0cda89

File tree

3 files changed

+18
-0
lines changed

3 files changed

+18
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1212

1313
- Fixed `VERTICAL_BREAKPOINTS` doesn't work https://github.com/Textualize/textual/pull/5785
1414
- Fixed `Button` allowing text selection https://github.com/Textualize/textual/pull/5770
15+
- Fixed `Input` invalid cursor position after updating the value https://github.com/Textualize/textual/issues/5811
1516

1617
## [3.2.0] - 2025-05-02
1718

src/textual/widgets/_input.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,10 @@ def _watch_value(self, value: str) -> None:
536536
if self._initial_value:
537537
self.cursor_position = len(self.value)
538538
self._initial_value = False
539+
else:
540+
# Force a re-validation of the selection to ensure it accounts for
541+
# the length of the new value
542+
self.selection = self.selection
539543

540544
def _watch_valid_empty(self) -> None:
541545
"""Repeat validation when valid_empty changes."""

tests/input/test_input_properties.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,16 @@ async def test_input_selection_deleted_programmatically():
9393
input_widget.selection = Selection(4, 0)
9494
input_widget.delete_selection()
9595
assert input_widget.value == "o, world!"
96+
97+
98+
async def test_input_selection_is_valid_after_updating_value():
99+
"""Regression test for https://github.com/Textualize/textual/issues/5811"""
100+
app = InputApp()
101+
async with app.run_test() as pilot:
102+
input_widget = pilot.app.query_one(Input)
103+
# Sanity check (by default focusing the input selects all text)
104+
assert input_widget.selection == (0, len(input_widget.value))
105+
106+
input_widget.value = "foo"
107+
108+
assert input_widget.selection == (0, len(input_widget.value))

0 commit comments

Comments
 (0)