Skip to main content

teksilo_app/
default_post_root.rs

1// SPDX-License-Identifier: MPL-2.0
2// SPDX-FileCopyrightText: 2026 FernTech
3
4//! App-wide default post-root wrapper.
5//!
6//! Stored in `app_state` by extensions (notably the debug inspector)
7//! that want to splice a wrapper widget around every window's root
8//! without per-window opt-in. `WindowManager::create_window` looks
9//! this up after invoking the user's `root_builder`, before computing
10//! modal focus targets.
11//!
12//! Per-window `WindowConfig::post_root` overrides this default for
13//! that window only — useful when a particular window opts out of the
14//! wrapper or wants a different one.
15
16use std::rc::Rc;
17
18use teksilo_core::widget_id::WidgetId;
19use teksilo_core::widget_tree::WidgetTree;
20
21/// Closure that runs after each window's `root_builder` returns, wrapping
22/// the user's root widget. Stored in `app_state` so it is shared across
23/// every window the app opens at runtime.
24///
25/// The closure may be invoked from many windows over the app's lifetime
26/// — it receives `&mut WidgetTree` and the user's root id, and returns
27/// the id of the (possibly wrapped) widget to use as the window's
28/// effective root.
29#[derive(Clone)]
30pub struct DefaultPostRoot(pub Rc<dyn Fn(&mut WidgetTree, WidgetId) -> WidgetId>);
31
32impl DefaultPostRoot {
33    pub fn new(f: impl Fn(&mut WidgetTree, WidgetId) -> WidgetId + 'static) -> Self {
34        Self(Rc::new(f))
35    }
36}
37
38impl std::fmt::Debug for DefaultPostRoot {
39    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40        f.debug_tuple("DefaultPostRoot")
41            .field(&"<closure>")
42            .finish()
43    }
44}