Skip to content

Commit 7970cf5

Browse files
authored
Merge pull request #5311 from Textualize/scroll-optimization
optimize scroll
2 parents a913540 + ec1a2ec commit 7970cf5

File tree

8 files changed

+267
-267
lines changed

8 files changed

+267
-267
lines changed

src/textual/scroll_view.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,8 @@ def _size_updated(
8282
layout: Perform layout if required.
8383
8484
Returns:
85-
True if anything changed, or False if nothing changed.
85+
True if a resize event should be sent, otherwise False.
8686
"""
87-
if self._size != size or self._container_size != container_size:
88-
self.refresh()
8987
if (
9088
self._size != size
9189
or virtual_size != self.virtual_size
@@ -96,9 +94,8 @@ def _size_updated(
9694
virtual_size = self.virtual_size
9795
self._container_size = size - self.styles.gutter.totals
9896
self._scroll_update(virtual_size)
99-
return True
100-
else:
101-
return False
97+
98+
return self._size != size or self._container_size != container_size
10299

103100
def render(self) -> RenderableType:
104101
"""Render the scrollable region (if `render_lines` is not implemented).

src/textual/widget.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3695,8 +3695,9 @@ def _size_updated(
36953695
layout: Perform layout if required.
36963696
36973697
Returns:
3698-
True if anything changed, or False if nothing changed.
3698+
True if a resize event should be sent, otherwise False.
36993699
"""
3700+
37003701
self._layout_cache.clear()
37013702
if (
37023703
self._size != size

src/textual/widgets/_option_list.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -362,19 +362,19 @@ def _add_lines(
362362
self._lines.append(OptionLineSpan(-1, 0))
363363

364364
self.virtual_size = Size(width, len(self._lines))
365+
self.refresh(layout=self.styles.auto_dimensions)
366+
self._scroll_update(self.virtual_size)
365367

366368
def _populate(self) -> None:
367369
"""Populate the lines data-structure."""
368-
if self._lines is not None:
369-
return
370+
370371
self._lines = []
371372
self._spans = []
372373

373374
self._add_lines(
374375
self._contents,
375376
self.scrollable_content_region.width - self._left_gutter_width(),
376377
)
377-
self.refresh(layout=True)
378378

379379
def get_content_width(self, container: Size, viewport: Size) -> int:
380380
"""Get maximum width of options."""
@@ -824,8 +824,9 @@ def get_option_index(self, option_id: str) -> int:
824824
) from None
825825

826826
def render_line(self, y: int) -> Strip:
827-
self._populate()
828827
assert self._lines is not None
828+
if not self._lines:
829+
self._populate()
829830

830831
_scroll_x, scroll_y = self.scroll_offset
831832
line_number = scroll_y + y
@@ -879,9 +880,12 @@ def scroll_to_highlight(self, top: bool = False) -> None:
879880
top: Scroll highlight to top of the list.
880881
"""
881882
highlighted = self.highlighted
882-
if highlighted is None or self._spans is None:
883+
if highlighted is None or not self.is_mounted:
883884
return
884885

886+
if not self._spans:
887+
self._populate()
888+
885889
try:
886890
y, height = self._spans[highlighted]
887891
except IndexError:
@@ -894,6 +898,7 @@ def scroll_to_highlight(self, top: bool = False) -> None:
894898
force=True,
895899
animate=False,
896900
top=top,
901+
immediate=True,
897902
)
898903

899904
def validate_highlighted(self, highlighted: int | None) -> int | None:
@@ -953,7 +958,6 @@ def _page(self, direction: Direction) -> None:
953958
# If we find ourselves in a position where we don't know where we're
954959
# going, we need a fallback location. Where we go will depend on the
955960
# direction.
956-
self._populate()
957961
assert self._spans is not None
958962
assert self._lines is not None
959963

src/textual/widgets/_select.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def select(self, index: int | None) -> None:
6666
index: Index of new selection.
6767
"""
6868
self.highlighted = index
69-
self.scroll_to_highlight(top=True)
69+
self.scroll_to_highlight()
7070

7171
def action_dismiss(self) -> None:
7272
"""Dismiss the overlay."""
@@ -520,7 +520,7 @@ def _watch_expanded(self, expanded: bool) -> None:
520520
value = self.value
521521
for index, (_prompt, prompt_value) in enumerate(self._options):
522522
if value == prompt_value:
523-
overlay.select(index)
523+
self.call_after_refresh(overlay.select, index)
524524
break
525525
self.query_one(SelectCurrent).has_value = True
526526

tests/snapshot_tests/__snapshots__/test_snapshots/test_loading_indicator_disables_widget.svg

Lines changed: 61 additions & 62 deletions
Loading

tests/snapshot_tests/__snapshots__/test_snapshots/test_missing_vertical_scroll.svg

Lines changed: 61 additions & 62 deletions
Loading

tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_tables.svg

Lines changed: 65 additions & 65 deletions
Loading

tests/snapshot_tests/__snapshots__/test_snapshots/test_select_width_auto.svg

Lines changed: 63 additions & 63 deletions
Loading

0 commit comments

Comments
 (0)