From 6f9f1ea87ab91572ee6a4cdf63f2fb726cb38c6f Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sat, 10 Jan 2026 09:54:47 +0000 Subject: [PATCH 1/2] blank --- CHANGELOG.md | 11 +++++++++++ pyproject.toml | 2 +- src/textual/strip.py | 1 + src/textual/widget.py | 8 ++++++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index caa22bfbc4..0296d7a704 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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/). +## [7.1.0] - 2026-01-10 + +### Fixed + +- Fixed issue with missing refresh + +### Added + +- Added Widget.BLANK which can optimize rendering of large widgets (typically containers that scroll) + ## [7.0.3] - 2026-01-09 ### Fixed @@ -3290,6 +3300,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.1.0]: https://github.com/Textualize/textual/compare/v7.0.3...v7.1.0 [7.0.3]: https://github.com/Textualize/textual/compare/v7.0.2...v7.0.3 [7.0.2]: https://github.com/Textualize/textual/compare/v7.0.1...v7.0.2 [7.0.1]: https://github.com/Textualize/textual/compare/v7.0.0...v7.0.1 diff --git a/pyproject.toml b/pyproject.toml index dc28faf4ef..c625b3eab6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "textual" -version = "7.0.3" +version = "7.1.0" homepage = "https://github.com/Textualize/textual" repository = "https://github.com/Textualize/textual" documentation = "https://textual.textualize.io/" diff --git a/src/textual/strip.py b/src/textual/strip.py index d97b5820ec..72ca43460d 100644 --- a/src/textual/strip.py +++ b/src/textual/strip.py @@ -135,6 +135,7 @@ def link_ids(self) -> set[str]: return self._link_ids @classmethod + @lru_cache(maxsize=1024) def blank(cls, cell_length: int, style: StyleType | None = None) -> Strip: """Create a blank strip. diff --git a/src/textual/widget.py b/src/textual/widget.py index 94b254b520..f086834259 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -307,6 +307,7 @@ class Widget(DOMNode): } """ COMPONENT_CLASSES: ClassVar[set[str]] = set() + """A set of component classes.""" BORDER_TITLE: ClassVar[str] = "" """Initial value for border_title attribute.""" @@ -329,6 +330,9 @@ class Widget(DOMNode): FOCUS_ON_CLICK: ClassVar[bool] = True """Should focusable widgets be automatically focused on click? Default return value of [Widget.focus_on_click][textual.widget.Widget.focus_on_click].""" + BLANK: ClassVar[bool] = False + """Is this widget blank (solid border, no border, no content)? Enable for very large scrolling containers.""" + can_focus: bool = False """Widget may receive focus.""" can_focus_children: bool = True @@ -2646,6 +2650,7 @@ def _set_dirty(self, *regions: Region) -> None: self._dirty_regions.clear() self._repaint_regions.clear() self._styles_cache.clear() + self._styles_cache.set_dirty(self.size.region) outer_size = self.outer_size self._dirty_regions.add(outer_size.region) if outer_size: @@ -4187,6 +4192,9 @@ def render_line(self, y: int) -> Strip: Returns: A rendered line. """ + if self.BLANK: + return Strip.blank(self.size.width, self.visual_style.rich_style) + if self._dirty_regions: self._render_content() try: From c933d944d75cdb9b9aa4f11101efacbf9b843d59 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sat, 10 Jan 2026 09:57:59 +0000 Subject: [PATCH 2/2] fix doc --- src/textual/widget.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/widget.py b/src/textual/widget.py index f086834259..8221ab3742 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -331,7 +331,7 @@ class Widget(DOMNode): """Should focusable widgets be automatically focused on click? Default return value of [Widget.focus_on_click][textual.widget.Widget.focus_on_click].""" BLANK: ClassVar[bool] = False - """Is this widget blank (solid border, no border, no content)? Enable for very large scrolling containers.""" + """Is this widget blank (no border, no content)? Enable for very large scrolling containers.""" can_focus: bool = False """Widget may receive focus."""