Skip to content

Commit d8ba63d

Browse files
authored
Merge pull request #5221 from Textualize/invalidate-css
Invalidate CSS
2 parents da1178f + 466b09e commit d8ba63d

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

src/textual/app.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,9 @@ def __init__(
786786

787787
self._hover_effects_timer: Timer | None = None
788788

789+
self._css_update_count: int = 0
790+
"""Incremented when CSS is invalidated."""
791+
789792
if self.ENABLE_COMMAND_PALETTE:
790793
for _key, binding in self._bindings:
791794
if binding.action in {"command_palette", "app.command_palette"}:
@@ -1189,6 +1192,10 @@ def get_css_variables(self) -> dict[str, str]:
11891192
variables = design.generate()
11901193
return variables
11911194

1195+
def _invalidate_css(self) -> None:
1196+
"""Invalidate CSS, so it will be refreshed."""
1197+
self._css_update_count += 1
1198+
11921199
def watch_dark(self, dark: bool) -> None:
11931200
"""Watches the dark bool.
11941201
@@ -1198,16 +1205,19 @@ def watch_dark(self, dark: bool) -> None:
11981205
self.set_class(dark, "-dark-mode", update=False)
11991206
self.set_class(not dark, "-light-mode", update=False)
12001207
self._refresh_truecolor_filter(self.ansi_theme)
1208+
self._invalidate_css()
12011209
self.call_next(self.refresh_css)
12021210

12031211
def watch_ansi_theme_dark(self, theme: TerminalTheme) -> None:
12041212
if self.dark:
12051213
self._refresh_truecolor_filter(theme)
1214+
self._invalidate_css()
12061215
self.call_next(self.refresh_css)
12071216

12081217
def watch_ansi_theme_light(self, theme: TerminalTheme) -> None:
12091218
if not self.dark:
12101219
self._refresh_truecolor_filter(theme)
1220+
self._invalidate_css()
12111221
self.call_next(self.refresh_css)
12121222

12131223
@property
@@ -2203,7 +2213,9 @@ def _init_mode(self, mode: str) -> AwaitMount:
22032213
screen, await_mount = self._get_screen(new_screen)
22042214
stack.append(screen)
22052215
self._load_screen_css(screen)
2206-
self.refresh_css()
2216+
if screen._css_update_count != self._css_update_count:
2217+
self.refresh_css()
2218+
22072219
screen.post_message(events.ScreenResume())
22082220
else:
22092221
# Mode is not defined
@@ -2248,7 +2260,8 @@ def switch_mode(self, mode: str) -> AwaitMount:
22482260
await_mount = AwaitMount(self.screen, [])
22492261

22502262
self._current_mode = mode
2251-
self.refresh_css()
2263+
if self.screen._css_update_count != self._css_update_count:
2264+
self.refresh_css()
22522265
self.screen._screen_resized(self.size)
22532266
self.screen.post_message(events.ScreenResume())
22542267

@@ -3365,6 +3378,7 @@ def refresh_css(self, animate: bool = True) -> None:
33653378
stylesheet.update(self.app, animate=animate)
33663379
try:
33673380
self.screen._refresh_layout(self.size)
3381+
self.screen._css_update_count = self._css_update_count
33683382
except ScreenError:
33693383
pass
33703384
# The other screens in the stack will need to know about some style
@@ -3373,6 +3387,7 @@ def refresh_css(self, animate: bool = True) -> None:
33733387
for screen in self.screen_stack:
33743388
if screen != self.screen:
33753389
stylesheet.update(screen, animate=animate)
3390+
screen._css_update_count = self._css_update_count
33763391

33773392
def _display(self, screen: Screen, renderable: RenderableType | None) -> None:
33783393
"""Display a renderable within a sync.

src/textual/screen.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,9 @@ def __init__(
267267
self.bindings_updated_signal: Signal[Screen] = Signal(self, "bindings_updated")
268268
"""A signal published when the bindings have been updated"""
269269

270+
self._css_update_count = -1
271+
"""Track updates to CSS."""
272+
270273
@property
271274
def is_modal(self) -> bool:
272275
"""Is the screen modal?"""

0 commit comments

Comments
 (0)