Skip to content

Commit 57e65d9

Browse files
committed
more efficient order styles
1 parent d795c43 commit 57e65d9

File tree

5 files changed

+25
-10
lines changed

5 files changed

+25
-10
lines changed

src/textual/css/stylesheet.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,10 @@ def apply(
482482
node._has_hover_style = "hover" in all_pseudo_classes
483483
node._has_focus_within = "focus-within" in all_pseudo_classes
484484
node._has_order_style = not all_pseudo_classes.isdisjoint(
485-
{"first-of-type", "last-of-type", "odd", "even"}
485+
{"first-of-type", "last-of-type"}
486+
)
487+
node._has_odd_or_even = (
488+
"odd" in all_pseudo_classes or "even" in all_pseudo_classes
486489
)
487490

488491
cache_key: tuple | None = None

src/textual/demo/widgets.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -775,10 +775,9 @@ class WidgetsScreen(PageScreen):
775775
WidgetsScreen {
776776
align-horizontal: center;
777777
Markdown { background: transparent; }
778-
& > VerticalScroll {
778+
#container {
779779
scrollbar-gutter: stable;
780-
&> * {
781-
780+
& > * {
782781
&:even { background: $boost; }
783782
padding-bottom: 1;
784783
}
@@ -789,7 +788,7 @@ class WidgetsScreen(PageScreen):
789788
BINDINGS = [Binding("escape", "blur", "Unfocus any focused widget", show=False)]
790789

791790
def compose(self) -> ComposeResult:
792-
with lazy.Reveal(containers.VerticalScroll(can_focus=True)):
791+
with lazy.Reveal(containers.VerticalScroll(id="container", can_focus=True)):
793792
yield Markdown(WIDGETS_MD, classes="column")
794793
yield Buttons()
795794
yield Checkboxes()

src/textual/dom.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ def __init__(
223223
self._has_focus_within: bool = False
224224
self._has_order_style: bool = False
225225
"""The node has an ordered dependent pseudo-style (`:odd`, `:even`, `:first-of-type`, `:last-of-type`)"""
226+
self._has_odd_or_even: bool = False
227+
"""The node has the pseudo class `odd` or `even`."""
226228
self._reactive_connect: (
227229
dict[str, tuple[MessagePump, Reactive[object] | object]] | None
228230
) = None

src/textual/timer.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ async def _run(self) -> None:
177177

178178
async def _tick(self, *, next_timer: float, count: int) -> None:
179179
"""Triggers the Timer's action: either call its callback, or sends an event to its target"""
180+
181+
app = active_app.get()
182+
if app._exit:
183+
return
184+
180185
if self._callback is not None:
181186
try:
182187
await invoke(self._callback)
@@ -185,7 +190,6 @@ async def _tick(self, *, next_timer: float, count: int) -> None:
185190
# Re-raise CancelledErrors that would be caught by the following exception block in Python 3.7
186191
raise
187192
except Exception as error:
188-
app = active_app.get()
189193
app._handle_exception(error)
190194
else:
191195
event = events.Timer(

src/textual/widget.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,11 +1253,18 @@ def mount(
12531253
parent, *widgets, before=insert_before, after=insert_after
12541254
)
12551255

1256-
def update_styles(children: Iterable[DOMNode]) -> None:
1256+
def update_styles(children: list[DOMNode]) -> None:
12571257
"""Update order related CSS"""
1258-
for child in children:
1259-
if child._has_order_style:
1260-
child._update_styles()
1258+
if before is not None or after is not None:
1259+
# If the new children aren't at the end.
1260+
# we need to update both odd/even and first-of-type/last-of-type
1261+
for child in children:
1262+
if child._has_order_style or child._has_odd_or_even:
1263+
child._update_styles()
1264+
else:
1265+
for child in children:
1266+
if child._has_order_style:
1267+
child._update_styles()
12611268

12621269
self.call_later(update_styles, list(self.children))
12631270
await_mount = AwaitMount(self, mounted)

0 commit comments

Comments
 (0)