From 1937eda05316d590b30447cf4d4e832cfdb75bb2 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 7 Jan 2026 09:16:25 +0000 Subject: [PATCH 1/5] Add optional refresh to resume message --- CHANGELOG.md | 4 ++++ src/textual/_resolve.py | 17 ++++++++++++++--- src/textual/app.py | 4 +++- src/textual/events.py | 7 +++++++ src/textual/layouts/vertical.py | 2 ++ src/textual/screen.py | 8 +++++--- src/textual/widgets/_collapsible.py | 4 ++-- 7 files changed, 37 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d71e5a86d5..ba1262a696 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `Node.update_node_styles` has grown a `animate` parameter +### Added + +- Adde atom-one-dark and atom-one-light themes @NSPC911 https://github.com/Textualize/textual/pull/6301 + ## [6.12.0] - 2026-01-02 ### Fixed diff --git a/src/textual/_resolve.py b/src/textual/_resolve.py index 37e5727622..8eb4b8a24a 100644 --- a/src/textual/_resolve.py +++ b/src/textual/_resolve.py @@ -246,6 +246,8 @@ def resolve_box_models( margins = [widget.styles.margin.totals for widget in widgets] + print("--", size, margin) + print(widgets) # Fixed box models box_models: list[BoxModel | None] = [ ( @@ -272,6 +274,10 @@ def resolve_box_models( ) ] + from textual import log + + log(box_models) + if None not in box_models: # No fr units, so we're done return cast("list[BoxModel]", box_models) @@ -316,14 +322,19 @@ def resolve_box_models( ) ) + print("MARGINS") + log(margins) + remaining_space = int(max(0, size.height - total_remaining - margin_height)) fraction_unit = resolve_fraction_unit( [ styles for styles in widget_styles - if styles.height is not None - and styles.height.is_fraction - and styles.overlay != "screen" + if ( + styles.height is not None + and styles.height.is_fraction + and styles.overlay != "screen" + ) ], size, viewport_size, diff --git a/src/textual/app.py b/src/textual/app.py index a3d91f562d..fa16acc631 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -2979,7 +2979,9 @@ def pop_screen(self) -> AwaitComplete: previous_screen = screen_stack.pop() previous_screen._pop_result_callback() - self.screen.post_message(events.ScreenResume()) + self.screen.post_message( + events.ScreenResume(refresh_styles=previous_screen.styles.background.a < 0) + ) self.log.system(f"{self.screen} is active") async def do_pop() -> None: diff --git a/src/textual/events.py b/src/textual/events.py index b1d79d8d34..92e05a91a1 100644 --- a/src/textual/events.py +++ b/src/textual/events.py @@ -901,6 +901,7 @@ def __rich_repr__(self) -> rich.repr.Result: yield "text", self.text +@dataclass class ScreenResume(Event, bubble=False): """Sent to screen that has been made active. @@ -908,6 +909,12 @@ class ScreenResume(Event, bubble=False): - [ ] Verbose """ + refresh_styles: bool = True + """Should the resuming screen refresh its styles?""" + + def __rich_repr__(self) -> rich.repr.Result: + yield self.refresh_styles + class ScreenSuspend(Event, bubble=False): """Sent to screen when it is no longer active. diff --git a/src/textual/layouts/vertical.py b/src/textual/layouts/vertical.py index da3462267d..10118b4c8e 100644 --- a/src/textual/layouts/vertical.py +++ b/src/textual/layouts/vertical.py @@ -50,6 +50,8 @@ def arrange( else: resolve_margin = Size(0, 0) + print("!!", parent) + box_models = resolve_box_models( [styles.height for styles in child_styles], children, diff --git a/src/textual/screen.py b/src/textual/screen.py index cc1ef9fe28..2b0a3d06b5 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -1427,7 +1427,7 @@ def _screen_resized(self, size: Size) -> None: if self.stack_updates and self.is_attached: self._refresh_layout(size) - def _on_screen_resume(self) -> None: + def _on_screen_resume(self, event: events.ScreenResume) -> None: """Screen has resumed.""" if self.app.SUSPENDED_SCREEN_CLASS: self.remove_class(self.app.SUSPENDED_SCREEN_CLASS) @@ -1441,8 +1441,10 @@ def _on_screen_resume(self) -> None: if self.is_attached: self._compositor_refresh() - self.update_node_styles(animate=False) - self._refresh_layout(size) + if event.refresh_styles: + self.update_node_styles(animate=False) + if self._size != size: + self._refresh_layout(size) self.refresh() async def _compose(self) -> None: diff --git a/src/textual/widgets/_collapsible.py b/src/textual/widgets/_collapsible.py index d836e56a40..183ef66eb2 100644 --- a/src/textual/widgets/_collapsible.py +++ b/src/textual/widgets/_collapsible.py @@ -21,8 +21,8 @@ class CollapsibleTitle(Static, can_focus=True): DEFAULT_CSS = """ CollapsibleTitle { width: auto; - height: auto; - padding: 0 1; + height: auto; + padding: 0 1; text-style: $block-cursor-blurred-text-style; color: $block-cursor-blurred-foreground; From 33c051a9339cb68cafe0c2a5a510b20d4d4aa748 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 7 Jan 2026 11:11:58 +0000 Subject: [PATCH 2/5] remove debug --- src/textual/_resolve.py | 12 ++---------- src/textual/layouts/vertical.py | 2 -- src/textual/widgets/_collapsible.py | 2 +- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/textual/_resolve.py b/src/textual/_resolve.py index 8eb4b8a24a..16d0377936 100644 --- a/src/textual/_resolve.py +++ b/src/textual/_resolve.py @@ -246,8 +246,6 @@ def resolve_box_models( margins = [widget.styles.margin.totals for widget in widgets] - print("--", size, margin) - print(widgets) # Fixed box models box_models: list[BoxModel | None] = [ ( @@ -274,10 +272,6 @@ def resolve_box_models( ) ] - from textual import log - - log(box_models) - if None not in box_models: # No fr units, so we're done return cast("list[BoxModel]", box_models) @@ -322,10 +316,8 @@ def resolve_box_models( ) ) - print("MARGINS") - log(margins) - remaining_space = int(max(0, size.height - total_remaining - margin_height)) + fraction_unit = resolve_fraction_unit( [ styles @@ -336,7 +328,7 @@ def resolve_box_models( and styles.overlay != "screen" ) ], - size, + Size(size.width, remaining_space), viewport_size, Fraction(remaining_space), resolve_dimension, diff --git a/src/textual/layouts/vertical.py b/src/textual/layouts/vertical.py index 10118b4c8e..da3462267d 100644 --- a/src/textual/layouts/vertical.py +++ b/src/textual/layouts/vertical.py @@ -50,8 +50,6 @@ def arrange( else: resolve_margin = Size(0, 0) - print("!!", parent) - box_models = resolve_box_models( [styles.height for styles in child_styles], children, diff --git a/src/textual/widgets/_collapsible.py b/src/textual/widgets/_collapsible.py index 183ef66eb2..a35d7e2eb0 100644 --- a/src/textual/widgets/_collapsible.py +++ b/src/textual/widgets/_collapsible.py @@ -160,7 +160,7 @@ class Contents(Container): Contents { width: 100%; height: auto; - padding: 1 0 0 3; + padding: 1 0 0 3; } """ From b31707e7f4028d8488bd9dea37dddc7a1203423e Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 7 Jan 2026 11:16:12 +0000 Subject: [PATCH 3/5] restore --- src/textual/_resolve.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/_resolve.py b/src/textual/_resolve.py index 16d0377936..3a57dacb45 100644 --- a/src/textual/_resolve.py +++ b/src/textual/_resolve.py @@ -328,7 +328,7 @@ def resolve_box_models( and styles.overlay != "screen" ) ], - Size(size.width, remaining_space), + size, viewport_size, Fraction(remaining_space), resolve_dimension, From de3dbd020c600651e24725091ec0061ffe994b34 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 7 Jan 2026 11:18:13 +0000 Subject: [PATCH 4/5] changelog --- CHANGELOG.md | 8 ++++++++ pyproject.toml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba1262a696..e465369e84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ 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/). +## [7.0.1] - 2026-01-07 + +### Added + +- Added a `refresh_styles` boolean to the `ScreenResult` message which reduces style updates when popping screens + + ## [7.0.0] - 2026-01-03 ### Changed @@ -3272,6 +3279,7 @@ https://textual.textualize.io/blog/2022/11/08/version-040/#version-040 - New handler system for messages that doesn't require inheritance - Improved traceback handling +[7.0.1]: https://github.com/Textualize/textual/compare/v7.0.0...v7.0.1 [7.0.0]: https://github.com/Textualize/textual/compare/v6.11.0...v7.0.0 [6.11.0]: https://github.com/Textualize/textual/compare/v6.10.0...v6.11.0 [6.10.0]: https://github.com/Textualize/textual/compare/v6.9.0...v6.10.0 diff --git a/pyproject.toml b/pyproject.toml index 4f0ba51d03..9f140490c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "textual" -version = "7.0.0" +version = "7.0.1" homepage = "https://github.com/Textualize/textual" repository = "https://github.com/Textualize/textual" documentation = "https://textual.textualize.io/" From ba26b7e7f69f0bae9cae0ec150d882bcdffb6788 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 7 Jan 2026 11:18:47 +0000 Subject: [PATCH 5/5] changelog --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e465369e84..f8936b648f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added a `refresh_styles` boolean to the `ScreenResult` message which reduces style updates when popping screens - ## [7.0.0] - 2026-01-03 ### Changed @@ -20,7 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added -- Adde atom-one-dark and atom-one-light themes @NSPC911 https://github.com/Textualize/textual/pull/6301 +- Added atom-one-dark and atom-one-light themes @NSPC911 https://github.com/Textualize/textual/pull/6301 ## [6.12.0] - 2026-01-02