Skip to content
Merged
Show file tree
Hide file tree
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
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [6.12.0] - 2025-01-02

### Fixed

- Fixed unnecessary style update when popping screens, which may have caused noticable pauses changing screens (with a lot of widgets) https://github.com/Textualize/textual/pull/6304

### Changed

- Promoted private `_update_styes` to `update_node_styles` https://github.com/Textualize/textual/pull/6304

## [6.11.0] - 2025-12-18

### Added
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "textual"
version = "6.11.0"
version = "6.12.0"
homepage = "https://github.com/Textualize/textual"
repository = "https://github.com/Textualize/textual"
documentation = "https://textual.textualize.io/"
Expand Down
6 changes: 3 additions & 3 deletions src/textual/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3045,9 +3045,9 @@ def _set_mouse_over(
if hover_widget is not None:
hover_widget.mouse_hover = True
if hover_widget._has_hover_style:
hover_widget._update_styles()
hover_widget.update_node_styles()
if current_hover_over is not None and current_hover_over._has_hover_style:
current_hover_over._update_styles()
current_hover_over.update_node_styles()
self.hover_over = hover_widget

def _update_mouse_over(self, screen: Screen) -> None:
Expand Down Expand Up @@ -4247,7 +4247,7 @@ def post_mount() -> None:

def _watch_app_focus(self, focus: bool) -> None:
"""Respond to changes in app focus."""
self.screen._update_styles()
self.screen.update_node_styles()
if focus:
# If we've got a last-focused widget, if it still has a screen,
# and if the screen is still the current screen and if nothing
Expand Down
12 changes: 6 additions & 6 deletions src/textual/dom.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def __set__(self, obj: DOMNode, classes: str | Iterable[str]) -> None:
class_names = set(classes)
check_identifiers("class name", *class_names)
obj._classes = class_names
obj._update_styles()
obj.update_node_styles()


@rich.repr.auto
Expand Down Expand Up @@ -1733,10 +1733,10 @@ def set_classes(self, classes: str | Iterable[str]) -> Self:
self.classes = classes
return self

def _update_styles(self) -> None:
def update_node_styles(self) -> None:
"""Request an update of this node's styles.

Should be called whenever CSS classes / pseudo classes change.
Called by Textual whenever CSS classes / pseudo classes change.
"""
try:
self.app.update_styles(self)
Expand All @@ -1759,7 +1759,7 @@ def add_class(self, *class_names: str, update: bool = True) -> Self:
if old_classes == self._classes:
return self
if update:
self._update_styles()
self.update_node_styles()
return self

def remove_class(self, *class_names: str, update: bool = True) -> Self:
Expand All @@ -1778,7 +1778,7 @@ def remove_class(self, *class_names: str, update: bool = True) -> Self:
if old_classes == self._classes:
return self
if update:
self._update_styles()
self.update_node_styles()
return self

def toggle_class(self, *class_names: str) -> Self:
Expand All @@ -1795,7 +1795,7 @@ def toggle_class(self, *class_names: str) -> Self:
self._classes.symmetric_difference_update(class_names)
if old_classes == self._classes:
return self
self._update_styles()
self.update_node_styles()
return self

def has_pseudo_class(self, class_name: str) -> bool:
Expand Down
3 changes: 2 additions & 1 deletion src/textual/screen.py
Original file line number Diff line number Diff line change
Expand Up @@ -1441,7 +1441,8 @@ def _on_screen_resume(self) -> None:

if self.is_attached:
self._compositor_refresh()
self.app.stylesheet.update(self)
if self.stack_updates == 1:
self.app.stylesheet.update(self)
self._refresh_layout(size)
self.refresh()

Expand Down
10 changes: 5 additions & 5 deletions src/textual/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -1445,11 +1445,11 @@ def update_styles(children: list[DOMNode]) -> None:
# we need to update both odd/even, first-of-type/last-of-type and first-child/last-child
for child in children:
if child._has_order_style or child._has_odd_or_even:
child._update_styles()
child.update_node_styles()
else:
for child in children:
if child._has_order_style:
child._update_styles()
child.update_node_styles()

self.call_later(update_styles, self.displayed_children)
await_mount = AwaitMount(self, mounted)
Expand Down Expand Up @@ -4026,7 +4026,7 @@ def post_render(

def watch_has_focus(self, _has_focus: bool) -> None:
"""Update from CSS if has focus state changes."""
self._update_styles()
self.update_node_styles()

def watch_disabled(self, disabled: bool) -> None:
"""Update the styles of the widget and its children when disabled is toggled."""
Expand All @@ -4046,7 +4046,7 @@ def watch_disabled(self, disabled: bool) -> None:
except (ScreenStackError, NoActiveAppError, NoScreen):
pass

self._update_styles()
self.update_node_styles()

def _size_updated(
self, size: Size, virtual_size: Size, container_size: Size, layout: bool = True
Expand Down Expand Up @@ -4475,7 +4475,7 @@ def _check_refresh(self) -> None:
else:
if self._refresh_styles_required:
self._refresh_styles_required = False
self.call_later(self._update_styles)
self.call_later(self.update_node_styles)
if self._scroll_required:
self._scroll_required = False
if not self._layout_required:
Expand Down
Loading