Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions src/textual/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,20 @@ def is_anchored(self) -> bool:
"""
return self._anchored

@property
def follows_tail(self) -> bool:
"""Whether anchoring currently follows the latest content."""
return self._anchored and not self._anchor_released

def tail_follow_changed(self) -> None:
"""React to entering or leaving tail-follow, not to each scroll offset."""

def _set_anchor_state(self, *, anchored: bool, released: bool) -> None:
following = self.follows_tail
self._anchored, self._anchor_released = anchored, released
if self.follows_tail != following:
self.tail_follow_changed()

@property
def is_mouse_over(self) -> bool:
"""Is the mouse currently over this widget?
Expand Down Expand Up @@ -855,7 +869,7 @@ def anchor(self, anchor: bool = True) -> None:
anchor: Anchor the widget if `True`, clear the anchor if `False`.

"""
self._anchored = anchor
self._set_anchor_state(anchored=anchor, released=self._anchor_released)
if anchor:
self.scroll_end(immediate=True, animate=False)

Expand All @@ -866,7 +880,7 @@ def release_anchor(self) -> None:

"""
self.scroll_target_y = self.scroll_y
self._anchor_released = True
self._set_anchor_state(anchored=self._anchored, released=True)

def _check_anchor(self) -> None:
"""Check if the scroll position is near enough to the bottom to restore anchor."""
Expand All @@ -875,7 +889,7 @@ def _check_anchor(self) -> None:
and self._anchor_released
and self.scroll_y >= self.max_scroll_y
):
self._anchor_released = False
self._set_anchor_state(anchored=True, released=False)

def _check_disabled(self) -> bool:
"""Check if the widget is disabled either explicitly by setting `disabled`,
Expand Down Expand Up @@ -2907,7 +2921,7 @@ def _lazily_scroll_end() -> None:
)

if self._anchored and self._anchor_released:
self._anchor_released = False
self._set_anchor_state(anchored=True, released=False)

if immediate:
_lazily_scroll_end()
Expand Down