From 6270a8f7e17f3b32b32a06fc609f4161b17d3bcc Mon Sep 17 00:00:00 2001 From: Tristan Simas Date: Wed, 7 Oct 2026 23:03:33 -0400 Subject: [PATCH 1/2] Avoid node geometry analysis for detached rule normalization --- src/textual/css/styles.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/textual/css/styles.py b/src/textual/css/styles.py index 211432aadb..8ba4685a0f 100644 --- a/src/textual/css/styles.py +++ b/src/textual/css/styles.py @@ -975,7 +975,10 @@ def _update_rules( changes = updates + removed if not changes: return False - geometry = any( + # Detached styles normalize rules (including mount's prepared copy) + # but have no node geometry to invalidate. Keep validation and rule + # publication intact; acquire placement effects only for their owner. + geometry = self.node is not None and any( descriptor.affects_geometry(previous, value) for descriptor, key, previous, value in changes ) From 02d6d126d4281947afb3e799cb5afd96887b89ae Mon Sep 17 00:00:00 2001 From: Tristan Simas Date: Wed, 7 Oct 2026 23:05:05 -0400 Subject: [PATCH 2/2] Assert child layout intent through its current native owner --- tests/css/test_stylesheet.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/css/test_stylesheet.py b/tests/css/test_stylesheet.py index f437f935ba..4925e221e9 100644 --- a/tests/css/test_stylesheet.py +++ b/tests/css/test_stylesheet.py @@ -100,7 +100,8 @@ async def test_style_batch_keeps_child_damage_separate_and_flushes_interrupted_e parent.styles.refresh(layout=True) with parent.styles.batch_update(): parent.styles.color = "green" - refresh.assert_called_once_with(layout=False, repaint=True) + refresh.assert_called_once_with(repaint=True) + assert not child._layout_required assert child.rich_style.color == Color.parse("green").rich_color with pytest.raises(StyleValueError), parent.styles.batch_update(): parent.styles.color = "red"