Repository: zng-ui/zng (language: rust)

Issue:
Upgrade to Rust 2024



Discussion / hints:

Fix patch:
diff --git a/.github/workflows/ci-audit.yml b/.github/workflows/ci-audit.yml
index 958065b5e..30160d0fa 100644
--- a/.github/workflows/ci-audit.yml
+++ b/.github/workflows/ci-audit.yml
@@ -10,6 +10,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v4
+      - uses: dtolnay/rust-toolchain@stable
       - run: cargo generate-lockfile
       - name: install cargo-audit
         uses: baptiste0928/cargo-install@v3
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 95e5359ed..20b8ee795 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Unreleased
 
+* **Breaking** Upgrade all crates to Rust 2024 edition.
+* **Breaking** Many return impl Trait changed lifetimes slightly, some replaced with doc hidden types. In practice all code should still just compile, but these are breaking changes.
+* **Breaking** Some public `hashbrown::{HashMap, HashSet}` API replaced with the `std::collections` equivalent.
+* **Breaking** Remove deprecated `zng::text::justify` that was replaced with `justify_mode` in 0.13.11.
 
 # 0.13.12
 
diff --git a/crates/cargo-zng/Cargo.toml b/crates/cargo-zng/Cargo.toml
index ddd99c455..614c744a7 100644
--- a/crates/cargo-zng/Cargo.toml
+++ b/crates/cargo-zng/Cargo.toml
@@ -2,7 +2,7 @@
 name = "cargo-zng"
 version = "0.4.19"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Zng project manager."
diff --git a/crates/cargo-zng/src/fmt.rs b/crates/cargo-zng/src/fmt.rs
index 310436f19..fd6ed977d 100644
--- a/crates/cargo-zng/src/fmt.rs
+++ b/crates/cargo-zng/src/fmt.rs
@@ -218,8 +218,13 @@ fn fmt_code(code: &str, stream: TokenStream) -> String {
                     // #[..]
                     let mut attr = g.stream().into_iter();
                     let attr = [attr.next(), attr.next(), attr.next(), attr.next(), attr.next()];
-                    if let [Some(TokenTree::Ident(i0)), Some(TokenTree::Punct(p0)), Some(TokenTree::Punct(p1)), Some(TokenTree::Ident(i1)), None] =
-                        attr
+                    if let [
+                        Some(TokenTree::Ident(i0)),
+                        Some(TokenTree::Punct(p0)),
+                        Some(TokenTree::Punct(p1)),
+                        Some(TokenTree::Ident(i1)),
+                        None,
+                    ] = attr
                     {
                         if i0 == "rustfmt" && p0.as_char() == ':' && p1.as_char() == ':' && i1 == "skip" {
                             // #[rustfmt::skip]
diff --git a/crates/cargo-zng/src/l10n/scraper.rs b/crates/cargo-zng/src/l10n/scraper.rs
index 7a74d280b..1e3b56cb6 100644
--- a/crates/cargo-zng/src/l10n/scraper.rs
+++ b/crates/cargo-zng/src/l10n/scraper.rs
@@ -329,10 +329,14 @@ impl TryFrom<TokenStream> for CommandMacroArgs {
             if tail4.len() > 4 {
                 tail4.remove(0);
                 match &tail4[..] {
-                    [TokenTree::Ident(i0), TokenTree::Ident(id), TokenTree::Punct(p0), TokenTree::Group(g)]
-                        if i0 == "static"
-                            && p0.as_char() == '='
-                            && matches!(g.delimiter(), Delimiter::Brace | Delimiter::Parenthesis | Delimiter::Bracket) =>
+                    [
+                        TokenTree::Ident(i0),
+                        TokenTree::Ident(id),
+                        TokenTree::Punct(p0),
+                        TokenTree::Group(g),
+                    ] if i0 == "static"
+                        && p0.as_char() == '='
+                        && matches!(g.delimiter(), Delimiter::Brace | Delimiter::Parenthesis | Delimiter::Bracket) =>
                     {
                         match CommandMacroEntry::try_from(g.stream()) {
                             Ok(mut entry) => {
@@ -351,11 +355,7 @@ impl TryFrom<TokenStream> for CommandMacroArgs {
                 }
             }
         }
-        if entries.is_empty() {
-            Err(None)
-        } else {
-            Ok(Self { entries })
-        }
+        if entries.is_empty() { Err(None) } else { Ok(Self { entries }) }
     }
 }
 struct CommandMacroEntry {
@@ -379,9 +379,13 @@ impl TryFrom<TokenStream> for CommandMacroEntry {
         // parse l10n!: #lit
         let mut buf: Vec<_> = (&mut tts).take(5).collect();
         match &buf[..] {
-            [TokenTree::Ident(i), TokenTree::Punct(p0), TokenTree::Punct(p1), value, TokenTree::Punct(p2)]
-                if i == "l10n" && p0.as_char() == '!' && p1.as_char() == ':' && p2.as_char() == ',' =>
-            {
+            [
+                TokenTree::Ident(i),
+                TokenTree::Punct(p0),
+                TokenTree::Punct(p1),
+                value,
+                TokenTree::Punct(p2),
+            ] if i == "l10n" && p0.as_char() == '!' && p1.as_char() == ':' && p2.as_char() == ',' => {
                 match litrs::Literal::try_from(value) {
                     Ok(litrs::Literal::String(str)) => {
                         r.id = str.into_value().into_owned();
@@ -396,7 +400,7 @@ impl TryFrom<TokenStream> for CommandMacroEntry {
                         return Err(Some((
                             "unexpected l10n: value, must be string or bool literal".to_owned(),
                             value.span(),
-                        )))
+                        )));
                     }
                 }
             }
@@ -428,11 +432,7 @@ impl TryFrom<TokenStream> for CommandMacroEntry {
             }
         }
 
-        if r.metadata.is_empty() {
-            Err(None)
-        } else {
-            Ok(r)
-        }
+        if r.metadata.is_empty() { Err(None) } else { Ok(r) }
     }
 }
 struct CommandMetaEntry {
diff --git a/crates/cargo-zng/src/main.rs b/crates/cargo-zng/src/main.rs
index a105003e1..ecff92e9f 100644
--- a/crates/cargo-zng/src/main.rs
+++ b/crates/cargo-zng/src/main.rs
@@ -21,9 +21,9 @@ mod res;
 /// Note don't depend on `cargo-zng`, just copy the source code of the utilities you need.
 pub mod res_tool_util {
     pub use crate::res::built_in::{
-        display_path, path, ZR_APP, ZR_CACHE_DIR, ZR_CRATE_NAME, ZR_DESCRIPTION, ZR_FINAL, ZR_HELP, ZR_HOMEPAGE, ZR_LICENSE, ZR_ORG,
-        ZR_PKG_AUTHORS, ZR_PKG_NAME, ZR_QUALIFIER, ZR_REQUEST, ZR_REQUEST_DD, ZR_SOURCE_DIR, ZR_TARGET, ZR_TARGET_DD, ZR_TARGET_DIR,
-        ZR_VERSION, ZR_WORKSPACE_DIR,
+        ZR_APP, ZR_CACHE_DIR, ZR_CRATE_NAME, ZR_DESCRIPTION, ZR_FINAL, ZR_HELP, ZR_HOMEPAGE, ZR_LICENSE, ZR_ORG, ZR_PKG_AUTHORS,
+        ZR_PKG_NAME, ZR_QUALIFIER, ZR_REQUEST, ZR_REQUEST_DD, ZR_SOURCE_DIR, ZR_TARGET, ZR_TARGET_DD, ZR_TARGET_DIR, ZR_VERSION,
+        ZR_WORKSPACE_DIR, display_path, path,
     };
 }
 
diff --git a/crates/cargo-zng/src/new.rs b/crates/cargo-zng/src/new.rs
index 5a5763460..f2d04f9bc 100644
--- a/crates/cargo-zng/src/new.rs
+++ b/crates/cargo-zng/src/new.rs
@@ -530,7 +530,7 @@ fn make_replacements(keys: &KeyMap) -> io::Result<ReplaceMap> {
                 return Err(io::Error::new(
                     io::ErrorKind::InvalidInput,
                     format!("missing required key `{}`", kv.key),
-                ))
+                ));
             }
         };
         let clean_value = util::clean_value(value, kv.required)?;
diff --git a/crates/cargo-zng/src/res.rs b/crates/cargo-zng/src/res.rs
index 51cb8f100..4aaaa6878 100644
--- a/crates/cargo-zng/src/res.rs
+++ b/crates/cargo-zng/src/res.rs
@@ -5,9 +5,9 @@ use std::{
     time::Instant,
 };
 
-use anyhow::{bail, Context as _};
+use anyhow::{Context as _, bail};
 
-use built_in::{display_path, ZR_WORKSPACE_DIR};
+use built_in::{ZR_WORKSPACE_DIR, display_path};
 use clap::*;
 use color_print::cstr;
 use zng_env::About;
diff --git a/crates/cargo-zng/src/res/built_in.rs b/crates/cargo-zng/src/res/built_in.rs
index 97b19012a..d37401c6c 100644
--- a/crates/cargo-zng/src/res/built_in.rs
+++ b/crates/cargo-zng/src/res/built_in.rs
@@ -183,7 +183,8 @@ fn glob() {
     let target = path(ZR_TARGET);
     let target = target.parent().unwrap();
 
-    let mut lines = read_lines(&path(ZR_REQUEST));
+    let request_path = path(ZR_REQUEST);
+    let mut lines = read_lines(&request_path);
     let (ln, selection) = lines
         .next()
         .unwrap_or_else(|| fatal!("expected at least one path pattern"))
@@ -1076,34 +1077,36 @@ fn read_lines(path: &Path) -> impl Iterator<Item = io::Result<(usize, String)>>
     }
     // start -> open
     let mut state = State::Open(fs::File::open(path));
-    std::iter::from_fn(move || loop {
-        match std::mem::replace(&mut state, State::End) {
-            State::Lines(count, mut lines) => {
-                if let Some(l) = lines.next() {
-                    match l {
-                        // lines -> lines
-                        Ok(l) => {
-                            state = State::Lines(count + 1, lines);
-                            let test = l.trim();
-                            if !test.is_empty() && !test.starts_with('#') {
-                                return Some(Ok((count, l)));
+    std::iter::from_fn(move || {
+        loop {
+            match std::mem::replace(&mut state, State::End) {
+                State::Lines(count, mut lines) => {
+                    if let Some(l) = lines.next() {
+                        match l {
+                            // lines -> lines
+                            Ok(l) => {
+                                state = State::Lines(count + 1, lines);
+                                let test = l.trim();
+                                if !test.is_empty() && !test.starts_with('#') {
+                                    return Some(Ok((count, l)));
+                                }
+                            }
+                            // lines -> end
+                            Err(e) => {
+                                return Some(Err(e));
                             }
-                        }
-                        // lines -> end
-                        Err(e) => {
-                            return Some(Err(e));
                         }
                     }
                 }
+                State::Open(r) => match r {
+                    // open -> lines
+                    Ok(f) => state = State::Lines(1, io::BufReader::new(f).lines()),
+                    // open -> end
+                    Err(e) => return Some(Err(e)),
+                },
+                // end -> end
+                State::End => return None,
             }
-            State::Open(r) => match r {
-                // open -> lines
-                Ok(f) => state = State::Lines(1, io::BufReader::new(f).lines()),
-                // open -> end
-                Err(e) => return Some(Err(e)),
-            },
-            // end -> end
-            State::End => return None,
         }
     })
 }
diff --git a/crates/cargo-zng/src/res/tool.rs b/crates/cargo-zng/src/res/tool.rs
index 534fa50da..e9cb9555c 100644
--- a/crates/cargo-zng/src/res/tool.rs
+++ b/crates/cargo-zng/src/res/tool.rs
@@ -5,7 +5,7 @@ use std::{
     path::{Path, PathBuf},
 };
 
-use anyhow::{bail, Context};
+use anyhow::{Context, bail};
 use is_executable::IsExecutable as _;
 use parking_lot::Mutex;
 use zng_env::About;
diff --git a/crates/cargo-zng/src/util.rs b/crates/cargo-zng/src/util.rs
index 8f3ac7e22..7c6f90875 100644
--- a/crates/cargo-zng/src/util.rs
+++ b/crates/cargo-zng/src/util.rs
@@ -93,11 +93,7 @@ fn cmd_impl(line: &str, args: &[&str], env: &[(&str, &str)], silent: bool) -> io
         line_parts
             .map(|a| {
                 let a = a.trim();
-                if a.starts_with('"') {
-                    a.trim_matches('"')
-                } else {
-                    a
-                }
+                if a.starts_with('"') { a.trim_matches('"') } else { a }
             })
             .filter(|a| !a.is_empty()),
     );
diff --git a/crates/zng-app-context/Cargo.toml b/crates/zng-app-context/Cargo.toml
index b5c2d1c83..4658d5405 100644
--- a/crates/zng-app-context/Cargo.toml
+++ b/crates/zng-app-context/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-app-context"
 version = "0.5.14"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
@@ -35,7 +35,6 @@ zng-env = { path = "../zng-env", version = "0.3.9" }
 zng-txt = { path = "../zng-txt", version = "0.2.8" }
 parking_lot = "0.12"
 rustc-hash = "2.0"
-hashbrown = { version = "0.15", features = ["rayon"] }
 tracing = "0.1"
 serde = { version = "1.0", features = ["derive"] }
 bytemuck = { version = "1.15", features = ["derive"] }
diff --git a/crates/zng-app-context/src/lib.rs b/crates/zng-app-context/src/lib.rs
index 25dce8ad4..2457f8db9 100644
--- a/crates/zng-app-context/src/lib.rs
+++ b/crates/zng-app-context/src/lib.rs
@@ -69,7 +69,7 @@ impl LocalValueKind {
 /// `(value, is_context_var)`
 type LocalValue = (Arc<dyn Any + Send + Sync>, LocalValueKind);
 // equivalent to rustc_hash::FxHashMap, but can be constructed in `const`.
-type LocalData = hashbrown::HashMap<AppLocalId, LocalValue, BuildFxHasher>;
+type LocalData = std::collections::HashMap<AppLocalId, LocalValue, BuildFxHasher>;
 #[derive(Clone, Default)]
 struct BuildFxHasher;
 impl std::hash::BuildHasher for BuildFxHasher {
@@ -80,12 +80,12 @@ impl std::hash::BuildHasher for BuildFxHasher {
     }
 }
 const fn new_local_data() -> LocalData {
-    hashbrown::HashMap::with_hasher(BuildFxHasher)
+    LocalData::with_hasher(BuildFxHasher)
 }
 
-type LocalSet = hashbrown::HashSet<AppLocalId, BuildFxHasher>;
+type LocalSet = std::collections::HashSet<AppLocalId, BuildFxHasher>;
 const fn new_local_set() -> LocalSet {
-    hashbrown::HashSet::with_hasher(BuildFxHasher)
+    LocalSet::with_hasher(BuildFxHasher)
 }
 
 /// Represents an app lifetime, ends the app on drop.
@@ -156,8 +156,8 @@ impl LocalContext {
     /// Start an app scope in the current thread.
     pub fn start_app(id: AppId) -> AppScope {
         let valid = LOCAL.with_borrow_mut_dyn(|c| match c.entry(AppId::local_id()) {
-            hashbrown::hash_map::Entry::Occupied(_) => false,
-            hashbrown::hash_map::Entry::Vacant(e) => {
+            std::collections::hash_map::Entry::Occupied(_) => false,
+            std::collections::hash_map::Entry::Vacant(e) => {
                 e.insert((Arc::new(id), LocalValueKind::App));
                 true
             }
@@ -871,7 +871,7 @@ impl fmt::Debug for AppLocalId {
 macro_rules! app_local {
     ($(
         $(#[$meta:meta])*
-        $vis:vis static $IDENT:ident : $T:ty = $(const { $init_const:expr })? $($init:expr)?;
+        $vis:vis static $IDENT:ident : $T:ty = $(const { $init_const:expr })? $($init:expr_2021)?;
     )+) => {$(
         $crate::app_local_impl! {
             $(#[$meta])*
@@ -900,7 +900,7 @@ macro_rules! app_local_impl_single {
     };
     (
         $(#[$meta:meta])*
-        $vis:vis static $IDENT:ident : $T:ty = $init:expr;
+        $vis:vis static $IDENT:ident : $T:ty = $init:expr_2021;
     ) => {
         $(#[$meta])*
         $vis static $IDENT: $crate::AppLocal<$T> = {
@@ -947,7 +947,7 @@ macro_rules! app_local_impl_multi {
     };
     (
         $(#[$meta:meta])*
-        $vis:vis static $IDENT:ident : $T:ty = $init:expr;
+        $vis:vis static $IDENT:ident : $T:ty = $init:expr_2021;
     ) => {
         $(#[$meta])*
         $vis static $IDENT: $crate::AppLocal<$T> = {
diff --git a/crates/zng-app-proc-macros/Cargo.toml b/crates/zng-app-proc-macros/Cargo.toml
index d28e38994..e3d36dee5 100644
--- a/crates/zng-app-proc-macros/Cargo.toml
+++ b/crates/zng-app-proc-macros/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-app-proc-macros"
 version = "0.3.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-app-proc-macros/src/property.rs b/crates/zng-app-proc-macros/src/property.rs
index b2918175d..c7ed1da7b 100644
--- a/crates/zng-app-proc-macros/src/property.rs
+++ b/crates/zng-app-proc-macros/src/property.rs
@@ -1,10 +1,10 @@
 use std::mem;
 
 use proc_macro2::{Ident, Span, TokenStream};
-use quote::{quote, ToTokens};
+use quote::{ToTokens, quote};
 use syn::{parse::Parse, punctuated::Punctuated, spanned::Spanned, *};
 
-use crate::util::{crate_core, set_stream_span, Attributes, Errors};
+use crate::util::{Attributes, Errors, crate_core, set_stream_span};
 
 pub fn expand(args: proc_macro::TokenStream, input: proc_macro::TokenStream) -> proc_macro::TokenStream {
     let mut errors = Errors::default();
diff --git a/crates/zng-app-proc-macros/src/ui_node.rs b/crates/zng-app-proc-macros/src/ui_node.rs
index 3bbcfd150..2632f66c7 100644
--- a/crates/zng-app-proc-macros/src/ui_node.rs
+++ b/crates/zng-app-proc-macros/src/ui_node.rs
@@ -226,7 +226,7 @@ pub(crate) fn gen_ui_node(args: proc_macro::TokenStream, input: proc_macro::Toke
 
     // modify impl header for new_node and collect
     let (impl_generics, self_ty, decl) = if let Some(new_node) = new_node {
-        let gen = new_node.impl_generics;
+        let gens = new_node.impl_generics;
         let custom_gen = &generics.params;
         let sep = if custom_gen.trailing_punct() || custom_gen.is_empty() {
             TokenStream::new()
@@ -257,7 +257,7 @@ pub(crate) fn gen_ui_node(args: proc_macro::TokenStream, input: proc_macro::Toke
         }
         let node_gen = new_node.node_generics;
 
-        let impl_generics = quote! { <#custom_gen #sep #gen> };
+        let impl_generics = quote! { <#custom_gen #sep #gens> };
         let self_ty = quote! { #node_ident<#node_custom_gen #node_sep #node_gen> };
 
         let mut decl = new_node.decl;
diff --git a/crates/zng-app-proc-macros/src/util.rs b/crates/zng-app-proc-macros/src/util.rs
index 52802c5da..b8c38b737 100644
--- a/crates/zng-app-proc-macros/src/util.rs
+++ b/crates/zng-app-proc-macros/src/util.rs
@@ -1,14 +1,13 @@
 use std::{borrow::Cow, env, fmt, fs, path::PathBuf};
 
 use proc_macro2::*;
-use quote::{quote_spanned, ToTokens};
+use quote::{ToTokens, quote_spanned};
 use syn::{
-    self,
-    parse::{discouraged::Speculative, Parse, ParseStream},
+    self, Attribute, LitStr, Token,
+    parse::{Parse, ParseStream, discouraged::Speculative},
     parse_quote, parse_quote_spanned,
     punctuated::Punctuated,
     spanned::Spanned,
-    Attribute, LitStr, Token,
 };
 
 use once_cell::sync::OnceCell;
@@ -843,7 +842,7 @@ mod tests {
         [package]
         name = "crate-name"
         version = "0.1.0"
-        edition = "2021"
+        edition = "2024"
         license = "Apache-2.0"
         "#;
 
@@ -856,7 +855,7 @@ mod tests {
         let toml = r#"
         [package]
         version = "0.1.0"
-        edition = "2021"
+        edition = "2024"
         name = "crate-name"
         license = "Apache-2.0"
         "#;
@@ -871,7 +870,7 @@ mod tests {
         [package]
         name = "foo"
         version = "0.1.0"
-        edition = "2021"
+        edition = "2024"
         license = "Apache-2.0"
 
         [dependencies]
@@ -891,7 +890,7 @@ mod tests {
         [package]
         name = "foo"
         version = "0.1.0"
-        edition = "2021"
+        edition = "2024"
         license = "Apache-2.0"
 
         [dependencies]
@@ -911,7 +910,7 @@ mod tests {
         [package]
         name = "foo"
         version = "0.1.0"
-        edition = "2021"
+        edition = "2024"
         license = "Apache-2.0"
 
         [target.'cfg(windows)'.dependencies]
@@ -931,7 +930,7 @@ mod tests {
         [package]
         name = "foo"
         version = "0.1.0"
-        edition = "2021"
+        edition = "2024"
         license = "Apache-2.0"
 
         [dev-dependencies]
@@ -951,7 +950,7 @@ mod tests {
         [package]
         name = "foo"
         version = "0.1.0"
-        edition = "2021"
+        edition = "2024"
         license = "Apache-2.0"
 
         [dev-dependencies.super-foo]
@@ -971,7 +970,7 @@ mod tests {
         [package]
         name = "foo"
         version = "0.1.0"
-        edition = "2021"
+        edition = "2024"
         license = "Apache-2.0"
 
         [dependencies.super-foo]
@@ -991,7 +990,7 @@ mod tests {
         [package]
         name = "foo"
         version = "0.1.0"
-        edition = "2021"
+        edition = "2024"
         license = "Apache-2.0"
 
         [dependencies.crate-name]
diff --git a/crates/zng-app-proc-macros/src/widget.rs b/crates/zng-app-proc-macros/src/widget.rs
index 16c4299eb..028231a7b 100644
--- a/crates/zng-app-proc-macros/src/widget.rs
+++ b/crates/zng-app-proc-macros/src/widget.rs
@@ -1,9 +1,9 @@
 use proc_macro2::{Span, TokenStream, TokenTree};
-use quote::{quote, ToTokens};
+use quote::{ToTokens, quote};
 use syn::{ext::IdentExt, parse::Parse, spanned::Spanned, *};
 
 use crate::{
-    util::{self, parse_outer_attrs, ErrorRecoverable, Errors},
+    util::{self, ErrorRecoverable, Errors, parse_outer_attrs},
     widget_util::{self, WgtItem, WgtProperty, WgtWhen},
 };
 
@@ -190,7 +190,10 @@ pub fn expand(args: proc_macro::TokenStream, input: proc_macro::TokenStream, mix
                     let mut wgt__ = #struct_path::widget_new();
                     let wgt__ = &mut wgt__;
                 }
-                build { wgt__.widget_build() }
+                build {
+                    let wgt__ = wgt__.widget_build();
+                    wgt__
+                }
                 set { $($tt)* }
             }
         };
diff --git a/crates/zng-app-proc-macros/src/widget_util.rs b/crates/zng-app-proc-macros/src/widget_util.rs
index 46a6d347e..7eda3740c 100644
--- a/crates/zng-app-proc-macros/src/widget_util.rs
+++ b/crates/zng-app-proc-macros/src/widget_util.rs
@@ -1,17 +1,17 @@
 use std::{collections::HashMap, fmt, mem};
 
 use proc_macro2::{Ident, Span, TokenStream, TokenTree};
-use quote::{quote, ToTokens};
+use quote::{ToTokens, quote};
 use syn::{
     ext::IdentExt,
-    parse::{discouraged::Speculative, Parse},
+    parse::{Parse, discouraged::Speculative},
     punctuated::Punctuated,
     spanned::Spanned,
     *,
 };
 
 use crate::{
-    util::{self, parse_outer_attrs, parse_punct_terminated2, path_span, peek_any3, Attributes, ErrorRecoverable, Errors},
+    util::{self, Attributes, ErrorRecoverable, Errors, parse_outer_attrs, parse_punct_terminated2, path_span, peek_any3},
     wgt_property_attrs::PropertyAttrData,
 };
 
diff --git a/crates/zng-app/Cargo.toml b/crates/zng-app/Cargo.toml
index c299705ee..8acfd968e 100644
--- a/crates/zng-app/Cargo.toml
+++ b/crates/zng-app/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-app"
 version = "0.14.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
@@ -109,7 +109,6 @@ once_cell = "1.19"
 unic-langid = { version = "0.9", features = ["serde"] }
 unicase = "2.7"
 
-hashbrown = { version = "0.15", features = ["rayon"] }
 rustc-hash = "2.0"
 
 dunce = "1.0"
diff --git a/crates/zng-app/src/crash_handler.rs b/crates/zng-app/src/crash_handler.rs
index 4db8c97aa..b48509ac7 100644
--- a/crates/zng-app/src/crash_handler.rs
+++ b/crates/zng-app/src/crash_handler.rs
@@ -12,7 +12,7 @@ use std::{
     fmt,
     io::{BufRead, Write},
     path::{Path, PathBuf},
-    sync::{atomic::AtomicBool, Arc},
+    sync::{Arc, atomic::AtomicBool},
     time::SystemTime,
 };
 use zng_clone_move::clmv;
diff --git a/crates/zng-app/src/event.rs b/crates/zng-app/src/event.rs
index fd2940ed9..59d1b5ea7 100644
--- a/crates/zng-app/src/event.rs
+++ b/crates/zng-app/src/event.rs
@@ -7,8 +7,8 @@ use std::{
     mem,
     ops::{ControlFlow, Deref},
     sync::{
-        atomic::{AtomicBool, Ordering},
         Arc,
+        atomic::{AtomicBool, Ordering},
     },
     time::Instant,
 };
diff --git a/crates/zng-app/src/event/args.rs b/crates/zng-app/src/event/args.rs
index 67c98840e..7ae66ee3f 100644
--- a/crates/zng-app/src/event/args.rs
+++ b/crates/zng-app/src/event/args.rs
@@ -2,8 +2,8 @@ use std::{
     any::Any,
     fmt,
     sync::{
-        atomic::{AtomicBool, Ordering::Relaxed},
         Arc,
+        atomic::{AtomicBool, Ordering::Relaxed},
     },
 };
 
diff --git a/crates/zng-app/src/event/channel.rs b/crates/zng-app/src/event/channel.rs
index b814966ee..f10e33921 100644
--- a/crates/zng-app/src/event/channel.rs
+++ b/crates/zng-app/src/event/channel.rs
@@ -1,6 +1,6 @@
-use std::{future::Future, time::Duration};
+use std::time::Duration;
 
-use crate::{update::UpdatesTrace, AppEventSender};
+use crate::{AppEventSender, update::UpdatesTrace};
 
 use super::*;
 
diff --git a/crates/zng-app/src/event/command.rs b/crates/zng-app/src/event/command.rs
index 0d4516678..87709b3d1 100644
--- a/crates/zng-app/src/event/command.rs
+++ b/crates/zng-app/src/event/command.rs
@@ -1,11 +1,11 @@
 use std::{
     any::TypeId,
-    collections::{hash_map, HashMap},
+    collections::{HashMap, hash_map},
     mem, ops,
     thread::ThreadId,
 };
 
-use crate::{shortcut::CommandShortcutExt, update::UpdatesTrace, widget::info::WidgetInfo, window::WindowId, APP};
+use crate::{APP, shortcut::CommandShortcutExt, update::UpdatesTrace, widget::info::WidgetInfo, window::WindowId};
 
 use super::*;
 
@@ -156,7 +156,7 @@ use zng_app_context::AppId;
 use zng_state_map::{OwnedStateMap, StateId, StateMapMut, StateValue};
 use zng_txt::Txt;
 use zng_unique_id::{static_id, unique_id_64};
-use zng_var::{impl_from_and_into_var, types::ArcCowVar, var, AnyVar, ArcVar, BoxedVar, ReadOnlyArcVar, Var, VarValue};
+use zng_var::{AnyVar, ArcVar, BoxedVar, ReadOnlyArcVar, Var, VarValue, impl_from_and_into_var, types::ArcCowVar, var};
 
 #[doc(hidden)]
 pub use zng_app_context::app_local;
@@ -733,11 +733,7 @@ impl CommandArgs {
     /// [`param`]: Self::param()
     /// [`enabled`]: Self::enabled
     pub fn enabled_param<T: Any>(&self) -> Option<&T> {
-        if self.enabled {
-            self.param::<T>()
-        } else {
-            None
-        }
+        if self.enabled { self.param::<T>() } else { None }
     }
 
     /// Returns [`param`] if is not [`enabled`].
@@ -745,11 +741,7 @@ impl CommandArgs {
     /// [`param`]: Self::param()
     /// [`enabled`]: Self::enabled
     pub fn disabled_param<T: Any>(&self) -> Option<&T> {
-        if !self.enabled {
-            self.param::<T>()
-        } else {
-            None
-        }
+        if !self.enabled { self.param::<T>() } else { None }
     }
 
     /// Call `handler` if propagation is not stopped and the command and local handler are enabled. Stops propagation
diff --git a/crates/zng-app/src/event/events.rs b/crates/zng-app/src/event/events.rs
index db5229472..bdcb8eae1 100644
--- a/crates/zng-app/src/event/events.rs
+++ b/crates/zng-app/src/event/events.rs
@@ -1,9 +1,9 @@
-use hashbrown::HashSet;
+use std::collections::HashSet;
 use zng_app_context::app_local;
 use zng_time::INSTANT_APP;
 use zng_txt::Txt;
 
-use crate::update::{UpdatesTrace, UPDATES};
+use crate::update::{UPDATES, UpdatesTrace};
 
 use super::*;
 
diff --git a/crates/zng-app/src/handler.rs b/crates/zng-app/src/handler.rs
index 3e4fef902..d9e2d9db0 100644
--- a/crates/zng-app/src/handler.rs
+++ b/crates/zng-app/src/handler.rs
@@ -1,7 +1,6 @@
 //! Handler types and macros.
 
 use std::any::Any;
-use std::future::Future;
 use std::marker::PhantomData;
 use std::time::Duration;
 use std::{mem, thread};
@@ -427,11 +426,13 @@ where
 ///
 /// ## Futures and Clone-Move
 ///
-/// You may want to always *clone-move* captures for async handlers, because they then automatically get cloned again for each event. This
+/// You want to always *clone-move* captures for async handlers, because they then automatically get cloned again for each event. This
 /// needs to happen because you can have more then one *handler task* running at the same type, and both want access to the captured variables.
 ///
 /// This second cloning can be avoided by using the [`async_hn_once!`] macro instead, but only if you expect a single event.
 ///
+/// Note that this means you are declaring a normal closure that returns a `'static` future, not an async closure, see [`async_clmv_fn!`].
+///
 /// [`async_clmv_fn!`]: zng_clone_move::async_clmv_fn
 #[macro_export]
 macro_rules! async_hn {
@@ -1206,11 +1207,7 @@ where
     F: FnMut(&A) -> bool + Send + 'static,
 {
     fn event(&mut self, args: &A) -> bool {
-        if (self.filter)(args) {
-            self.handler.event(args)
-        } else {
-            false
-        }
+        if (self.filter)(args) { self.handler.event(args) } else { false }
     }
 
     fn update(&mut self) -> bool {
diff --git a/crates/zng-app/src/lib.rs b/crates/zng-app/src/lib.rs
index 809dc12d7..3d64fe4f8 100644
--- a/crates/zng-app/src/lib.rs
+++ b/crates/zng-app/src/lib.rs
@@ -17,11 +17,9 @@
 #![warn(missing_docs)]
 
 use std::{
-    any::{type_name, TypeId},
+    any::{TypeId, type_name},
     collections::HashMap,
-    fmt,
-    future::{Future, IntoFuture},
-    ops,
+    fmt, ops,
     path::PathBuf,
     sync::Arc,
 };
@@ -49,9 +47,9 @@ use zng_txt::Txt;
 #[doc(hidden)]
 pub use zng_var as var;
 
-pub use zng_time::{DInstant, Deadline, InstantMode, INSTANT};
+pub use zng_time::{DInstant, Deadline, INSTANT, InstantMode};
 
-use update::{EventUpdate, InfoUpdates, LayoutUpdates, RenderUpdates, UpdatesTrace, WidgetUpdates, UPDATES};
+use update::{EventUpdate, InfoUpdates, LayoutUpdates, RenderUpdates, UPDATES, UpdatesTrace, WidgetUpdates};
 use window::WindowMode;
 use zng_app_context::{AppId, AppScope, LocalContext};
 use zng_task::UiTask;
@@ -101,12 +99,12 @@ pub mod __proc_macro_util {
         pub mod builder {
             #[doc(hidden)]
             pub use crate::widget::builder::{
-                getter_var, iter_input_build_actions, nest_group_items, new_dyn_other, new_dyn_ui_node, new_dyn_ui_node_list, new_dyn_var,
-                new_dyn_widget_handler, panic_input, state_var, ui_node_list_to_args, ui_node_to_args, value_to_args, var_to_args,
-                when_condition_expr_var, widget_handler_to_args, AnyArcWidgetHandler, ArcWidgetHandler, Importance, InputKind,
-                PropertyArgs, PropertyId, PropertyInfo, PropertyInput, PropertyInputTypes, PropertyNewArgs, SourceLocation,
-                UiNodeInWhenExprError, UiNodeListInWhenExprError, WgtInfo, WhenInput, WhenInputMember, WhenInputVar,
-                WidgetHandlerInWhenExprError, WidgetType,
+                AnyArcWidgetHandler, ArcWidgetHandler, Importance, InputKind, PropertyArgs, PropertyId, PropertyInfo, PropertyInput,
+                PropertyInputTypes, PropertyNewArgs, SourceLocation, UiNodeInWhenExprError, UiNodeListInWhenExprError, WgtInfo, WhenInput,
+                WhenInputMember, WhenInputVar, WidgetHandlerInWhenExprError, WidgetType, getter_var, iter_input_build_actions,
+                nest_group_items, new_dyn_other, new_dyn_ui_node, new_dyn_ui_node_list, new_dyn_var, new_dyn_widget_handler, panic_input,
+                state_var, ui_node_list_to_args, ui_node_to_args, value_to_args, var_to_args, when_condition_expr_var,
+                widget_handler_to_args,
             };
         }
 
@@ -118,7 +116,7 @@ pub mod __proc_macro_util {
         #[doc(hidden)]
         pub mod node {
             pub use crate::widget::node::{
-                ui_node_list_default, ArcNode, ArcNodeList, BoxedUiNode, BoxedUiNodeList, NilUiNode, UiNode, UiNodeList, UiVec,
+                ArcNode, ArcNodeList, BoxedUiNode, BoxedUiNodeList, NilUiNode, UiNode, UiNodeList, UiVec, ui_node_list_default,
             };
         }
 
@@ -168,7 +166,7 @@ pub mod __proc_macro_util {
     #[doc(hidden)]
     pub mod var {
         #[doc(hidden)]
-        pub use crate::var::{expr_var, AnyVar, AnyVarValue, BoxedVar, Var};
+        pub use crate::var::{AnyVar, AnyVarValue, BoxedVar, Var, expr_var};
 
         #[doc(hidden)]
         pub mod animation {
diff --git a/crates/zng-app/src/render.rs b/crates/zng-app/src/render.rs
index fb8fbdc54..9968d822a 100644
--- a/crates/zng-app/src/render.rs
+++ b/crates/zng-app/src/render.rs
@@ -7,40 +7,39 @@ use crate::{
     window::WINDOW,
 };
 use zng_color::{
-    colors,
+    RenderMixBlendMode, Rgba, colors,
     filter::RenderFilter,
     gradient::{RenderExtendMode, RenderGradientStop},
-    RenderMixBlendMode, Rgba,
 };
 use zng_layout::unit::{
-    euclid, AngleRadian, Factor, FactorUnits, Px, PxCornerRadius, PxLine, PxPoint, PxRect, PxSideOffsets, PxSize, PxTransform, PxVector,
+    AngleRadian, Factor, FactorUnits, Px, PxCornerRadius, PxLine, PxPoint, PxRect, PxSideOffsets, PxSize, PxTransform, PxVector, euclid,
 };
 use zng_task::rayon::iter::{ParallelBridge, ParallelIterator};
 use zng_unique_id::{impl_unique_id_bytemuck, unique_id_32};
-use zng_var::{impl_from_and_into_var, Var, VarCapability, VarValue};
+use zng_var::{Var, VarCapability, VarValue, impl_from_and_into_var};
 use zng_view_api::{
+    ReferenceFrameId as RenderReferenceFrameId, ViewProcessGen,
     api_extension::{ApiExtensionId, ApiExtensionPayload},
     config::FontAntiAliasing,
     display_list::{DisplayList, DisplayListBuilder, FilterOp, NinePatchSource, ReuseStart},
     font::{GlyphInstance, GlyphOptions},
     window::FrameId,
-    ReferenceFrameId as RenderReferenceFrameId, ViewProcessGen,
 };
 
 use crate::{
     update::{RenderUpdates, UpdateFlags},
     view_process::ViewRenderer,
     widget::{
-        base::{Parallel, PARALLEL_VAR},
+        WIDGET, WidgetId,
+        base::{PARALLEL_VAR, Parallel},
         border::{self, BorderSides},
         info::{HitTestClips, ParallelBuilder, WidgetInfo, WidgetInfoTree, WidgetRenderInfo},
-        WidgetId, WIDGET,
     },
 };
 
 pub use zng_view_api::{
-    display_list::{FrameValue, FrameValueUpdate, ReuseRange},
     ImageRendering, RepeatMode, TransformStyle,
+    display_list::{FrameValue, FrameValueUpdate, ReuseRange},
 };
 
 /// A text font.
@@ -184,11 +183,11 @@ impl FrameBuilder {
         let auto_hide_rect = PxRect::from_size(root_size).inflate(root_size.width, root_size.height);
         root_bounds.set_outer_transform(PxTransform::identity(), info_tree);
 
-        let gen = renderer
+        let vp_gen = renderer
             .as_ref()
             .and_then(|r| r.generation().ok())
             .unwrap_or(ViewProcessGen::INVALID);
-        let view_process_has_frame = gen != ViewProcessGen::INVALID && gen == info_tree.view_process_gen();
+        let view_process_has_frame = vp_gen != ViewProcessGen::INVALID && vp_gen == info_tree.view_process_gen();
 
         FrameBuilder {
             render_widgets,
@@ -574,11 +573,7 @@ impl FrameBuilder {
 
                     let transform_patch = self.undo_prev_outer_transform.and_then(|t| {
                         let t = t.then(&self.outer_transform);
-                        if t != PxTransform::identity() {
-                            Some(t)
-                        } else {
-                            None
-                        }
+                        if t != PxTransform::identity() { Some(t) } else { None }
                     });
 
                     let current_wgt = tree.get(id).unwrap();
@@ -2290,8 +2285,8 @@ enum RenderLineCommand {
 }
 impl border::LineStyle {
     fn render_command(self) -> RenderLineCommand {
-        use border::LineStyle as LS;
         use RenderLineCommand::*;
+        use border::LineStyle as LS;
         match self {
             LS::Solid => Line(zng_view_api::LineStyle::Solid),
             LS::Double => Border(zng_view_api::BorderStyle::Double),
diff --git a/crates/zng-app/src/running.rs b/crates/zng-app/src/running.rs
index ec0becdd0..467894eaa 100644
--- a/crates/zng-app/src/running.rs
+++ b/crates/zng-app/src/running.rs
@@ -9,28 +9,28 @@ use std::{
 
 use crate::Deadline;
 use parking_lot::Mutex;
-use zng_app_context::{app_local, AppScope};
+use zng_app_context::{AppScope, app_local};
 use zng_task::DEADLINE_APP;
-use zng_time::{InstantMode, INSTANT_APP};
+use zng_time::{INSTANT_APP, InstantMode};
 use zng_txt::Txt;
-use zng_var::{response_var, ArcVar, ReadOnlyArcVar, ResponderVar, ResponseVar, Var as _, VARS, VARS_APP};
+use zng_var::{ArcVar, ReadOnlyArcVar, ResponderVar, ResponseVar, VARS, VARS_APP, Var as _, response_var};
 
 use crate::{
+    APP, AppControlFlow, AppEventObserver, AppExtension, AppExtensionsInfo, DInstant, INSTANT,
     event::{
-        command, event, AnyEventArgs, AppDisconnected, CommandHandle, CommandInfoExt, CommandNameExt, EventPropagationHandle,
-        TimeoutOrAppDisconnected, EVENTS,
+        AnyEventArgs, AppDisconnected, CommandHandle, CommandInfoExt, CommandNameExt, EVENTS, EventPropagationHandle,
+        TimeoutOrAppDisconnected, command, event,
     },
     event_args,
-    shortcut::shortcut,
     shortcut::CommandShortcutExt,
+    shortcut::shortcut,
     timer::TimersService,
     update::{
-        ContextUpdates, EventUpdate, InfoUpdates, LayoutUpdates, RenderUpdates, UpdateOp, UpdateTrace, UpdatesTrace, WidgetUpdates, UPDATES,
+        ContextUpdates, EventUpdate, InfoUpdates, LayoutUpdates, RenderUpdates, UPDATES, UpdateOp, UpdateTrace, UpdatesTrace, WidgetUpdates,
     },
     view_process::{raw_device_events::DeviceId, *},
     widget::WidgetId,
     window::WindowId,
-    AppControlFlow, AppEventObserver, AppExtension, AppExtensionsInfo, DInstant, APP, INSTANT,
 };
 
 /// Represents a running app controlled by an external event loop.
@@ -519,7 +519,9 @@ impl<E: AppExtension> RunningApp<E> {
             }
 
             Event::RecoveredFromComponentPanic { component, recover, panic } => {
-                tracing::error!("view-process recovered from internal component panic\n  component: {component}\n  recover: {recover}\n```panic\n{panic}\n```");
+                tracing::error!(
+                    "view-process recovered from internal component panic\n  component: {component}\n  recover: {recover}\n```panic\n{panic}\n```"
+                );
             }
 
             // Others
@@ -632,9 +634,9 @@ impl<E: AppExtension> RunningApp<E> {
                     self.notify_event(VIEW_PROCESS_SUSPENDED_EVENT.new_update(args), observer);
                     APP_PROCESS_SV.read().is_suspended.set(true);
                 }
-                zng_view_api::Event::Disconnected(gen) => {
+                zng_view_api::Event::Disconnected(vp_gen) => {
                     // update ViewProcess immediately.
-                    VIEW_PROCESS.handle_disconnect(gen);
+                    VIEW_PROCESS.handle_disconnect(vp_gen);
                 }
                 ev => {
                     if let Some(last) = self.pending_view_events.last_mut() {
@@ -1328,36 +1330,38 @@ pub(crate) fn check_deadlock() {
         return;
     }
 
-    thread::spawn(|| loop {
-        thread::sleep(Duration::from_secs(10));
+    thread::spawn(|| {
+        loop {
+            thread::sleep(Duration::from_secs(10));
 
-        let deadlocks = deadlock::check_deadlock();
-        if deadlocks.is_empty() {
-            continue;
-        }
+            let deadlocks = deadlock::check_deadlock();
+            if deadlocks.is_empty() {
+                continue;
+            }
 
-        use std::fmt::Write;
-        let mut msg = String::new();
+            use std::fmt::Write;
+            let mut msg = String::new();
 
-        let _ = writeln!(&mut msg, "{} deadlocks detected", deadlocks.len());
-        for (i, threads) in deadlocks.iter().enumerate() {
-            let _ = writeln!(&mut msg, "Deadlock #{}, {} threads", i, threads.len());
-            for t in threads {
-                let _ = writeln!(&mut msg, "Thread Id {:#?}", t.thread_id());
-                let _ = writeln!(&mut msg, "{:#?}", t.backtrace());
+            let _ = writeln!(&mut msg, "{} deadlocks detected", deadlocks.len());
+            for (i, threads) in deadlocks.iter().enumerate() {
+                let _ = writeln!(&mut msg, "Deadlock #{}, {} threads", i, threads.len());
+                for t in threads {
+                    let _ = writeln!(&mut msg, "Thread Id {:#?}", t.thread_id());
+                    let _ = writeln!(&mut msg, "{:#?}", t.backtrace());
+                }
             }
-        }
 
-        #[cfg(not(feature = "test_util"))]
-        eprint!("{msg}");
+            #[cfg(not(feature = "test_util"))]
+            eprint!("{msg}");
 
-        #[cfg(feature = "test_util")]
-        {
-            // test runner captures output and ignores panics in background threads, so
-            // we write directly to stderr and exit the process.
-            use std::io::Write;
-            let _ = write!(&mut std::io::stderr(), "{msg}");
-            zng_env::exit(-1);
+            #[cfg(feature = "test_util")]
+            {
+                // test runner captures output and ignores panics in background threads, so
+                // we write directly to stderr and exit the process.
+                use std::io::Write;
+                let _ = write!(&mut std::io::stderr(), "{msg}");
+                zng_env::exit(-1);
+            }
         }
     });
 }
diff --git a/crates/zng-app/src/shortcut.rs b/crates/zng-app/src/shortcut.rs
index 58d99681b..9c6c7146d 100644
--- a/crates/zng-app/src/shortcut.rs
+++ b/crates/zng-app/src/shortcut.rs
@@ -8,7 +8,7 @@ use std::fmt;
 use bitflags::bitflags;
 use zng_txt::{ToTxt, Txt};
 use zng_unique_id::static_id;
-use zng_var::{impl_from_and_into_var, BoxedVar, Var};
+use zng_var::{BoxedVar, Var, impl_from_and_into_var};
 
 #[doc(hidden)]
 pub use zng_view_api::keyboard::{Key, KeyCode};
diff --git a/crates/zng-app/src/third_party.rs b/crates/zng-app/src/third_party.rs
index 5168cf7f0..b77e21dce 100644
--- a/crates/zng-app/src/third_party.rs
+++ b/crates/zng-app/src/third_party.rs
@@ -2,10 +2,10 @@
 
 use zng_app_context::app_local;
 pub use zng_tp_licenses::{License, LicenseUsed, User, UserLicense};
-use zng_var::{var, ArcVar, Var as _};
+use zng_var::{ArcVar, Var as _, var};
 
 use crate::{
-    event::{command, CommandNameExt as _},
+    event::{CommandNameExt as _, command},
     view_process::VIEW_PROCESS,
 };
 
diff --git a/crates/zng-app/src/timer.rs b/crates/zng-app/src/timer.rs
index cc1039a53..d071357fc 100644
--- a/crates/zng-app/src/timer.rs
+++ b/crates/zng-app/src/timer.rs
@@ -7,13 +7,11 @@
 use crate::Deadline;
 use parking_lot::Mutex;
 use std::{
-    fmt,
-    future::Future,
-    mem,
+    fmt, mem,
     pin::Pin,
     sync::{
-        atomic::{AtomicBool, AtomicUsize, Ordering},
         Arc,
+        atomic::{AtomicBool, AtomicUsize, Ordering},
     },
     task::Waker,
     time::Duration,
@@ -21,12 +19,12 @@ use std::{
 use zng_app_context::app_local;
 use zng_handle::{Handle, HandleOwner, WeakHandle};
 use zng_time::{DInstant, INSTANT, INSTANT_APP};
-use zng_var::{types::WeakArcVar, var, ReadOnlyArcVar, Var, WeakVar};
+use zng_var::{ReadOnlyArcVar, Var, WeakVar, types::WeakArcVar, var};
 
 use crate::{
+    LoopTimer,
     handler::{AppHandler, AppHandlerArgs, AppWeakHandle},
     update::UPDATES,
-    LoopTimer,
 };
 
 struct DeadlineHandlerEntry {
@@ -96,7 +94,7 @@ impl TimersService {
         timer.read_only()
     }
 
-    fn wait_deadline(&mut self, deadline: Deadline) -> impl std::future::Future<Output = ()> + Send + Sync {
+    fn wait_deadline(&mut self, deadline: Deadline) -> impl Future<Output = ()> + Send + Sync + use<> {
         let deadline = Arc::new(WaitDeadline {
             deadline,
             wakers: Mutex::new(vec![]),
@@ -174,7 +172,7 @@ impl TimersService {
                 if !t.handle.is_dropped() && !t.handle.data().paused.load(Ordering::Relaxed) {
                     // not dropped and not paused
                     var.with(|t| {
-                        let deadline = t.0 .0.data().deadline.lock();
+                        let deadline = t.0.0.data().deadline.lock();
                         timer.register(deadline.current_deadline());
                     });
                 }
@@ -239,10 +237,10 @@ impl TimersService {
                 if !t.handle.is_dropped() {
                     if !t.handle.data().paused.load(Ordering::Relaxed) {
                         var.with(|t| {
-                            let mut deadline = t.0 .0.data().deadline.lock();
+                            let mut deadline = t.0.0.data().deadline.lock();
 
                             if timer.elapsed(deadline.current_deadline()) {
-                                t.0 .0.data().count.fetch_add(1, Ordering::Relaxed);
+                                t.0.0.data().count.fetch_add(1, Ordering::Relaxed);
                                 var.update();
 
                                 deadline.last = now;
@@ -482,7 +480,7 @@ impl TIMERS {
     /// Implementation of the [`task::deadline`] function when called from app threads.
     ///
     /// [`task::deadline`]: zng_task::deadline
-    pub fn wait_deadline(&self, deadline: impl Into<Deadline>) -> impl std::future::Future<Output = ()> + Send + Sync {
+    pub fn wait_deadline(&self, deadline: impl Into<Deadline>) -> impl Future<Output = ()> + Send + Sync + 'static {
         TIMERS_SV.write().wait_deadline(deadline.into())
     }
 }
@@ -1052,6 +1050,6 @@ impl TimerArgs {
     }
 }
 
-pub(crate) fn deadline_service(deadline: Deadline) -> Pin<Box<dyn std::future::Future<Output = ()> + Send + Sync>> {
+pub(crate) fn deadline_service(deadline: Deadline) -> Pin<Box<dyn Future<Output = ()> + Send + Sync>> {
     Box::pin(TIMERS.wait_deadline(deadline))
 }
diff --git a/crates/zng-app/src/update.rs b/crates/zng-app/src/update.rs
index 7b492282e..3e4d21bcc 100644
--- a/crates/zng-app/src/update.rs
+++ b/crates/zng-app/src/update.rs
@@ -1,9 +1,9 @@
 //! App updates API.
 
 use std::{
-    collections::{hash_map, HashMap},
+    collections::{HashMap, hash_map},
     fmt, mem,
-    sync::{atomic::AtomicBool, Arc},
+    sync::{Arc, atomic::AtomicBool},
     task::Waker,
 };
 
@@ -14,16 +14,16 @@ use zng_unique_id::IdSet;
 use zng_var::VARS_APP;
 
 use crate::{
+    AppEventSender, AppExtension, LoopTimer,
     event::{AnyEvent, AnyEventArgs, AppDisconnected, EVENTS, EVENTS_SV},
-    handler::{async_app_hn_once, AppHandler, AppHandlerArgs, AppWeakHandle},
+    handler::{AppHandler, AppHandlerArgs, AppWeakHandle, async_app_hn_once},
     timer::TIMERS_SV,
     widget::{
+        WIDGET, WidgetId,
         info::{InteractionPath, WidgetInfo, WidgetInfoTree, WidgetPath},
         node::{BoxedUiNode, UiNode},
-        WidgetId, WIDGET,
     },
-    window::{WindowId, WINDOW},
-    AppEventSender, AppExtension, LoopTimer,
+    window::{WINDOW, WindowId},
 };
 
 /// Represents all the widgets and windows marked to receive an update.
@@ -1336,7 +1336,7 @@ impl UPDATES {
     /// Schedule the `future` to run in the app context, each future awake work runs as a *preview* update.
     ///
     /// Returns a handle that can be dropped to cancel execution.
-    pub fn run<F: std::future::Future<Output = ()> + Send + 'static>(&self, future: F) -> OnUpdateHandle {
+    pub fn run<F: Future<Output = ()> + Send + 'static>(&self, future: F) -> OnUpdateHandle {
         self.run_hn_once(async_app_hn_once!(|_| future.await))
     }
 
diff --git a/crates/zng-app/src/view_process.rs b/crates/zng-app/src/view_process.rs
index 02a5f17e7..bc80fa675 100644
--- a/crates/zng-app/src/view_process.rs
+++ b/crates/zng-app/src/view_process.rs
@@ -22,7 +22,7 @@ use zng_task::SignalOnce;
 use zng_txt::Txt;
 use zng_var::ResponderVar;
 use zng_view_api::{
-    self,
+    self, DragDropId, Event, FocusResult, ViewProcessGen, ViewProcessOffline,
     api_extension::{ApiExtensionId, ApiExtensionName, ApiExtensionPayload, ApiExtensionRecvError, ApiExtensions},
     config::{AnimationsConfig, ChromeConfig, ColorsConfig, FontAntiAliasing, LocaleConfig, MultiClickConfig, TouchConfig},
     dialog::{FileDialog, FileDialogResponse, MsgDialog, MsgDialogResponse},
@@ -34,20 +34,19 @@ use zng_view_api::{
         CursorIcon, FocusIndicator, FrameRequest, FrameUpdateRequest, HeadlessOpenData, HeadlessRequest, MonitorInfo, RenderMode,
         ResizeDirection, VideoMode, WindowButton, WindowRequest, WindowStateAll,
     },
-    DragDropId, Event, FocusResult, ViewProcessGen, ViewProcessOffline,
 };
 
+pub(crate) use zng_view_api::{Controller, DeviceId as ApiDeviceId, window::MonitorId as ApiMonitorId, window::WindowId as ApiWindowId};
 use zng_view_api::{
     clipboard::{ClipboardData, ClipboardError, ClipboardType},
     config::KeyRepeatConfig,
     font::{FontFaceId, FontId, FontVariationName},
     image::{ImageId, ImageLoadedData},
 };
-pub(crate) use zng_view_api::{window::MonitorId as ApiMonitorId, window::WindowId as ApiWindowId, Controller, DeviceId as ApiDeviceId};
 
 use self::raw_device_events::DeviceId;
 
-use super::{AppId, APP};
+use super::{APP, AppId};
 
 /// Connection to the running view-process for the context app.
 #[expect(non_camel_case_types)]
@@ -293,8 +292,8 @@ impl VIEW_PROCESS {
     /// The process will exit if the view-process was killed by the user.
     ///
     /// [`Event::Disconnected`]: zng_view_api::Event::Disconnected
-    pub fn handle_disconnect(&self, gen: ViewProcessGen) {
-        self.write().process.handle_disconnect(gen)
+    pub fn handle_disconnect(&self, vp_gen: ViewProcessGen) {
+        self.write().process.handle_disconnect(vp_gen)
     }
 
     /// Spawn the View Process.
@@ -356,10 +355,10 @@ impl VIEW_PROCESS {
     /// The view-process becomes online only after this call.
     ///
     /// [`Event::Inited`]: zng_view_api::Event::Inited
-    pub(super) fn handle_inited(&self, gen: ViewProcessGen, extensions: ApiExtensions) {
+    pub(super) fn handle_inited(&self, vp_gen: ViewProcessGen, extensions: ApiExtensions) {
         let mut me = self.write();
         me.extensions = extensions;
-        me.process.handle_inited(gen);
+        me.process.handle_inited(vp_gen);
     }
 
     pub(super) fn handle_suspended(&self) {
@@ -548,10 +547,10 @@ impl VIEW_PROCESS {
 impl ViewProcessService {
     #[must_use = "if `true` all current WinId, DevId and MonId are invalid"]
     fn check_generation(&mut self) -> bool {
-        let gen = self.process.generation();
-        let invalid = gen != self.data_generation;
+        let vp_gen = self.process.generation();
+        let invalid = vp_gen != self.data_generation;
         if invalid {
-            self.data_generation = gen;
+            self.data_generation = vp_gen;
             self.device_ids.clear();
             self.monitor_ids.clear();
         }
diff --git a/crates/zng-app/src/view_process/raw_device_events.rs b/crates/zng-app/src/view_process/raw_device_events.rs
index dcf361e97..9cc9d0e1a 100644
--- a/crates/zng-app/src/view_process/raw_device_events.rs
+++ b/crates/zng-app/src/view_process/raw_device_events.rs
@@ -12,9 +12,9 @@ use crate::event::*;
 
 use zng_layout::unit::euclid;
 use zng_view_api::{
+    AxisId,
     keyboard::{KeyCode, KeyState},
     mouse::{ButtonId, ButtonState, MouseScrollDelta},
-    AxisId,
 };
 
 use once_cell::sync::Lazy;
diff --git a/crates/zng-app/src/view_process/raw_events.rs b/crates/zng-app/src/view_process/raw_events.rs
index 5e98168f6..56ba66d52 100644
--- a/crates/zng-app/src/view_process/raw_events.rs
+++ b/crates/zng-app/src/view_process/raw_events.rs
@@ -17,6 +17,7 @@
 use zng_layout::unit::{DipPoint, DipSideOffsets, DipSize, Factor, PxPoint, PxRect};
 use zng_txt::Txt;
 use zng_view_api::{
+    AxisId, DragDropId, Ime,
     api_extension::{ApiExtensionId, ApiExtensionPayload},
     config::{
         AnimationsConfig, ChromeConfig, ColorsConfig, FontAntiAliasing, KeyRepeatConfig, LocaleConfig, MultiClickConfig, TouchConfig,
@@ -26,7 +27,6 @@ use zng_view_api::{
     mouse::{ButtonState, MouseButton, MouseScrollDelta},
     touch::{TouchPhase, TouchUpdate},
     window::{EventCause, FrameId, FrameWaitId, HeadlessOpenData, MonitorInfo, WindowStateAll},
-    AxisId, DragDropId, Ime,
 };
 
 use crate::{
@@ -34,7 +34,7 @@ use crate::{
     window::{MonitorId, WindowId},
 };
 
-use super::{raw_device_events::DeviceId, ViewHeadless, ViewImage, ViewWindow, WindowOpenData};
+use super::{ViewHeadless, ViewImage, ViewWindow, WindowOpenData, raw_device_events::DeviceId};
 
 event_args! {
     /// Arguments for the [`RAW_KEY_INPUT_EVENT`].
diff --git a/crates/zng-app/src/widget.rs b/crates/zng-app/src/widget.rs
index 90d29e8b1..12054ce18 100644
--- a/crates/zng-app/src/widget.rs
+++ b/crates/zng-app/src/widget.rs
@@ -14,22 +14,21 @@ use atomic::Atomic;
 use parking_lot::{Mutex, RwLock};
 use std::{
     borrow::Cow,
-    future::IntoFuture,
-    sync::{atomic::Ordering::Relaxed, Arc},
+    sync::{Arc, atomic::Ordering::Relaxed},
 };
 use zng_app_context::context_local;
 use zng_handle::Handle;
 use zng_layout::unit::{DipPoint, DipToPx as _, Layout1d, Layout2d, Px, PxPoint, PxTransform};
 use zng_state_map::{OwnedStateMap, StateId, StateMapMut, StateMapRef, StateValue};
 use zng_task::UiTask;
-use zng_txt::{formatx, Txt};
+use zng_txt::{Txt, formatx};
 use zng_var::{AnyVar, AnyVarHookArgs, AnyVarValue, ResponseVar, Var, VarHandle, VarHandles, VarValue};
 use zng_view_api::display_list::ReuseRange;
 
 use crate::{
     event::{Event, EventArgs, EventHandle, EventHandles},
-    handler::{app_hn, app_hn_once, AppHandler, AppHandlerArgs},
-    update::{LayoutUpdates, RenderUpdates, UpdateFlags, UpdateOp, UpdatesTrace, UPDATES},
+    handler::{AppHandler, AppHandlerArgs, app_hn, app_hn_once},
+    update::{LayoutUpdates, RenderUpdates, UPDATES, UpdateFlags, UpdateOp, UpdatesTrace},
     window::WINDOW,
 };
 
@@ -662,11 +661,7 @@ impl WIDGET {
 
     /// Get the widget ID, if called inside a widget.
     pub fn try_id(&self) -> Option<WidgetId> {
-        if self.is_in_widget() {
-            Some(WIDGET_CTX.get().id)
-        } else {
-            None
-        }
+        if self.is_in_widget() { Some(WIDGET_CTX.get().id) } else { None }
     }
 
     /// Gets a text with detailed path to the current widget.
@@ -1678,12 +1673,12 @@ pub trait UiTaskWidget<R> {
     /// [`UiNode::info`]: crate::widget::node::UiNode::info
     fn new<F>(target: Option<WidgetId>, task: impl IntoFuture<IntoFuture = F>) -> Self
     where
-        F: std::future::Future<Output = R> + Send + 'static;
+        F: Future<Output = R> + Send + 'static;
 }
 impl<R> UiTaskWidget<R> for UiTask<R> {
     fn new<F>(target: Option<WidgetId>, task: impl IntoFuture<IntoFuture = F>) -> Self
     where
-        F: std::future::Future<Output = R> + Send + 'static,
+        F: Future<Output = R> + Send + 'static,
     {
         UiTask::new_raw(UPDATES.waker(target), task)
     }
diff --git a/crates/zng-app/src/widget/base.rs b/crates/zng-app/src/widget/base.rs
index 9920fc09c..1a8932161 100644
--- a/crates/zng-app/src/widget/base.rs
+++ b/crates/zng-app/src/widget/base.rs
@@ -5,20 +5,20 @@ use std::{any::TypeId, cell::RefCell, fmt};
 use crate::{source_location, widget::WidgetId};
 
 use super::{
+    WIDGET,
     builder::{
         AnyPropertyBuildAction, Importance, PropertyArgs, PropertyId, SourceLocation, WhenBuildAction, WhenInfo, WhenInput, WidgetBuilder,
         WidgetType,
     },
     node::{FillUiNode, UiNode, UiNodeOp},
-    WIDGET,
 };
 
 use crate::widget::{
-    builder::{property_id, NestGroup},
+    builder::{NestGroup, property_id},
     node::match_node,
     property,
 };
-use zng_var::{context_var, impl_from_and_into_var, BoxedVar, IntoValue};
+use zng_var::{BoxedVar, IntoValue, context_var, impl_from_and_into_var};
 
 /// Base widget.
 ///
@@ -70,7 +70,7 @@ impl WidgetBase {
     /// Build the widget.
     ///
     /// After this call trying to set a property will panic.
-    pub fn widget_build(&mut self) -> impl UiNode {
+    pub fn widget_build(&mut self) -> impl UiNode + use<> {
         let mut wgt = self.widget_take();
         wgt.push_build_action(|wgt| {
             if !wgt.has_child() {
@@ -145,8 +145,8 @@ impl WidgetBase {
             when: RefCell::new(self.when.borrow_mut().take()),
         };
         f(&mut inner);
-        *self.builder.borrow_mut() = inner.builder.into_inner().take();
-        *self.when.borrow_mut() = inner.when.into_inner().take();
+        *self.builder.borrow_mut() = inner.builder.into_inner();
+        *self.when.borrow_mut() = inner.when.into_inner();
         debug_assert_eq!(self.importance, inner.importance);
     }
 
@@ -282,7 +282,10 @@ macro_rules! WidgetBaseMacro__ {
                 let mut wgt__ = $crate::widget::base::WidgetBase::widget_new();
                 let wgt__ = &mut wgt__;
             }
-            build { wgt__.widget_build() }
+            build {
+                let wgt__ = wgt__.widget_build();
+                wgt__
+            }
             set { $($tt)* }
         }
     }
@@ -447,9 +450,9 @@ pub mod node {
         render::{FrameBuilder, FrameUpdate, FrameValueKey},
         update::{EventUpdate, WidgetUpdates},
         widget::{
+            WidgetCtx, WidgetUpdateMode,
             info::{WidgetInfoBuilder, WidgetLayout, WidgetMeasure},
             node::BoxedUiNode,
-            WidgetCtx, WidgetUpdateMode,
         },
     };
 
diff --git a/crates/zng-app/src/widget/border.rs b/crates/zng-app/src/widget/border.rs
index 3af16fa65..22b5c759f 100644
--- a/crates/zng-app/src/widget/border.rs
+++ b/crates/zng-app/src/widget/border.rs
@@ -3,24 +3,25 @@
 use std::{fmt, mem, sync::Arc};
 
 use zng_app_context::context_local;
-use zng_color::{colors, Hsla, Hsva, Rgba};
+use zng_color::{Hsla, Hsva, Rgba, colors};
 use zng_layout::{
-    context::{LayoutMask, LAYOUT},
+    context::{LAYOUT, LayoutMask},
     unit::{
         Factor, FactorPercent, FactorSideOffsets, FactorUnits, Layout2d, Length, PxCornerRadius, PxPoint, PxRect, PxSideOffsets, PxSize,
         Size,
     },
 };
 use zng_var::{
-    animation::{easing::EasingStep, Transitionable},
-    context_var, impl_from_and_into_var, Var,
+    Var,
+    animation::{Transitionable, easing::EasingStep},
+    context_var, impl_from_and_into_var,
 };
 
 pub use zng_view_api::LineOrientation;
 
 use crate::widget::VarLayout;
 
-use super::{info::WidgetBorderInfo, WidgetId, WIDGET};
+use super::{WIDGET, WidgetId, info::WidgetBorderInfo};
 
 /// Represents a line style.
 #[derive(Clone, Copy, PartialEq, serde::Serialize, serde::Deserialize)]
@@ -147,11 +148,7 @@ impl From<BorderStyle> for zng_view_api::BorderStyle {
 impl Transitionable for BorderStyle {
     /// Returns `self` for `step < 1.fct()` or `to` for `step >= 1.fct()`.
     fn lerp(self, to: &Self, step: EasingStep) -> Self {
-        if step < 1.fct() {
-            self
-        } else {
-            *to
-        }
+        if step < 1.fct() { self } else { *to }
     }
 }
 
diff --git a/crates/zng-app/src/widget/builder.rs b/crates/zng-app/src/widget/builder.rs
index a6e8056ae..3f927b9f4 100644
--- a/crates/zng-app/src/widget/builder.rs
+++ b/crates/zng-app/src/widget/builder.rs
@@ -3,7 +3,7 @@
 use crate::{handler::WidgetHandler, widget::node::WhenUiNodeListBuilder};
 use std::{
     any::{Any, TypeId},
-    collections::{hash_map, HashMap},
+    collections::{HashMap, hash_map},
     fmt, ops,
     sync::Arc,
 };
@@ -216,18 +216,17 @@ use parking_lot::Mutex;
 pub use widget_type;
 use zng_app_context::context_local;
 use zng_app_proc_macros::widget;
-use zng_txt::{formatx, Txt};
-use zng_unique_id::{unique_id_32, IdEntry, IdMap, IdSet};
+use zng_txt::{Txt, formatx};
+use zng_unique_id::{IdEntry, IdMap, IdSet, unique_id_32};
 use zng_var::{
-    impl_from_and_into_var,
+    AnyVar, AnyVarValue, BoxedAnyVar, BoxedVar, ContextInitHandle, IntoValue, IntoVar, LocalVar, Var, VarValue, impl_from_and_into_var,
     types::{AnyWhenVarBuilder, ContextualizedVar, WeakContextInitHandle},
-    AnyVar, AnyVarValue, BoxedAnyVar, BoxedVar, ContextInitHandle, IntoValue, IntoVar, LocalVar, Var, VarValue,
 };
 
 use super::{
     base::{WidgetBase, WidgetExt},
     node::{
-        with_new_context_init_id, ArcNode, ArcNodeList, BoxedUiNode, BoxedUiNodeList, FillUiNode, UiNode, UiNodeList, WhenUiNodeBuilder,
+        ArcNode, ArcNodeList, BoxedUiNode, BoxedUiNodeList, FillUiNode, UiNode, UiNodeList, WhenUiNodeBuilder, with_new_context_init_id,
     },
 };
 
diff --git a/crates/zng-app/src/widget/easing.rs b/crates/zng-app/src/widget/easing.rs
index 22a08184b..a2b03a143 100644
--- a/crates/zng-app/src/widget/easing.rs
+++ b/crates/zng-app/src/widget/easing.rs
@@ -3,12 +3,12 @@ use std::{any::Any, sync::Arc, time::Duration};
 use super::builder::*;
 use zng_layout::unit::*;
 use zng_var::{
+    BoxedVar, Var, VarValue,
     animation::{
-        easing::{EasingStep, EasingTime},
         Transitionable,
+        easing::{EasingStep, EasingTime},
     },
     types::{ArcWhenVar, ContextualizedVar},
-    BoxedVar, Var, VarValue,
 };
 
 pub use zng_app_proc_macros::easing;
diff --git a/crates/zng-app/src/widget/info.rs b/crates/zng-app/src/widget/info.rs
index d2af1ccd7..c325a1d12 100644
--- a/crates/zng-app/src/widget/info.rs
+++ b/crates/zng-app/src/widget/info.rs
@@ -23,22 +23,22 @@ use zng_clone_move::clmv;
 use zng_layout::{
     context::{LayoutMask, LayoutMetricsSnapshot},
     unit::{
-        euclid, DistanceKey, Factor, FactorUnits, Orientation2D, Px, PxBox, PxCornerRadius, PxPoint, PxRect, PxSideOffsets, PxSize,
-        PxTransform, PxVector,
+        DistanceKey, Factor, FactorUnits, Orientation2D, Px, PxBox, PxCornerRadius, PxPoint, PxRect, PxSideOffsets, PxSize, PxTransform,
+        PxVector, euclid,
     },
 };
 use zng_state_map::{OwnedStateMap, StateMapRef};
-use zng_txt::{formatx, Txt};
+use zng_txt::{Txt, formatx};
 use zng_unique_id::{IdEntry, IdMap};
 use zng_var::impl_from_and_into_var;
-use zng_view_api::{display_list::FrameValueUpdate, window::FrameId, ViewProcessGen};
+use zng_view_api::{ViewProcessGen, display_list::FrameValueUpdate, window::FrameId};
 
-use crate::{render::TransformStyle, window::WindowId, DInstant};
+use crate::{DInstant, render::TransformStyle, window::WindowId};
 
 pub use self::hit::RelativeHitZ;
 use self::{access::AccessEnabled, hit::ParallelSegmentId, iter::TreeIterator};
 
-use super::{node::ZIndex, WidgetId};
+use super::{WidgetId, node::ZIndex};
 
 /// Stats over the lifetime of a widget info tree.
 ///
@@ -227,7 +227,7 @@ impl WidgetInfoTree {
     }
 
     /// Iterator over all widgets with inner-bounds not fully contained by their parent inner bounds.
-    pub fn out_of_bounds(&self) -> impl std::iter::ExactSizeIterator<Item = WidgetInfo> {
+    pub fn out_of_bounds(&self) -> impl std::iter::ExactSizeIterator<Item = WidgetInfo> + 'static + use<> {
         let out = self.0.frame.read().out_of_bounds.clone();
         let me = self.clone();
         (0..out.len()).map(move |i| WidgetInfo::new(me.clone(), out[i]))
@@ -296,8 +296,8 @@ impl WidgetInfoTree {
         frame.spatial_bounds = spatial_bounds;
 
         frame.scale_factor = scale_factor;
-        if let Some(gen) = view_process_gen {
-            frame.view_process_gen = gen;
+        if let Some(vp_gen) = view_process_gen {
+            frame.view_process_gen = vp_gen;
         }
         if let Some(w) = widget_count_offsets {
             frame.widget_count_offsets = w;
@@ -533,11 +533,7 @@ impl WidgetBoundsInfo {
     /// [`baseline`]: Self::baseline
     pub fn final_baseline(&self) -> Px {
         let s = self.0.lock();
-        if s.inner_offset_baseline {
-            Px(0)
-        } else {
-            s.baseline
-        }
+        if s.inner_offset_baseline { Px(0) } else { s.baseline }
     }
 
     /// Gets the global transform of the widget's outer bounds during the last render or render update.
@@ -1415,7 +1411,7 @@ impl WidgetInfo {
     }
 
     /// All parent children except this widget.
-    pub fn siblings(&self) -> impl Iterator<Item = WidgetInfo> {
+    pub fn siblings(&self) -> impl Iterator<Item = WidgetInfo> + 'static + use<> {
         self.prev_siblings().chain(self.next_siblings())
     }
 
@@ -1630,7 +1626,7 @@ impl WidgetInfo {
     }
 
     /// Iterator over all descendants with inner bounds not fully contained by their parent inner bounds.
-    pub fn out_of_bounds(&self) -> impl Iterator<Item = WidgetInfo> {
+    pub fn out_of_bounds(&self) -> impl Iterator<Item = WidgetInfo> + 'static + use<> {
         let range = self.descendants_range();
         self.tree.out_of_bounds().filter(move |w| range.contains(w))
     }
@@ -1640,7 +1636,10 @@ impl WidgetInfo {
     /// If the `filter` returns `false` the widget and all it's in-bounds descendants are skipped, otherwise they are yielded. After
     /// all in-bounds descendants reachable from `self` and filtered the iterator changes to each out-of-bounds descendants and their
     /// in-bounds descendants that are also filtered.
-    pub fn spatial_iter(&self, filter: impl Fn(&WidgetInfo) -> bool + Clone) -> impl Iterator<Item = WidgetInfo> {
+    pub fn spatial_iter<F>(&self, filter: F) -> impl Iterator<Item = WidgetInfo> + use<F>
+    where
+        F: Fn(&WidgetInfo) -> bool + Clone,
+    {
         let self_id = self.id();
         self.self_and_descendants()
             .tree_filter(clmv!(filter, |w| {
@@ -1663,37 +1662,37 @@ impl WidgetInfo {
     }
 
     /// Iterator over self and all descendants with inner bounds that contain the `point`.
-    pub fn inner_contains(&self, point: PxPoint) -> impl Iterator<Item = WidgetInfo> {
+    pub fn inner_contains(&self, point: PxPoint) -> impl Iterator<Item = WidgetInfo> + 'static + use<> {
         self.spatial_iter(move |w| w.inner_bounds().contains(point))
     }
 
     /// Spatial iterator over self and descendants with inner bounds that intersects the `rect`.
-    pub fn inner_intersects(&self, rect: PxRect) -> impl Iterator<Item = WidgetInfo> {
+    pub fn inner_intersects(&self, rect: PxRect) -> impl Iterator<Item = WidgetInfo> + 'static + use<> {
         let rect = rect.to_box2d();
         self.spatial_iter(move |w| w.inner_bounds().to_box2d().intersects(&rect))
     }
 
     /// Spatial iterator over self and descendants with inner bounds that fully envelops the `rect`.
-    pub fn inner_contains_rect(&self, rect: PxRect) -> impl Iterator<Item = WidgetInfo> {
+    pub fn inner_contains_rect(&self, rect: PxRect) -> impl Iterator<Item = WidgetInfo> + 'static + use<> {
         let rect = rect.to_box2d();
         self.spatial_iter(move |w| w.inner_bounds().to_box2d().contains_box(&rect))
     }
 
     /// Spatial iterator over self and descendants with inner bounds that are fully inside the `rect`.
-    pub fn inner_contained(&self, rect: PxRect) -> impl Iterator<Item = WidgetInfo> {
+    pub fn inner_contained(&self, rect: PxRect) -> impl Iterator<Item = WidgetInfo> + 'static + use<> {
         let rect = rect.to_box2d();
         self.spatial_iter(move |w| rect.contains_box(&w.inner_bounds().to_box2d()))
     }
 
     /// Spatial iterator over self and descendants with center point inside the `area`.
-    pub fn center_contained(&self, area: PxRect) -> impl Iterator<Item = WidgetInfo> {
+    pub fn center_contained(&self, area: PxRect) -> impl Iterator<Item = WidgetInfo> + 'static + use<> {
         let area = area.to_box2d();
         self.spatial_iter(move |w| w.inner_bounds().to_box2d().intersects(&area))
             .filter(move |w| area.contains(w.center()))
     }
 
     /// Spatial iterator over self and descendants with center point within the `max_radius` of the `origin`.
-    pub fn center_in_distance(&self, origin: PxPoint, max_radius: Px) -> impl Iterator<Item = WidgetInfo> + '_ {
+    pub fn center_in_distance(&self, origin: PxPoint, max_radius: Px) -> impl Iterator<Item = WidgetInfo> + 'static + use<> {
         let area = PxRect::new(origin, PxSize::splat(max_radius))
             .inflate(max_radius, max_radius)
             .to_box2d();
@@ -1817,7 +1816,12 @@ impl WidgetInfo {
     /// [`spatial_bounds`]: WidgetInfoTree::spatial_bounds
     /// [`center`]: WidgetInfo::center
     /// [`Orientation2D::point_is`]: zng_layout::unit::Orientation2D::point_is
-    pub fn oriented(&self, origin: PxPoint, max_distance: Px, orientation: Orientation2D) -> impl Iterator<Item = WidgetInfo> {
+    pub fn oriented(
+        &self,
+        origin: PxPoint,
+        max_distance: Px,
+        orientation: Orientation2D,
+    ) -> impl Iterator<Item = WidgetInfo> + 'static + use<> {
         let distance_bounded = max_distance != Px::MAX;
         let distance_key = if distance_bounded {
             DistanceKey::from_distance(max_distance)
@@ -1853,7 +1857,12 @@ impl WidgetInfo {
     /// [`inner_bounds`]: WidgetInfo::inner_bounds
     /// [`center`]: WidgetInfo::center
     /// [`Orientation2D::box_is`]: zng_layout::unit::Orientation2D::box_is
-    pub fn oriented_box(&self, origin: PxBox, max_distance: Px, orientation: Orientation2D) -> impl Iterator<Item = WidgetInfo> {
+    pub fn oriented_box(
+        &self,
+        origin: PxBox,
+        max_distance: Px,
+        orientation: Orientation2D,
+    ) -> impl Iterator<Item = WidgetInfo> + 'static + use<> {
         let distance_bounded = max_distance != Px::MAX;
         let distance_key = if distance_bounded {
             DistanceKey::from_distance(max_distance)
diff --git a/crates/zng-app/src/widget/info/access.rs b/crates/zng-app/src/widget/info/access.rs
index 5cef67e6f..82506a932 100644
--- a/crates/zng-app/src/widget/info/access.rs
+++ b/crates/zng-app/src/widget/info/access.rs
@@ -5,7 +5,7 @@ use std::num::NonZeroU32;
 use parking_lot::Mutex;
 use unic_langid::LanguageIdentifier;
 use zng_layout::unit::{Factor, PxSize, PxTransform};
-use zng_state_map::{static_id, StateId};
+use zng_state_map::{StateId, static_id};
 use zng_txt::Txt;
 use zng_unique_id::IdMap;
 use zng_var::{BoxedVar, IntoVar, Var};
@@ -16,7 +16,7 @@ use zng_view_api::access::{AccessNodeId, AccessState};
 
 use crate::widget::WidgetId;
 
-use super::{iter::TreeIterator, WidgetInfo, WidgetInfoBuilder, WidgetInfoTree};
+use super::{WidgetInfo, WidgetInfoBuilder, WidgetInfoTree, iter::TreeIterator};
 
 impl WidgetInfoBuilder {
     /// Accessibility metadata builder.
diff --git a/crates/zng-app/src/widget/info/builder.rs b/crates/zng-app/src/widget/info/builder.rs
index 0f8f6f9ca..50c171cc7 100644
--- a/crates/zng-app/src/widget/info/builder.rs
+++ b/crates/zng-app/src/widget/info/builder.rs
@@ -1,17 +1,17 @@
 use parking_lot::Mutex;
 use zng_layout::{
-    context::{InlineConstraints, InlineConstraintsLayout, InlineConstraintsMeasure, InlineSegment, InlineSegmentPos, LayoutMask, LAYOUT},
+    context::{InlineConstraints, InlineConstraintsLayout, InlineConstraintsMeasure, InlineSegment, InlineSegmentPos, LAYOUT, LayoutMask},
     unit::{Factor, Px, PxBox, PxPoint, PxRect, PxSize, PxVector},
 };
 use zng_state_map::{OwnedStateMap, StateId, StateMapMut, StateValue};
 use zng_unique_id::{IdMap, IdSet};
 
 use crate::{
+    DInstant, INSTANT,
     render::TransformStyle,
     update::{InfoUpdates, LayoutUpdates, UpdateFlags},
-    widget::{border::BORDER, node::UiNode, WidgetId, WidgetUpdateMode, WIDGET},
-    window::{WindowId, WINDOW},
-    DInstant, INSTANT,
+    widget::{WIDGET, WidgetId, WidgetUpdateMode, border::BORDER, node::UiNode},
+    window::{WINDOW, WindowId},
 };
 
 use super::{hit::ParallelSegmentOffsets, *};
@@ -591,11 +591,7 @@ impl InteractivityChangedArgs {
         let new = self.new_interactivity(widget_id);
         let prev = self.prev_interactivity(widget_id);
         if let Some(prev) = prev {
-            if mtd(prev) != mtd(new) {
-                Some((Some(prev), new))
-            } else {
-                None
-            }
+            if mtd(prev) != mtd(new) { Some((Some(prev), new)) } else { None }
         } else {
             Some((prev, new))
         }
diff --git a/crates/zng-app/src/widget/info/hit.rs b/crates/zng-app/src/widget/info/hit.rs
index 75bcdd205..7cc51b9d6 100644
--- a/crates/zng-app/src/widget/info/hit.rs
+++ b/crates/zng-app/src/widget/info/hit.rs
@@ -1,4 +1,4 @@
-use std::sync::{atomic::AtomicUsize, Arc};
+use std::sync::{Arc, atomic::AtomicUsize};
 
 use zng_layout::unit::{PxBox, PxCornerRadius, PxPoint, PxSize, PxTransform, PxVector};
 use zng_view_api::display_list::{FrameValue, FrameValueUpdate};
diff --git a/crates/zng-app/src/widget/info/iter.rs b/crates/zng-app/src/widget/info/iter.rs
index c8a614a4a..9dade6aba 100644
--- a/crates/zng-app/src/widget/info/iter.rs
+++ b/crates/zng-app/src/widget/info/iter.rs
@@ -436,15 +436,15 @@ mod tests {
     use zng_layout::unit::FactorUnits;
 
     use crate::{
+        APP,
         widget::{
+            WIDGET, WidgetCtx, WidgetId, WidgetUpdateMode,
             info::{
-                access::AccessEnabled, iter::TreeIterator, TreeFilter, WidgetBorderInfo, WidgetBoundsInfo, WidgetInfo, WidgetInfoBuilder,
-                WidgetInfoTree,
+                TreeFilter, WidgetBorderInfo, WidgetBoundsInfo, WidgetInfo, WidgetInfoBuilder, WidgetInfoTree, access::AccessEnabled,
+                iter::TreeIterator,
             },
-            WidgetCtx, WidgetId, WidgetUpdateMode, WIDGET,
         },
-        window::{WindowId, WINDOW},
-        APP,
+        window::{WINDOW, WindowId},
     };
 
     trait WidgetInfoBuilderExt {
@@ -712,7 +712,9 @@ mod tests {
 
         assert_eq!(
             result,
-            vec!["c-2-2", "c-2-2-0", "c-2-1", "c-2-0", "c-1", "c-1-1", "c-1-1-1", "c-1-1-0", "c-1-0", "c-0", "c-0-2", "c-0-1", "c-0-0",]
+            vec![
+                "c-2-2", "c-2-2-0", "c-2-1", "c-2-0", "c-1", "c-1-1", "c-1-1-1", "c-1-1-0", "c-1-0", "c-0", "c-0-2", "c-0-1", "c-0-0",
+            ]
         );
     }
 
@@ -728,7 +730,9 @@ mod tests {
 
         assert_eq!(
             result,
-            vec!["c-2-2-0", "c-2-1", "c-2-0", "c-1", "c-1-1", "c-1-1-1", "c-1-1-0", "c-1-0", "c-0", "c-0-2", "c-0-1", "c-0-0"]
+            vec![
+                "c-2-2-0", "c-2-1", "c-2-0", "c-1", "c-1-1", "c-1-1-1", "c-1-1-0", "c-1-0", "c-0", "c-0-2", "c-0-1", "c-0-0"
+            ]
         );
     }
 
diff --git a/crates/zng-app/src/widget/inspector.rs b/crates/zng-app/src/widget/inspector.rs
index c51062a4f..10aa6807d 100644
--- a/crates/zng-app/src/widget/inspector.rs
+++ b/crates/zng-app/src/widget/inspector.rs
@@ -9,7 +9,7 @@ mod inspector_only {
 
     use crate::widget::{
         builder::{InputKind, PropertyId},
-        node::{match_node, BoxedUiNode, UiNode, UiNodeOp},
+        node::{BoxedUiNode, UiNode, UiNodeOp, match_node},
     };
 
     pub(crate) fn insert_widget_builder_info(child: BoxedUiNode, info: super::InspectorInfo) -> impl UiNode {
@@ -53,9 +53,9 @@ use zng_var::{BoxedAnyVar, BoxedVar, VarValue};
 use std::{any::TypeId, collections::HashMap, sync::Arc};
 
 use super::{
+    WIDGET, WidgetUpdateMode,
     builder::{InputKind, NestGroup, PropertyArgs, PropertyId, WidgetBuilder, WidgetType},
     info::WidgetInfo,
-    WidgetUpdateMode, WIDGET,
 };
 
 static_id! {
diff --git a/crates/zng-app/src/widget/node.rs b/crates/zng-app/src/widget/node.rs
index 863fd2fe8..f24a79aef 100644
--- a/crates/zng-app/src/widget/node.rs
+++ b/crates/zng-app/src/widget/node.rs
@@ -32,9 +32,9 @@ use crate::{
 };
 
 use super::{
-    base::{Parallel, PARALLEL_VAR},
+    WIDGET, WidgetId, WidgetUpdateMode,
+    base::{PARALLEL_VAR, Parallel},
     info::{WidgetInfoBuilder, WidgetLayout, WidgetMeasure},
-    WidgetId, WidgetUpdateMode, WIDGET,
 };
 
 /// Represents an UI tree node.
@@ -1288,19 +1288,11 @@ impl<U: UiNode> UiNode for Option<U> {
     }
 
     fn measure(&mut self, wm: &mut WidgetMeasure) -> PxSize {
-        if let Some(node) = self {
-            node.measure(wm)
-        } else {
-            PxSize::zero()
-        }
+        if let Some(node) = self { node.measure(wm) } else { PxSize::zero() }
     }
 
     fn layout(&mut self, wl: &mut WidgetLayout) -> PxSize {
-        if let Some(node) = self {
-            node.layout(wl)
-        } else {
-            PxSize::zero()
-        }
+        if let Some(node) = self { node.layout(wl) } else { PxSize::zero() }
     }
 
     fn render(&mut self, frame: &mut FrameBuilder) {
diff --git a/crates/zng-app/src/widget/node/arc.rs b/crates/zng-app/src/widget/node/arc.rs
index 246e7cffc..9226fe2e1 100644
--- a/crates/zng-app/src/widget/node/arc.rs
+++ b/crates/zng-app/src/widget/node/arc.rs
@@ -104,7 +104,10 @@ impl<U: UiNode> ArcNode<U> {
     /// Create a slot node that takes ownership of this node when `var` updates to `true`.
     ///
     /// The slot node also takes ownership on init if the `var` is already `true`.
-    pub fn take_when(&self, var: impl IntoVar<bool>) -> TakeSlot<U, impl TakeOn> {
+    pub fn take_when<I>(&self, var: I) -> TakeSlot<U, impls::TakeWhenVar<I::Var>>
+    where
+        I: IntoVar<bool>,
+    {
         impls::TakeSlot {
             slot: self.0.slots.lock().next_slot(),
             rc: self.0.clone(),
@@ -118,12 +121,11 @@ impl<U: UiNode> ArcNode<U> {
     /// Create a slot node that takes ownership of this node when `event` updates and `filter` returns `true`.
     ///
     /// The slot node also takes ownership on init if `take_on_init` is `true`.
-    pub fn take_on<A: EventArgs>(
-        &self,
-        event: Event<A>,
-        filter: impl FnMut(&A) -> bool + Send + 'static,
-        take_on_init: bool,
-    ) -> TakeSlot<U, impl TakeOn> {
+    pub fn take_on<A, F>(&self, event: Event<A>, filter: F, take_on_init: bool) -> TakeSlot<U, impls::TakeOnEvent<A, F>>
+    where
+        A: EventArgs,
+        F: FnMut(&A) -> bool + Send + 'static,
+    {
         impls::TakeSlot {
             slot: self.0.slots.lock().next_slot(),
             rc: self.0.clone(),
@@ -141,7 +143,7 @@ impl<U: UiNode> ArcNode<U> {
     /// Create a slot node that takes ownership of this node as soon as the node is inited.
     ///
     /// This is equivalent to `self.take_when(true)`.
-    pub fn take_on_init(&self) -> TakeSlot<U, impl TakeOn> {
+    pub fn take_on_init(&self) -> TakeSlot<U, impls::TakeWhenVar<zng_var::LocalVar<bool>>> {
         self.take_when(true)
     }
 
@@ -307,11 +309,11 @@ mod impls {
     use crate::{
         event::{Event, EventArgs},
         render::{FrameBuilder, FrameUpdate},
-        update::{EventUpdate, WidgetUpdates, UPDATES},
+        update::{EventUpdate, UPDATES, WidgetUpdates},
         widget::{
+            WIDGET, WidgetHandlesCtx, WidgetUpdateMode,
             info::{WidgetInfoBuilder, WidgetLayout, WidgetMeasure},
             node::{BoxedUiNode, BoxedUiNodeList, UiNode, UiNodeList, UiNodeListObserver},
-            WidgetHandlesCtx, WidgetUpdateMode, WIDGET,
         },
     };
 
@@ -334,7 +336,8 @@ mod impls {
         }
     }
 
-    pub(super) struct TakeWhenVar<V: Var<bool>> {
+    #[doc(hidden)]
+    pub struct TakeWhenVar<V: Var<bool>> {
         pub(super) var: V,
     }
     impl<V: Var<bool>> TakeOn for TakeWhenVar<V> {
@@ -348,7 +351,8 @@ mod impls {
         }
     }
 
-    pub(super) struct TakeOnEvent<A: EventArgs, F: FnMut(&A) -> bool + Send + 'static> {
+    #[doc(hidden)]
+    pub struct TakeOnEvent<A: EventArgs, F: FnMut(&A) -> bool + Send + 'static> {
         pub(super) event: Event<A>,
         pub(super) filter: F,
         pub(super) take_on_init: bool,
@@ -496,11 +500,7 @@ mod impls {
         }
 
         fn delegate_owned<R>(&self, del: impl FnOnce(&U) -> R) -> Option<R> {
-            if self.is_owner() {
-                Some(del(&*self.rc.item.lock()))
-            } else {
-                None
-            }
+            if self.is_owner() { Some(del(&*self.rc.item.lock())) } else { None }
         }
         fn delegate_owned_mut<R>(&mut self, del: impl FnOnce(&mut U) -> R) -> Option<R> {
             if self.is_owner() {
diff --git a/crates/zng-app/src/widget/node/list.rs b/crates/zng-app/src/widget/node/list.rs
index a51c30d86..69d0f1cd5 100644
--- a/crates/zng-app/src/widget/node/list.rs
+++ b/crates/zng-app/src/widget/node/list.rs
@@ -2,8 +2,8 @@ use std::{
     cmp::Ordering,
     mem, ops,
     sync::{
-        atomic::{AtomicBool, Ordering::Relaxed},
         Arc,
+        atomic::{AtomicBool, Ordering::Relaxed},
     },
 };
 
@@ -72,11 +72,11 @@ macro_rules! ui_vec {
 pub use crate::ui_vec;
 use crate::{
     render::{FrameBuilder, FrameUpdate, FrameValueKey},
-    update::{EventUpdate, WidgetUpdates, UPDATES},
+    update::{EventUpdate, UPDATES, WidgetUpdates},
     widget::{
-        base::{Parallel, PARALLEL_VAR},
+        WIDGET, WidgetUpdateMode,
+        base::{PARALLEL_VAR, Parallel},
         info::{WidgetInfo, WidgetInfoBuilder, WidgetLayout, WidgetMeasure},
-        WidgetUpdateMode, WIDGET,
     },
 };
 
diff --git a/crates/zng-app/src/widget/node/match_node.rs b/crates/zng-app/src/widget/node/match_node.rs
index 3924b6e8a..14d7b3df2 100644
--- a/crates/zng-app/src/widget/node/match_node.rs
+++ b/crates/zng-app/src/widget/node/match_node.rs
@@ -6,8 +6,9 @@ use crate::{
     render::{FrameBuilder, FrameUpdate},
     update::{EventUpdate, WidgetUpdates},
     widget::{
+        WidgetUpdateMode,
         info::{WidgetInfoBuilder, WidgetLayout, WidgetMeasure},
-        ui_node, WidgetUpdateMode,
+        ui_node,
     },
 };
 
diff --git a/crates/zng-app/src/widget/node/when.rs b/crates/zng-app/src/widget/node/when.rs
index ac794997a..a49da4058 100644
--- a/crates/zng-app/src/widget/node/when.rs
+++ b/crates/zng-app/src/widget/node/when.rs
@@ -3,7 +3,7 @@ use zng_var::{BoxedVar, Var};
 
 use crate::{
     update::{EventUpdate, WidgetUpdates},
-    widget::{WidgetHandlesCtx, WIDGET},
+    widget::{WIDGET, WidgetHandlesCtx},
 };
 
 use super::{BoxedUiNode, BoxedUiNodeList, UiNode, UiNodeList, UiNodeListObserver};
diff --git a/crates/zng-app/src/window.rs b/crates/zng-app/src/window.rs
index 875470dc0..3f8dfced3 100644
--- a/crates/zng-app/src/window.rs
+++ b/crates/zng-app/src/window.rs
@@ -120,11 +120,7 @@ impl WINDOW {
 
     /// Gets the window ID, if called inside a window.
     pub fn try_id(&self) -> Option<WindowId> {
-        if WINDOW_CTX.is_default() {
-            None
-        } else {
-            Some(WINDOW_CTX.get().id)
-        }
+        if WINDOW_CTX.is_default() { None } else { Some(WINDOW_CTX.get().id) }
     }
 
     /// Gets the window ID.
@@ -224,20 +220,20 @@ impl WINDOW {
 mod _impl {
     use zng_color::colors;
     use zng_layout::{
-        context::{InlineConstraints, InlineConstraintsLayout, InlineConstraintsMeasure, LayoutMetrics, LAYOUT},
+        context::{InlineConstraints, InlineConstraintsLayout, InlineConstraintsMeasure, LAYOUT, LayoutMetrics},
         unit::{FactorUnits, Length, Px, PxConstraints2d, PxSize, PxTransform},
     };
-    use zng_state_map::{static_id, StateId};
+    use zng_state_map::{StateId, static_id};
     use zng_view_api::config::FontAntiAliasing;
 
     use super::*;
     use crate::{
         render::FrameValueKey,
-        update::{ContextUpdates, EventUpdate, LayoutUpdates, UpdateDeliveryList, WidgetUpdates, UPDATES},
+        update::{ContextUpdates, EventUpdate, LayoutUpdates, UPDATES, UpdateDeliveryList, WidgetUpdates},
         widget::{
+            WIDGET, WIDGET_CTX, WidgetCtx, WidgetId, WidgetUpdateMode,
             info::{WidgetBorderInfo, WidgetBoundsInfo, WidgetPath},
             node::UiNode,
-            WidgetCtx, WidgetId, WidgetUpdateMode, WIDGET, WIDGET_CTX,
         },
     };
     use atomic::Ordering::Relaxed;
diff --git a/crates/zng-clone-move/Cargo.toml b/crates/zng-clone-move/Cargo.toml
index 4ae8ba224..40ba9dae0 100644
--- a/crates/zng-clone-move/Cargo.toml
+++ b/crates/zng-clone-move/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-clone-move"
 version = "0.2.5"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-clone-move/src/lib.rs b/crates/zng-clone-move/src/lib.rs
index def091ce3..3a76004a6 100644
--- a/crates/zng-clone-move/src/lib.rs
+++ b/crates/zng-clone-move/src/lib.rs
@@ -162,7 +162,7 @@ macro_rules! __clmv {
 /// In the example `bar` is *clone-moved* into the `'static` future given to `foo`.
 ///
 /// ```
-/// # use std::{future::Future, time::Duration};
+/// # use std::{time::Duration};
 /// # use zng_clone_move::*;
 /// # trait TimeUnits { fn ms(self) -> Duration; }
 /// # impl TimeUnits for u64 { fn ms(self) -> Duration { Duration::from_millis(self) } }
@@ -183,7 +183,7 @@ macro_rules! __clmv {
 /// Expands to:
 ///
 /// ```
-/// # use std::{future::Future, time::Duration};
+/// # use std::{time::Duration};
 /// # use zng_clone_move::*;
 /// # async fn foo(mut f: impl Future<Output=()> + 'static) {
 /// #     f.await;
@@ -208,7 +208,7 @@ macro_rules! __clmv {
 /// variables cloned to achieve these effects.
 ///
 /// ```
-/// # use std::{future::Future, sync::Arc};
+/// # use std::{sync::Arc};
 /// # use zng_clone_move::*;
 /// async fn foo(mut f: impl Future<Output=()> + 'static) {
 ///     f.await;
@@ -226,7 +226,7 @@ macro_rules! __clmv {
 /// Expands to:
 ///
 /// ```
-/// # use std::{future::Future, sync::Arc};
+/// # use std::{sync::Arc};
 /// # use zng_clone_move::*;
 /// # async fn foo(mut f: impl Future<Output=()> + 'static) {
 /// #     f.await;
@@ -304,7 +304,6 @@ macro_rules! __async_clmv {
 ///
 /// ```
 /// # use zng_clone_move::async_clmv_fn;
-/// # use std::future::Future;
 /// async fn foo<F: Future<Output=()>, H: FnMut(bool) -> F + 'static>(mut f: H) {
 ///     f(true).await;
 /// }
@@ -322,7 +321,6 @@ macro_rules! __async_clmv {
 ///
 /// ```
 /// # use zng_clone_move::async_clmv_fn;
-/// # use std::future::Future;
 /// # async fn foo<F: Future<Output=()>, H: FnMut(bool) -> F + 'static>(mut f: H) {
 /// #     f(true).await;
 /// # }
@@ -340,6 +338,8 @@ macro_rules! __async_clmv {
 /// # println!("original: {bar}");
 /// ```
 ///
+/// Note that this is different from an async closure, it returns `'static` futures that do not borrow the closure.
+///
 /// # Once
 ///
 /// See [`async_clmv_fn_once!`] for creating `FnOnce` closures.
@@ -475,7 +475,7 @@ macro_rules! __async_clmv_fn {
 
 ///<span data-del-macro-root></span> Async clone move closure that can only be called once.
 ///
-/// The macro syntax is exactly the same as [`async_clmv_fn!`](macro@crate::async_clmv_fn), but it does not clone variables
+/// The macro syntax is exactly the same as [`async_clmv_fn!`], but it does not clone variables
 /// again inside the call to move to the returned future. Because it moves the captured variables to the returned `Future`,
 /// the closure can only be `FnOnce`.
 ///
@@ -485,7 +485,6 @@ macro_rules! __async_clmv_fn {
 ///
 /// ```
 /// # use zng_clone_move::async_clmv_fn;
-/// # use std::future::Future;
 /// async fn foo<F: Future<Output=()>, H: FnOnce(bool) -> F + 'static>(mut f: H) {
 ///     f(true).await;
 /// }
@@ -503,7 +502,6 @@ macro_rules! __async_clmv_fn {
 ///
 /// ```
 /// # use zng_clone_move::async_clmv_fn;
-/// # use std::future::Future;
 /// # async fn foo<F: Future<Output=()>, H: FnOnce(bool) -> F + 'static>(mut f: H) {
 /// #     f(true).await;
 /// # }
@@ -517,6 +515,11 @@ macro_rules! __async_clmv_fn {
 /// });
 /// # println!("original: {bar}");
 /// ```
+///
+/// Note that this is different from an async once closure, it is an once closure that returns a future, this is so it is more similar with
+/// [`async_clmv_fn!`], that macro cannot be implemented an async closure.
+///
+/// [`async_clmv_fn!`]: macro@crate::async_clmv_fn
 #[macro_export]
 macro_rules! async_clmv_fn_once {
     ($($tt:tt)+) => { $crate::__async_clmv_fn_once! { [][][] $($tt)+ } }
diff --git a/crates/zng-color-proc-macros/Cargo.toml b/crates/zng-color-proc-macros/Cargo.toml
index 45fd66254..1f45cf214 100644
--- a/crates/zng-color-proc-macros/Cargo.toml
+++ b/crates/zng-color-proc-macros/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-color-proc-macros"
 version = "0.2.7"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-color-proc-macros/src/hex_color.rs b/crates/zng-color-proc-macros/src/hex_color.rs
index a100aea73..3f4c0aad6 100644
--- a/crates/zng-color-proc-macros/src/hex_color.rs
+++ b/crates/zng-color-proc-macros/src/hex_color.rs
@@ -1,5 +1,5 @@
 use proc_macro2::{Span, TokenStream};
-use syn::{parse::Parse, parse_macro_input, LitInt, Path, Token};
+use syn::{LitInt, Path, Token, parse::Parse, parse_macro_input};
 
 struct Input {
     crate_: Path,
diff --git a/crates/zng-color/Cargo.toml b/crates/zng-color/Cargo.toml
index 95d437ccc..a1123cfe4 100644
--- a/crates/zng-color/Cargo.toml
+++ b/crates/zng-color/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-color"
 version = "0.4.6"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-color/src/colors.rs b/crates/zng-color/src/colors.rs
index bc02e9178..a56d08aff 100644
--- a/crates/zng-color/src/colors.rs
+++ b/crates/zng-color/src/colors.rs
@@ -7,7 +7,7 @@
 
 use zng_var::context_var;
 
-use crate::{light_dark, LightDark};
+use crate::{LightDark, light_dark};
 
 use super::Rgba;
 
diff --git a/crates/zng-color/src/filter.rs b/crates/zng-color/src/filter.rs
index 0cc538650..e9e4d8ade 100644
--- a/crates/zng-color/src/filter.rs
+++ b/crates/zng-color/src/filter.rs
@@ -4,15 +4,15 @@ use std::fmt;
 
 use zng_layout::{
     context::LayoutMask,
-    unit::{about_eq, about_eq_hash, AngleDegree, Factor, FactorUnits, Layout1d, Layout2d, Length, Point},
+    unit::{AngleDegree, Factor, FactorUnits, Layout1d, Layout2d, Length, Point, about_eq, about_eq_hash},
 };
 use zng_var::{
-    animation::{easing::EasingStep, Transitionable},
+    animation::{Transitionable, easing::EasingStep},
     impl_from_and_into_var,
 };
 use zng_view_api::display_list::{FilterOp, FrameValue};
 
-use crate::{lerp_rgba, Rgba};
+use crate::{Rgba, lerp_rgba};
 
 /// A color filter or combination of filters.
 ///
diff --git a/crates/zng-color/src/gradient.rs b/crates/zng-color/src/gradient.rs
index 5ae260076..0f405c5a4 100644
--- a/crates/zng-color/src/gradient.rs
+++ b/crates/zng-color/src/gradient.rs
@@ -765,11 +765,13 @@ impl GradientStops {
                 color: colors[0].into(),
                 offset: Length::zero(),
             };
-            let mut middle = vec![ColorStop {
-                color: start.color,
-                offset: (offset - tran).fct().into(),
-            }
-            .into()];
+            let mut middle = vec![
+                ColorStop {
+                    color: start.color,
+                    offset: (offset - tran).fct().into(),
+                }
+                .into(),
+            ];
 
             for &color in &colors[1..last] {
                 let color = color.into();
diff --git a/crates/zng-color/src/lib.rs b/crates/zng-color/src/lib.rs
index 56b38c5f9..c1c6bffcc 100644
--- a/crates/zng-color/src/lib.rs
+++ b/crates/zng-color/src/lib.rs
@@ -13,12 +13,12 @@
 use std::{fmt, ops, sync::Arc};
 use zng_app_context::context_local;
 
-use zng_layout::unit::{about_eq, about_eq_hash, AngleDegree, Factor, FactorUnits};
+use zng_layout::unit::{AngleDegree, Factor, FactorUnits, about_eq, about_eq_hash};
 use zng_var::{
-    animation::{easing::EasingStep, Transition, Transitionable},
+    IntoVar, Var, VarValue,
+    animation::{Transition, Transitionable, easing::EasingStep},
     context_var, expr_var, impl_from_and_into_var,
     types::ContextualizedVar,
-    IntoVar, Var, VarValue,
 };
 
 pub use zng_view_api::config::ColorScheme;
diff --git a/crates/zng-color/src/mix.rs b/crates/zng-color/src/mix.rs
index a715c27a9..0877a07ec 100644
--- a/crates/zng-color/src/mix.rs
+++ b/crates/zng-color/src/mix.rs
@@ -1,4 +1,4 @@
-use super::{clamp_normal, Hsla, Hsva, PreMulRgba, Rgba};
+use super::{Hsla, Hsva, PreMulRgba, Rgba, clamp_normal};
 use zng_layout::unit::Factor;
 
 use paste::*;
diff --git a/crates/zng-env-proc-macros/Cargo.toml b/crates/zng-env-proc-macros/Cargo.toml
index a43a2b5fd..0dbe1b514 100644
--- a/crates/zng-env-proc-macros/Cargo.toml
+++ b/crates/zng-env-proc-macros/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-env-proc-macros"
 version = "0.2.2"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-env/Cargo.toml b/crates/zng-env/Cargo.toml
index a4d49ead4..180faf3ab 100644
--- a/crates/zng-env/Cargo.toml
+++ b/crates/zng-env/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-env"
 version = "0.3.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-env/src/lib.rs b/crates/zng-env/src/lib.rs
index 90c821b24..167e6d6d0 100644
--- a/crates/zng-env/src/lib.rs
+++ b/crates/zng-env/src/lib.rs
@@ -83,7 +83,7 @@ lazy_static! {
 ///
 /// ```
 /// # macro_rules! demo { () => {
-/// #[no_mangle]
+/// #[unsafe(no_mangle)]
 /// fn android_main(app: zng::view_process::default::android::AndroidApp) {
 ///     zng::env::init!();
 ///     zng::view_process::default::android::init_android_app(app);
@@ -362,7 +362,7 @@ fn res_impl(relative_path: &Path) -> PathBuf {
 ///
 /// ```
 /// # macro_rules! demo { () => {
-/// #[no_mangle]
+/// #[unsafe(no_mangle)]
 /// fn android_main(app: zng::view_process::default::android::AndroidApp) {
 ///     zng::env::init!();
 ///     zng::view_process::default::android::init_android_app(app.clone());
diff --git a/crates/zng-ext-clipboard/Cargo.toml b/crates/zng-ext-clipboard/Cargo.toml
index a3fdb08f3..45738b6dd 100644
--- a/crates/zng-ext-clipboard/Cargo.toml
+++ b/crates/zng-ext-clipboard/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-ext-clipboard"
 version = "0.3.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-ext-clipboard/src/lib.rs b/crates/zng-ext-clipboard/src/lib.rs
index 1c3ff1363..845dba4e7 100644
--- a/crates/zng-ext-clipboard/src/lib.rs
+++ b/crates/zng-ext-clipboard/src/lib.rs
@@ -13,17 +13,17 @@ use core::fmt;
 use std::{any::Any, path::PathBuf};
 
 use zng_app::{
-    event::{command, CommandInfoExt as _, CommandNameExt as _},
-    shortcut::{shortcut, CommandShortcutExt as _, ShortcutFilter},
-    view_process::{ViewClipboard, ViewImage, VIEW_PROCESS},
-    AppExtension, APP,
+    APP, AppExtension,
+    event::{CommandInfoExt as _, CommandNameExt as _, command},
+    shortcut::{CommandShortcutExt as _, ShortcutFilter, shortcut},
+    view_process::{VIEW_PROCESS, ViewClipboard, ViewImage},
 };
 use zng_app_context::app_local;
-use zng_ext_image::{ImageHasher, ImageVar, Img, IMAGES};
+use zng_ext_image::{IMAGES, ImageHasher, ImageVar, Img};
 use zng_txt::Txt;
-use zng_var::{response_var, ResponderVar, ResponseVar};
+use zng_var::{ResponderVar, ResponseVar, response_var};
 use zng_view_api::ViewProcessOffline;
-use zng_wgt::{wgt_fn, CommandIconExt as _, ICONS};
+use zng_wgt::{CommandIconExt as _, ICONS, wgt_fn};
 
 use zng_view_api::clipboard as clipboard_api;
 use zng_view_api::ipc::IpcBytes;
diff --git a/crates/zng-ext-config/Cargo.toml b/crates/zng-ext-config/Cargo.toml
index bfc3439fe..f6a954f36 100644
--- a/crates/zng-ext-config/Cargo.toml
+++ b/crates/zng-ext-config/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-ext-config"
 version = "0.4.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-ext-config/src/json.rs b/crates/zng-ext-config/src/json.rs
index 1f38996af..b328ea0e8 100644
--- a/crates/zng-ext-config/src/json.rs
+++ b/crates/zng-ext-config/src/json.rs
@@ -12,7 +12,7 @@ impl ConfigMap for indexmap::IndexMap<ConfigKey, serde_json::Value> {
     }
 
     fn write(self, file: &mut WriteFile) -> io::Result<()> {
-        file.write_json(&self, true).map_err(Into::into)
+        file.write_json(&self, true)
     }
 
     fn get_raw(&self, key: &ConfigKey) -> Result<Option<RawConfigValue>, Arc<dyn std::error::Error + Send + Sync>> {
diff --git a/crates/zng-ext-config/src/lib.rs b/crates/zng-ext-config/src/lib.rs
index edb6428f4..311a49d1f 100644
--- a/crates/zng-ext-config/src/lib.rs
+++ b/crates/zng-ext-config/src/lib.rs
@@ -45,18 +45,18 @@ pub mod settings;
 
 use std::{
     any::Any,
-    collections::{hash_map, HashMap},
+    collections::{HashMap, hash_map},
     fmt, io,
     sync::Arc,
 };
 
-use zng_app::{update::EventUpdate, view_process::raw_events::LOW_MEMORY_EVENT, AppExtension};
+use zng_app::{AppExtension, update::EventUpdate, view_process::raw_events::LOW_MEMORY_EVENT};
 use zng_app_context::app_local;
 use zng_clone_move::clmv;
 use zng_ext_fs_watcher::{WatchFile, WatcherReadStatus, WatcherSyncStatus, WriteFile};
 use zng_task as task;
 use zng_txt::Txt;
-use zng_var::{types::WeakArcVar, var, AnyVar, AnyWeakVar, ArcVar, BoxedVar, LocalVar, Var, VarHandles, VarModify, VarValue, WeakVar};
+use zng_var::{AnyVar, AnyWeakVar, ArcVar, BoxedVar, LocalVar, Var, VarHandles, VarModify, VarValue, WeakVar, types::WeakArcVar, var};
 
 /// Application extension that provides mouse events and service.
 ///
diff --git a/crates/zng-ext-config/src/settings.rs b/crates/zng-ext-config/src/settings.rs
index 20632ae50..1b38fa449 100644
--- a/crates/zng-ext-config/src/settings.rs
+++ b/crates/zng-ext-config/src/settings.rs
@@ -8,9 +8,9 @@ use std::{any::TypeId, cmp::Ordering, mem, ops, sync::Arc};
 use zng_app_context::app_local;
 use zng_state_map::{OwnedStateMap, StateId, StateMapMut, StateMapRef, StateValue};
 use zng_txt::Txt;
-use zng_var::{impl_from_and_into_var, var, AnyVar, AnyVarHookArgs, AnyVarValue, BoxedAnyVar, BoxedVar, IntoVar, LocalVar, Var};
+use zng_var::{AnyVar, AnyVarHookArgs, AnyVarValue, BoxedAnyVar, BoxedVar, IntoVar, LocalVar, Var, impl_from_and_into_var, var};
 
-use crate::{Config, ConfigKey, ConfigValue, FallbackConfigReset, CONFIG};
+use crate::{CONFIG, Config, ConfigKey, ConfigValue, FallbackConfigReset};
 
 /// Settings metadata service.
 pub struct SETTINGS;
@@ -412,11 +412,7 @@ impl Setting {
 
         let r = self.name.with(|s| {
             let s = s.to_lowercase();
-            if s.contains(search) {
-                Some(s.len() - search.len())
-            } else {
-                None
-            }
+            if s.contains(search) { Some(s.len() - search.len()) } else { None }
         });
         if r.is_some() {
             return r;
diff --git a/crates/zng-ext-config/src/sync.rs b/crates/zng-ext-config/src/sync.rs
index 73ac80627..39ffdc2ed 100644
--- a/crates/zng-ext-config/src/sync.rs
+++ b/crates/zng-ext-config/src/sync.rs
@@ -3,7 +3,7 @@ use std::{path::PathBuf, sync::atomic::AtomicBool};
 use atomic::{Atomic, Ordering};
 use zng_clone_move::clmv;
 use zng_ext_fs_watcher::WATCHER;
-use zng_var::{ReadOnlyArcVar, VarUpdateId, VARS};
+use zng_var::{ReadOnlyArcVar, VARS, VarUpdateId};
 
 use super::*;
 
diff --git a/crates/zng-ext-config/src/yaml.rs b/crates/zng-ext-config/src/yaml.rs
index e71052eb0..c50c6b710 100644
--- a/crates/zng-ext-config/src/yaml.rs
+++ b/crates/zng-ext-config/src/yaml.rs
@@ -154,7 +154,7 @@ fn yaml_map_key(key: serde_yaml::Value) -> Result<String, YamlValueRawError> {
         serde_yaml::Value::Number(n) => n.to_string(),
         serde_yaml::Value::String(s) => s,
         serde_yaml::Value::Sequence(_) | serde_yaml::Value::Mapping(_) | serde_yaml::Value::Tagged(_) => {
-            return Err(YamlValueRawError::InvalidMapKey)
+            return Err(YamlValueRawError::InvalidMapKey);
         }
     };
     Ok(ok)
diff --git a/crates/zng-ext-font/Cargo.toml b/crates/zng-ext-font/Cargo.toml
index 9e69053e0..996de3b5d 100644
--- a/crates/zng-ext-font/Cargo.toml
+++ b/crates/zng-ext-font/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-ext-font"
 version = "0.5.11"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-ext-font/src/emoji_util.rs b/crates/zng-ext-font/src/emoji_util.rs
index 9a53bdce3..c0e7fdb39 100644
--- a/crates/zng-ext-font/src/emoji_util.rs
+++ b/crates/zng-ext-font/src/emoji_util.rs
@@ -6,7 +6,7 @@ use std::{fmt, mem::size_of};
 
 use byteorder::{BigEndian, ReadBytesExt};
 use icu_properties::sets;
-use zng_color::{rgba, ColorScheme, Rgba};
+use zng_color::{ColorScheme, Rgba, rgba};
 use zng_var::impl_from_and_into_var;
 use zng_view_api::font::GlyphIndex;
 
diff --git a/crates/zng-ext-font/src/font_features.rs b/crates/zng-ext-font/src/font_features.rs
index 010f5ed85..6c0e8c0a8 100644
--- a/crates/zng-ext-font/src/font_features.rs
+++ b/crates/zng-ext-font/src/font_features.rs
@@ -1,7 +1,7 @@
 //! Font features and variation types.
 
 use std::{
-    collections::{hash_map, HashMap, HashSet},
+    collections::{HashMap, HashSet, hash_map},
     fmt,
     marker::PhantomData,
     num::NonZeroU32,
@@ -974,11 +974,7 @@ impl FontFeatureExclusiveSetsState for CapsVariant {
     }
 
     fn variant(self) -> Option<u32> {
-        if self == CapsVariant::Auto {
-            None
-        } else {
-            Some(self as u32)
-        }
+        if self == CapsVariant::Auto { None } else { Some(self as u32) }
     }
 
     fn from_variant(v: u32) -> Self {
@@ -1207,11 +1203,7 @@ impl fmt::Debug for FontStyleSet {
             write!(f, "FontStyleSet::")?;
         }
         let n = *self as u8;
-        if n == 0 {
-            write!(f, "Auto")
-        } else {
-            write!(f, "S{n:0<2}")
-        }
+        if n == 0 { write!(f, "Auto") } else { write!(f, "S{n:0<2}") }
     }
 }
 impl_from_and_into_var! {
@@ -1246,11 +1238,7 @@ impl FontFeatureExclusiveSetState for FontStyleSet {
     }
 
     fn variant(self) -> Option<u32> {
-        if self == FontStyleSet::Auto {
-            None
-        } else {
-            Some(self as u32)
-        }
+        if self == FontStyleSet::Auto { None } else { Some(self as u32) }
     }
 
     fn from_variant(v: u32) -> Self {
@@ -1272,11 +1260,7 @@ impl CharVariant {
     ///
     /// `v == 0 || v > 99` is Auto, `v >= 1 && v <= 99` maps to their variant.
     pub const fn new(v: u8) -> Self {
-        if v > 99 {
-            CharVariant(0)
-        } else {
-            CharVariant(v)
-        }
+        if v > 99 { CharVariant(0) } else { CharVariant(v) }
     }
 
     /// New auto.
@@ -1403,19 +1387,11 @@ impl FontFeatureExclusiveSetState for CharVariant {
     }
 
     fn variant(self) -> Option<u32> {
-        if self.is_auto() {
-            None
-        } else {
-            Some(self.0 as u32)
-        }
+        if self.is_auto() { None } else { Some(self.0 as u32) }
     }
 
     fn from_variant(v: u32) -> Self {
-        if v > 99 {
-            CharVariant::auto()
-        } else {
-            CharVariant(v as u8)
-        }
+        if v > 99 { CharVariant::auto() } else { CharVariant(v as u8) }
     }
 
     fn auto() -> Self {
@@ -1544,11 +1520,7 @@ impl FontFeatureExclusiveSetState for JpVariant {
     }
 
     fn variant(self) -> Option<u32> {
-        if self == JpVariant::Auto {
-            None
-        } else {
-            Some(self as u32)
-        }
+        if self == JpVariant::Auto { None } else { Some(self as u32) }
     }
 
     fn from_variant(v: u32) -> Self {
@@ -1704,11 +1676,7 @@ impl FontFeatureExclusiveSetState for EastAsianWidth {
     }
 
     fn variant(self) -> Option<u32> {
-        if self == EastAsianWidth::Auto {
-            None
-        } else {
-            Some(self as u32)
-        }
+        if self == EastAsianWidth::Auto { None } else { Some(self as u32) }
     }
 
     fn from_variant(v: u32) -> Self {
diff --git a/crates/zng-ext-font/src/hyphenation.rs b/crates/zng-ext-font/src/hyphenation.rs
index cfd5cbe65..d6871efce 100644
--- a/crates/zng-ext-font/src/hyphenation.rs
+++ b/crates/zng-ext-font/src/hyphenation.rs
@@ -173,7 +173,7 @@ mod util {
     use super::*;
     use hyphenation::Language::*;
     use regex::Regex;
-    use zng_ext_l10n::{lang, Lang};
+    use zng_ext_l10n::{Lang, lang};
 
     app_local! {
         pub static LANG_TO_LANGUAGE_MAP: Vec<(Lang, hyphenation::Language)> = vec![
diff --git a/crates/zng-ext-font/src/lib.rs b/crates/zng-ext-font/src/lib.rs
index 57fda6993..5f29d0f86 100644
--- a/crates/zng-ext-font/src/lib.rs
+++ b/crates/zng-ext-font/src/lib.rs
@@ -46,28 +46,28 @@ pub use unit::*;
 use parking_lot::{Mutex, RwLock};
 use paste::paste;
 use zng_app::{
+    AppExtension,
     event::{event, event_args},
     render::FontSynthesis,
     update::{EventUpdate, UPDATES},
     view_process::{
+        VIEW_PROCESS_INITED_EVENT, ViewRenderer,
         raw_events::{RAW_FONT_AA_CHANGED_EVENT, RAW_FONT_CHANGED_EVENT},
-        ViewRenderer, VIEW_PROCESS_INITED_EVENT,
     },
-    AppExtension,
 };
 use zng_app_context::app_local;
-use zng_ext_l10n::{lang, Lang, LangMap};
+use zng_ext_l10n::{Lang, LangMap, lang};
 use zng_layout::unit::{
-    about_eq, about_eq_hash, about_eq_ord, euclid, Factor, FactorPercent, Px, PxPoint, PxRect, PxSize, TimeUnits as _, EQ_EPSILON,
-    EQ_EPSILON_100,
+    EQ_EPSILON, EQ_EPSILON_100, Factor, FactorPercent, Px, PxPoint, PxRect, PxSize, TimeUnits as _, about_eq, about_eq_hash, about_eq_ord,
+    euclid,
 };
 use zng_task as task;
 use zng_txt::Txt;
 use zng_var::{
-    animation::Transitionable, impl_from_and_into_var, response_done_var, response_var, var, AnyVar, ArcVar, IntoVar, LocalVar,
-    ResponderVar, ResponseVar, Var,
+    AnyVar, ArcVar, IntoVar, LocalVar, ResponderVar, ResponseVar, Var, animation::Transitionable, impl_from_and_into_var,
+    response_done_var, response_var, var,
 };
-use zng_view_api::{config::FontAntiAliasing, ViewProcessOffline};
+use zng_view_api::{ViewProcessOffline, config::FontAntiAliasing};
 
 /// Font family name.
 ///
diff --git a/crates/zng-ext-font/src/query_util.rs b/crates/zng-ext-font/src/query_util.rs
index 31dd0fd74..e78800e93 100644
--- a/crates/zng-ext-font/src/query_util.rs
+++ b/crates/zng-ext-font/src/query_util.rs
@@ -84,7 +84,7 @@ mod desktop {
                     font_kit::error::SelectionError::CannotAccessSource { reason } => Err(FontLoadingError::Io(Arc::new(
                         std::io::Error::new(std::io::ErrorKind::Other, reason.unwrap_or_default()),
                     ))),
-                }
+                };
             }
         };
         for handle in ubuntu.fonts() {
diff --git a/crates/zng-ext-font/src/segmenting.rs b/crates/zng-ext-font/src/segmenting.rs
index 2e8468c37..9ffb7483c 100644
--- a/crates/zng-ext-font/src/segmenting.rs
+++ b/crates/zng-ext-font/src/segmenting.rs
@@ -694,11 +694,7 @@ impl<'a> Iterator for SegmentedTextIter<'a> {
 }
 
 fn from_unic_level(d: unicode_bidi::Level) -> LayoutDirection {
-    if d.is_ltr() {
-        LayoutDirection::LTR
-    } else {
-        LayoutDirection::RTL
-    }
+    if d.is_ltr() { LayoutDirection::LTR } else { LayoutDirection::RTL }
 }
 fn into_unic_level(d: LayoutDirection) -> unicode_bidi::Level {
     match d {
diff --git a/crates/zng-ext-font/src/shaping.rs b/crates/zng-ext-font/src/shaping.rs
index 5b75d3e1a..e9dbd728a 100644
--- a/crates/zng-ext-font/src/shaping.rs
+++ b/crates/zng-ext-font/src/shaping.rs
@@ -6,19 +6,19 @@ use std::{
 };
 
 use zng_app::widget::info::InlineSegmentInfo;
-use zng_ext_image::{ImageDataFormat, ImageSource, ImageVar, IMAGES};
-use zng_ext_l10n::{lang, Lang};
+use zng_ext_image::{IMAGES, ImageDataFormat, ImageSource, ImageVar};
+use zng_ext_l10n::{Lang, lang};
 use zng_layout::{
     context::{InlineConstraintsLayout, InlineConstraintsMeasure, InlineSegmentPos, LayoutDirection, TextSegmentKind},
-    unit::{about_eq, euclid, Align, Factor2d, FactorUnits, Px, PxBox, PxConstraints2d, PxPoint, PxRect, PxSize},
+    unit::{Align, Factor2d, FactorUnits, Px, PxBox, PxConstraints2d, PxPoint, PxRect, PxSize, about_eq, euclid},
 };
 use zng_txt::Txt;
 use zng_var::{AnyVar, Var as _};
 use zng_view_api::font::{GlyphIndex, GlyphInstance};
 
 use crate::{
-    font_features::RFontFeatures, BidiLevel, CaretIndex, Font, FontList, Hyphens, Justify, LineBreak, SegmentedText, TextSegment,
-    WordBreak, HYPHENATION,
+    BidiLevel, CaretIndex, Font, FontList, HYPHENATION, Hyphens, Justify, LineBreak, SegmentedText, TextSegment, WordBreak,
+    font_features::RFontFeatures,
 };
 
 /// Reasons why a font might fail to load a glyph.
@@ -3385,7 +3385,7 @@ impl<'a> ShapedLine<'a> {
     }
 
     /// Iterate over word and space segments in this line.
-    pub fn segs(&self) -> impl DoubleEndedIterator<Item = ShapedSegment<'a>> + ExactSizeIterator {
+    pub fn segs(&self) -> impl DoubleEndedIterator<Item = ShapedSegment<'a>> + ExactSizeIterator + use<'a> {
         let text = self.text;
         let line_index = self.index;
         self.seg_range.iter().map(move |i| ShapedSegment {
@@ -3495,11 +3495,7 @@ impl<'a> ShapedLine<'a> {
                 seg.text.end
             } else {
                 // start of LineBreak segment
-                if end == 1 {
-                    0
-                } else {
-                    self.text.segments.0[end - 2].text.end
-                }
+                if end == 1 { 0 } else { self.text.segments.0[end - 2].text.end }
             }
         };
 
@@ -3760,7 +3756,9 @@ impl<'a> ShapedSegment<'a> {
     /// Glyphs in the segment, paired with the *x-advance*.
     ///
     /// Yields `(Font, [(glyph, advance)])`.
-    pub fn glyphs_with_x_advance(&self) -> impl Iterator<Item = (&'a Font, impl Iterator<Item = (GlyphInstance, f32)> + 'a)> + 'a {
+    pub fn glyphs_with_x_advance(
+        &self,
+    ) -> impl Iterator<Item = (&'a Font, impl Iterator<Item = (GlyphInstance, f32)> + use<'a>)> + use<'a> {
         let r = self.glyphs_range();
         self.text.seg_glyphs_with_x_advance(self.index, r)
     }
@@ -3768,7 +3766,9 @@ impl<'a> ShapedSegment<'a> {
     /// Glyphs per cluster in the segment, paired with the *x-advance* of the cluster.
     ///
     /// Yields `(Font, [(cluster, [glyph], advance)])`.
-    pub fn cluster_glyphs_with_x_advance(&self) -> impl Iterator<Item = (&Font, impl Iterator<Item = (u32, &[GlyphInstance], f32)>)> {
+    pub fn cluster_glyphs_with_x_advance(
+        &self,
+    ) -> impl Iterator<Item = (&'a Font, impl Iterator<Item = (u32, &'a [GlyphInstance], f32)> + use<'a>)> + use<'a> {
         let r = self.glyphs_range();
         self.text.seg_cluster_glyphs_with_x_advance(self.index, r)
     }
@@ -3899,7 +3899,7 @@ impl<'a> ShapedSegment<'a> {
     /// Underline spanning the word or spaces, skipping glyph descends that intercept the line.
     ///
     /// Returns an iterator of start point + width for underline segments.
-    pub fn underline_skip_glyphs(&self, thickness: Px) -> impl Iterator<Item = (PxPoint, Px)> + 'a {
+    pub fn underline_skip_glyphs(&self, thickness: Px) -> impl Iterator<Item = (PxPoint, Px)> + use<'a> {
         let y = (self.text.line_height * Px((self.line_index as i32) + 1)) - self.text.underline;
         let (x, _) = self.x_width();
 
@@ -3927,11 +3927,7 @@ impl<'a> ShapedSegment<'a> {
                     Px(px.round() as i32)
                 }
                 let r = (PxPoint::new(f32_to_px(self.x), self.y), f32_to_px(self.width));
-                if r.1 >= self.min_width {
-                    Some(r)
-                } else {
-                    None
-                }
+                if r.1 >= self.min_width { Some(r) } else { None }
             }
         }
         impl<'a, I, J> Iterator for UnderlineSkipGlyphs<'a, I, J>
@@ -4134,11 +4130,7 @@ impl<'a> ShapedSegment<'a> {
                 let middle_x = glyphs[0].point.x + advance / 2.0;
 
                 return if is_rtl {
-                    if x <= middle_x {
-                        char_b
-                    } else {
-                        char_a
-                    }
+                    if x <= middle_x { char_b } else { char_a }
                 } else if x <= middle_x {
                     char_a
                 } else {
@@ -4151,11 +4143,7 @@ impl<'a> ShapedSegment<'a> {
         if matches!(self.kind(), TextSegmentKind::LineBreak) {
             start = !start;
         }
-        if start {
-            txt_range.start
-        } else {
-            txt_range.end
-        }
+        if start { txt_range.start } else { txt_range.end }
     }
 
     /// Gets the segment index in the line.
@@ -4662,7 +4650,7 @@ fn into_harf_direction(d: LayoutDirection) -> rustybuzz::Direction {
 
 #[cfg(test)]
 mod tests {
-    use crate::{Font, FontManager, FontName, FontStretch, FontStyle, FontWeight, SegmentedText, TextShapingArgs, WordContextKey, FONTS};
+    use crate::{FONTS, Font, FontManager, FontName, FontStretch, FontStyle, FontWeight, SegmentedText, TextShapingArgs, WordContextKey};
     use zng_app::APP;
     use zng_ext_l10n::lang;
     use zng_layout::{
diff --git a/crates/zng-ext-fs-watcher/Cargo.toml b/crates/zng-ext-fs-watcher/Cargo.toml
index ec08cbf89..d5e7fe4dd 100644
--- a/crates/zng-ext-fs-watcher/Cargo.toml
+++ b/crates/zng-ext-fs-watcher/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-ext-fs-watcher"
 version = "0.3.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-ext-fs-watcher/src/lib.rs b/crates/zng-ext-fs-watcher/src/lib.rs
index 8426247e8..359883736 100644
--- a/crates/zng-ext-fs-watcher/src/lib.rs
+++ b/crates/zng-ext-fs-watcher/src/lib.rs
@@ -22,11 +22,11 @@ use std::{
 
 use path_absolutize::Absolutize;
 use zng_app::{
-    event::{event, event_args, EventHandle},
+    AppExtension,
+    event::{EventHandle, event, event_args},
     handler::{AppHandler, FilterAppHandler},
     update::EventUpdate,
     view_process::raw_events::LOW_MEMORY_EVENT,
-    AppExtension,
 };
 use zng_handle::Handle;
 use zng_txt::Txt;
diff --git a/crates/zng-ext-fs-watcher/src/service.rs b/crates/zng-ext-fs-watcher/src/service.rs
index 1bd8b58f8..c29b85c49 100644
--- a/crates/zng-ext-fs-watcher/src/service.rs
+++ b/crates/zng-ext-fs-watcher/src/service.rs
@@ -1,8 +1,8 @@
 use std::{
-    collections::{hash_map, HashMap},
+    collections::{HashMap, hash_map},
     io, mem,
     path::{Path, PathBuf},
-    sync::{atomic::AtomicBool, Arc},
+    sync::{Arc, atomic::AtomicBool},
     time::{Duration, SystemTime},
 };
 
@@ -11,21 +11,20 @@ use notify::Watcher;
 use parking_lot::Mutex;
 use path_absolutize::Absolutize;
 use zng_app::{
-    app_hn_once,
+    DInstant, INSTANT, app_hn_once,
     timer::{DeadlineHandle, TIMERS},
-    DInstant, INSTANT,
 };
-use zng_app_context::{app_local, LocalContext};
+use zng_app_context::{LocalContext, app_local};
 use zng_clone_move::clmv;
 use zng_handle::{Handle, HandleOwner};
 use zng_unit::TimeUnits;
 use zng_var::{
-    types::WeakArcVar, var, AnyVar, AnyVarHookArgs, AnyWeakVar, ArcVar, ReadOnlyArcVar, Var, VarUpdateId, VarValue, WeakVar, VARS,
+    AnyVar, AnyVarHookArgs, AnyWeakVar, ArcVar, ReadOnlyArcVar, VARS, Var, VarUpdateId, VarValue, WeakVar, types::WeakArcVar, var,
 };
 
 use crate::{
-    fs_event, FsChange, FsChangeNote, FsChangeNoteHandle, FsChangesArgs, WatchFile, WatcherHandle, WatcherReadStatus, WatcherSyncStatus,
-    WatcherSyncWriteNote, WriteFile, FS_CHANGES_EVENT, WATCHER,
+    FS_CHANGES_EVENT, FsChange, FsChangeNote, FsChangeNoteHandle, FsChangesArgs, WATCHER, WatchFile, WatcherHandle, WatcherReadStatus,
+    WatcherSyncStatus, WatcherSyncWriteNote, WriteFile, fs_event,
 };
 
 use zng_task as task;
@@ -1051,31 +1050,33 @@ impl notify::Watcher for PollWatcher {
         let mut dirs = HashMap::<PathBuf, PollInfo, _>::new();
         let worker = std::thread::Builder::new()
             .name(String::from("poll-watcher"))
-            .spawn(move || loop {
-                match rcv.recv_timeout(config.poll_interval_v2().unwrap_or_default()) {
-                    Ok(msg) => match msg {
-                        PollMsg::Watch(d, r) => {
-                            let info = PollInfo::new(&d, r);
-                            dirs.insert(d, info);
-                        }
-                        PollMsg::Unwatch(d) => {
-                            if dirs.remove(&d).is_none() {
-                                event_handler.handle_event(Err(notify::Error {
-                                    kind: notify::ErrorKind::WatchNotFound,
-                                    paths: vec![d],
-                                }))
+            .spawn(move || {
+                loop {
+                    match rcv.recv_timeout(config.poll_interval_v2().unwrap_or_default()) {
+                        Ok(msg) => match msg {
+                            PollMsg::Watch(d, r) => {
+                                let info = PollInfo::new(&d, r);
+                                dirs.insert(d, info);
                             }
-                        }
-                        PollMsg::SetConfig(c) => config = c,
-                    },
-                    Err(e) => match e {
-                        flume::RecvTimeoutError::Timeout => {}           // ok
-                        flume::RecvTimeoutError::Disconnected => return, // stop thread
-                    },
-                }
+                            PollMsg::Unwatch(d) => {
+                                if dirs.remove(&d).is_none() {
+                                    event_handler.handle_event(Err(notify::Error {
+                                        kind: notify::ErrorKind::WatchNotFound,
+                                        paths: vec![d],
+                                    }))
+                                }
+                            }
+                            PollMsg::SetConfig(c) => config = c,
+                        },
+                        Err(e) => match e {
+                            flume::RecvTimeoutError::Timeout => {}           // ok
+                            flume::RecvTimeoutError::Disconnected => return, // stop thread
+                        },
+                    }
 
-                for (dir, info) in &mut dirs {
-                    info.poll(dir, &mut event_handler);
+                    for (dir, info) in &mut dirs {
+                        info.poll(dir, &mut event_handler);
+                    }
                 }
             })
             .expect("failed to spawn poll-watcher thread");
diff --git a/crates/zng-ext-hot-reload-proc-macros/Cargo.toml b/crates/zng-ext-hot-reload-proc-macros/Cargo.toml
index 8c6171116..9f65e728f 100644
--- a/crates/zng-ext-hot-reload-proc-macros/Cargo.toml
+++ b/crates/zng-ext-hot-reload-proc-macros/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-ext-hot-reload-proc-macros"
 version = "0.1.2"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-ext-hot-reload-proc-macros/src/util.rs b/crates/zng-ext-hot-reload-proc-macros/src/util.rs
index 11ad12acb..8ba684c5a 100644
--- a/crates/zng-ext-hot-reload-proc-macros/src/util.rs
+++ b/crates/zng-ext-hot-reload-proc-macros/src/util.rs
@@ -1,5 +1,5 @@
 use proc_macro2::{Span, TokenStream};
-use quote::{quote_spanned, ToTokens};
+use quote::{ToTokens, quote_spanned};
 
 /// `Ident` with custom span.
 macro_rules! ident_spanned {
diff --git a/crates/zng-ext-hot-reload/Cargo.toml b/crates/zng-ext-hot-reload/Cargo.toml
index fc25885cc..d8302c231 100644
--- a/crates/zng-ext-hot-reload/Cargo.toml
+++ b/crates/zng-ext-hot-reload/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-ext-hot-reload"
 version = "0.2.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-ext-hot-reload/src/cargo.rs b/crates/zng-ext-hot-reload/src/cargo.rs
index 3b65c5564..681464b05 100644
--- a/crates/zng-ext-hot-reload/src/cargo.rs
+++ b/crates/zng-ext-hot-reload/src/cargo.rs
@@ -114,7 +114,7 @@ fn run_build(manifest_path: PathBuf, stdout: ChildStdout) -> Result<PathBuf, Bui
                 None => {
                     return Err(BuildError::UnknownMessageFormat {
                         pat: MANIFEST_FIELD.into(),
-                    })
+                    });
                 }
             };
             let line = &line[i + MANIFEST_FIELD.len()..];
@@ -123,7 +123,7 @@ fn run_build(manifest_path: PathBuf, stdout: ChildStdout) -> Result<PathBuf, Bui
                 None => {
                     return Err(BuildError::UnknownMessageFormat {
                         pat: MANIFEST_FIELD.into(),
-                    })
+                    });
                 }
             };
             let line_manifest = PathBuf::from(&line[..i]);
@@ -138,7 +138,7 @@ fn run_build(manifest_path: PathBuf, stdout: ChildStdout) -> Result<PathBuf, Bui
                 None => {
                     return Err(BuildError::UnknownMessageFormat {
                         pat: FILENAMES_FIELD.into(),
-                    })
+                    });
                 }
             };
             let line = &line[i + FILENAMES_FIELD.len()..];
@@ -147,7 +147,7 @@ fn run_build(manifest_path: PathBuf, stdout: ChildStdout) -> Result<PathBuf, Bui
                 None => {
                     return Err(BuildError::UnknownMessageFormat {
                         pat: FILENAMES_FIELD.into(),
-                    })
+                    });
                 }
             };
 
diff --git a/crates/zng-ext-hot-reload/src/lib.rs b/crates/zng-ext-hot-reload/src/lib.rs
index e5577bc2b..1f7efe95b 100644
--- a/crates/zng-ext-hot-reload/src/lib.rs
+++ b/crates/zng-ext-hot-reload/src/lib.rs
@@ -24,15 +24,15 @@ pub use cargo::BuildError;
 use node::*;
 
 use zng_app::{
+    AppExtension, DInstant, INSTANT,
     event::{event, event_args},
     handler::async_clmv,
     update::UPDATES,
-    AppExtension, DInstant, INSTANT,
 };
-use zng_app_context::{app_local, LocalContext};
+use zng_app_context::{LocalContext, app_local};
 use zng_ext_fs_watcher::WATCHER;
 pub use zng_ext_hot_reload_proc_macros::hot_node;
-use zng_task::{parking_lot::Mutex, SignalOnce};
+use zng_task::{SignalOnce, parking_lot::Mutex};
 use zng_txt::Txt;
 use zng_unique_id::hot_reload::HOT_STATICS;
 use zng_unit::TimeUnits as _;
@@ -44,13 +44,17 @@ pub use zng_unique_id::{hot_static, hot_static_ref, lazy_static};
 /// Declare hot reload entry.
 ///
 /// Must be called at the root of the crate.
+///
+/// # Safety
+///
+/// Must be called only once at the hot-reload crate.
 #[macro_export]
 macro_rules! zng_hot_entry {
     () => {
         #[doc(hidden)] // used by proc-macro
         pub use $crate::zng_hot_entry;
 
-        #[no_mangle]
+        #[unsafe(no_mangle)] // SAFETY: docs struct users to call the macro only once, name is unlikely to have collisions.
         #[doc(hidden)] // used by lib loader
         pub extern "C" fn zng_hot_entry(
             manifest_dir: &&str,
@@ -61,7 +65,7 @@ macro_rules! zng_hot_entry {
             $crate::zng_hot_entry::entry(manifest_dir, node_name, ctx, exchange)
         }
 
-        #[no_mangle]
+        #[unsafe(no_mangle)] // SAFETY: docs struct users to call the macro only once, name is unlikely to have collisions.
         #[doc(hidden)]
         pub extern "C" fn zng_hot_entry_init(patch: &$crate::StaticPatch) {
             $crate::zng_hot_entry::init(patch)
@@ -148,7 +152,10 @@ impl StaticPatch {
         for (key, patch) in HOT_STATICS.iter() {
             if let Some(val) = self.entries.get(key) {
                 // println!("patched `{key:?}`");
-                patch(val(std::ptr::null()));
+                // SAFETY: HOT_STATICS is defined using linkme, so all entries are defined by the hot_static! macro
+                unsafe {
+                    patch(val(std::ptr::null()));
+                }
             } else {
                 eprintln!("did not find `{key:?}` to patch, static references may fail");
             }
diff --git a/crates/zng-ext-hot-reload/src/node.rs b/crates/zng-ext-hot-reload/src/node.rs
index 4d62ce9f3..e683ca2ee 100644
--- a/crates/zng-ext-hot-reload/src/node.rs
+++ b/crates/zng-ext-hot-reload/src/node.rs
@@ -4,9 +4,9 @@ use zng_app::{
     render::{FrameBuilder, FrameUpdate},
     update::{EventUpdate, WidgetUpdates},
     widget::{
+        WIDGET, WidgetUpdateMode,
         info::{WidgetInfoBuilder, WidgetLayout, WidgetMeasure},
         node::{ArcNode, ArcNodeList, BoxedUiNode, BoxedUiNodeList, NilUiNode, UiNode, UiNodeList},
-        WidgetUpdateMode, WIDGET,
     },
 };
 use zng_app_context::LocalContext;
diff --git a/crates/zng-ext-image/Cargo.toml b/crates/zng-ext-image/Cargo.toml
index 5198bb76b..2f64576fa 100644
--- a/crates/zng-ext-image/Cargo.toml
+++ b/crates/zng-ext-image/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-ext-image"
 version = "0.3.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-ext-image/src/lib.rs b/crates/zng-ext-image/src/lib.rs
index a43c1d34c..7cdbf7066 100644
--- a/crates/zng-ext-image/src/lib.rs
+++ b/crates/zng-ext-image/src/lib.rs
@@ -10,26 +10,24 @@
 #![warn(missing_docs)]
 
 use std::{
-    env,
-    future::{Future, IntoFuture},
-    mem,
+    env, mem,
     path::{Path, PathBuf},
     sync::{
-        atomic::{AtomicBool, Ordering},
         Arc,
+        atomic::{AtomicBool, Ordering},
     },
 };
 
 use parking_lot::Mutex;
 use task::io::AsyncReadExt;
 use zng_app::{
+    AppExtension,
     update::EventUpdate,
     view_process::{
-        raw_events::{LOW_MEMORY_EVENT, RAW_IMAGE_LOADED_EVENT, RAW_IMAGE_LOAD_ERROR_EVENT, RAW_IMAGE_METADATA_LOADED_EVENT},
-        ViewImage, VIEW_PROCESS, VIEW_PROCESS_INITED_EVENT,
+        VIEW_PROCESS, VIEW_PROCESS_INITED_EVENT, ViewImage,
+        raw_events::{LOW_MEMORY_EVENT, RAW_IMAGE_LOAD_ERROR_EVENT, RAW_IMAGE_LOADED_EVENT, RAW_IMAGE_METADATA_LOADED_EVENT},
     },
     widget::UiTaskWidget,
-    AppExtension,
 };
 use zng_app_context::app_local;
 use zng_clone_move::{async_clmv, clmv};
@@ -40,13 +38,13 @@ pub use types::*;
 
 mod render;
 #[doc(inline)]
-pub use render::{render_retain, ImageRenderWindowRoot, ImageRenderWindowsService, IMAGES_WINDOW, IMAGE_RENDER};
+pub use render::{IMAGE_RENDER, IMAGES_WINDOW, ImageRenderWindowRoot, ImageRenderWindowsService, render_retain};
 use zng_layout::unit::{ByteLength, ByteUnits};
 use zng_task::UiTask;
-use zng_txt::{formatx, ToTxt, Txt};
+use zng_txt::{ToTxt, Txt, formatx};
 use zng_unique_id::{IdEntry, IdMap};
-use zng_var::{types::WeakArcVar, var, AnyVar, AnyWeakVar, ArcVar, Var, WeakVar};
-use zng_view_api::{image::ImageRequest, ipc::IpcBytes, ViewProcessOffline};
+use zng_var::{AnyVar, AnyWeakVar, ArcVar, Var, WeakVar, types::WeakArcVar, var};
+use zng_view_api::{ViewProcessOffline, image::ImageRequest, ipc::IpcBytes};
 
 /// Application extension that provides an image cache.
 ///
@@ -534,7 +532,7 @@ impl ImagesService {
                         limits,
                         downscale,
                         mask,
-                    )
+                    );
                 }
                 ProxyGetResult::Image(img) => {
                     IMAGES_SV.write().proxies.append(&mut proxies);
diff --git a/crates/zng-ext-image/src/render.rs b/crates/zng-ext-image/src/render.rs
index 8ed52d9e8..1ee09389e 100644
--- a/crates/zng-ext-image/src/render.rs
+++ b/crates/zng-ext-image/src/render.rs
@@ -3,17 +3,18 @@ use std::{any::Any, sync::Arc};
 use zng_app::{
     update::{EventUpdate, UPDATES},
     widget::{
-        node::{match_node, BoxedUiNode, UiNode, UiNodeOp},
-        property, WIDGET,
+        WIDGET,
+        node::{BoxedUiNode, UiNode, UiNodeOp, match_node},
+        property,
     },
-    window::{WindowId, WINDOW},
+    window::{WINDOW, WindowId},
 };
 use zng_layout::unit::Factor;
-use zng_state_map::{static_id, StateId};
-use zng_var::{types::WeakArcVar, var, ArcVar, IntoVar, Var, WeakVar};
+use zng_state_map::{StateId, static_id};
+use zng_var::{ArcVar, IntoVar, Var, WeakVar, types::WeakArcVar, var};
 use zng_view_api::{image::ImageMaskMode, window::RenderMode};
 
-use crate::{ImageManager, ImageRenderArgs, ImageSource, ImageVar, ImagesService, Img, IMAGES, IMAGES_SV};
+use crate::{IMAGES, IMAGES_SV, ImageManager, ImageRenderArgs, ImageSource, ImageVar, ImagesService, Img};
 
 impl ImagesService {
     fn render<N, R>(&mut self, mask: Option<ImageMaskMode>, render: N) -> ImageVar
diff --git a/crates/zng-ext-image/src/types.rs b/crates/zng-ext-image/src/types.rs
index c4807a4ca..8b276630e 100644
--- a/crates/zng-ext-image/src/types.rs
+++ b/crates/zng-ext-image/src/types.rs
@@ -17,8 +17,8 @@ use zng_layout::{
 };
 use zng_task::{self as task, SignalOnce};
 use zng_txt::Txt;
-use zng_var::{impl_from_and_into_var, AnyVar, ReadOnlyArcVar};
-use zng_view_api::{image::ImageTextureId, ViewProcessOffline};
+use zng_var::{AnyVar, ReadOnlyArcVar, impl_from_and_into_var};
+use zng_view_api::{ViewProcessOffline, image::ImageTextureId};
 
 use crate::render::ImageRenderWindowRoot;
 
@@ -214,13 +214,13 @@ impl Img {
     /// Returns an error message if the image failed to load.
     pub fn error(&self) -> Option<Txt> {
         match self.view.get() {
-            Some(v) => v.error().map(Txt::from),
+            Some(v) => v.error(),
             None => None,
         }
     }
 
     /// Returns a future that awaits until this image is loaded or encountered an error.
-    pub fn wait_done(&self) -> impl std::future::Future<Output = ()> + Send + Sync + 'static {
+    pub fn wait_done(&self) -> impl Future<Output = ()> + Send + Sync + 'static {
         self.done_signal.clone()
     }
 
diff --git a/crates/zng-ext-input/Cargo.toml b/crates/zng-ext-input/Cargo.toml
index 9ef70b361..dbf5c0896 100644
--- a/crates/zng-ext-input/Cargo.toml
+++ b/crates/zng-ext-input/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-ext-input"
 version = "0.6.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-ext-input/src/drag_drop.rs b/crates/zng-ext-input/src/drag_drop.rs
index cf38f3605..f2f8d6eab 100644
--- a/crates/zng-ext-input/src/drag_drop.rs
+++ b/crates/zng-ext-input/src/drag_drop.rs
@@ -6,27 +6,27 @@ use std::{mem, sync::Arc};
 
 use parking_lot::Mutex;
 use zng_app::{
-    event::{event, event_args, AnyEventArgs},
+    AppExtension,
+    event::{AnyEventArgs, event, event_args},
     static_id,
     update::{EventUpdate, UPDATES},
     view_process::raw_events::{
         RAW_APP_DRAG_ENDED_EVENT, RAW_DRAG_CANCELLED_EVENT, RAW_DRAG_DROPPED_EVENT, RAW_DRAG_HOVERED_EVENT, RAW_DRAG_MOVED_EVENT,
     },
     widget::{
+        WIDGET, WidgetId,
         info::{HitTestInfo, InteractionPath, WidgetInfo, WidgetInfoBuilder},
-        WidgetId, WIDGET,
     },
     window::WindowId,
-    AppExtension,
 };
 use zng_app_context::app_local;
 use zng_ext_window::{NestedWindowWidgetInfoExt as _, WINDOWS, WINDOWS_DRAG_DROP};
 use zng_handle::{Handle, HandleOwner, WeakHandle};
 use zng_layout::unit::{DipPoint, DipToPx as _, PxToDip as _};
 use zng_state_map::StateId;
-use zng_txt::{formatx, Txt};
-use zng_var::{var, ArcVar, ReadOnlyArcVar, Var};
-use zng_view_api::{mouse::ButtonState, touch::TouchPhase, DragDropId};
+use zng_txt::{Txt, formatx};
+use zng_var::{ArcVar, ReadOnlyArcVar, Var, var};
+use zng_view_api::{DragDropId, mouse::ButtonState, touch::TouchPhase};
 
 use crate::{mouse::MOUSE_INPUT_EVENT, touch::TOUCH_INPUT_EVENT};
 
diff --git a/crates/zng-ext-input/src/focus.rs b/crates/zng-ext-input/src/focus.rs
index b3485f86e..ac1da88f8 100644
--- a/crates/zng-ext-input/src/focus.rs
+++ b/crates/zng-ext-input/src/focus.rs
@@ -6,25 +6,25 @@ mod focus_info;
 pub use focus_info::*;
 
 use zng_app::{
+    AppExtension, DInstant, INSTANT,
     access::{ACCESS_CLICK_EVENT, ACCESS_FOCUS_EVENT, ACCESS_FOCUS_NAV_ORIGIN_EVENT},
     event::{event, event_args},
     update::{EventUpdate, InfoUpdates, RenderUpdates, UPDATES},
     view_process::raw_events::RAW_KEY_INPUT_EVENT,
     widget::{
-        info::{InteractionPath, WidgetBoundsInfo, WidgetInfoTree, WIDGET_INFO_CHANGED_EVENT},
         WidgetId,
+        info::{InteractionPath, WIDGET_INFO_CHANGED_EVENT, WidgetBoundsInfo, WidgetInfoTree},
     },
     window::WindowId,
-    AppExtension, DInstant, INSTANT,
 };
 
 pub mod cmd;
 use cmd::FocusCommands;
 use zng_app_context::app_local;
-use zng_ext_window::{WINDOWS, WINDOW_FOCUS, WINDOW_FOCUS_CHANGED_EVENT};
+use zng_ext_window::{WINDOW_FOCUS, WINDOW_FOCUS_CHANGED_EVENT, WINDOWS};
 use zng_layout::unit::{Px, PxPoint, PxRect, TimeUnits};
 use zng_unique_id::{IdEntry, IdMap};
-use zng_var::{var, AnyVar, ArcVar, ReadOnlyArcVar, Var};
+use zng_var::{AnyVar, ArcVar, ReadOnlyArcVar, Var, var};
 use zng_view_api::window::FrameId;
 
 use std::{mem, time::Duration};
diff --git a/crates/zng-ext-input/src/focus/cmd.rs b/crates/zng-ext-input/src/focus/cmd.rs
index 9e262a608..fe7644a1e 100644
--- a/crates/zng-ext-input/src/focus/cmd.rs
+++ b/crates/zng-ext-input/src/focus/cmd.rs
@@ -3,12 +3,12 @@
 //! [`Command`]: zng_app::event::Command
 
 use zng_app::{
-    event::{command, Command, CommandHandle, CommandInfoExt, CommandNameExt, CommandScope, EventArgs},
-    shortcut::{shortcut, CommandShortcutExt},
+    event::{Command, CommandHandle, CommandInfoExt, CommandNameExt, CommandScope, EventArgs, command},
+    shortcut::{CommandShortcutExt, shortcut},
     update::EventUpdate,
     widget::info::WidgetInfo,
 };
-use zng_var::{merge_var, BoxedVar};
+use zng_var::{BoxedVar, merge_var};
 
 use super::*;
 
diff --git a/crates/zng-ext-input/src/focus/focus_info.rs b/crates/zng-ext-input/src/focus/focus_info.rs
index a9284fe18..20cfe0beb 100644
--- a/crates/zng-ext-input/src/focus/focus_info.rs
+++ b/crates/zng-ext-input/src/focus/focus_info.rs
@@ -5,14 +5,14 @@ use atomic::Atomic;
 use parking_lot::Mutex;
 use zng_app::{
     widget::{
-        info::{TreeFilter, Visibility, WidgetInfo, WidgetInfoBuilder, WidgetInfoTree, WidgetPath},
         WidgetId,
+        info::{TreeFilter, Visibility, WidgetInfo, WidgetInfoBuilder, WidgetInfoTree, WidgetPath},
     },
     window::WindowId,
 };
 use zng_ext_window::NestedWindowWidgetInfoExt;
 use zng_layout::unit::{DistanceKey, Orientation2D, Px, PxBox, PxPoint, PxRect, PxSize};
-use zng_state_map::{static_id, StateId};
+use zng_state_map::{StateId, static_id};
 use zng_unique_id::IdSet;
 use zng_var::impl_from_and_into_var;
 use zng_view_api::window::FocusIndicator;
@@ -592,11 +592,7 @@ impl WidgetInfoFocusExt for WidgetInfo {
     }
     fn into_focusable(self, focus_disabled_widgets: bool, focus_hidden_widgets: bool) -> Option<WidgetFocusInfo> {
         let r = self.into_focus_info(focus_disabled_widgets, focus_hidden_widgets);
-        if r.is_focusable() {
-            Some(r)
-        } else {
-            None
-        }
+        if r.is_focusable() { Some(r) } else { None }
     }
 }
 
@@ -784,11 +780,7 @@ impl WidgetFocusInfo {
         let focus_hidden_widgets = self.focus_hidden_widgets();
         self.info.ancestors().filter_map(move |i| {
             let i = i.into_focus_info(focus_disabled_widgets, focus_hidden_widgets);
-            if i.is_scope() {
-                Some(i)
-            } else {
-                None
-            }
+            if i.is_scope() { Some(i) } else { None }
         })
     }
 
@@ -962,11 +954,7 @@ impl WidgetFocusInfo {
             }
         }
 
-        if best.0.is_skip() {
-            None
-        } else {
-            Some(best.1)
-        }
+        if best.0.is_skip() { None } else { Some(best.1) }
     }
 
     /// Last descendant considering TAB index.
@@ -981,11 +969,7 @@ impl WidgetFocusInfo {
             }
         }
 
-        if best.0 < 0 {
-            None
-        } else {
-            Some(best.1)
-        }
+        if best.0 < 0 { None } else { Some(best.1) }
     }
 
     /// Iterator over all focusable widgets in the same scope after this widget.
@@ -1068,11 +1052,7 @@ impl WidgetFocusInfo {
             }
         }
 
-        if best.0.is_skip() {
-            None
-        } else {
-            Some(best.1)
-        }
+        if best.0.is_skip() { None } else { Some(best.1) }
     }
 
     /// Iterator over all focusable widgets in the same scope before this widget in reverse.
@@ -1148,11 +1128,7 @@ impl WidgetFocusInfo {
             }
         }
 
-        if best.0 < 0 {
-            None
-        } else {
-            Some(best.1)
-        }
+        if best.0 < 0 { None } else { Some(best.1) }
     }
 
     /// Widget to focus when pressing TAB from this widget.
diff --git a/crates/zng-ext-input/src/focus/iter.rs b/crates/zng-ext-input/src/focus/iter.rs
index b93204c7a..2548efb70 100644
--- a/crates/zng-ext-input/src/focus/iter.rs
+++ b/crates/zng-ext-input/src/focus/iter.rs
@@ -2,8 +2,8 @@
 //!
 
 use zng_app::widget::info::{
-    iter::{self as w_iter, TreeIterator},
     WidgetInfo,
+    iter::{self as w_iter, TreeIterator},
 };
 
 use super::*;
diff --git a/crates/zng-ext-input/src/gesture.rs b/crates/zng-ext-input/src/gesture.rs
index c9036d372..47a07e604 100644
--- a/crates/zng-ext-input/src/gesture.rs
+++ b/crates/zng-ext-input/src/gesture.rs
@@ -9,36 +9,36 @@ use std::{
     time::Duration,
 };
 use zng_app::{
-    access::{AccessClickArgs, ACCESS_CLICK_EVENT},
-    event::{event, event_args, AnyEventArgs, Command, CommandScope, EventPropagationHandle, EVENTS},
+    AppExtension, DInstant, HeadlessApp,
+    access::{ACCESS_CLICK_EVENT, AccessClickArgs},
+    event::{AnyEventArgs, Command, CommandScope, EVENTS, EventPropagationHandle, event, event_args},
     shortcut::{
-        shortcut, CommandShortcutExt, GestureKey, KeyChord, KeyGesture, ModifierGesture, ModifiersState, Shortcut, ShortcutFilter,
-        Shortcuts,
+        CommandShortcutExt, GestureKey, KeyChord, KeyGesture, ModifierGesture, ModifiersState, Shortcut, ShortcutFilter, Shortcuts,
+        shortcut,
     },
     update::EventUpdate,
     view_process::raw_device_events::DeviceId,
     widget::{
-        info::{HitTestInfo, InteractionPath, WidgetPath},
         WidgetId,
+        info::{HitTestInfo, InteractionPath, WidgetPath},
     },
     window::WindowId,
-    AppExtension, DInstant, HeadlessApp,
 };
 use zng_app_context::app_local;
 use zng_ext_window::WINDOWS;
 use zng_handle::{Handle, HandleOwner, WeakHandle};
 use zng_layout::unit::DipPoint;
-use zng_var::{var, ArcVar, Var};
+use zng_var::{ArcVar, Var, var};
 use zng_view_api::{
     keyboard::{Key, KeyCode, KeyLocation, KeyState, NativeKeyCode},
     mouse::MouseButton,
 };
 
 use crate::{
-    focus::{FocusRequest, FocusTarget, FOCUS},
-    keyboard::{HeadlessAppKeyboardExt, KeyInputArgs, KEY_INPUT_EVENT},
-    mouse::{MouseClickArgs, MOUSE_CLICK_EVENT},
-    touch::{TouchLongPressArgs, TouchTapArgs, TOUCH_LONG_PRESS_EVENT, TOUCH_TAP_EVENT},
+    focus::{FOCUS, FocusRequest, FocusTarget},
+    keyboard::{HeadlessAppKeyboardExt, KEY_INPUT_EVENT, KeyInputArgs},
+    mouse::{MOUSE_CLICK_EVENT, MouseClickArgs},
+    touch::{TOUCH_LONG_PRESS_EVENT, TOUCH_TAP_EVENT, TouchLongPressArgs, TouchTapArgs},
 };
 
 /// Specific information from the source of a [`ClickArgs`].
diff --git a/crates/zng-ext-input/src/keyboard.rs b/crates/zng-ext-input/src/keyboard.rs
index 3da4ab9bb..5fa8e32f9 100644
--- a/crates/zng-ext-input/src/keyboard.rs
+++ b/crates/zng-ext-input/src/keyboard.rs
@@ -3,27 +3,27 @@
 use std::{collections::HashSet, time::Duration};
 
 use zng_app::{
+    AppExtension, DInstant, HeadlessApp,
     event::{event, event_args},
     shortcut::ModifiersState,
     update::EventUpdate,
     view_process::{
+        VIEW_PROCESS_INITED_EVENT,
         raw_device_events::DeviceId,
         raw_events::{
-            RawKeyInputArgs, RAW_ANIMATIONS_CONFIG_CHANGED_EVENT, RAW_KEY_INPUT_EVENT, RAW_KEY_REPEAT_CONFIG_CHANGED_EVENT,
-            RAW_WINDOW_FOCUS_EVENT,
+            RAW_ANIMATIONS_CONFIG_CHANGED_EVENT, RAW_KEY_INPUT_EVENT, RAW_KEY_REPEAT_CONFIG_CHANGED_EVENT, RAW_WINDOW_FOCUS_EVENT,
+            RawKeyInputArgs,
         },
-        VIEW_PROCESS_INITED_EVENT,
     },
-    widget::{info::InteractionPath, WidgetId},
+    widget::{WidgetId, info::InteractionPath},
     window::WindowId,
-    AppExtension, DInstant, HeadlessApp,
 };
 use zng_app_context::app_local;
 use zng_clone_move::clmv;
 use zng_ext_window::WINDOWS;
 use zng_layout::unit::{Factor, FactorUnits};
 use zng_txt::Txt;
-use zng_var::{types::ArcCowVar, var, var_default, ArcVar, ReadOnlyArcVar, Var};
+use zng_var::{ArcVar, ReadOnlyArcVar, Var, types::ArcCowVar, var, var_default};
 use zng_view_api::config::AnimationsConfig;
 pub use zng_view_api::{
     config::KeyRepeatConfig,
diff --git a/crates/zng-ext-input/src/mouse.rs b/crates/zng-ext-input/src/mouse.rs
index e6b032855..4447e7170 100644
--- a/crates/zng-ext-input/src/mouse.rs
+++ b/crates/zng-ext-input/src/mouse.rs
@@ -5,30 +5,30 @@
 use std::{collections::HashMap, mem, num::NonZeroU32, time::*};
 
 use zng_app::{
-    event::{event, event_args, EventPropagationHandle},
+    AppExtension, DInstant, INSTANT,
+    event::{EventPropagationHandle, event, event_args},
     shortcut::ModifiersState,
     timer::{DeadlineVar, TIMERS},
     update::EventUpdate,
     view_process::{
+        VIEW_PROCESS_INITED_EVENT,
         raw_device_events::DeviceId,
         raw_events::{
             RAW_FRAME_RENDERED_EVENT, RAW_MOUSE_INPUT_EVENT, RAW_MOUSE_LEFT_EVENT, RAW_MOUSE_MOVED_EVENT, RAW_MOUSE_WHEEL_EVENT,
             RAW_MULTI_CLICK_CONFIG_CHANGED_EVENT, RAW_WINDOW_FOCUS_EVENT,
         },
-        VIEW_PROCESS_INITED_EVENT,
     },
     widget::{
-        info::{HitTestInfo, InteractionPath, WidgetInfo, WidgetInfoBuilder, WIDGET_INFO_CHANGED_EVENT},
-        WidgetId, WIDGET,
+        WIDGET, WidgetId,
+        info::{HitTestInfo, InteractionPath, WIDGET_INFO_CHANGED_EVENT, WidgetInfo, WidgetInfoBuilder},
     },
     window::WindowId,
-    AppExtension, DInstant, INSTANT,
 };
 use zng_app_context::app_local;
 use zng_ext_window::{NestedWindowWidgetInfoExt, WINDOWS};
 use zng_layout::unit::{Dip, DipPoint, DipToPx, Factor, PxPoint, PxToDip};
-use zng_state_map::{state_map, static_id, StateId};
-use zng_var::{impl_from_and_into_var, types::ArcCowVar, var, ArcVar, BoxedVar, IntoVar, LocalVar, ReadOnlyArcVar, Var};
+use zng_state_map::{StateId, state_map, static_id};
+use zng_var::{ArcVar, BoxedVar, IntoVar, LocalVar, ReadOnlyArcVar, Var, impl_from_and_into_var, types::ArcCowVar, var};
 use zng_view_api::touch::TouchPhase;
 pub use zng_view_api::{
     config::MultiClickConfig,
@@ -627,11 +627,7 @@ impl MouseWheelArgs {
     ///
     /// [`modifiers`]: Self::modifiers
     pub fn zoom_delta(&self) -> Option<MouseScrollDelta> {
-        if self.is_zoom() {
-            Some(self.delta)
-        } else {
-            None
-        }
+        if self.is_zoom() { Some(self.delta) } else { None }
     }
 
     /// Returns `true` if the widget is enabled in [`target`].
diff --git a/crates/zng-ext-input/src/pointer_capture.rs b/crates/zng-ext-input/src/pointer_capture.rs
index e6e8fccfd..b35c477f6 100644
--- a/crates/zng-ext-input/src/pointer_capture.rs
+++ b/crates/zng-ext-input/src/pointer_capture.rs
@@ -6,27 +6,27 @@ use std::{
 };
 
 use zng_app::{
+    AppExtension,
     event::{event, event_args},
     update::{EventUpdate, UPDATES},
     view_process::{
+        VIEW_PROCESS_INITED_EVENT,
         raw_device_events::DeviceId,
         raw_events::{
             RAW_FRAME_RENDERED_EVENT, RAW_MOUSE_INPUT_EVENT, RAW_MOUSE_MOVED_EVENT, RAW_TOUCH_EVENT, RAW_WINDOW_CLOSE_EVENT,
             RAW_WINDOW_FOCUS_EVENT,
         },
-        VIEW_PROCESS_INITED_EVENT,
     },
     widget::{
-        info::{InteractionPath, WidgetInfoTree, WidgetPath, WIDGET_INFO_CHANGED_EVENT},
-        WidgetId, WIDGET,
+        WIDGET, WidgetId,
+        info::{InteractionPath, WIDGET_INFO_CHANGED_EVENT, WidgetInfoTree, WidgetPath},
     },
-    window::{WindowId, WINDOW},
-    AppExtension,
+    window::{WINDOW, WindowId},
 };
 use zng_app_context::app_local;
 use zng_ext_window::{NestedWindowWidgetInfoExt, WINDOWS};
 use zng_layout::unit::{DipPoint, DipToPx};
-use zng_var::{impl_from_and_into_var, var, ArcVar, ReadOnlyArcVar, Var};
+use zng_var::{ArcVar, ReadOnlyArcVar, Var, impl_from_and_into_var, var};
 use zng_view_api::{
     mouse::{ButtonState, MouseButton},
     touch::{TouchId, TouchPhase},
diff --git a/crates/zng-ext-input/src/touch.rs b/crates/zng-ext-input/src/touch.rs
index c9a7a7bfa..0a5150e2a 100644
--- a/crates/zng-ext-input/src/touch.rs
+++ b/crates/zng-ext-input/src/touch.rs
@@ -4,29 +4,29 @@
 
 use std::{collections::HashMap, mem, num::NonZeroU32, ops, time::Duration};
 use zng_app::{
-    event::{event, event_args, AnyEventArgs, EventPropagationHandle},
+    AppExtension, DInstant,
+    event::{AnyEventArgs, EventPropagationHandle, event, event_args},
     shortcut::ModifiersState,
     timer::{DeadlineVar, TIMERS},
     update::EventUpdate,
     view_process::{
-        raw_device_events::DeviceId,
-        raw_events::{RawTouchArgs, RAW_FRAME_RENDERED_EVENT, RAW_MOUSE_LEFT_EVENT, RAW_TOUCH_CONFIG_CHANGED_EVENT, RAW_TOUCH_EVENT},
         VIEW_PROCESS_INITED_EVENT,
+        raw_device_events::DeviceId,
+        raw_events::{RAW_FRAME_RENDERED_EVENT, RAW_MOUSE_LEFT_EVENT, RAW_TOUCH_CONFIG_CHANGED_EVENT, RAW_TOUCH_EVENT, RawTouchArgs},
     },
     widget::{
+        WIDGET, WidgetId,
         info::{HitTestInfo, InteractionPath, WIDGET_INFO_CHANGED_EVENT},
-        WidgetId, WIDGET,
     },
     window::WindowId,
-    AppExtension, DInstant,
 };
 
 use zng_app_context::app_local;
 use zng_ext_window::{NestedWindowWidgetInfoExt as _, WINDOWS};
 use zng_layout::unit::{
-    euclid, AngleRadian, Dip, DipPoint, DipToPx, DipVector, Factor, Px, PxPoint, PxToDip, PxTransform, PxVector, TimeUnits,
+    AngleRadian, Dip, DipPoint, DipToPx, DipVector, Factor, Px, PxPoint, PxToDip, PxTransform, PxVector, TimeUnits, euclid,
 };
-use zng_var::{impl_from_and_into_var, types::ArcCowVar, var, ArcVar, ReadOnlyArcVar, Var};
+use zng_var::{ArcVar, ReadOnlyArcVar, Var, impl_from_and_into_var, types::ArcCowVar, var};
 pub use zng_view_api::{
     config::TouchConfig,
     touch::{TouchForce, TouchId, TouchPhase, TouchUpdate},
diff --git a/crates/zng-ext-l10n-proc-macros/Cargo.toml b/crates/zng-ext-l10n-proc-macros/Cargo.toml
index a8c209707..c3b4f3b22 100644
--- a/crates/zng-ext-l10n-proc-macros/Cargo.toml
+++ b/crates/zng-ext-l10n-proc-macros/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-ext-l10n-proc-macros"
 version = "0.2.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-ext-l10n-proc-macros/src/lang.rs b/crates/zng-ext-l10n-proc-macros/src/lang.rs
index acb03a0d1..52711c86f 100644
--- a/crates/zng-ext-l10n-proc-macros/src/lang.rs
+++ b/crates/zng-ext-l10n-proc-macros/src/lang.rs
@@ -1,7 +1,7 @@
 use proc_macro2::TokenStream;
 use quote::{quote, quote_spanned};
 use std::str::FromStr;
-use syn::{ext::IdentExt, parse::Parse, parse_macro_input, Ident, LitStr};
+use syn::{Ident, LitStr, ext::IdentExt, parse::Parse, parse_macro_input};
 
 pub fn expand(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
     let Input { unic_langid, lang } = parse_macro_input!(input as Input);
diff --git a/crates/zng-ext-l10n-proc-macros/src/util.rs b/crates/zng-ext-l10n-proc-macros/src/util.rs
index bd534a8b4..6b96b4339 100644
--- a/crates/zng-ext-l10n-proc-macros/src/util.rs
+++ b/crates/zng-ext-l10n-proc-macros/src/util.rs
@@ -1,5 +1,5 @@
 use proc_macro2::{Span, TokenStream};
-use quote::{quote_spanned, ToTokens};
+use quote::{ToTokens, quote_spanned};
 
 /// Collection of compile errors.
 #[derive(Default)]
diff --git a/crates/zng-ext-l10n/Cargo.toml b/crates/zng-ext-l10n/Cargo.toml
index aebc9b1a9..65f7bbf14 100644
--- a/crates/zng-ext-l10n/Cargo.toml
+++ b/crates/zng-ext-l10n/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-ext-l10n"
 version = "0.6.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-ext-l10n/src/lib.rs b/crates/zng-ext-l10n/src/lib.rs
index 9d5262fab..a5b863f95 100644
--- a/crates/zng-ext-l10n/src/lib.rs
+++ b/crates/zng-ext-l10n/src/lib.rs
@@ -13,16 +13,16 @@ use std::{collections::HashMap, path::PathBuf, sync::Arc};
 
 use semver::Version;
 use zng_app::{
+    AppExtension,
     event::{Command, CommandMetaVar, EVENTS_L10N},
     update::EventUpdate,
-    view_process::{raw_events::RAW_LOCALE_CONFIG_CHANGED_EVENT, VIEW_PROCESS_INITED_EVENT},
-    AppExtension,
+    view_process::{VIEW_PROCESS_INITED_EVENT, raw_events::RAW_LOCALE_CONFIG_CHANGED_EVENT},
 };
 use zng_layout::context::LayoutDirection;
 use zng_task as task;
 
 use zng_txt::Txt;
-use zng_var::{types::ArcCowVar, ArcEq, ArcVar, BoxedVar, ReadOnlyArcVar, Var};
+use zng_var::{ArcEq, ArcVar, BoxedVar, ReadOnlyArcVar, Var, types::ArcCowVar};
 
 #[doc(hidden)]
 pub use zng_ext_l10n_proc_macros::lang as __lang;
diff --git a/crates/zng-ext-l10n/src/service.rs b/crates/zng-ext-l10n/src/service.rs
index 2c223a122..07b160de2 100644
--- a/crates/zng-ext-l10n/src/service.rs
+++ b/crates/zng-ext-l10n/src/service.rs
@@ -1,6 +1,6 @@
 use std::{
     borrow::Cow,
-    collections::{hash_map, HashMap},
+    collections::{HashMap, hash_map},
     fmt, ops,
     path::PathBuf,
     str::FromStr,
@@ -11,7 +11,7 @@ use parking_lot::Mutex;
 use zng_app_context::app_local;
 use zng_txt::Txt;
 use zng_var::{
-    merge_var, types::ArcCowVar, var, ArcEq, ArcVar, BoxedVar, BoxedWeakVar, LocalVar, MergeVarBuilder, ReadOnlyArcVar, Var, WeakVar,
+    ArcEq, ArcVar, BoxedVar, BoxedWeakVar, LocalVar, MergeVarBuilder, ReadOnlyArcVar, Var, WeakVar, merge_var, types::ArcCowVar, var,
 };
 use zng_view_api::config::LocaleConfig;
 
diff --git a/crates/zng-ext-l10n/src/sources/dir.rs b/crates/zng-ext-l10n/src/sources/dir.rs
index 6fd1a8323..0eef7eb1c 100644
--- a/crates/zng-ext-l10n/src/sources/dir.rs
+++ b/crates/zng-ext-l10n/src/sources/dir.rs
@@ -4,7 +4,7 @@ use semver::Version;
 use zng_clone_move::clmv;
 use zng_ext_fs_watcher::WATCHER;
 use zng_txt::Txt;
-use zng_var::{types::WeakArcVar, var, ArcEq, ArcVar, BoxedVar, BoxedWeakVar, LocalVar, Var as _, WeakVar as _};
+use zng_var::{ArcEq, ArcVar, BoxedVar, BoxedWeakVar, LocalVar, Var as _, WeakVar as _, types::WeakArcVar, var};
 
 use crate::{FluentParserErrors, L10nSource, Lang, LangFilePath, LangMap, LangResourceStatus};
 
diff --git a/crates/zng-ext-l10n/src/sources/swap.rs b/crates/zng-ext-l10n/src/sources/swap.rs
index 049199fe9..f15b88fd2 100644
--- a/crates/zng-ext-l10n/src/sources/swap.rs
+++ b/crates/zng-ext-l10n/src/sources/swap.rs
@@ -1,6 +1,6 @@
 use std::{collections::HashMap, path::PathBuf, sync::Arc};
 
-use zng_var::{types::WeakArcVar, var, ArcEq, ArcVar, BoxedVar, BoxedWeakVar, Var as _, VarHandle, WeakVar as _};
+use zng_var::{ArcEq, ArcVar, BoxedVar, BoxedWeakVar, Var as _, VarHandle, WeakVar as _, types::WeakArcVar, var};
 
 use crate::{L10nSource, Lang, LangFilePath, LangMap, LangResourceStatus};
 
diff --git a/crates/zng-ext-l10n/src/sources/tar.rs b/crates/zng-ext-l10n/src/sources/tar.rs
index 463580fd2..59f883c97 100644
--- a/crates/zng-ext-l10n/src/sources/tar.rs
+++ b/crates/zng-ext-l10n/src/sources/tar.rs
@@ -3,7 +3,7 @@ use std::{borrow::Cow, collections::HashMap, fmt, io::Read as _, path::PathBuf,
 use semver::Version;
 use zng_clone_move::clmv;
 use zng_txt::Txt;
-use zng_var::{types::WeakArcVar, var, ArcEq, ArcVar, BoxedVar, BoxedWeakVar, LocalVar, Var as _, WeakVar as _};
+use zng_var::{ArcEq, ArcVar, BoxedVar, BoxedWeakVar, LocalVar, Var as _, WeakVar as _, types::WeakArcVar, var};
 
 use crate::{FluentParserErrors, L10nSource, Lang, LangFilePath, LangMap, LangResourceStatus};
 
diff --git a/crates/zng-ext-l10n/src/types.rs b/crates/zng-ext-l10n/src/types.rs
index 2a4096149..c34a3b3f7 100644
--- a/crates/zng-ext-l10n/src/types.rs
+++ b/crates/zng-ext-l10n/src/types.rs
@@ -6,9 +6,9 @@ use semver::Version;
 use zng_ext_fs_watcher::WatcherReadStatus;
 use zng_layout::context::LayoutDirection;
 use zng_txt::{ToTxt, Txt};
-use zng_var::{context_var, impl_from_and_into_var, ArcEq, ArcVar, BoxedVar, IntoVar, LocalVar, ReadOnlyArcVar, Var, VarValue};
+use zng_var::{ArcEq, ArcVar, BoxedVar, IntoVar, LocalVar, ReadOnlyArcVar, Var, VarValue, context_var, impl_from_and_into_var};
 
-use crate::{lang, service::L10N_SV, L10N};
+use crate::{L10N, lang, service::L10N_SV};
 
 /// Handle to multiple localization resources.
 #[derive(Clone, Debug)]
@@ -710,11 +710,7 @@ impl fmt::Display for FluentParserErrors {
 }
 impl std::error::Error for FluentParserErrors {
     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
-        if self.0.len() == 1 {
-            Some(&self.0[0])
-        } else {
-            None
-        }
+        if self.0.len() == 1 { Some(&self.0[0]) } else { None }
     }
 }
 
diff --git a/crates/zng-ext-single-instance/Cargo.toml b/crates/zng-ext-single-instance/Cargo.toml
index b4ba723d5..c423aa28a 100644
--- a/crates/zng-ext-single-instance/Cargo.toml
+++ b/crates/zng-ext-single-instance/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-ext-single-instance"
 version = "0.4.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-ext-single-instance/src/lib.rs b/crates/zng-ext-single-instance/src/lib.rs
index 780ca0cf8..b857077b7 100644
--- a/crates/zng-ext-single-instance/src/lib.rs
+++ b/crates/zng-ext-single-instance/src/lib.rs
@@ -13,9 +13,9 @@ use std::{
 };
 
 use zng_app::{
+    AppExtension,
     event::{event, event_args},
     handler::{async_app_hn, clmv},
-    AppExtension,
 };
 use zng_ext_fs_watcher::WATCHER;
 use zng_txt::{ToTxt, Txt};
diff --git a/crates/zng-ext-svg/Cargo.toml b/crates/zng-ext-svg/Cargo.toml
index 29c947c27..f9e81303f 100644
--- a/crates/zng-ext-svg/Cargo.toml
+++ b/crates/zng-ext-svg/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-ext-svg"
 version = "0.2.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-ext-svg/src/lib.rs b/crates/zng-ext-svg/src/lib.rs
index 5a29e507b..b7d45d9ad 100644
--- a/crates/zng-ext-svg/src/lib.rs
+++ b/crates/zng-ext-svg/src/lib.rs
@@ -13,7 +13,7 @@ use std::sync::Arc;
 
 use zng_app::AppExtension;
 use zng_ext_image::*;
-use zng_txt::{formatx, Txt};
+use zng_txt::{Txt, formatx};
 use zng_unit::{Px, PxSize};
 
 /// Application extension that installs SVG handling.
diff --git a/crates/zng-ext-undo/Cargo.toml b/crates/zng-ext-undo/Cargo.toml
index bc7792d55..1410143d6 100644
--- a/crates/zng-ext-undo/Cargo.toml
+++ b/crates/zng-ext-undo/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-ext-undo"
 version = "0.3.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-ext-undo/src/lib.rs b/crates/zng-ext-undo/src/lib.rs
index c620aec88..0b2b8be6a 100644
--- a/crates/zng-ext-undo/src/lib.rs
+++ b/crates/zng-ext-undo/src/lib.rs
@@ -16,8 +16,8 @@ use std::{
     any::Any,
     fmt, mem,
     sync::{
-        atomic::{AtomicBool, Ordering},
         Arc,
+        atomic::{AtomicBool, Ordering},
     },
     time::Duration,
 };
@@ -25,23 +25,23 @@ use std::{
 use atomic::Atomic;
 use parking_lot::Mutex;
 use zng_app::{
+    AppExtension, DInstant, INSTANT,
     event::CommandScope,
-    event::{command, AnyEventArgs, Command, CommandNameExt},
-    shortcut::{shortcut, CommandShortcutExt},
+    event::{AnyEventArgs, Command, CommandNameExt, command},
+    shortcut::{CommandShortcutExt, shortcut},
     update::EventUpdate,
     widget::{
+        WIDGET, WidgetId,
         info::{WidgetInfo, WidgetInfoBuilder},
-        WidgetId, WIDGET,
     },
-    AppExtension, DInstant, INSTANT,
 };
-use zng_app_context::{app_local, context_local, RunOnDrop};
+use zng_app_context::{RunOnDrop, app_local, context_local};
 use zng_clone_move::clmv;
 use zng_ext_input::{focus::cmd::CommandFocusExt, keyboard::KEYBOARD};
-use zng_state_map::{static_id, StateId, StateMapRef};
+use zng_state_map::{StateId, StateMapRef, static_id};
 use zng_txt::Txt;
-use zng_var::{context_var, var, BoxedVar, Var, VarHandle, VarValue, WeakVar};
-use zng_wgt::{wgt_fn, CommandIconExt as _, ICONS};
+use zng_var::{BoxedVar, Var, VarHandle, VarValue, WeakVar, context_var, var};
+use zng_wgt::{CommandIconExt as _, ICONS, wgt_fn};
 
 mod private {
     // https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed
@@ -1139,11 +1139,7 @@ impl UndoAction for UndoRedoFullOp {
                     merged: &mut merged,
                 },
             );
-            if merged {
-                Ok(self)
-            } else {
-                Err((self, args.next))
-            }
+            if merged { Ok(self) } else { Err((self, args.next)) }
         } else {
             Err((self, args.next))
         }
diff --git a/crates/zng-ext-window/Cargo.toml b/crates/zng-ext-window/Cargo.toml
index 75209847c..419e5ebc9 100644
--- a/crates/zng-ext-window/Cargo.toml
+++ b/crates/zng-ext-window/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-ext-window"
 version = "0.4.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-ext-window/src/cmd.rs b/crates/zng-ext-window/src/cmd.rs
index 2f11c5ee0..271318d8f 100644
--- a/crates/zng-ext-window/src/cmd.rs
+++ b/crates/zng-ext-window/src/cmd.rs
@@ -1,16 +1,16 @@
 //! Commands that control the scoped window.
 
 use zng_app::{
-    event::{command, CommandHandle, CommandInfoExt, CommandNameExt},
-    shortcut::{shortcut, CommandShortcutExt},
+    event::{CommandHandle, CommandInfoExt, CommandNameExt, command},
+    shortcut::{CommandShortcutExt, shortcut},
     update::EventUpdate,
-    window::{WindowId, WINDOW},
+    window::{WINDOW, WindowId},
 };
 use zng_var::Var;
 use zng_view_api::window::WindowState;
-use zng_wgt::{wgt_fn, CommandIconExt as _, ICONS};
+use zng_wgt::{CommandIconExt as _, ICONS, wgt_fn};
 
-use crate::{WindowVars, WINDOWS};
+use crate::{WINDOWS, WindowVars};
 
 pub use zng_view_api::window::ResizeDirection;
 
diff --git a/crates/zng-ext-window/src/control.rs b/crates/zng-ext-window/src/control.rs
index 8a3592a43..ba732f6b9 100644
--- a/crates/zng-ext-window/src/control.rs
+++ b/crates/zng-ext-window/src/control.rs
@@ -4,34 +4,34 @@ use std::{mem, sync::Arc};
 
 use parking_lot::Mutex;
 use zng_app::{
+    Deadline,
     access::{ACCESS_DEINITED_EVENT, ACCESS_INITED_EVENT},
     app_hn_once,
     event::{AnyEventArgs, CommandHandle},
     render::{FrameBuilder, FrameUpdate},
     static_id,
     timer::TIMERS,
-    update::{EventUpdate, InfoUpdates, LayoutUpdates, RenderUpdates, WidgetUpdates, UPDATES},
+    update::{EventUpdate, InfoUpdates, LayoutUpdates, RenderUpdates, UPDATES, WidgetUpdates},
     view_process::{
+        VIEW_PROCESS, VIEW_PROCESS_INITED_EVENT, ViewHeadless, ViewRenderer, ViewWindow,
         raw_events::{
-            RawWindowFocusArgs, RAW_COLORS_CONFIG_CHANGED_EVENT, RAW_FRAME_RENDERED_EVENT, RAW_HEADLESS_OPEN_EVENT, RAW_IME_EVENT,
-            RAW_WINDOW_CHANGED_EVENT, RAW_WINDOW_FOCUS_EVENT, RAW_WINDOW_OPEN_EVENT, RAW_WINDOW_OR_HEADLESS_OPEN_ERROR_EVENT,
+            RAW_COLORS_CONFIG_CHANGED_EVENT, RAW_FRAME_RENDERED_EVENT, RAW_HEADLESS_OPEN_EVENT, RAW_IME_EVENT, RAW_WINDOW_CHANGED_EVENT,
+            RAW_WINDOW_FOCUS_EVENT, RAW_WINDOW_OPEN_EVENT, RAW_WINDOW_OR_HEADLESS_OPEN_ERROR_EVENT, RawWindowFocusArgs,
         },
-        ViewHeadless, ViewRenderer, ViewWindow, VIEW_PROCESS, VIEW_PROCESS_INITED_EVENT,
     },
     widget::{
-        info::{access::AccessEnabled, WidgetInfoBuilder, WidgetInfoTree, WidgetLayout, WidgetMeasure, WidgetPath},
+        VarLayout, WIDGET, WidgetCtx, WidgetId, WidgetUpdateMode,
+        info::{WidgetInfoBuilder, WidgetInfoTree, WidgetLayout, WidgetMeasure, WidgetPath, access::AccessEnabled},
         node::{BoxedUiNode, UiNode},
-        VarLayout, WidgetCtx, WidgetId, WidgetUpdateMode, WIDGET,
     },
-    window::{WindowCtx, WindowId, WindowMode, WINDOW},
-    Deadline,
+    window::{WINDOW, WindowCtx, WindowId, WindowMode},
 };
 use zng_app_context::LocalContext;
 use zng_clone_move::clmv;
-use zng_color::{colors, LightDark, Rgba};
-use zng_ext_image::{ImageRenderArgs, ImageSource, ImageVar, Img, IMAGES};
+use zng_color::{LightDark, Rgba, colors};
+use zng_ext_image::{IMAGES, ImageRenderArgs, ImageSource, ImageVar, Img};
 use zng_layout::{
-    context::{LayoutMetrics, LayoutPassId, DIRECTION_VAR, LAYOUT},
+    context::{DIRECTION_VAR, LAYOUT, LayoutMetrics, LayoutPassId},
     unit::{
         Dip, DipPoint, DipRect, DipSize, DipToPx, Factor, FactorUnits, Layout1d, Layout2d, Length, Ppi, Px, PxConstraints, PxPoint, PxRect,
         PxSize, PxToDip, PxVector, TimeUnits,
@@ -40,21 +40,21 @@ use zng_layout::{
 use zng_state_map::StateId;
 use zng_var::{AnyVar, ReadOnlyArcVar, Var, VarHandle, VarHandles};
 use zng_view_api::{
+    DragDropId, FocusResult, Ime, ViewProcessOffline,
     config::{ColorScheme, FontAntiAliasing},
     drag_drop::{DragDropData, DragDropEffect, DragDropError},
     window::{
         EventCause, FrameCapture, FrameId, FrameRequest, FrameUpdateRequest, FrameWaitId, HeadlessRequest, RenderMode, WindowRequest,
         WindowState, WindowStateAll,
     },
-    DragDropId, FocusResult, Ime, ViewProcessOffline,
 };
 use zng_wgt::prelude::WidgetInfo;
 
 use crate::{
-    cmd::{WindowCommands, MINIMIZE_CMD, RESTORE_CMD},
-    AutoSize, FrameCaptureMode, FrameImageReadyArgs, HeadlessMonitor, MonitorInfo, StartPosition, WINDOW_Ext, WidgetInfoImeArea,
-    WindowChangedArgs, WindowIcon, WindowRoot, WindowVars, FRAME_IMAGE_READY_EVENT, MONITORS, MONITORS_CHANGED_EVENT, WINDOWS,
-    WINDOWS_DRAG_DROP, WINDOW_CHANGED_EVENT, WINDOW_FOCUS,
+    AutoSize, FRAME_IMAGE_READY_EVENT, FrameCaptureMode, FrameImageReadyArgs, HeadlessMonitor, MONITORS, MONITORS_CHANGED_EVENT,
+    MonitorInfo, StartPosition, WINDOW_CHANGED_EVENT, WINDOW_Ext, WINDOW_FOCUS, WINDOWS, WINDOWS_DRAG_DROP, WidgetInfoImeArea,
+    WindowChangedArgs, WindowIcon, WindowRoot, WindowVars,
+    cmd::{MINIMIZE_CMD, RESTORE_CMD, WindowCommands},
 };
 
 struct ImageResources {
diff --git a/crates/zng-ext-window/src/ime.rs b/crates/zng-ext-window/src/ime.rs
index 2e020f7cc..10ba94985 100644
--- a/crates/zng-ext-window/src/ime.rs
+++ b/crates/zng-ext-window/src/ime.rs
@@ -6,7 +6,7 @@ use zng_app::{
     widget::info::{WidgetInfo, WidgetInfoBuilder, WidgetPath},
 };
 use zng_layout::unit::PxRect;
-use zng_state_map::{static_id, StateId};
+use zng_state_map::{StateId, static_id};
 use zng_txt::Txt;
 
 event_args! {
diff --git a/crates/zng-ext-window/src/lib.rs b/crates/zng-ext-window/src/lib.rs
index 62ea31a7d..fa8e9d778 100644
--- a/crates/zng-ext-window/src/lib.rs
+++ b/crates/zng-ext-window/src/lib.rs
@@ -32,14 +32,13 @@ pub use vars::*;
 mod service;
 pub use service::*;
 
-use std::future::{Future, IntoFuture};
 use zng_app::{
+    AppControlFlow, AppExtended, AppExtension, HeadlessApp,
     update::{EventUpdate, InfoUpdates, LayoutUpdates, RenderUpdates, WidgetUpdates},
-    view_process::raw_events::{RawWindowFocusArgs, RAW_WINDOW_FOCUS_EVENT},
+    view_process::raw_events::{RAW_WINDOW_FOCUS_EVENT, RawWindowFocusArgs},
     window::WindowId,
-    AppControlFlow, AppExtended, AppExtension, HeadlessApp,
 };
-use zng_ext_image::{ImageVar, IMAGES_WINDOW};
+use zng_ext_image::{IMAGES_WINDOW, ImageVar};
 use zng_view_api::image::ImageMaskMode;
 
 pub mod cmd;
diff --git a/crates/zng-ext-window/src/monitor.rs b/crates/zng-ext-window/src/monitor.rs
index f7bad8343..555440502 100644
--- a/crates/zng-ext-window/src/monitor.rs
+++ b/crates/zng-ext-window/src/monitor.rs
@@ -1,16 +1,16 @@
 use core::fmt;
 use std::sync::Arc;
 
-use zng_app::event::{event, event_args, AnyEventArgs};
+use zng_app::event::{AnyEventArgs, event, event_args};
 use zng_app::update::EventUpdate;
-use zng_app::view_process::raw_events::{RawMonitorsChangedArgs, RAW_MONITORS_CHANGED_EVENT, RAW_SCALE_FACTOR_CHANGED_EVENT};
 use zng_app::view_process::VIEW_PROCESS_INITED_EVENT;
-use zng_app::window::{MonitorId, WindowId, WINDOW};
+use zng_app::view_process::raw_events::{RAW_MONITORS_CHANGED_EVENT, RAW_SCALE_FACTOR_CHANGED_EVENT, RawMonitorsChangedArgs};
+use zng_app::window::{MonitorId, WINDOW, WindowId};
 use zng_app_context::app_local;
 use zng_layout::unit::{Dip, DipRect, DipSize, DipToPx, Factor, FactorUnits, Ppi, Px, PxPoint, PxRect, PxSize, PxToDip};
 use zng_txt::{ToTxt, Txt};
 use zng_unique_id::IdMap;
-use zng_var::{impl_from_and_into_var, var, ArcVar, ReadOnlyArcVar, Var, VarValue};
+use zng_var::{ArcVar, ReadOnlyArcVar, Var, VarValue, impl_from_and_into_var, var};
 use zng_view_api::window::VideoMode;
 
 use crate::WINDOWS;
diff --git a/crates/zng-ext-window/src/service.rs b/crates/zng-ext-window/src/service.rs
index c25e7be56..010e83457 100644
--- a/crates/zng-ext-window/src/service.rs
+++ b/crates/zng-ext-window/src/service.rs
@@ -1,63 +1,56 @@
-use std::{
-    any::Any,
-    future::{Future, IntoFuture},
-    mem,
-    sync::Arc,
-};
+use std::{any::Any, mem, sync::Arc};
 
 use parking_lot::Mutex;
 use zng_app::{
-    app_hn_once,
+    APP, AppEventSender, Deadline, EXIT_REQUESTED_EVENT, app_hn_once,
     event::AnyEventArgs,
     timer::{DeadlineHandle, TIMERS},
-    update::{EventUpdate, InfoUpdates, LayoutUpdates, RenderUpdates, WidgetUpdates, UPDATES},
+    update::{EventUpdate, InfoUpdates, LayoutUpdates, RenderUpdates, UPDATES, WidgetUpdates},
     view_process::{
-        self,
+        self, VIEW_PROCESS, VIEW_PROCESS_INITED_EVENT, ViewImage, ViewRenderer, ViewWindowOrHeadless,
         raw_events::{
-            RAW_CHROME_CONFIG_CHANGED_EVENT, RAW_COLORS_CONFIG_CHANGED_EVENT, RAW_IMAGE_LOADED_EVENT, RAW_IMAGE_LOAD_ERROR_EVENT,
+            RAW_CHROME_CONFIG_CHANGED_EVENT, RAW_COLORS_CONFIG_CHANGED_EVENT, RAW_IMAGE_LOAD_ERROR_EVENT, RAW_IMAGE_LOADED_EVENT,
             RAW_WINDOW_CLOSE_EVENT, RAW_WINDOW_CLOSE_REQUESTED_EVENT, RAW_WINDOW_FOCUS_EVENT,
         },
-        ViewImage, ViewRenderer, ViewWindowOrHeadless, VIEW_PROCESS, VIEW_PROCESS_INITED_EVENT,
     },
     widget::{
+        UiTaskWidget, WidgetId,
         info::{InteractionPath, WidgetInfo, WidgetInfoTree},
         node::{BoxedUiNode, NilUiNode, UiNode},
-        UiTaskWidget, WidgetId,
     },
-    window::{WindowCtx, WindowId, WindowMode, WINDOW},
-    AppEventSender, Deadline, APP, EXIT_REQUESTED_EVENT,
+    window::{WINDOW, WindowCtx, WindowId, WindowMode},
 };
 use zng_app_context::app_local;
 
-use zng_color::{colors::ACCENT_COLOR_VAR, COLOR_SCHEME_VAR};
+use zng_color::{COLOR_SCHEME_VAR, colors::ACCENT_COLOR_VAR};
 use zng_ext_image::{ImageRenderWindowRoot, ImageRenderWindowsService, ImageVar, Img};
 use zng_layout::unit::TimeUnits as _;
 use zng_layout::unit::{Factor, FactorUnits, LengthUnits, PxRect};
 use zng_task::{
-    rayon::iter::{IntoParallelRefMutIterator, ParallelIterator},
     ParallelIteratorExt, UiTask,
+    rayon::iter::{IntoParallelRefMutIterator, ParallelIterator},
 };
-use zng_txt::{formatx, ToTxt as _, Txt};
+use zng_txt::{ToTxt as _, Txt, formatx};
 use zng_unique_id::{IdMap, IdSet};
 use zng_var::{
-    impl_from_and_into_var, response_done_var, response_var, types::WeakArcVar, var, AnyWeakVar, ArcVar, BoxedVar, LocalVar,
-    ReadOnlyArcVar, ResponderVar, ResponseVar, Var, WeakVar,
+    AnyWeakVar, ArcVar, BoxedVar, LocalVar, ReadOnlyArcVar, ResponderVar, ResponseVar, Var, WeakVar, impl_from_and_into_var,
+    response_done_var, response_var, types::WeakArcVar, var,
 };
 use zng_view_api::{
+    DragDropId, ViewProcessOffline,
     api_extension::{ApiExtensionId, ApiExtensionPayload},
     config::{ChromeConfig, ColorsConfig},
     drag_drop::{DragDropData, DragDropEffect, DragDropError},
     image::ImageMaskMode,
     window::{RenderMode, WindowState},
-    DragDropId, ViewProcessOffline,
 };
 use zng_wgt::node::with_context_var;
 
 use crate::{
-    cmd::WindowCommands, control::WindowCtrl, CloseWindowResult, FrameCaptureMode, HeadlessMonitor, StartPosition, ViewExtensionError,
-    WindowCloseArgs, WindowCloseRequestedArgs, WindowFocusChangedArgs, WindowLoadingHandle, WindowNotFound, WindowOpenArgs, WindowRoot,
-    WindowVars, FRAME_IMAGE_READY_EVENT, MONITORS, WINDOW_CLOSE_EVENT, WINDOW_CLOSE_REQUESTED_EVENT, WINDOW_FOCUS_CHANGED_EVENT,
-    WINDOW_LOAD_EVENT, WINDOW_VARS_ID,
+    CloseWindowResult, FRAME_IMAGE_READY_EVENT, FrameCaptureMode, HeadlessMonitor, MONITORS, StartPosition, ViewExtensionError,
+    WINDOW_CLOSE_EVENT, WINDOW_CLOSE_REQUESTED_EVENT, WINDOW_FOCUS_CHANGED_EVENT, WINDOW_LOAD_EVENT, WINDOW_VARS_ID, WindowCloseArgs,
+    WindowCloseRequestedArgs, WindowFocusChangedArgs, WindowLoadingHandle, WindowNotFound, WindowOpenArgs, WindowRoot, WindowVars,
+    cmd::WindowCommands, control::WindowCtrl,
 };
 
 app_local! {
diff --git a/crates/zng-ext-window/src/types.rs b/crates/zng-ext-window/src/types.rs
index 92be97b49..4b195ef28 100644
--- a/crates/zng-ext-window/src/types.rs
+++ b/crates/zng-ext-window/src/types.rs
@@ -5,14 +5,14 @@ use std::{
 };
 
 use zng_app::{
+    AppEventSender, Deadline,
     event::{event, event_args},
     update::UpdateOp,
     widget::{
-        node::{BoxedUiNode, UiNode},
         WidgetId,
+        node::{BoxedUiNode, UiNode},
     },
-    window::{WindowId, WINDOW},
-    AppEventSender, Deadline,
+    window::{WINDOW, WindowId},
 };
 use zng_ext_image::{ImageSource, ImageVar, Img};
 use zng_layout::unit::{DipPoint, DipSize, Point, PxPoint};
@@ -20,9 +20,9 @@ use zng_txt::Txt;
 use zng_unique_id::IdSet;
 use zng_var::impl_from_and_into_var;
 use zng_view_api::{
+    ViewProcessOffline,
     image::{ImageDataFormat, ImageMaskMode},
     window::{CursorIcon, EventCause, FrameId},
-    ViewProcessOffline,
 };
 
 pub use zng_view_api::window::{FocusIndicator, RenderMode, VideoMode, WindowButton, WindowState};
@@ -674,11 +674,7 @@ impl WindowFocusChangedArgs {
 
     /// Gets the previous focused window if it was closed.
     pub fn closed(&self) -> Option<WindowId> {
-        if self.closed {
-            self.prev_focus
-        } else {
-            None
-        }
+        if self.closed { self.prev_focus } else { None }
     }
 }
 impl WindowCloseRequestedArgs {
diff --git a/crates/zng-ext-window/src/vars.rs b/crates/zng-ext-window/src/vars.rs
index 6429f8c37..0a9f48ba3 100644
--- a/crates/zng-ext-window/src/vars.rs
+++ b/crates/zng-ext-window/src/vars.rs
@@ -1,18 +1,18 @@
 use std::sync::Arc;
 
 use zng_app::{
-    widget::{info::access::AccessEnabled, WidgetId},
-    window::{MonitorId, WindowId, WINDOW},
+    widget::{WidgetId, info::access::AccessEnabled},
+    window::{MonitorId, WINDOW, WindowId},
 };
 use zng_color::LightDark;
 use zng_ext_image::Img;
 use zng_layout::unit::{
     Dip, DipPoint, DipRect, DipSideOffsets, DipSize, DipToPx, Factor, FactorUnits, Length, LengthUnits, Point, PxPoint, PxSize, Size,
 };
-use zng_state_map::{static_id, StateId};
+use zng_state_map::{StateId, static_id};
 use zng_txt::Txt;
 use zng_unique_id::IdSet;
-use zng_var::{merge_var, var, var_from, ArcVar, BoxedVar, ReadOnlyArcVar, Var};
+use zng_var::{ArcVar, BoxedVar, ReadOnlyArcVar, Var, merge_var, var, var_from};
 use zng_view_api::{
     config::{ColorScheme, ColorsConfig},
     window::{CursorIcon, FocusIndicator, RenderMode, VideoMode, WindowButton, WindowState},
diff --git a/crates/zng-handle/Cargo.toml b/crates/zng-handle/Cargo.toml
index c3d06e490..7621027e0 100644
--- a/crates/zng-handle/Cargo.toml
+++ b/crates/zng-handle/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-handle"
 version = "0.2.5"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-handle/src/lib.rs b/crates/zng-handle/src/lib.rs
index 57e0c8785..a850b2da4 100644
--- a/crates/zng-handle/src/lib.rs
+++ b/crates/zng-handle/src/lib.rs
@@ -14,8 +14,8 @@ use std::{
     fmt,
     hash::Hasher,
     sync::{
-        atomic::{AtomicU8, Ordering},
         Arc, Weak,
+        atomic::{AtomicU8, Ordering},
     },
 };
 
@@ -149,11 +149,7 @@ impl<D: Send + Sync> WeakHandle<D> {
     pub fn upgrade(&self) -> Option<Handle<D>> {
         if let Some(arc) = self.0.upgrade() {
             let handle = Handle(arc);
-            if handle.is_dropped() {
-                None
-            } else {
-                Some(handle)
-            }
+            if handle.is_dropped() { None } else { Some(handle) }
         } else {
             None
         }
@@ -203,8 +199,8 @@ impl<D: Send + Sync> HandleOwner<D> {
     /// The handle is considered dropped when all handle and clones are dropped or when [`force_drop`](Handle::force_drop)
     /// was called in any of the clones.
     pub fn is_dropped(&self) -> bool {
-        let state = self.0 .0.state.load(Ordering::Relaxed);
-        state == FORCE_DROP || (state != PERMANENT && Arc::strong_count(&self.0 .0) <= 1)
+        let state = self.0.0.state.load(Ordering::Relaxed);
+        state == FORCE_DROP || (state != PERMANENT && Arc::strong_count(&self.0.0) <= 1)
     }
 
     /*
@@ -240,7 +236,7 @@ impl<D: Send + Sync> HandleOwner<D> {
 }
 impl<D: Send + Sync> Drop for HandleOwner<D> {
     fn drop(&mut self) {
-        self.0 .0.state.store(FORCE_DROP, Ordering::Relaxed);
+        self.0.0.state.store(FORCE_DROP, Ordering::Relaxed);
     }
 }
 
diff --git a/crates/zng-layout/Cargo.toml b/crates/zng-layout/Cargo.toml
index 9c41a0283..6c0985c99 100644
--- a/crates/zng-layout/Cargo.toml
+++ b/crates/zng-layout/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-layout"
 version = "0.2.37"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-layout/src/context.rs b/crates/zng-layout/src/context.rs
index 84f28cb4c..4eb0e6182 100644
--- a/crates/zng-layout/src/context.rs
+++ b/crates/zng-layout/src/context.rs
@@ -5,7 +5,7 @@ use std::{fmt, sync::Arc};
 use bitflags::bitflags;
 use unicode_bidi::BidiDataSource as _;
 use zng_app_context::context_local;
-use zng_unit::{about_eq, about_eq_hash, euclid, Factor, Px, PxRect, PxSize};
+use zng_unit::{Factor, Px, PxRect, PxSize, about_eq, about_eq_hash, euclid};
 use zng_var::context_var;
 
 use atomic::{Atomic, Ordering::Relaxed};
@@ -852,8 +852,8 @@ impl From<char> for TextSegmentKind {
 
 impl From<unicode_bidi::BidiClass> for TextSegmentKind {
     fn from(value: unicode_bidi::BidiClass) -> Self {
-        use unicode_bidi::BidiClass::*;
         use TextSegmentKind::*;
+        use unicode_bidi::BidiClass::*;
 
         match value {
             WS => Space,
@@ -884,8 +884,8 @@ impl From<unicode_bidi::BidiClass> for TextSegmentKind {
 }
 impl From<TextSegmentKind> for unicode_bidi::BidiClass {
     fn from(value: TextSegmentKind) -> Self {
-        use unicode_bidi::BidiClass::*;
         use TextSegmentKind::*;
+        use unicode_bidi::BidiClass::*;
 
         match value {
             Space => WS,
diff --git a/crates/zng-layout/src/unit.rs b/crates/zng-layout/src/unit.rs
index a8ff6279a..deda5c69c 100644
--- a/crates/zng-layout/src/unit.rs
+++ b/crates/zng-layout/src/unit.rs
@@ -238,7 +238,7 @@ mod tests {
 
     use zng_app_context::{AppId, LocalContext};
 
-    use crate::context::{LayoutMetrics, LAYOUT};
+    use crate::context::{LAYOUT, LayoutMetrics};
 
     use super::*;
 
diff --git a/crates/zng-layout/src/unit/alignment.rs b/crates/zng-layout/src/unit/alignment.rs
index 6a62627c5..e497cdd46 100644
--- a/crates/zng-layout/src/unit/alignment.rs
+++ b/crates/zng-layout/src/unit/alignment.rs
@@ -6,7 +6,7 @@ use std::{
 
 use crate::context::LayoutDirection;
 use zng_var::{
-    animation::{easing::EasingStep, Transitionable},
+    animation::{Transitionable, easing::EasingStep},
     impl_from_and_into_var,
 };
 
@@ -73,11 +73,7 @@ impl Align {
     pub fn x(self, direction: LayoutDirection) -> Factor {
         let x = if self.x.0.is_finite() { self.x } else { 0.fct() };
 
-        if self.x_rtl_aware && direction.is_rtl() {
-            x.flip()
-        } else {
-            x
-        }
+        if self.x_rtl_aware && direction.is_rtl() { x.flip() } else { x }
     }
 
     /// Gets the best finite [`y`] align value.
diff --git a/crates/zng-layout/src/unit/constraints.rs b/crates/zng-layout/src/unit/constraints.rs
index ffdd21e4a..0657e659c 100644
--- a/crates/zng-layout/src/unit/constraints.rs
+++ b/crates/zng-layout/src/unit/constraints.rs
@@ -2,7 +2,7 @@ use std::fmt;
 
 use zng_var::{animation::Transitionable, impl_from_and_into_var};
 
-use super::{euclid, FactorUnits, Px, PxSize};
+use super::{FactorUnits, Px, PxSize, euclid};
 
 pub use euclid::BoolVector2D;
 
@@ -80,11 +80,7 @@ impl PxConstraints {
     ///
     /// [`with_new_min`]: Self::with_new_min
     pub fn with_min(self, min: Px) -> Self {
-        if min > self.min {
-            self.with_new_min(min)
-        } else {
-            self
-        }
+        if min > self.min { self.with_new_min(min) } else { self }
     }
 
     /// Returns a copy of the current constraints that has `max` as the upper bound and min adjusted to be <= `max`.
@@ -98,11 +94,7 @@ impl PxConstraints {
     ///
     /// [`with_new_max`]: Self::with_new_max
     pub fn with_max(self, max: Px) -> Self {
-        if max < self.max {
-            self.with_new_max(max)
-        } else {
-            self
-        }
+        if max < self.max { self.with_new_max(max) } else { self }
     }
 
     /// Returns a copy of the current constraints that has max and min set to `len` and fill enabled.
@@ -188,22 +180,14 @@ impl PxConstraints {
 
     /// Gets the fixed length if the constraints only allow one length.
     pub fn exact(self) -> Option<Px> {
-        if self.is_exact() {
-            Some(self.max)
-        } else {
-            None
-        }
+        if self.is_exact() { Some(self.max) } else { None }
     }
 
     /// Gets the maximum allowed length, or `None` if is unbounded.
     ///
     /// The maximum is inclusive.
     pub fn max(self) -> Option<Px> {
-        if self.max < Px::MAX {
-            Some(self.max)
-        } else {
-            None
-        }
+        if self.max < Px::MAX { Some(self.max) } else { None }
     }
 
     /// Gets the minimum allowed length.
@@ -215,11 +199,7 @@ impl PxConstraints {
 
     /// Gets the maximum length if it is bounded, or the minimum if not.
     pub fn max_bounded(self) -> Px {
-        if self.max < Px::MAX {
-            self.max
-        } else {
-            self.min
-        }
+        if self.max < Px::MAX { self.max } else { self.min }
     }
 
     /// Clamp the `px` by min and max.
@@ -229,11 +209,7 @@ impl PxConstraints {
 
     /// Gets the fill length, if fill is `true` this is the maximum length, otherwise it is the minimum length.
     pub fn fill(self) -> Px {
-        if self.fill && !self.is_unbounded() {
-            self.max
-        } else {
-            self.min
-        }
+        if self.fill && !self.is_unbounded() { self.max } else { self.min }
     }
 
     /// Gets the maximum if fill is preferred and max is bounded, or `length` clamped by the constraints.
@@ -256,11 +232,7 @@ impl PxConstraints {
 
     /// Gets the maximum length if bounded or `length` clamped by the constraints.
     pub fn max_or(self, length: Px) -> Px {
-        if self.is_unbounded() {
-            self.clamp(length)
-        } else {
-            self.max
-        }
+        if self.is_unbounded() { self.clamp(length) } else { self.max }
     }
 }
 impl_from_and_into_var! {
diff --git a/crates/zng-layout/src/unit/grid.rs b/crates/zng-layout/src/unit/grid.rs
index cdcb1ff99..5543c5141 100644
--- a/crates/zng-layout/src/unit/grid.rs
+++ b/crates/zng-layout/src/unit/grid.rs
@@ -2,7 +2,7 @@ use std::{fmt, mem, ops};
 
 use zng_var::{animation::Transitionable, impl_from_and_into_var};
 
-use super::{impl_length_comp_conversions, Factor, Factor2d, FactorPercent, Layout1d, LayoutMask, Length, Px, PxVector};
+use super::{Factor, Factor2d, FactorPercent, Layout1d, LayoutMask, Length, Px, PxVector, impl_length_comp_conversions};
 
 /// Spacing in-between grid cells in [`Length`] units.
 #[derive(Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, Transitionable)]
diff --git a/crates/zng-layout/src/unit/length.rs b/crates/zng-layout/src/unit/length.rs
index 90bb3af70..22360fee0 100644
--- a/crates/zng-layout/src/unit/length.rs
+++ b/crates/zng-layout/src/unit/length.rs
@@ -1,14 +1,14 @@
 use super::{
-    about_eq, ByteLength, ByteUnits, Dip, DipToPx, Factor, FactorPercent, FactorUnits, LayoutAxis, Px, EQ_EPSILON, EQ_EPSILON_100,
+    ByteLength, ByteUnits, Dip, DipToPx, EQ_EPSILON, EQ_EPSILON_100, Factor, FactorPercent, FactorUnits, LayoutAxis, Px, about_eq,
 };
 use std::{fmt, mem, ops};
 
 use zng_var::{
-    animation::{easing::EasingStep, Transitionable},
+    animation::{Transitionable, easing::EasingStep},
     impl_from_and_into_var,
 };
 
-use crate::context::{LayoutMask, LAYOUT};
+use crate::context::{LAYOUT, LayoutMask};
 
 /// 1D length units.
 ///
@@ -575,11 +575,7 @@ impl Length {
 
     /// Sum total memory used in nested [`Length::Expr`] heap memory.
     pub fn heap_memory_used(&self) -> ByteLength {
-        if let Length::Expr(e) = self {
-            e.memory_used()
-        } else {
-            0.bytes()
-        }
+        if let Length::Expr(e) = self { e.memory_used() } else { 0.bytes() }
     }
 
     /// 96.0 / 72.0
diff --git a/crates/zng-layout/src/unit/point.rs b/crates/zng-layout/src/unit/point.rs
index 2cf4d7bad..31e0682c6 100644
--- a/crates/zng-layout/src/unit/point.rs
+++ b/crates/zng-layout/src/unit/point.rs
@@ -2,7 +2,7 @@ use std::{fmt, ops};
 
 use zng_var::{animation::Transitionable, impl_from_and_into_var};
 
-use super::{impl_length_comp_conversions, DipPoint, Factor, Factor2d, FactorPercent, Layout1d, LayoutMask, Length, PxPoint, Size, Vector};
+use super::{DipPoint, Factor, Factor2d, FactorPercent, Layout1d, LayoutMask, Length, PxPoint, Size, Vector, impl_length_comp_conversions};
 
 /// 2D point in [`Length`] units.
 #[derive(Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, Transitionable)]
diff --git a/crates/zng-layout/src/unit/rect.rs b/crates/zng-layout/src/unit/rect.rs
index 35ea91e53..297d9743c 100644
--- a/crates/zng-layout/src/unit/rect.rs
+++ b/crates/zng-layout/src/unit/rect.rs
@@ -2,7 +2,7 @@ use std::{fmt, ops};
 
 use zng_var::{animation::Transitionable, impl_from_and_into_var};
 
-use super::{impl_length_comp_conversions, DipRect, Factor2d, LayoutMask, Length, Point, PxRect, Size, Vector};
+use super::{DipRect, Factor2d, LayoutMask, Length, Point, PxRect, Size, Vector, impl_length_comp_conversions};
 
 /// 2D rect in [`Length`] units.
 #[derive(Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, Transitionable)]
diff --git a/crates/zng-layout/src/unit/side_offsets.rs b/crates/zng-layout/src/unit/side_offsets.rs
index 95aa2c448..a69145930 100644
--- a/crates/zng-layout/src/unit/side_offsets.rs
+++ b/crates/zng-layout/src/unit/side_offsets.rs
@@ -3,7 +3,7 @@ use std::{fmt, ops};
 use zng_unit::DipSideOffsets;
 use zng_var::{animation::Transitionable, impl_from_and_into_var};
 
-use super::{impl_length_comp_conversions, Factor, FactorPercent, FactorSideOffsets, Layout1d, LayoutMask, Length, PxSideOffsets};
+use super::{Factor, FactorPercent, FactorSideOffsets, Layout1d, LayoutMask, Length, PxSideOffsets, impl_length_comp_conversions};
 
 /// 2D size offsets in [`Length`] units.
 ///
diff --git a/crates/zng-layout/src/unit/size.rs b/crates/zng-layout/src/unit/size.rs
index b5c897805..8172ba61b 100644
--- a/crates/zng-layout/src/unit/size.rs
+++ b/crates/zng-layout/src/unit/size.rs
@@ -2,7 +2,7 @@ use std::{fmt, ops};
 
 use zng_var::{animation::Transitionable, impl_from_and_into_var};
 
-use super::{impl_length_comp_conversions, DipSize, Factor, Factor2d, FactorPercent, Layout1d, LayoutMask, Length, PxSize, Rect, Vector};
+use super::{DipSize, Factor, Factor2d, FactorPercent, Layout1d, LayoutMask, Length, PxSize, Rect, Vector, impl_length_comp_conversions};
 
 /// 2D size in [`Length`] units.
 #[derive(Clone, Default, PartialEq, serde::Serialize, serde::Deserialize, Transitionable)]
diff --git a/crates/zng-layout/src/unit/transform.rs b/crates/zng-layout/src/unit/transform.rs
index 316cf150b..3491f7672 100644
--- a/crates/zng-layout/src/unit/transform.rs
+++ b/crates/zng-layout/src/unit/transform.rs
@@ -1,7 +1,7 @@
-use super::{euclid, Px};
+use super::{Px, euclid};
 
 use zng_var::{
-    animation::{easing::EasingStep, Transitionable},
+    animation::{Transitionable, easing::EasingStep},
     impl_from_and_into_var,
     types::{is_slerp_enabled, slerp_enabled},
 };
diff --git a/crates/zng-layout/src/unit/vector.rs b/crates/zng-layout/src/unit/vector.rs
index 82e485259..01866f645 100644
--- a/crates/zng-layout/src/unit/vector.rs
+++ b/crates/zng-layout/src/unit/vector.rs
@@ -3,8 +3,8 @@ use std::{fmt, ops};
 use zng_var::{animation::Transitionable, impl_from_and_into_var};
 
 use super::{
-    impl_length_comp_conversions, Dip, DipVector, Factor, Factor2d, FactorPercent, Layout1d, LayoutMask, Length, LengthUnits, Point, Px,
-    PxVector, Size, Transform,
+    Dip, DipVector, Factor, Factor2d, FactorPercent, Layout1d, LayoutMask, Length, LengthUnits, Point, Px, PxVector, Size, Transform,
+    impl_length_comp_conversions,
 };
 
 /// 2D vector in [`Length`] units.
diff --git a/crates/zng-state-map/Cargo.toml b/crates/zng-state-map/Cargo.toml
index 4aa5ff1c7..6f039e526 100644
--- a/crates/zng-state-map/Cargo.toml
+++ b/crates/zng-state-map/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-state-map"
 version = "0.3.8"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-task-proc-macros/Cargo.toml b/crates/zng-task-proc-macros/Cargo.toml
index cc1c37218..62a61df88 100644
--- a/crates/zng-task-proc-macros/Cargo.toml
+++ b/crates/zng-task-proc-macros/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-task-proc-macros"
 version = "0.2.6"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-task-proc-macros/src/any_all.rs b/crates/zng-task-proc-macros/src/any_all.rs
index e51629b69..f0b9a2295 100644
--- a/crates/zng-task-proc-macros/src/any_all.rs
+++ b/crates/zng-task-proc-macros/src/any_all.rs
@@ -1,10 +1,10 @@
 //! Macro for `task::any!` or `task::all!` calls with more then 8 futures.
 
 use syn::{
+    Expr, Path, Token,
     parse::{Parse, ParseStream},
     parse_macro_input,
     punctuated::Punctuated,
-    Expr, Path, Token,
 };
 
 pub fn expand(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
diff --git a/crates/zng-task/Cargo.toml b/crates/zng-task/Cargo.toml
index eb3a93f11..4c80fae77 100644
--- a/crates/zng-task/Cargo.toml
+++ b/crates/zng-task/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-task"
 version = "0.4.18"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-task/src/http.rs b/crates/zng-task/src/http.rs
index 356d88fb9..71cbe2d48 100644
--- a/crates/zng-task/src/http.rs
+++ b/crates/zng-task/src/http.rs
@@ -41,13 +41,13 @@ use super::io::AsyncRead;
 use isahc::config::Configurable;
 pub use isahc::config::RedirectPolicy;
 pub use isahc::cookies::{Cookie, CookieJar};
-pub use isahc::http::{header, uri, Method, StatusCode, Uri};
+pub use isahc::http::{Method, StatusCode, Uri, header, uri};
 
 use futures_lite::io::{AsyncReadExt, BufReader};
 use isahc::{AsyncReadResponseExt, ResponseExt};
-use parking_lot::{const_mutex, Mutex};
+use parking_lot::{Mutex, const_mutex};
 
-use zng_txt::{formatx, Txt};
+use zng_txt::{Txt, formatx};
 use zng_unit::*;
 
 /// Marker trait for types that try-to-convert to [`Uri`].
diff --git a/crates/zng-task/src/http/cache.rs b/crates/zng-task/src/http/cache.rs
index cbeeed19a..815a3e2dc 100644
--- a/crates/zng-task/src/http/cache.rs
+++ b/crates/zng-task/src/http/cache.rs
@@ -336,11 +336,7 @@ mod file_cache {
                     })
                     .await;
 
-                    if ok {
-                        Some(entry.write_body(body).await)
-                    } else {
-                        Some(body)
-                    }
+                    if ok { Some(entry.write_body(body).await) } else { Some(body) }
                 }
                 _ => Some(body),
             }
@@ -891,7 +887,7 @@ mod tests {
     #[track_caller]
     fn async_test<F>(test: F) -> F::Output
     where
-        F: std::future::Future,
+        F: Future,
     {
         task::block_on(task::with_deadline(test, 30.secs())).unwrap()
     }
diff --git a/crates/zng-task/src/io.rs b/crates/zng-task/src/io.rs
index b320acd2e..53b58c9f8 100644
--- a/crates/zng-task/src/io.rs
+++ b/crates/zng-task/src/io.rs
@@ -17,8 +17,8 @@ use crate::{McWaker, Progress};
 
 #[doc(no_inline)]
 pub use futures_lite::io::{
-    copy, empty, repeat, sink, split, AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, AsyncWrite,
-    AsyncWriteExt, BoxedReader, BoxedWriter, BufReader, BufWriter, Cursor, ReadHalf, WriteHalf,
+    AsyncBufRead, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt, AsyncWrite, AsyncWriteExt, BoxedReader, BoxedWriter,
+    BufReader, BufWriter, Cursor, ReadHalf, WriteHalf, copy, empty, repeat, sink, split,
 };
 use parking_lot::Mutex;
 use std::io::{Error, Result};
@@ -896,7 +896,7 @@ mod tests {
     #[track_caller]
     fn async_test<F>(test: F) -> F::Output
     where
-        F: std::future::Future,
+        F: Future,
     {
         task::block_on(task::with_deadline(test, 5.secs())).unwrap()
     }
diff --git a/crates/zng-task/src/ipc.rs b/crates/zng-task/src/ipc.rs
index 01189757c..3563f8d6b 100644
--- a/crates/zng-task/src/ipc.rs
+++ b/crates/zng-task/src/ipc.rs
@@ -75,7 +75,7 @@
 //! on different modules.
 
 use core::fmt;
-use std::{future::Future, marker::PhantomData, path::PathBuf, pin::Pin, sync::Arc};
+use std::{marker::PhantomData, path::PathBuf, pin::Pin, sync::Arc};
 
 use parking_lot::Mutex;
 use zng_clone_move::{async_clmv, clmv};
@@ -84,7 +84,7 @@ use zng_unique_id::IdMap;
 use zng_unit::TimeUnits as _;
 
 #[doc(no_inline)]
-pub use ipc_channel::ipc::{bytes_channel, IpcBytesReceiver, IpcBytesSender, IpcReceiver, IpcSender};
+pub use ipc_channel::ipc::{IpcBytesReceiver, IpcBytesSender, IpcReceiver, IpcSender, bytes_channel};
 
 /// Represents a type that can be an input and output of IPC workers.
 ///
@@ -194,14 +194,16 @@ impl<I: IpcValue, O: IpcValue> Worker<I, O> {
                     let code = output.status.code().unwrap_or(0);
                     return Err(std::io::Error::new(
                         std::io::ErrorKind::TimedOut,
-                        format!("worker process did not connect in 10 seconds\nworker exit code: {code}\n--worker stdout--\n{stdout}\n--worker stderr--\n{stderr}"),
+                        format!(
+                            "worker process did not connect in 10 seconds\nworker exit code: {code}\n--worker stdout--\n{stdout}\n--worker stderr--\n{stderr}"
+                        ),
                     ));
                 }
                 Err(e) => {
                     return Err(std::io::Error::new(
                         std::io::ErrorKind::TimedOut,
                         format!("worker process did not connect in 10s\ncannot be kill worker process, {e}"),
-                    ))
+                    ));
                 }
             },
         };
diff --git a/crates/zng-task/src/lib.rs b/crates/zng-task/src/lib.rs
index 6fa95dbdf..316356c5b 100644
--- a/crates/zng-task/src/lib.rs
+++ b/crates/zng-task/src/lib.rs
@@ -11,13 +11,12 @@
 
 use std::{
     fmt,
-    future::{Future, IntoFuture},
     hash::Hash,
     mem, panic,
     pin::Pin,
     sync::{
-        atomic::{AtomicBool, Ordering},
         Arc,
+        atomic::{AtomicBool, Ordering},
     },
     task::Poll,
 };
@@ -29,9 +28,9 @@ use parking_lot::Mutex;
 mod crate_util;
 
 use crate::crate_util::PanicResult;
-use zng_app_context::{app_local, LocalContext};
+use zng_app_context::{LocalContext, app_local};
 use zng_time::Deadline;
-use zng_var::{response_done_var, response_var, AnyVar, ResponseVar, VarValue};
+use zng_var::{AnyVar, ResponseVar, VarValue, response_done_var, response_var};
 
 #[cfg(test)]
 mod tests;
@@ -1071,7 +1070,6 @@ macro_rules! __all {
             $(let mut $ident = (Some($fut), None);)+
             $crate::future_fn(move |cx| {
                 use std::task::Poll;
-                use std::future::Future;
 
                 let mut pending = false;
 
@@ -1207,7 +1205,6 @@ macro_rules! __any {
             $(let mut $ident = $fut;)+
             $crate::future_fn(move |cx| {
                 use std::task::Poll;
-                use std::future::Future;
                 $(
                     // SAFETY: the closure owns $ident and is an exclusive borrow inside a
                     // Future::poll call, so it will not move.
@@ -1336,7 +1333,6 @@ macro_rules! __any_ok {
             $(let mut $ident = (Some($fut), None);)+
             $crate::future_fn(move |cx| {
                 use std::task::Poll;
-                use std::future::Future;
 
                 let mut pending = false;
 
@@ -1479,7 +1475,6 @@ macro_rules! __any_some {
             $(let mut $ident = Some($fut);)+
             $crate::future_fn(move |cx| {
                 use std::task::Poll;
-                use std::future::Future;
 
                 let mut pending = false;
 
@@ -1636,7 +1631,6 @@ macro_rules! __all_ok {
 
             $crate::future_fn(move |cx| {
                 use std::task::Poll;
-                use std::future::Future;
 
                 let mut pending = false;
 
@@ -1793,7 +1787,6 @@ macro_rules! __all_some {
             $(let mut $ident = (Some($fut), None);)+
             $crate::future_fn(move |cx| {
                 use std::task::Poll;
-                use std::future::Future;
 
                 let mut pending = false;
 
@@ -1968,11 +1961,7 @@ impl McWaker {
     ///
     /// [`cancel`]: Self::cancel
     pub fn push(&self, waker: std::task::Waker) -> Option<std::task::Waker> {
-        if self.0.push(waker) {
-            Some(self.0.clone().into())
-        } else {
-            None
-        }
+        if self.0.push(waker) { Some(self.0.clone().into()) } else { None }
     }
 
     /// Clear current registered wakers.
diff --git a/crates/zng-task/src/rayon_ctx.rs b/crates/zng-task/src/rayon_ctx.rs
index a7d4a0990..f80401a38 100644
--- a/crates/zng-task/src/rayon_ctx.rs
+++ b/crates/zng-task/src/rayon_ctx.rs
@@ -224,8 +224,8 @@ impl<P: Producer> Producer for ParallelCtxProducer<P> {
 #[cfg(test)]
 mod tests {
     use std::sync::{
-        atomic::{AtomicBool, AtomicU32, Ordering},
         Arc,
+        atomic::{AtomicBool, AtomicU32, Ordering},
     };
 
     use super::*;
diff --git a/crates/zng-task/src/ui.rs b/crates/zng-task/src/ui.rs
index 6e1e2fdb2..cab12b746 100644
--- a/crates/zng-task/src/ui.rs
+++ b/crates/zng-task/src/ui.rs
@@ -1,9 +1,7 @@
 //! UI-thread bound tasks.
 
 use std::{
-    fmt,
-    future::{Future, IntoFuture},
-    mem,
+    fmt, mem,
     pin::Pin,
     task::{Poll, Waker},
 };
@@ -89,11 +87,7 @@ impl<R> UiTask<R> {
             }
         }
 
-        if let UiTaskState::Ready(r) = &self.0 {
-            Some(r)
-        } else {
-            None
-        }
+        if let UiTaskState::Ready(r) = &self.0 { Some(r) } else { None }
     }
 
     /// Returns `true` if the task is done.
diff --git a/crates/zng-time/Cargo.toml b/crates/zng-time/Cargo.toml
index c0f254b0d..9e2cb77f1 100644
--- a/crates/zng-time/Cargo.toml
+++ b/crates/zng-time/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-time"
 version = "0.2.26"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-tp-licenses/Cargo.toml b/crates/zng-tp-licenses/Cargo.toml
index 1bc687815..7edf2ce56 100644
--- a/crates/zng-tp-licenses/Cargo.toml
+++ b/crates/zng-tp-licenses/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "zng-tp-licenses"
 version = "0.2.9"
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-tp-licenses/src/lib.rs b/crates/zng-tp-licenses/src/lib.rs
index a9ca625eb..99af1200b 100644
--- a/crates/zng-tp-licenses/src/lib.rs
+++ b/crates/zng-tp-licenses/src/lib.rs
@@ -266,9 +266,7 @@ macro_rules! include_bundle {
     () => {
         $crate::include_bundle!(concat!(env!("OUT_DIR"), "/zng-tp-licenses.bin"))
     };
-    ($custom_name:expr) => {{
-        $crate::decode_licenses(include_bytes!($custom_name))
-    }};
+    ($custom_name:expr) => {{ $crate::decode_licenses(include_bytes!($custom_name)) }};
 }
 
 /// Decode licenses encoded with [`encode_licenses`]. Note that the encoded format is only guaranteed to work
diff --git a/crates/zng-txt/Cargo.toml b/crates/zng-txt/Cargo.toml
index 4b8bb123e..a3bb9bf5e 100644
--- a/crates/zng-txt/Cargo.toml
+++ b/crates/zng-txt/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-txt"
 version = "0.2.8"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-txt/src/lib.rs b/crates/zng-txt/src/lib.rs
index ae3db7583..032280ecc 100644
--- a/crates/zng-txt/src/lib.rs
+++ b/crates/zng-txt/src/lib.rs
@@ -216,11 +216,7 @@ impl Txt {
             TxtData::Arc(s) => TxtData::String((*s).to_owned()),
         };
 
-        if let TxtData::String(s) = &mut self.0 {
-            s
-        } else {
-            unreachable!()
-        }
+        if let TxtData::String(s) = &mut self.0 { s } else { unreachable!() }
     }
 
     /// Convert the inner representation of the string to not be [`String`]. After
diff --git a/crates/zng-unique-id/Cargo.toml b/crates/zng-unique-id/Cargo.toml
index 30bfdc248..9a208b970 100644
--- a/crates/zng-unique-id/Cargo.toml
+++ b/crates/zng-unique-id/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-unique-id"
 version = "0.4.8"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-unique-id/src/hot_reload.rs b/crates/zng-unique-id/src/hot_reload.rs
index 3db4c9f5c..beaf2324a 100644
--- a/crates/zng-unique-id/src/hot_reload.rs
+++ b/crates/zng-unique-id/src/hot_reload.rs
@@ -66,7 +66,7 @@ macro_rules! hot_static_patchable {
             static mut $IDENT: &$Ty = &[<$IDENT _COLD>];
             #[allow(non_snake_case)]
             unsafe fn [<$IDENT _INIT>](static_ptr: *const ()) -> *const () {
-                $crate::hot_reload::init_static(&mut $IDENT, static_ptr)
+                unsafe { $crate::hot_reload::init_static(&mut $IDENT, static_ptr) }
             }
 
             // expanded from:
@@ -106,7 +106,7 @@ pub unsafe fn init_static<T>(s: &mut &'static T, static_ptr: *const ()) -> *cons
     if static_ptr.is_null() {
         *s as *const T as *const ()
     } else {
-        *s = &*(static_ptr as *const T);
+        *s = unsafe { &*(static_ptr as *const T) };
         std::ptr::null()
     }
 }
diff --git a/crates/zng-unique-id/src/named.rs b/crates/zng-unique-id/src/named.rs
index 259246702..de497de4e 100644
--- a/crates/zng-unique-id/src/named.rs
+++ b/crates/zng-unique-id/src/named.rs
@@ -3,7 +3,7 @@ use std::{
     hash::{BuildHasher, Hash},
 };
 
-use hashbrown::hash_map;
+use std::collections::hash_map;
 
 use crate::{IdEntry, IdMap};
 
@@ -16,10 +16,10 @@ impl BuildHasher for ConstDefaultHashBuilder {
     }
 }
 
-type DefaultHashMap<K, V> = hashbrown::HashMap<K, V, ConstDefaultHashBuilder>;
+type DefaultHashMap<K, V> = std::collections::HashMap<K, V, ConstDefaultHashBuilder>;
 
 const fn default_hash_map_new<K, V>() -> DefaultHashMap<K, V> {
-    hashbrown::HashMap::with_hasher(ConstDefaultHashBuilder)
+    DefaultHashMap::with_hasher(ConstDefaultHashBuilder)
 }
 
 #[doc(hidden)]
diff --git a/crates/zng-unit/Cargo.toml b/crates/zng-unit/Cargo.toml
index ffcc95fa6..76c9dc7ba 100644
--- a/crates/zng-unit/Cargo.toml
+++ b/crates/zng-unit/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-unit"
 version = "0.2.11"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-unit/src/angle.rs b/crates/zng-unit/src/angle.rs
index a8c075ec7..684678352 100644
--- a/crates/zng-unit/src/angle.rs
+++ b/crates/zng-unit/src/angle.rs
@@ -1,4 +1,4 @@
-use super::{about_eq, Factor, EQ_EPSILON, EQ_EPSILON_100};
+use super::{EQ_EPSILON, EQ_EPSILON_100, Factor, about_eq};
 
 use std::{
     f32::consts::{PI, TAU},
diff --git a/crates/zng-unit/src/color.rs b/crates/zng-unit/src/color.rs
index 65babe424..3761ca2f7 100644
--- a/crates/zng-unit/src/color.rs
+++ b/crates/zng-unit/src/color.rs
@@ -1,6 +1,6 @@
 use std::{fmt, ops};
 
-use crate::{about_eq, about_eq_hash, Factor, FactorPercent};
+use crate::{Factor, FactorPercent, about_eq, about_eq_hash};
 
 /// RGB + alpha.
 ///
@@ -144,7 +144,7 @@ impl fmt::Display for Rgba {
         if a == 255 {
             write!(f, "#{rgb:0>6X}")
         } else {
-            let rgba = rgb << 8 | a;
+            let rgba = (rgb << 8) | a;
             write!(f, "#{rgba:0>8X}")
         }
     }
diff --git a/crates/zng-unit/src/factor.rs b/crates/zng-unit/src/factor.rs
index 19040b5b2..3df140c6f 100644
--- a/crates/zng-unit/src/factor.rs
+++ b/crates/zng-unit/src/factor.rs
@@ -1,8 +1,8 @@
 use std::{fmt, ops, time::Duration};
 
 use crate::{
-    about_eq, about_eq_hash, about_eq_ord, Dip, DipPoint, DipRect, DipSize, DipVector, Px, PxPoint, PxRect, PxSize, PxVector, EQ_EPSILON,
-    EQ_EPSILON_100,
+    Dip, DipPoint, DipRect, DipSize, DipVector, EQ_EPSILON, EQ_EPSILON_100, Px, PxPoint, PxRect, PxSize, PxVector, about_eq, about_eq_hash,
+    about_eq_ord,
 };
 
 /// Extension methods for initializing factor units.
@@ -547,11 +547,7 @@ impl ops::Neg for Factor {
 }
 impl From<bool> for Factor {
     fn from(value: bool) -> Self {
-        if value {
-            Factor(1.0)
-        } else {
-            Factor(0.0)
-        }
+        if value { Factor(1.0) } else { Factor(0.0) }
     }
 }
 
diff --git a/crates/zng-unit/src/orientation.rs b/crates/zng-unit/src/orientation.rs
index 2b5771297..d69715c46 100644
--- a/crates/zng-unit/src/orientation.rs
+++ b/crates/zng-unit/src/orientation.rs
@@ -65,7 +65,7 @@ impl Orientation2D {
 
     /// Iterator that yields quadrants for efficient search in a quad-tree, if a point is inside a quadrant and
     /// passes the [`Orientation2D::point_is`] check it is in the orientation, them if it is within the `max_distance` it is valid.
-    pub fn search_bounds(self, origin: PxPoint, max_distance: Px, spatial_bounds: PxBox) -> impl Iterator<Item = PxBox> {
+    pub fn search_bounds(self, origin: PxPoint, max_distance: Px, spatial_bounds: PxBox) -> impl Iterator<Item = PxBox> + 'static {
         let mut bounds = PxRect::new(origin, PxSize::splat(max_distance));
         match self {
             Orientation2D::Above => {
diff --git a/crates/zng-unit/src/px_dip.rs b/crates/zng-unit/src/px_dip.rs
index 2ae385984..873daa1bb 100644
--- a/crates/zng-unit/src/px_dip.rs
+++ b/crates/zng-unit/src/px_dip.rs
@@ -2,7 +2,7 @@ use std::{cmp, fmt, ops};
 
 use serde::{Deserialize, Serialize};
 
-use crate::{side_offsets::SideOffsets2D, CornerRadius2D, Factor};
+use crate::{CornerRadius2D, Factor, side_offsets::SideOffsets2D};
 
 /// Same value used in `60`.
 const DIP_TO_PX: i32 = 60;
@@ -439,11 +439,7 @@ impl num_traits::ToPrimitive for Dip {
     }
 
     fn to_u64(&self) -> Option<u64> {
-        if self.0 >= 0 {
-            Some(Dip::to_i32(*self) as u64)
-        } else {
-            None
-        }
+        if self.0 >= 0 { Some(Dip::to_i32(*self) as u64) } else { None }
     }
 
     fn to_f32(&self) -> Option<f32> {
diff --git a/crates/zng-var-proc-macros/Cargo.toml b/crates/zng-var-proc-macros/Cargo.toml
index 63749d868..d924281fa 100644
--- a/crates/zng-var-proc-macros/Cargo.toml
+++ b/crates/zng-var-proc-macros/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-var-proc-macros"
 version = "0.2.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-var-proc-macros/src/expr_var.rs b/crates/zng-var-proc-macros/src/expr_var.rs
index 3eabcb21d..0ea9cf72e 100644
--- a/crates/zng-var-proc-macros/src/expr_var.rs
+++ b/crates/zng-var-proc-macros/src/expr_var.rs
@@ -1,10 +1,11 @@
 use proc_macro2::{Group, TokenStream, TokenTree};
 use quote::ToTokens;
 use syn::{
+    Expr, Ident, Path, Token,
     parse::{Parse, ParseStream},
-    parse2, parse_macro_input,
+    parse_macro_input, parse2,
     spanned::Spanned,
-    token, Expr, Ident, Path, Token,
+    token,
 };
 
 use crate::util::{token_stream_eq, tokens_to_ident_str};
diff --git a/crates/zng-var-proc-macros/src/merge_var.rs b/crates/zng-var-proc-macros/src/merge_var.rs
index 2a4d5e7da..2b50904a4 100644
--- a/crates/zng-var-proc-macros/src/merge_var.rs
+++ b/crates/zng-var-proc-macros/src/merge_var.rs
@@ -1,8 +1,8 @@
 use syn::{
+    Expr, Path, Token,
     parse::{Parse, ParseStream},
     parse_macro_input,
     punctuated::Punctuated,
-    Expr, Path, Token,
 };
 
 pub fn expand(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
diff --git a/crates/zng-var-proc-macros/src/when_var.rs b/crates/zng-var-proc-macros/src/when_var.rs
index 9870a703a..dda8603f7 100644
--- a/crates/zng-var-proc-macros/src/when_var.rs
+++ b/crates/zng-var-proc-macros/src/when_var.rs
@@ -1,9 +1,8 @@
 use syn::{
-    parenthesized,
+    Attribute, Expr, Path, Token, parenthesized,
     parse::{Parse, ParseStream},
     parse_macro_input,
     punctuated::Punctuated,
-    Attribute, Expr, Path, Token,
 };
 
 pub fn expand(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
diff --git a/crates/zng-var/Cargo.toml b/crates/zng-var/Cargo.toml
index ff04ff874..842dec976 100644
--- a/crates/zng-var/Cargo.toml
+++ b/crates/zng-var/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-var"
 version = "0.5.16"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-var/src/animation/easing.rs b/crates/zng-var/src/animation/easing.rs
index 5152c5fb3..868c17118 100644
--- a/crates/zng-var/src/animation/easing.rs
+++ b/crates/zng-var/src/animation/easing.rs
@@ -85,7 +85,7 @@ impl EasingTime {
     ///
     /// [`FactorPercent`]: zng_unit::FactorPercent
     pub fn pct(self) -> FactorPercent {
-        self.0 .0.pct()
+        self.0.0.pct()
     }
 
     /// Flip the time.
diff --git a/crates/zng-var/src/context.rs b/crates/zng-var/src/context.rs
index 35eb53a75..5d59f338c 100644
--- a/crates/zng-var/src/context.rs
+++ b/crates/zng-var/src/context.rs
@@ -1,4 +1,4 @@
-use zng_app_context::{context_local, AppLocalId, ContextLocal, ContextLocalKeyProvider};
+use zng_app_context::{AppLocalId, ContextLocal, ContextLocalKeyProvider, context_local};
 
 use super::*;
 
diff --git a/crates/zng-var/src/impls.rs b/crates/zng-var/src/impls.rs
index 36c71b210..f05ff0fe6 100644
--- a/crates/zng-var/src/impls.rs
+++ b/crates/zng-var/src/impls.rs
@@ -6,12 +6,12 @@ use zng_app_context::{app_local, context_local};
 use zng_time::{DInstant, Deadline};
 use zng_txt::Txt;
 use zng_unit::{
-    euclid, AngleDegree, AngleGradian, AngleRadian, AngleTurn, ByteLength, CornerRadius2D, Dip, Factor, FactorPercent, FactorUnits,
-    Orientation2D, Px, Rgba,
+    AngleDegree, AngleGradian, AngleRadian, AngleTurn, ByteLength, CornerRadius2D, Dip, Factor, FactorPercent, FactorUnits, Orientation2D,
+    Px, Rgba, euclid,
 };
 
 use crate::{
-    animation::{easing::EasingStep, Transition, Transitionable},
+    animation::{Transition, Transitionable, easing::EasingStep},
     impl_from_and_into_var,
 };
 
@@ -165,11 +165,7 @@ where
 }
 impl Transitionable for bool {
     fn lerp(self, to: &Self, step: EasingStep) -> Self {
-        if step >= 1.fct() {
-            *to
-        } else {
-            self
-        }
+        if step >= 1.fct() { *to } else { self }
     }
 }
 impl<T, U> Transitionable for CornerRadius2D<T, U>
diff --git a/crates/zng-var/src/lib.rs b/crates/zng-var/src/lib.rs
index 2bfed7a08..b8ccf948c 100644
--- a/crates/zng-var/src/lib.rs
+++ b/crates/zng-var/src/lib.rs
@@ -13,8 +13,8 @@
 #![deny(clippy::future_not_send)]
 
 use animation::{
-    easing::{EasingStep, EasingTime},
     Transitionable,
+    easing::{EasingStep, EasingTime},
 };
 use bitflags::bitflags;
 use parking_lot::Mutex;
@@ -22,18 +22,17 @@ use std::{
     any::{Any, TypeId},
     borrow::Cow,
     fmt,
-    future::Future,
     marker::PhantomData,
     ops,
     sync::{
-        atomic::{AtomicBool, Ordering::Relaxed},
         Arc,
+        atomic::{AtomicBool, Ordering::Relaxed},
     },
     time::Duration,
 };
 use zng_app_context::{AppLocalId, ContextLocal};
 use zng_clone_move::clmv;
-use zng_txt::{formatx, ToTxt, Txt};
+use zng_txt::{ToTxt, Txt, formatx};
 use zng_unit::{Factor, FactorUnits};
 
 pub mod animation;
@@ -59,7 +58,7 @@ mod when;
 #[macro_use]
 mod util;
 
-pub use arc::{getter_var, state_var, var, var_default, var_from, ArcVar};
+pub use arc::{ArcVar, getter_var, state_var, var, var_default, var_from};
 pub use boxed::{BoxedAnyVar, BoxedAnyWeakVar, BoxedVar, BoxedWeakVar};
 #[doc(inline)]
 pub use context::{ContextInitHandle, ContextVar, ReadOnlyContextVar};
@@ -67,7 +66,7 @@ pub use local::LocalVar;
 #[doc(inline)]
 pub use merge::MergeVarBuilder;
 pub use read_only::ReadOnlyArcVar;
-pub use response::{response_done_var, response_var, ResponderVar, ResponseVar};
+pub use response::{ResponderVar, ResponseVar, response_done_var, response_var};
 pub use vars::*;
 pub use vec::ObservableVec;
 
@@ -82,17 +81,17 @@ pub mod types {
 
     pub use super::arc::WeakArcVar;
     pub use super::boxed::{VarBoxed, WeakVarBoxed};
-    pub use super::context::{context_var_init, WeakContextInitHandle};
+    pub use super::context::{WeakContextInitHandle, context_var_init};
     pub use super::contextualized::{ContextualizedVar, WeakContextualizedVar};
     pub use super::cow::{ArcCowVar, WeakCowVar};
     pub use super::expr::{__expr_var, expr_var_as, expr_var_into, expr_var_map};
     pub use super::flat_map::{ArcFlatMapVar, WeakFlatMapVar};
     pub use super::map_ref::{MapRef, MapRefBidi, WeakMapRef, WeakMapRefBidi};
-    pub use super::merge::{ArcMergeVar, ArcMergeVarInput, MergeVarInputs, WeakMergeVar, __merge_var};
+    pub use super::merge::{__merge_var, ArcMergeVar, ArcMergeVarInput, MergeVarInputs, WeakMergeVar};
     pub use super::read_only::{ReadOnlyVar, WeakReadOnlyVar};
     pub use super::response::Response;
     pub use super::vec::VecChange;
-    pub use super::when::{AnyWhenVarBuilder, ArcWhenVar, ContextualizedArcWhenVar, WeakWhenVar, WhenVarBuilder, __when_var};
+    pub use super::when::{__when_var, AnyWhenVarBuilder, ArcWhenVar, ContextualizedArcWhenVar, WeakWhenVar, WhenVarBuilder};
 
     use super::*;
 
@@ -1187,11 +1186,7 @@ pub trait Var<T: VarValue>: IntoVar<T, Var = Self> + AnyVar + Clone {
     where
         F: FnOnce(&T) -> R,
     {
-        if self.is_new() {
-            Some(self.with(read))
-        } else {
-            None
-        }
+        if self.is_new() { Some(self.with(read)) } else { None }
     }
 
     /// Get a clone of the current value.
@@ -1231,11 +1226,7 @@ pub trait Var<T: VarValue>: IntoVar<T, Var = Self> + AnyVar + Clone {
     ///
     /// [`is_new`]: AnyVar::is_new
     fn get_new(&self) -> Option<T> {
-        if self.is_new() {
-            Some(self.with(Clone::clone))
-        } else {
-            None
-        }
+        if self.is_new() { Some(self.with(Clone::clone)) } else { None }
     }
 
     /// Get a clone of the current value into `value` if the current value [`is_new`].
diff --git a/crates/zng-var/src/response.rs b/crates/zng-var/src/response.rs
index e59838b9f..e8a809b98 100644
--- a/crates/zng-var/src/response.rs
+++ b/crates/zng-var/src/response.rs
@@ -1,5 +1,3 @@
-use std::future::IntoFuture;
-
 use super::*;
 
 /// New paired [`ResponderVar`] and [`ResponseVar`] in the waiting state.
diff --git a/crates/zng-var/src/util.rs b/crates/zng-var/src/util.rs
index 2b2283b30..c04a6640c 100644
--- a/crates/zng-var/src/util.rs
+++ b/crates/zng-var/src/util.rs
@@ -65,7 +65,7 @@ use parking_lot::RwLock;
 
 use crate::{AnyVarHookArgs, AnyVarValue};
 
-use super::{animation::ModifyInfo, VarHandle, VarHook, VarModify, VarUpdateId, VarValue, VARS};
+use super::{VARS, VarHandle, VarHook, VarModify, VarUpdateId, VarValue, animation::ModifyInfo};
 
 #[doc(hidden)]
 #[macro_export]
diff --git a/crates/zng-var/src/vec.rs b/crates/zng-var/src/vec.rs
index 82ec8d1fd..3727ae1b7 100644
--- a/crates/zng-var/src/vec.rs
+++ b/crates/zng-var/src/vec.rs
@@ -1,6 +1,6 @@
 use std::ops;
 
-use crate::{VarUpdateId, VarValue, VARS};
+use crate::{VARS, VarUpdateId, VarValue};
 
 /// Represents a [`Vec<T>`] that tracks changes when used inside a variable.
 ///
@@ -95,11 +95,7 @@ impl<T: VarValue> ObservableVec<T> {
     ///
     /// See [`Vec::pop`].
     pub fn pop(&mut self) -> Option<T> {
-        if self.is_empty() {
-            None
-        } else {
-            Some(self.remove(self.len() - 1))
-        }
+        if self.is_empty() { None } else { Some(self.remove(self.len() - 1)) }
     }
 
     /// Shortens the vector, keeping the first `len` elements and dropping the rest.
diff --git a/crates/zng-view-api/Cargo.toml b/crates/zng-view-api/Cargo.toml
index bc79d7a1a..f7c180667 100644
--- a/crates/zng-view-api/Cargo.toml
+++ b/crates/zng-view-api/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-view-api"
 version = "0.11.6"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-view-api/src/api_extension.rs b/crates/zng-view-api/src/api_extension.rs
index 7abe4c34d..3e6c1dd82 100644
--- a/crates/zng-view-api/src/api_extension.rs
+++ b/crates/zng-view-api/src/api_extension.rs
@@ -289,11 +289,7 @@ impl std::str::FromStr for ApiExtensionId {
         match s.parse::<u32>() {
             Ok(i) => {
                 let r = Self::from_index(i as _);
-                if r == Self::INVALID {
-                    Err(r)
-                } else {
-                    Ok(r)
-                }
+                if r == Self::INVALID { Err(r) } else { Ok(r) }
             }
             Err(_) => Err(Self::INVALID),
         }
@@ -335,10 +331,6 @@ impl fmt::Display for ApiExtensionRecvError {
 }
 impl std::error::Error for ApiExtensionRecvError {
     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
-        if let Self::Deserialize(e) = self {
-            Some(e)
-        } else {
-            None
-        }
+        if let Self::Deserialize(e) = self { Some(e) } else { None }
     }
 }
diff --git a/crates/zng-view-api/src/app_process.rs b/crates/zng-view-api/src/app_process.rs
index 0c3d20416..ee6327275 100644
--- a/crates/zng-view-api/src/app_process.rs
+++ b/crates/zng-view-api/src/app_process.rs
@@ -11,7 +11,7 @@ use std::time::Duration;
 
 use zng_txt::Txt;
 
-use crate::{ipc, AnyResult, Event, Request, Response, ViewConfig, ViewProcessGen, ViewProcessOffline, VpResult};
+use crate::{AnyResult, Event, Request, Response, ViewConfig, ViewProcessGen, ViewProcessOffline, VpResult, ipc};
 
 /// The listener returns the closure on join for reuse in respawn.
 type EventListenerJoin = JoinHandle<Box<dyn FnMut(Event) + Send>>;
@@ -167,11 +167,7 @@ impl Controller {
     }
 
     fn offline_err(&self) -> Result<(), ViewProcessOffline> {
-        if self.online() {
-            Ok(())
-        } else {
-            Err(ViewProcessOffline)
-        }
+        if self.online() { Ok(()) } else { Err(ViewProcessOffline) }
     }
 
     fn try_talk(&mut self, req: Request) -> ipc::IpcResult<Response> {
@@ -297,16 +293,16 @@ impl Controller {
     /// Handle an [`Event::Inited`].
     ///
     /// Set the online flag to `true`.
-    pub fn handle_inited(&mut self, gen: ViewProcessGen) {
+    pub fn handle_inited(&mut self, vp_gen: ViewProcessGen) {
         match self.view_state {
             ViewState::Offline => {
-                if self.generation == gen {
+                if self.generation == vp_gen {
                     // crash respawn already sets gen
                     self.view_state = ViewState::Online;
                 }
             }
             ViewState::Suspended => {
-                self.generation = gen;
+                self.generation = vp_gen;
                 self.view_state = ViewState::Online;
             }
             ViewState::Online => {}
@@ -339,8 +335,8 @@ impl Controller {
     /// If the an error happens three times when trying to spawn the new view-process.
     ///
     /// If another disconnect happens during the view-process startup dialog.
-    pub fn handle_disconnect(&mut self, gen: ViewProcessGen) {
-        if gen == self.generation {
+    pub fn handle_disconnect(&mut self, vp_gen: ViewProcessGen) {
+        if vp_gen == self.generation {
             #[cfg(not(ipc))]
             {
                 tracing::error!(target: "vp_respawn", "cannot recover in same_process mode (no ipc)");
diff --git a/crates/zng-view-api/src/display_list.rs b/crates/zng-view-api/src/display_list.rs
index 01c9e12c5..6aa4cc1ac 100644
--- a/crates/zng-view-api/src/display_list.rs
+++ b/crates/zng-view-api/src/display_list.rs
@@ -2,18 +2,18 @@
 
 use std::{
     ops,
-    sync::{atomic::AtomicUsize, Arc},
+    sync::{Arc, atomic::AtomicUsize},
 };
 
 use serde::{Deserialize, Serialize};
 
 use crate::{
+    AlphaType, BorderSide, ExtendMode, GradientStop, ImageRendering, LineOrientation, LineStyle, MixBlendMode, ReferenceFrameId,
+    RepeatMode, TransformStyle,
     api_extension::{ApiExtensionId, ApiExtensionPayload},
     font::{FontId, GlyphInstance, GlyphOptions},
     image::ImageTextureId,
     window::FrameId,
-    AlphaType, BorderSide, ExtendMode, GradientStop, ImageRendering, LineOrientation, LineStyle, MixBlendMode, ReferenceFrameId,
-    RepeatMode, TransformStyle,
 };
 use zng_unit::*;
 
@@ -634,11 +634,7 @@ impl FrameValueId {
     #[must_use]
     pub const fn next(self) -> Self {
         let r = Self(self.0.wrapping_add(1));
-        if r.0 == Self::INVALID.0 {
-            Self::first()
-        } else {
-            r
-        }
+        if r.0 == Self::INVALID.0 { Self::first() } else { r }
     }
     /// Replace self with [`next`] and returns.
     ///
diff --git a/crates/zng-view-api/src/ipc.rs b/crates/zng-view-api/src/ipc.rs
index e21b1355a..6d186ef42 100644
--- a/crates/zng-view-api/src/ipc.rs
+++ b/crates/zng-view-api/src/ipc.rs
@@ -5,7 +5,7 @@ use std::{fmt, ops::Deref, time::Duration};
 use crate::{AnyResult, Event, Request, Response};
 
 #[cfg(ipc)]
-use ipc_channel::ipc::{channel, IpcOneShotServer, IpcReceiver, IpcSender};
+use ipc_channel::ipc::{IpcOneShotServer, IpcReceiver, IpcSender, channel};
 
 #[cfg(not(ipc))]
 use flume::unbounded as channel;
diff --git a/crates/zng-view-api/src/lib.rs b/crates/zng-view-api/src/lib.rs
index 1b22a1997..d5604d7a0 100644
--- a/crates/zng-view-api/src/lib.rs
+++ b/crates/zng-view-api/src/lib.rs
@@ -270,7 +270,7 @@ declare_api! {
     ///
     /// Sends an [`Event::Inited`] once the view is completely online.
     /// Other methods may only be called after this event.
-    fn init(&mut self, gen: ViewProcessGen, is_respawn: bool, device_events: bool, headless: bool);
+    fn init(&mut self, vp_gen: ViewProcessGen, is_respawn: bool, device_events: bool, headless: bool);
 
     /// Called once after exit, if running in a managed external process it will be killed after this call.
     fn exit(&mut self);
diff --git a/crates/zng-view-api/src/view_process.rs b/crates/zng-view-api/src/view_process.rs
index 524abac8c..38f787524 100644
--- a/crates/zng-view-api/src/view_process.rs
+++ b/crates/zng-view-api/src/view_process.rs
@@ -168,7 +168,10 @@ impl StaticPatch {
     ///
     /// Only safe if it is the first view-process code to run in the dynamic library.
     pub unsafe fn install(&self) {
-        *std::ptr::addr_of_mut!(SAME_PROCESS) = &*self.same_process;
+        // SAFETY: safety handled by the caller
+        unsafe {
+            *std::ptr::addr_of_mut!(SAME_PROCESS) = &*self.same_process;
+        }
         self.tracing.install();
     }
 }
diff --git a/crates/zng-view-api/src/window.rs b/crates/zng-view-api/src/window.rs
index 94512885f..648e83858 100644
--- a/crates/zng-view-api/src/window.rs
+++ b/crates/zng-view-api/src/window.rs
@@ -991,7 +991,7 @@ impl FrameId {
 
     /// Get the raw ID.
     pub fn get(self) -> u64 {
-        (self.0 as u64) << 32 | (self.1 as u64)
+        ((self.0 as u64) << 32) | (self.1 as u64)
     }
 
     /// Get the full frame ID.
diff --git a/crates/zng-view-prebuilt/Cargo.toml b/crates/zng-view-prebuilt/Cargo.toml
index aab20b886..151f22bd5 100644
--- a/crates/zng-view-prebuilt/Cargo.toml
+++ b/crates/zng-view-prebuilt/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-view-prebuilt"
 version = "0.13.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-view/Cargo.toml b/crates/zng-view/Cargo.toml
index 043b067aa..4622797b0 100644
--- a/crates/zng-view/Cargo.toml
+++ b/crates/zng-view/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-view"
 version = "0.7.6"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-view/src/config/dconf.rs b/crates/zng-view/src/config/dconf.rs
index 258f09e3d..2cfd5029d 100644
--- a/crates/zng-view/src/config/dconf.rs
+++ b/crates/zng-view/src/config/dconf.rs
@@ -2,11 +2,11 @@ use std::{io::BufRead as _, time::Duration};
 
 use zng_unit::{Rgba, TimeUnits as _};
 use zng_view_api::{
+    Event,
     config::{
         AnimationsConfig, ChromeConfig, ColorScheme, ColorsConfig, FontAntiAliasing, KeyRepeatConfig, LocaleConfig, MultiClickConfig,
         TouchConfig,
     },
-    Event,
 };
 
 use crate::AppEvent;
diff --git a/crates/zng-view/src/config/windows.rs b/crates/zng-view/src/config/windows.rs
index 43bd6e13f..5f2b3614d 100644
--- a/crates/zng-view/src/config/windows.rs
+++ b/crates/zng-view/src/config/windows.rs
@@ -20,7 +20,6 @@ fn config_listener(event_loop: crate::AppEventSender) {
 
     use crate::AppEvent;
     use windows_sys::{
-        core::*,
         Win32::{
             Foundation::GetLastError,
             System::{
@@ -29,6 +28,7 @@ fn config_listener(event_loop: crate::AppEventSender) {
             },
             UI::WindowsAndMessaging::*,
         },
+        core::*,
     };
     use zng_view_api::Event;
 
@@ -318,14 +318,14 @@ pub fn colors_config() -> ColorsConfig {
     use std::mem;
 
     use windows_sys::{
-        core::PCSTR,
         Win32::{
             System::LibraryLoader::{GetProcAddress, LoadLibraryA},
             UI::{
                 Accessibility::{HCF_HIGHCONTRASTON, HIGHCONTRASTA},
-                WindowsAndMessaging::{SystemParametersInfoA, SPI_GETHIGHCONTRAST},
+                WindowsAndMessaging::{SPI_GETHIGHCONTRAST, SystemParametersInfoA},
             },
         },
+        core::PCSTR,
     };
 
     fn should_apps_use_dark_mode() -> bool {
diff --git a/crates/zng-view/src/display_list.rs b/crates/zng-view/src/display_list.rs
index fbe1fd6b9..78d166f7a 100644
--- a/crates/zng-view/src/display_list.rs
+++ b/crates/zng-view/src/display_list.rs
@@ -4,11 +4,11 @@ use rustc_hash::FxHashMap;
 use webrender::api as wr;
 use zng_unit::{Factor, Px, PxCornerRadius, PxRect, PxSideOffsets, PxSize, PxTransform, Rgba};
 use zng_view_api::{
+    GradientStop, ReferenceFrameId, RepeatMode,
     api_extension::{ApiExtensionId, ApiExtensionPayload},
     display_list::{DisplayItem, DisplayList, FilterOp, FrameValue, FrameValueId, FrameValueUpdate, NinePatchSource, SegmentId},
     font::{GlyphIndex, GlyphInstance},
     window::FrameId,
-    GradientStop, ReferenceFrameId, RepeatMode,
 };
 
 use crate::px_wr::PxToWr;
@@ -716,10 +716,11 @@ fn display_item_to_webrender(
             end_point,
             extend_mode,
             stops,
-            mut tile_origin,
+            tile_origin,
             tile_size,
             tile_spacing,
         } => {
+            let mut tile_origin = *tile_origin;
             tile_origin.x.0 = tile_origin.x.0.rem_euclid(tile_size.width.0);
             tile_origin.y.0 = tile_origin.y.0.rem_euclid(tile_size.height.0);
             let bounds = PxRect::new(
@@ -757,10 +758,11 @@ fn display_item_to_webrender(
             end_offset,
             extend_mode,
             stops,
-            mut tile_origin,
+            tile_origin,
             tile_size,
             tile_spacing,
         } => {
+            let mut tile_origin = *tile_origin;
             tile_origin.x.0 = tile_origin.x.0.rem_euclid(tile_size.width.0);
             tile_origin.y.0 = tile_origin.y.0.rem_euclid(tile_size.height.0);
             let bounds = PxRect::new(
@@ -798,10 +800,11 @@ fn display_item_to_webrender(
             end_offset,
             extend_mode,
             stops,
-            mut tile_origin,
+            tile_origin,
             tile_size,
             tile_spacing,
         } => {
+            let mut tile_origin = *tile_origin;
             tile_origin.x.0 = tile_origin.x.0.rem_euclid(tile_size.width.0);
             tile_origin.y.0 = tile_origin.y.0.rem_euclid(tile_size.height.0);
             let bounds = PxRect::new(
diff --git a/crates/zng-view/src/extensions.rs b/crates/zng-view/src/extensions.rs
index 8914620ad..b7068d9ae 100644
--- a/crates/zng-view/src/extensions.rs
+++ b/crates/zng-view/src/extensions.rs
@@ -9,15 +9,15 @@ use std::rc::Rc;
 use std::{any::Any, sync::Arc};
 
 use webrender::api::{
-    units::TexelRect, AsyncBlobImageRasterizer, BlobImageHandler, BlobImageParams, BlobImageRequest, BlobImageResult, DocumentId,
-    ExternalImageId, PipelineId,
+    AsyncBlobImageRasterizer, BlobImageHandler, BlobImageParams, BlobImageRequest, BlobImageResult, DocumentId, ExternalImageId,
+    PipelineId, units::TexelRect,
 };
 use webrender::{DebugFlags, RenderApi};
 use zng_unit::{Factor, PxSize};
 use zng_view_api::window::RenderMode;
 use zng_view_api::{
-    api_extension::{ApiExtensionId, ApiExtensionName, ApiExtensionPayload, ApiExtensions},
     Event,
+    api_extension::{ApiExtensionId, ApiExtensionName, ApiExtensionPayload, ApiExtensions},
 };
 
 use crate::display_list::{DisplayExtensionArgs, DisplayExtensionItemArgs, DisplayExtensionUpdateArgs, DisplayListExtension, SpaceAndClip};
diff --git a/crates/zng-view/src/gl.rs b/crates/zng-view/src/gl.rs
index 0a40325b4..49b76051f 100644
--- a/crates/zng-view/src/gl.rs
+++ b/crates/zng-view/src/gl.rs
@@ -15,7 +15,7 @@ use zng_view_api::window::{RenderMode, WindowId};
 
 use raw_window_handle::*;
 
-use crate::{util, AppEvent, AppEventSender};
+use crate::{AppEvent, AppEventSender, util};
 
 /// Create and track the current OpenGL context.
 pub(crate) struct GlContextManager {
diff --git a/crates/zng-view/src/image_cache.rs b/crates/zng-view/src/image_cache.rs
index ae14546f5..6701b0ab6 100644
--- a/crates/zng-view/src/image_cache.rs
+++ b/crates/zng-view/src/image_cache.rs
@@ -6,12 +6,12 @@ use winit::{
     event_loop::ActiveEventLoop,
     window::{CustomCursor, Icon},
 };
-use zng_txt::{formatx, ToTxt, Txt};
+use zng_txt::{ToTxt, Txt, formatx};
 use zng_unit::{Px, PxPoint, PxSize};
 use zng_view_api::{
+    Event,
     image::{ImageDataFormat, ImageDownscale, ImageId, ImageLoadedData, ImageMaskMode, ImagePpi, ImageRequest},
     ipc::{IpcBytes, IpcBytesReceiver},
-    Event,
 };
 
 use crate::{AppEvent, AppEventSender};
@@ -1159,12 +1159,12 @@ mod external {
 
     use rustc_hash::FxHashMap;
     use webrender::{
+        RenderApi,
         api::{
-            units::{ImageDirtyRect, TexelRect},
             DocumentId, ExternalImage, ExternalImageData, ExternalImageHandler, ExternalImageId, ExternalImageSource, ExternalImageType,
             ImageKey,
+            units::{ImageDirtyRect, TexelRect},
         },
-        RenderApi,
     };
     use zng_view_api::image::ImageTextureId;
 
@@ -1300,15 +1300,15 @@ mod capture {
     use zng_txt::formatx;
     use zng_unit::{Factor, PxRect};
     use zng_view_api::{
+        Event,
         image::{ImageDataFormat, ImageId, ImageLoadedData, ImageMaskMode, ImagePpi, ImageRequest},
         ipc::IpcBytes,
         window::{FrameId, WindowId},
-        Event,
     };
 
     use crate::{
-        image_cache::{Image, ImageData},
         AppEvent,
+        image_cache::{Image, ImageData},
     };
 
     use super::ImageCache;
diff --git a/crates/zng-view/src/lib.rs b/crates/zng-view/src/lib.rs
index 5f541edd5..243cc0d7c 100644
--- a/crates/zng-view/src/lib.rs
+++ b/crates/zng-view/src/lib.rs
@@ -145,6 +145,7 @@ use window::Window;
 use zng_txt::Txt;
 use zng_unit::{Dip, DipPoint, DipRect, DipSideOffsets, DipSize, Factor, Px, PxPoint, PxRect, PxToDip};
 use zng_view_api::{
+    Inited,
     api_extension::{ApiExtensionId, ApiExtensionPayload},
     dialog::{DialogId, FileDialog, MsgDialog, MsgDialogResponse},
     drag_drop::*,
@@ -159,7 +160,7 @@ use zng_view_api::{
         HeadlessOpenData, HeadlessRequest, MonitorId, MonitorInfo, VideoMode, WindowChanged, WindowId, WindowOpenData, WindowRequest,
         WindowState, WindowStateAll,
     },
-    Inited, *,
+    *,
 };
 
 use rustc_hash::FxHashMap;
@@ -205,7 +206,7 @@ pub fn view_process_main() {
 
 #[cfg(ipc)]
 #[doc(hidden)]
-#[no_mangle]
+#[unsafe(no_mangle)] // SAFETY: minimal risk of name collision, nothing else to do
 pub extern "C" fn extern_view_process_main() {
     std::panic::set_hook(Box::new(ffi_abort));
     view_process_main()
@@ -282,7 +283,7 @@ pub fn run_same_process_extended(run_app: impl FnOnce() + Send + 'static, ext: f
 
 #[cfg(ipc)]
 #[doc(hidden)]
-#[no_mangle]
+#[unsafe(no_mangle)] // SAFETY minimal risk of name collision, nothing else to do
 pub extern "C" fn extern_run_same_process(patch: &StaticPatch, run_app: extern "C" fn()) {
     std::panic::set_hook(Box::new(ffi_abort));
 
@@ -1722,12 +1723,12 @@ impl App {
 }
 
 impl Api for App {
-    fn init(&mut self, gen: ViewProcessGen, is_respawn: bool, device_events: bool, headless: bool) {
+    fn init(&mut self, vp_gen: ViewProcessGen, is_respawn: bool, device_events: bool, headless: bool) {
         if self.exited {
             panic!("cannot restart exited");
         }
 
-        self.generation = gen;
+        self.generation = vp_gen;
         self.device_events = device_events;
         self.headless = headless;
 
@@ -1735,7 +1736,7 @@ impl Api for App {
 
         let available_monitors = self.available_monitors();
         self.notify(Event::Inited(Inited {
-            generation: gen,
+            generation: vp_gen,
             is_respawn,
             available_monitors,
             multi_click_config: config::multi_click_config(),
diff --git a/crates/zng-view/src/low_memory.rs b/crates/zng-view/src/low_memory.rs
index 8fdd73a14..dd3709f6c 100644
--- a/crates/zng-view/src/low_memory.rs
+++ b/crates/zng-view/src/low_memory.rs
@@ -3,7 +3,7 @@
 #[cfg(windows)]
 mod windows {
     use windows::Win32::{
-        Foundation::{CloseHandle, BOOL, HANDLE},
+        Foundation::{BOOL, CloseHandle, HANDLE},
         System::Memory::*,
     };
 
diff --git a/crates/zng-view/src/px_wr.rs b/crates/zng-view/src/px_wr.rs
index fd8503249..c6f1f3922 100644
--- a/crates/zng-view/src/px_wr.rs
+++ b/crates/zng-view/src/px_wr.rs
@@ -4,11 +4,11 @@ use webrender::{
 };
 use zng_unit::{Px, PxBox, PxCornerRadius, PxPoint, PxRect, PxSideOffsets, PxSize, PxTransform, PxVector, Rgba};
 use zng_view_api::{
+    AlphaType, BorderSide, BorderStyle, ExtendMode, ImageRendering, LineOrientation, LineStyle, MixBlendMode, ReferenceFrameId, RepeatMode,
+    TransformStyle,
     config::FontAntiAliasing,
     display_list::{FilterOp, FrameValue, FrameValueId, FrameValueUpdate},
     font::FontOptions,
-    AlphaType, BorderSide, BorderStyle, ExtendMode, ImageRendering, LineOrientation, LineStyle, MixBlendMode, ReferenceFrameId, RepeatMode,
-    TransformStyle,
 };
 
 /// Conversion from [`Px`] to `webrender` units.
diff --git a/crates/zng-view/src/surface.rs b/crates/zng-view/src/surface.rs
index 8d22158ff..228f9e072 100644
--- a/crates/zng-view/src/surface.rs
+++ b/crates/zng-view/src/surface.rs
@@ -2,21 +2,22 @@ use std::{collections::VecDeque, fmt};
 
 use tracing::span::EnteredSpan;
 use webrender::{
-    api::{DocumentId, DynamicProperties, FontInstanceKey, FontKey, FontVariation, PipelineId},
     RenderApi, Renderer, Transaction,
+    api::{DocumentId, DynamicProperties, FontInstanceKey, FontKey, FontVariation, PipelineId},
 };
 use winit::event_loop::ActiveEventLoop;
 use zng_unit::{DipSize, DipToPx, Factor, Px, PxRect, Rgba};
 use zng_view_api::{
+    ViewProcessGen,
     api_extension::{ApiExtensionId, ApiExtensionPayload},
     font::{FontFaceId, FontId, FontOptions, FontVariationName},
     image::{ImageId, ImageLoadedData, ImageMaskMode, ImageTextureId},
     window::{FrameCapture, FrameId, FrameRequest, FrameUpdateRequest, HeadlessRequest, RenderMode, WindowId},
-    ViewProcessGen,
 };
 
 use crate::{
-    display_list::{display_list_to_webrender, DisplayListCache},
+    AppEventSender, FrameReadyMsg, WrNotifier,
+    display_list::{DisplayListCache, display_list_to_webrender},
     extensions::{
         self, BlobExtensionsImgHandler, DisplayListExtAdapter, FrameReadyArgs, RedrawArgs, RendererCommandArgs, RendererConfigArgs,
         RendererDeinitedArgs, RendererExtension, RendererInitedArgs, WindowConfigArgs, WindowExtension,
@@ -24,8 +25,7 @@ use crate::{
     gl::{GlContext, GlContextManager},
     image_cache::{Image, ImageCache, ImageUseMap, WrImageCache},
     px_wr::PxToWr as _,
-    util::{frame_render_reasons, frame_update_render_reasons, PxToWinit},
-    AppEventSender, FrameReadyMsg, WrNotifier,
+    util::{PxToWinit, frame_render_reasons, frame_update_render_reasons},
 };
 
 /// A headless "window".
@@ -62,7 +62,7 @@ impl fmt::Debug for Surface {
 }
 impl Surface {
     pub fn open(
-        gen: ViewProcessGen,
+        vp_gen: ViewProcessGen,
         cfg: HeadlessRequest,
         winit_loop: &ActiveEventLoop,
         gl_manager: &mut GlContextManager,
@@ -99,7 +99,7 @@ impl Surface {
             enable_aa: true,
             enable_subpixel_aa: cfg!(not(target_os = "android")),
 
-            renderer_id: Some((gen.get() as u64) << 32 | id.get() as u64),
+            renderer_id: Some(((vp_gen.get() as u64) << 32) | id.get() as u64),
 
             // this clear color paints over the one set using `Renderer::set_clear_color`.
             clear_color: webrender::api::ColorF::new(0.0, 0.0, 0.0, 0.0),
@@ -141,7 +141,7 @@ impl Surface {
 
         let mut api = sender.create_api();
         let document_id = api.add_document(device_size);
-        let pipeline_id = webrender::api::PipelineId(gen.get(), id.get());
+        let pipeline_id = webrender::api::PipelineId(vp_gen.get(), id.get());
 
         renderer_exts.retain_mut(|(_, ext)| {
             ext.renderer_inited(&mut RendererInitedArgs {
diff --git a/crates/zng-view/src/util.rs b/crates/zng-view/src/util.rs
index 357ea1363..be8cdcf5b 100644
--- a/crates/zng-view/src/util.rs
+++ b/crates/zng-view/src/util.rs
@@ -85,16 +85,16 @@ where
     match msg {
         WM_DESTROY => {
             // last call and cleanup.
-            let mut handler = Box::from_raw(data as *mut H);
+            let mut handler = unsafe { Box::from_raw(data as *mut H) };
             handler(hwnd, msg, wparam, lparam).unwrap_or_default()
         }
 
         msg => {
-            let handler = &mut *(data as *mut H);
+            let handler = unsafe { &mut *(data as *mut H) };
             if let Some(r) = handler(hwnd, msg, wparam, lparam) {
                 r
             } else {
-                windows_sys::Win32::UI::Shell::DefSubclassProc(hwnd, msg, wparam, lparam)
+                unsafe { windows_sys::Win32::UI::Shell::DefSubclassProc(hwnd, msg, wparam, lparam) }
             }
         }
     }
@@ -1056,7 +1056,7 @@ pub fn get_instance_handle() -> isize {
     // This is preferred over GetModuleHandle(NULL) because it also works in DLLs:
     // https://stackoverflow.com/questions/21718027/getmodulehandlenull-vs-hinstance
 
-    extern "C" {
+    unsafe extern "C" {
         static __ImageBase: windows_sys::Win32::System::SystemServices::IMAGE_DOS_HEADER;
     }
 
@@ -1073,8 +1073,8 @@ pub mod taskbar_com {
     use std::ffi::c_void;
 
     use windows_sys::{
-        core::{IUnknown, GUID, HRESULT},
         Win32::Foundation::{BOOL, HWND},
+        core::{GUID, HRESULT, IUnknown},
     };
 
     #[repr(C)]
diff --git a/crates/zng-view/src/window.rs b/crates/zng-view/src/window.rs
index 35ac9989b..efebbde17 100644
--- a/crates/zng-view/src/window.rs
+++ b/crates/zng-view/src/window.rs
@@ -2,15 +2,15 @@ use std::{
     collections::VecDeque,
     fmt, mem,
     sync::{
-        atomic::{AtomicBool, Ordering},
         Arc,
+        atomic::{AtomicBool, Ordering},
     },
 };
 
 use tracing::span::EnteredSpan;
 use webrender::{
-    api::{DocumentId, DynamicProperties, FontInstanceKey, FontKey, FontVariation, PipelineId},
     RenderApi, Renderer, Transaction, UploadMethod, VertexUsageHint,
+    api::{DocumentId, DynamicProperties, FontInstanceKey, FontKey, FontVariation, PipelineId},
 };
 
 use winit::{
@@ -21,6 +21,7 @@ use winit::{
 use zng_txt::{ToTxt, Txt};
 use zng_unit::{DipPoint, DipRect, DipSideOffsets, DipSize, DipToPx, Factor, Px, PxPoint, PxRect, PxToDip, PxVector, Rgba};
 use zng_view_api::{
+    DeviceId, Event, ViewProcessGen,
     api_extension::{ApiExtensionId, ApiExtensionPayload},
     font::{FontFaceId, FontId, FontOptions, FontVariationName},
     image::{ImageId, ImageLoadedData, ImageMaskMode, ImageTextureId},
@@ -28,7 +29,6 @@ use zng_view_api::{
         CursorIcon, FocusIndicator, FrameCapture, FrameId, FrameRequest, FrameUpdateRequest, RenderMode, ResizeDirection, VideoMode,
         WindowButton, WindowId, WindowRequest, WindowState, WindowStateAll,
     },
-    DeviceId, Event, ViewProcessGen,
 };
 
 use zng_view_api::dialog as dlg_api;
@@ -37,7 +37,8 @@ use zng_view_api::dialog as dlg_api;
 use zng_view_api::keyboard::{Key, KeyCode, KeyState};
 
 use crate::{
-    display_list::{display_list_to_webrender, DisplayListCache},
+    AppEvent, AppEventSender, FrameReadyMsg, WrNotifier,
+    display_list::{DisplayListCache, display_list_to_webrender},
     extensions::{
         self, BlobExtensionsImgHandler, DisplayListExtAdapter, FrameReadyArgs, RedrawArgs, RendererCommandArgs, RendererConfigArgs,
         RendererDeinitedArgs, RendererExtension, RendererInitedArgs, WindowCommandArgs, WindowConfigArgs, WindowDeinitedArgs,
@@ -47,10 +48,9 @@ use crate::{
     image_cache::{Image, ImageCache, ImageUseMap, WrImageCache},
     px_wr::PxToWr as _,
     util::{
-        frame_render_reasons, frame_update_render_reasons, CursorToWinit, DipToWinit, PxToWinit, ResizeDirectionToWinit as _,
-        WindowButtonsToWinit as _, WinitToDip, WinitToPx,
+        CursorToWinit, DipToWinit, PxToWinit, ResizeDirectionToWinit as _, WindowButtonsToWinit as _, WinitToDip, WinitToPx,
+        frame_render_reasons, frame_update_render_reasons,
     },
-    AppEvent, AppEventSender, FrameReadyMsg, WrNotifier,
 };
 
 /// A headed window.
@@ -140,7 +140,7 @@ impl fmt::Debug for Window {
 impl Window {
     #[expect(clippy::too_many_arguments)]
     pub fn open(
-        gen: ViewProcessGen,
+        vp_gen: ViewProcessGen,
         cfg_icon: Option<Icon>,
         cfg_cursor_image: Option<CustomCursor>,
         cfg: WindowRequest,
@@ -351,7 +351,7 @@ impl Window {
             enable_aa: true,
             enable_subpixel_aa: cfg!(not(target_os = "android")),
 
-            renderer_id: Some((gen.get() as u64) << 32 | id.get() as u64),
+            renderer_id: Some(((vp_gen.get() as u64) << 32) | id.get() as u64),
 
             // this clear color paints over the one set using `Renderer::set_clear_color`.
             clear_color: webrender::api::ColorF::new(0.0, 0.0, 0.0, 0.0),
@@ -400,7 +400,7 @@ impl Window {
 
         let mut api = sender.create_api();
         let document_id = api.add_document(device_size);
-        let pipeline_id = webrender::api::PipelineId(gen.get(), id.get());
+        let pipeline_id = webrender::api::PipelineId(vp_gen.get(), id.get());
 
         renderer_exts.retain_mut(|(_, ext)| {
             ext.renderer_inited(&mut RendererInitedArgs {
@@ -1881,11 +1881,7 @@ impl Window {
                 &patterns
                     .map(|s| {
                         let s = s.trim_start_matches(['*', '.']);
-                        if s.is_empty() {
-                            "*"
-                        } else {
-                            s
-                        }
+                        if s.is_empty() { "*" } else { s }
                     })
                     .collect::<Vec<_>>(),
             );
@@ -1913,7 +1909,7 @@ impl Window {
     }
     /// Run dialog unblocked.
     #[cfg(not(target_os = "android"))]
-    fn run_dialog(run: impl std::future::Future + Send + 'static) {
+    fn run_dialog(run: impl Future + Send + 'static) {
         let mut task = Box::pin(run);
         std::thread::spawn(move || {
             struct ThreadWaker(std::thread::Thread);
diff --git a/crates/zng-wgt-access/Cargo.toml b/crates/zng-wgt-access/Cargo.toml
index 2eebd752a..5fb8e32a9 100644
--- a/crates/zng-wgt-access/Cargo.toml
+++ b/crates/zng-wgt-access/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-access"
 version = "0.3.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-ansi-text/Cargo.toml b/crates/zng-wgt-ansi-text/Cargo.toml
index ce6dc37c5..792813856 100644
--- a/crates/zng-wgt-ansi-text/Cargo.toml
+++ b/crates/zng-wgt-ansi-text/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-ansi-text"
 version = "0.4.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-ansi-text/src/lib.rs b/crates/zng-wgt-ansi-text/src/lib.rs
index 73dea317e..c9e8da77f 100644
--- a/crates/zng-wgt-ansi-text/src/lib.rs
+++ b/crates/zng-wgt-ansi-text/src/lib.rs
@@ -15,7 +15,7 @@ use zng_ext_font::*;
 use zng_wgt::{prelude::*, *};
 use zng_wgt_fill::*;
 use zng_wgt_filter::*;
-use zng_wgt_scroll::{lazy, LazyMode};
+use zng_wgt_scroll::{LazyMode, lazy};
 use zng_wgt_stack::{Stack, StackDirection};
 use zng_wgt_text::*;
 
diff --git a/crates/zng-wgt-button/Cargo.toml b/crates/zng-wgt-button/Cargo.toml
index 4fc459ba9..c510ec4cc 100644
--- a/crates/zng-wgt-button/Cargo.toml
+++ b/crates/zng-wgt-button/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-button"
 version = "0.5.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-button/src/lib.rs b/crates/zng-wgt-button/src/lib.rs
index 40adec84a..71620bd46 100644
--- a/crates/zng-wgt-button/src/lib.rs
+++ b/crates/zng-wgt-button/src/lib.rs
@@ -17,23 +17,22 @@ use colors::{ACCENT_COLOR_VAR, BASE_COLOR_VAR};
 use zng_app::event::CommandParam;
 use zng_var::ReadOnlyContextVar;
 use zng_wgt::{base_color, border, corner_radius, is_disabled, prelude::*};
-use zng_wgt_access::{access_role, labelled_by_child, AccessRole};
-use zng_wgt_container::{child_align, padding, Container};
+use zng_wgt_access::{AccessRole, access_role, labelled_by_child};
+use zng_wgt_container::{Container, child_align, padding};
 use zng_wgt_fill::background_color;
 use zng_wgt_filter::{child_opacity, saturate};
 use zng_wgt_input::{
-    cursor,
+    CursorIcon, cursor,
     focus::FocusableMix,
-    gesture::{on_click, on_disabled_click, ClickArgs},
+    gesture::{ClickArgs, on_click, on_disabled_click},
     is_cap_hovered, is_pressed,
-    pointer_capture::{capture_pointer, CaptureMode},
-    CursorIcon,
+    pointer_capture::{CaptureMode, capture_pointer},
 };
-use zng_wgt_style::{impl_style_fn, style_fn, Style, StyleMix};
-use zng_wgt_text::{font_color, underline, Text, FONT_COLOR_VAR};
+use zng_wgt_style::{Style, StyleMix, impl_style_fn, style_fn};
+use zng_wgt_text::{FONT_COLOR_VAR, Text, font_color, underline};
 
 #[cfg(feature = "tooltip")]
-use zng_wgt_tooltip::{tooltip, tooltip_fn, Tip, TooltipArgs};
+use zng_wgt_tooltip::{Tip, TooltipArgs, tooltip, tooltip_fn};
 
 /// A clickable container.
 ///
diff --git a/crates/zng-wgt-checkerboard/Cargo.toml b/crates/zng-wgt-checkerboard/Cargo.toml
index 1d45e3702..1c719e17f 100644
--- a/crates/zng-wgt-checkerboard/Cargo.toml
+++ b/crates/zng-wgt-checkerboard/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-checkerboard"
 version = "0.4.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-container/Cargo.toml b/crates/zng-wgt-container/Cargo.toml
index bee419725..dda946a66 100644
--- a/crates/zng-wgt-container/Cargo.toml
+++ b/crates/zng-wgt-container/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-container"
 version = "0.5.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-data-view/Cargo.toml b/crates/zng-wgt-data-view/Cargo.toml
index 77ff91179..5a0f2bc97 100644
--- a/crates/zng-wgt-data-view/Cargo.toml
+++ b/crates/zng-wgt-data-view/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-data-view"
 version = "0.4.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-data-view/src/lib.rs b/crates/zng-wgt-data-view/src/lib.rs
index 168696913..4eeebb824 100644
--- a/crates/zng-wgt-data-view/src/lib.rs
+++ b/crates/zng-wgt-data-view/src/lib.rs
@@ -38,11 +38,7 @@ impl<D: VarValue> DataViewArgs<D> {
     /// [`view_is_nil`]: Self::view_is_nil
     /// [`data`]: Self::data
     pub fn get_new(&self) -> Option<D> {
-        if self.is_nil {
-            Some(self.data.get())
-        } else {
-            self.data.get_new()
-        }
+        if self.is_nil { Some(self.data.get()) } else { self.data.get_new() }
     }
 
     /// If the current child is nil node.
diff --git a/crates/zng-wgt-data/Cargo.toml b/crates/zng-wgt-data/Cargo.toml
index 5c651fc33..62aa272c3 100644
--- a/crates/zng-wgt-data/Cargo.toml
+++ b/crates/zng-wgt-data/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-data"
 version = "0.3.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-data/src/lib.rs b/crates/zng-wgt-data/src/lib.rs
index 0f06bedf3..6e5d54067 100644
--- a/crates/zng-wgt-data/src/lib.rs
+++ b/crates/zng-wgt-data/src/lib.rs
@@ -12,7 +12,7 @@
 use std::{any::Any, collections::HashMap, fmt, mem, num::NonZeroU8, ops, sync::Arc};
 
 use zng_color::COLOR_SCHEME_VAR;
-use zng_var::{types::ContextualizedVar, BoxedAnyVar};
+use zng_var::{BoxedAnyVar, types::ContextualizedVar};
 use zng_wgt::prelude::*;
 
 use task::parking_lot::RwLock;
diff --git a/crates/zng-wgt-dialog/Cargo.toml b/crates/zng-wgt-dialog/Cargo.toml
index 37ae3c244..2df5484c4 100644
--- a/crates/zng-wgt-dialog/Cargo.toml
+++ b/crates/zng-wgt-dialog/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-dialog"
 version = "0.2.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-dialog/src/backdrop.rs b/crates/zng-wgt-dialog/src/backdrop.rs
index e6a64b2e1..dc48a2add 100644
--- a/crates/zng-wgt-dialog/src/backdrop.rs
+++ b/crates/zng-wgt-dialog/src/backdrop.rs
@@ -3,9 +3,9 @@
 use zng_wgt::{prelude::*, *};
 use zng_wgt_container::Container;
 use zng_wgt_fill::background_color;
-use zng_wgt_input::gesture::{on_click, ClickArgs};
+use zng_wgt_input::gesture::{ClickArgs, on_click};
 use zng_wgt_layer::popup::POPUP_CLOSE_REQUESTED_EVENT;
-use zng_wgt_style::{impl_style_fn, style_fn, Style, StyleMix};
+use zng_wgt_style::{Style, StyleMix, impl_style_fn, style_fn};
 
 use crate::DIALOG;
 
diff --git a/crates/zng-wgt-dialog/src/lib.rs b/crates/zng-wgt-dialog/src/lib.rs
index dd7443f33..dc0e57f85 100644
--- a/crates/zng-wgt-dialog/src/lib.rs
+++ b/crates/zng-wgt-dialog/src/lib.rs
@@ -16,8 +16,8 @@ use std::{fmt, ops, path::PathBuf, sync::Arc};
 use bitflags::bitflags;
 use parking_lot::Mutex;
 use zng_ext_l10n::l10n;
-use zng_ext_window::{WindowCloseRequestedArgs, WINDOWS, WINDOW_CLOSE_REQUESTED_EVENT};
-use zng_var::{animation::easing, ContextInitHandle};
+use zng_ext_window::{WINDOW_CLOSE_REQUESTED_EVENT, WINDOWS, WindowCloseRequestedArgs};
+use zng_var::{ContextInitHandle, animation::easing};
 use zng_view_api::dialog as native_api;
 use zng_wgt::{prelude::*, *};
 use zng_wgt_container::Container;
@@ -25,10 +25,10 @@ use zng_wgt_fill::background_color;
 use zng_wgt_filter::drop_shadow;
 use zng_wgt_input::focus::FocusableMix;
 use zng_wgt_layer::{
-    popup::{ContextCapture, POPUP, POPUP_CLOSE_REQUESTED_EVENT},
     AnchorMode,
+    popup::{ContextCapture, POPUP, POPUP_CLOSE_REQUESTED_EVENT},
 };
-use zng_wgt_style::{impl_style_fn, style_fn, Style, StyleMix};
+use zng_wgt_style::{Style, StyleMix, impl_style_fn, style_fn};
 use zng_wgt_text::Text;
 use zng_wgt_text_input::selectable::SelectableText;
 use zng_wgt_wrap::Wrap;
diff --git a/crates/zng-wgt-fill/Cargo.toml b/crates/zng-wgt-fill/Cargo.toml
index 2084ae4af..c67d0a59d 100644
--- a/crates/zng-wgt-fill/Cargo.toml
+++ b/crates/zng-wgt-fill/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-fill"
 version = "0.3.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-fill/src/lib.rs b/crates/zng-wgt-fill/src/lib.rs
index dfb6be49f..1044363fb 100644
--- a/crates/zng-wgt-fill/src/lib.rs
+++ b/crates/zng-wgt-fill/src/lib.rs
@@ -9,8 +9,8 @@
 #![warn(unused_extern_crates)]
 #![warn(missing_docs)]
 
-use zng_wgt::prelude::gradient::{stops, GradientRadius, GradientStops, LinearGradientAxis};
-use zng_wgt::{hit_test_mode, node::interactive_node, prelude::*, HitTestMode};
+use zng_wgt::prelude::gradient::{GradientRadius, GradientStops, LinearGradientAxis, stops};
+use zng_wgt::{HitTestMode, hit_test_mode, node::interactive_node, prelude::*};
 
 pub mod node;
 
diff --git a/crates/zng-wgt-filter/Cargo.toml b/crates/zng-wgt-filter/Cargo.toml
index 697d6c604..47eee7893 100644
--- a/crates/zng-wgt-filter/Cargo.toml
+++ b/crates/zng-wgt-filter/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-filter"
 version = "0.3.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-grid/Cargo.toml b/crates/zng-wgt-grid/Cargo.toml
index 5573856b6..e8e6a481d 100644
--- a/crates/zng-wgt-grid/Cargo.toml
+++ b/crates/zng-wgt-grid/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-grid"
 version = "0.4.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-grid/src/lib.rs b/crates/zng-wgt-grid/src/lib.rs
index 31be5e38c..981578b3e 100644
--- a/crates/zng-wgt-grid/src/lib.rs
+++ b/crates/zng-wgt-grid/src/lib.rs
@@ -13,7 +13,7 @@ use std::{fmt, mem};
 
 use zng_layout::unit::{GridSpacing, PxGridSpacing};
 use zng_wgt::prelude::*;
-use zng_wgt_access::{access_role, AccessRole};
+use zng_wgt_access::{AccessRole, access_role};
 use zng_wgt_size_offset::*;
 
 /// Grid layout with cells of variable sizes.
@@ -548,11 +548,7 @@ pub mod column {
             child,
             |w, &i| {
                 let a = w.get(*INDEX_ID).copied().unwrap_or((0, 0)).0;
-                if a != i {
-                    Some(a)
-                } else {
-                    None
-                }
+                if a != i { Some(a) } else { None }
             },
             |_, &i| if i != 0 { Some(0) } else { None },
             state,
@@ -566,11 +562,7 @@ pub mod column {
             child,
             |w, &i| {
                 let a = w.get(*INDEX_ID).copied().unwrap_or((0, 0));
-                if a != i {
-                    Some(a)
-                } else {
-                    None
-                }
+                if a != i { Some(a) } else { None }
             },
             |_, &i| if i != (0, 0) { Some((0, 0)) } else { None },
             state,
@@ -585,11 +577,7 @@ pub mod column {
             |w, &i| {
                 let a = w.get(*INDEX_ID).copied().unwrap_or((0, 0));
                 let a = a.1 - a.0;
-                if a != i {
-                    Some(a)
-                } else {
-                    None
-                }
+                if a != i { Some(a) } else { None }
             },
             |_, &i| if i != 0 { Some(0) } else { None },
             state,
@@ -703,11 +691,7 @@ pub mod row {
             child,
             |w, &i| {
                 let a = w.get(*INDEX_ID).copied().unwrap_or((0, 0)).0;
-                if a != i {
-                    Some(a)
-                } else {
-                    None
-                }
+                if a != i { Some(a) } else { None }
             },
             |_, &i| if i != 0 { Some(0) } else { None },
             state,
@@ -721,11 +705,7 @@ pub mod row {
             child,
             |w, &i| {
                 let a = w.get(*INDEX_ID).copied().unwrap_or((0, 0));
-                if a != i {
-                    Some(a)
-                } else {
-                    None
-                }
+                if a != i { Some(a) } else { None }
             },
             |_, &i| if i != (0, 0) { Some((0, 0)) } else { None },
             state,
@@ -740,11 +720,7 @@ pub mod row {
             |w, &i| {
                 let a = w.get(*INDEX_ID).copied().unwrap_or((0, 0));
                 let a = a.1 - a.0;
-                if a != i {
-                    Some(a)
-                } else {
-                    None
-                }
+                if a != i { Some(a) } else { None }
             },
             |_, &i| if i != 0 { Some(0) } else { None },
             state,
@@ -997,11 +973,7 @@ impl ColRowMeta {
 
     /// Return the leftover factor if the column or row must be measured on a fraction of the leftover space.
     fn is_leftover(self) -> Option<Factor> {
-        if self.0 >= 0.0 {
-            Some(Factor(self.0))
-        } else {
-            None
-        }
+        if self.0 >= 0.0 { Some(Factor(self.0)) } else { None }
     }
 
     /// `width` or `height` contains the final length or is pending layout `Px::MIN`.
diff --git a/crates/zng-wgt-image/Cargo.toml b/crates/zng-wgt-image/Cargo.toml
index 31d6846b1..a9d70f019 100644
--- a/crates/zng-wgt-image/Cargo.toml
+++ b/crates/zng-wgt-image/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-image"
 version = "0.4.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-image/src/border.rs b/crates/zng-wgt-image/src/border.rs
index 62de6ee02..58a2f8da1 100644
--- a/crates/zng-wgt-image/src/border.rs
+++ b/crates/zng-wgt-image/src/border.rs
@@ -3,7 +3,7 @@
 use std::mem;
 
 use zng_app::render::RepeatMode;
-use zng_ext_image::{ImageCacheMode, ImageRenderArgs, ImageSource, Img, IMAGES};
+use zng_ext_image::{IMAGES, ImageCacheMode, ImageRenderArgs, ImageSource, Img};
 use zng_wgt::prelude::*;
 
 use crate::{IMAGE_CACHE_VAR, IMAGE_LIMITS_VAR, IMAGE_RENDERING_VAR};
diff --git a/crates/zng-wgt-image/src/lib.rs b/crates/zng-wgt-image/src/lib.rs
index b5070384e..31292cc9c 100644
--- a/crates/zng-wgt-image/src/lib.rs
+++ b/crates/zng-wgt-image/src/lib.rs
@@ -18,7 +18,7 @@ pub use image_properties::*;
 pub mod border;
 pub mod mask;
 
-use zng_wgt_access::{access_role, AccessRole};
+use zng_wgt_access::{AccessRole, access_role};
 
 pub mod node;
 
diff --git a/crates/zng-wgt-image/src/mask.rs b/crates/zng-wgt-image/src/mask.rs
index 5f4b1dffd..9aa384da5 100644
--- a/crates/zng-wgt-image/src/mask.rs
+++ b/crates/zng-wgt-image/src/mask.rs
@@ -3,7 +3,7 @@
 //! [`mask_image`]: fn@mask_image
 //! [`mask_mode`]: fn@mask_mode
 
-use zng_ext_image::{ImageCacheMode, ImageDownscale, ImageLimits, ImageMaskMode, ImageRenderArgs, ImageSource, IMAGES};
+use zng_ext_image::{IMAGES, ImageCacheMode, ImageDownscale, ImageLimits, ImageMaskMode, ImageRenderArgs, ImageSource};
 use zng_wgt::prelude::*;
 
 use crate::ImageFit;
diff --git a/crates/zng-wgt-image/src/node.rs b/crates/zng-wgt-image/src/node.rs
index 8eec63e09..814152fa6 100644
--- a/crates/zng-wgt-image/src/node.rs
+++ b/crates/zng-wgt-image/src/node.rs
@@ -2,13 +2,13 @@
 
 use std::mem;
 
-use zng_ext_image::{ImageCacheMode, ImagePpi, ImageRenderArgs, IMAGES};
+use zng_ext_image::{IMAGES, ImageCacheMode, ImagePpi, ImageRenderArgs};
 use zng_wgt_stack::stack_nodes_layout_by;
 
 use super::image_properties::{
-    ImageFit, ImgErrorArgs, ImgLoadingArgs, IMAGE_ALIGN_VAR, IMAGE_CACHE_VAR, IMAGE_CROP_VAR, IMAGE_DOWNSCALE_VAR, IMAGE_ERROR_FN_VAR,
-    IMAGE_FIT_VAR, IMAGE_LIMITS_VAR, IMAGE_LOADING_FN_VAR, IMAGE_OFFSET_VAR, IMAGE_RENDERING_VAR, IMAGE_SCALE_FACTOR_VAR,
-    IMAGE_SCALE_PPI_VAR, IMAGE_SCALE_VAR,
+    IMAGE_ALIGN_VAR, IMAGE_CACHE_VAR, IMAGE_CROP_VAR, IMAGE_DOWNSCALE_VAR, IMAGE_ERROR_FN_VAR, IMAGE_FIT_VAR, IMAGE_LIMITS_VAR,
+    IMAGE_LOADING_FN_VAR, IMAGE_OFFSET_VAR, IMAGE_RENDERING_VAR, IMAGE_SCALE_FACTOR_VAR, IMAGE_SCALE_PPI_VAR, IMAGE_SCALE_VAR, ImageFit,
+    ImgErrorArgs, ImgLoadingArgs,
 };
 
 use super::*;
diff --git a/crates/zng-wgt-input/Cargo.toml b/crates/zng-wgt-input/Cargo.toml
index b485bf643..a3c5d2b85 100644
--- a/crates/zng-wgt-input/Cargo.toml
+++ b/crates/zng-wgt-input/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-input"
 version = "0.3.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-input/src/cmd.rs b/crates/zng-wgt-input/src/cmd.rs
index 454a9013a..a2f0f6959 100644
--- a/crates/zng-wgt-input/src/cmd.rs
+++ b/crates/zng-wgt-input/src/cmd.rs
@@ -2,7 +2,7 @@
 //!
 
 use zng_ext_clipboard::{COPY_CMD, CUT_CMD, PASTE_CMD};
-use zng_wgt::{prelude::*, ICONS};
+use zng_wgt::{ICONS, prelude::*};
 
 command! {
     /// Represents the **new** action.
diff --git a/crates/zng-wgt-input/src/drag_drop.rs b/crates/zng-wgt-input/src/drag_drop.rs
index f235f1c45..6a2b7b421 100644
--- a/crates/zng-wgt-input/src/drag_drop.rs
+++ b/crates/zng-wgt-input/src/drag_drop.rs
@@ -3,8 +3,8 @@
 //! Drag&drop properties, event properties.
 
 use zng_ext_input::drag_drop::{
-    DragEndArgs, DragHoveredArgs, DragStartArgs, DropArgs, WidgetInfoBuilderDragDropExt as _, DRAG_END_EVENT, DRAG_HOVERED_EVENT,
-    DRAG_START_EVENT, DROP_EVENT,
+    DRAG_END_EVENT, DRAG_HOVERED_EVENT, DRAG_START_EVENT, DROP_EVENT, DragEndArgs, DragHoveredArgs, DragStartArgs, DropArgs,
+    WidgetInfoBuilderDragDropExt as _,
 };
 use zng_wgt::prelude::*;
 
diff --git a/crates/zng-wgt-input/src/focus.rs b/crates/zng-wgt-input/src/focus.rs
index 4887554ce..d2ef2edf1 100644
--- a/crates/zng-wgt-input/src/focus.rs
+++ b/crates/zng-wgt-input/src/focus.rs
@@ -1,8 +1,8 @@
 //! Keyboard focus properties, [`tab_index`](fn@tab_index), [`focusable`](fn@focusable),
 //! [`on_focus`](fn@on_focus), [`is_focused`](fn@is_focused) and more.
 
-use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::Arc;
+use std::sync::atomic::{AtomicBool, Ordering};
 
 use zng_app::widget::info::WIDGET_INFO_CHANGED_EVENT;
 use zng_ext_input::focus::*;
diff --git a/crates/zng-wgt-input/src/gesture.rs b/crates/zng-wgt-input/src/gesture.rs
index 7337e225c..bcd431cab 100644
--- a/crates/zng-wgt-input/src/gesture.rs
+++ b/crates/zng-wgt-input/src/gesture.rs
@@ -4,7 +4,7 @@
 //! Prefer using these events over the events directly tied to an input device.
 
 use zng_app::shortcut::Shortcuts;
-use zng_ext_input::gesture::{ShortcutClick, CLICK_EVENT, GESTURES};
+use zng_ext_input::gesture::{CLICK_EVENT, GESTURES, ShortcutClick};
 use zng_view_api::access::AccessCmdName;
 use zng_wgt::prelude::*;
 
diff --git a/crates/zng-wgt-input/src/keyboard.rs b/crates/zng-wgt-input/src/keyboard.rs
index 0c389069a..fb6d25d1a 100644
--- a/crates/zng-wgt-input/src/keyboard.rs
+++ b/crates/zng-wgt-input/src/keyboard.rs
@@ -4,7 +4,7 @@
 //! Before using them review the [`gesture`](super::gesture) properties, in particular
 //! the [`click_shortcut`](fn@super::gesture::click_shortcut) property.
 
-use zng_ext_input::keyboard::{KeyInputArgs, KeyState, KEY_INPUT_EVENT};
+use zng_ext_input::keyboard::{KEY_INPUT_EVENT, KeyInputArgs, KeyState};
 use zng_wgt::prelude::*;
 
 event_property! {
diff --git a/crates/zng-wgt-input/src/misc.rs b/crates/zng-wgt-input/src/misc.rs
index f78348d63..35da580ca 100644
--- a/crates/zng-wgt-input/src/misc.rs
+++ b/crates/zng-wgt-input/src/misc.rs
@@ -1,9 +1,9 @@
 use std::sync::{
-    atomic::{AtomicBool, Ordering},
     Arc,
+    atomic::{AtomicBool, Ordering},
 };
 
-use zng_ext_input::mouse::{ClickMode, WidgetInfoBuilderMouseExt as _, MOUSE_HOVERED_EVENT};
+use zng_ext_input::mouse::{ClickMode, MOUSE_HOVERED_EVENT, WidgetInfoBuilderMouseExt as _};
 use zng_ext_window::WINDOW_Ext as _;
 use zng_wgt::prelude::*;
 
diff --git a/crates/zng-wgt-input/src/mouse.rs b/crates/zng-wgt-input/src/mouse.rs
index 30c83140d..9dbcfce5b 100644
--- a/crates/zng-wgt-input/src/mouse.rs
+++ b/crates/zng-wgt-input/src/mouse.rs
@@ -6,8 +6,8 @@
 //! [`on_click`](fn@super::gesture::on_click) event.
 
 use zng_ext_input::mouse::{
-    MouseClickArgs, MouseHoverArgs, MouseInputArgs, MouseMoveArgs, MouseWheelArgs, MOUSE_CLICK_EVENT, MOUSE_HOVERED_EVENT,
-    MOUSE_INPUT_EVENT, MOUSE_MOVE_EVENT, MOUSE_WHEEL_EVENT,
+    MOUSE_CLICK_EVENT, MOUSE_HOVERED_EVENT, MOUSE_INPUT_EVENT, MOUSE_MOVE_EVENT, MOUSE_WHEEL_EVENT, MouseClickArgs, MouseHoverArgs,
+    MouseInputArgs, MouseMoveArgs, MouseWheelArgs,
 };
 use zng_wgt::prelude::*;
 
diff --git a/crates/zng-wgt-input/src/pointer_capture.rs b/crates/zng-wgt-input/src/pointer_capture.rs
index 6d4fae0ef..a515f5e2d 100644
--- a/crates/zng-wgt-input/src/pointer_capture.rs
+++ b/crates/zng-wgt-input/src/pointer_capture.rs
@@ -2,7 +2,7 @@
 
 use zng_ext_input::{
     mouse::MOUSE_INPUT_EVENT,
-    pointer_capture::{PointerCaptureArgs, POINTER_CAPTURE, POINTER_CAPTURE_EVENT},
+    pointer_capture::{POINTER_CAPTURE, POINTER_CAPTURE_EVENT, PointerCaptureArgs},
     touch::TOUCH_INPUT_EVENT,
 };
 use zng_wgt::prelude::*;
diff --git a/crates/zng-wgt-input/src/state.rs b/crates/zng-wgt-input/src/state.rs
index c415fde77..ee32dbb55 100644
--- a/crates/zng-wgt-input/src/state.rs
+++ b/crates/zng-wgt-input/src/state.rs
@@ -3,7 +3,7 @@ use std::{collections::HashSet, time::Duration};
 use zng_app::timer::TIMERS;
 use zng_ext_input::{
     gesture::{CLICK_EVENT, GESTURES},
-    mouse::{ClickMode, WidgetInfoMouseExt as _, MOUSE_HOVERED_EVENT, MOUSE_INPUT_EVENT},
+    mouse::{ClickMode, MOUSE_HOVERED_EVENT, MOUSE_INPUT_EVENT, WidgetInfoMouseExt as _},
     pointer_capture::POINTER_CAPTURE_EVENT,
     touch::TOUCHED_EVENT,
 };
diff --git a/crates/zng-wgt-input/src/touch.rs b/crates/zng-wgt-input/src/touch.rs
index 901b8f981..8592ef53c 100644
--- a/crates/zng-wgt-input/src/touch.rs
+++ b/crates/zng-wgt-input/src/touch.rs
@@ -6,8 +6,8 @@
 //! [`on_click`](fn@super::gesture::on_click) event.
 
 use zng_ext_input::touch::{
-    TouchInputArgs, TouchLongPressArgs, TouchMoveArgs, TouchTapArgs, TouchTransformArgs, TouchedArgs, TOUCHED_EVENT, TOUCH_INPUT_EVENT,
-    TOUCH_LONG_PRESS_EVENT, TOUCH_MOVE_EVENT, TOUCH_TAP_EVENT, TOUCH_TRANSFORM_EVENT,
+    TOUCH_INPUT_EVENT, TOUCH_LONG_PRESS_EVENT, TOUCH_MOVE_EVENT, TOUCH_TAP_EVENT, TOUCH_TRANSFORM_EVENT, TOUCHED_EVENT, TouchInputArgs,
+    TouchLongPressArgs, TouchMoveArgs, TouchTapArgs, TouchTransformArgs, TouchedArgs,
 };
 use zng_wgt::prelude::*;
 
diff --git a/crates/zng-wgt-input/src/touch_props.rs b/crates/zng-wgt-input/src/touch_props.rs
index 80c9b38d0..5e91fb61a 100644
--- a/crates/zng-wgt-input/src/touch_props.rs
+++ b/crates/zng-wgt-input/src/touch_props.rs
@@ -1,4 +1,4 @@
-use zng_ext_input::touch::{TouchTransformMode, TOUCH_TRANSFORM_EVENT};
+use zng_ext_input::touch::{TOUCH_TRANSFORM_EVENT, TouchTransformMode};
 use zng_view_api::touch::TouchPhase;
 use zng_wgt::prelude::*;
 
diff --git a/crates/zng-wgt-inspector/Cargo.toml b/crates/zng-wgt-inspector/Cargo.toml
index 13811b883..8e4431398 100644
--- a/crates/zng-wgt-inspector/Cargo.toml
+++ b/crates/zng-wgt-inspector/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-inspector"
 version = "0.3.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-inspector/src/crash_handler.rs b/crates/zng-wgt-inspector/src/crash_handler.rs
index 1ef4cfe8d..fc08e4519 100644
--- a/crates/zng-wgt-inspector/src/crash_handler.rs
+++ b/crates/zng-wgt-inspector/src/crash_handler.rs
@@ -9,23 +9,23 @@ use std::path::PathBuf;
 use zng_app::crash_handler::*;
 use zng_ext_config::CONFIG;
 use zng_ext_l10n::l10n;
-use zng_ext_window::{StartPosition, WindowRoot, WINDOWS};
+use zng_ext_window::{StartPosition, WINDOWS, WindowRoot};
 use zng_wgt::prelude::*;
 use zng_wgt::{align, corner_radius, enabled, margin};
 use zng_wgt_ansi_text::AnsiText;
 use zng_wgt_button::Button;
-use zng_wgt_container::{padding, Container};
-use zng_wgt_dialog::{FileDialogFilters, FileDialogResponse, DIALOG};
+use zng_wgt_container::{Container, padding};
+use zng_wgt_dialog::{DIALOG, FileDialogFilters, FileDialogResponse};
 use zng_wgt_fill::background_color;
 use zng_wgt_scroll::Scroll;
 use zng_wgt_stack::Stack;
 use zng_wgt_stack::StackDirection;
-use zng_wgt_style::style_fn;
 use zng_wgt_style::Style;
+use zng_wgt_style::style_fn;
 use zng_wgt_text::Text;
 use zng_wgt_text_input::selectable::SelectableText;
 use zng_wgt_toggle::{self as toggle, Toggle};
-use zng_wgt_tooltip::{tooltip, Tip};
+use zng_wgt_tooltip::{Tip, tooltip};
 use zng_wgt_window::Window;
 use zng_wgt_wrap::Wrap;
 
diff --git a/crates/zng-wgt-inspector/src/lib.rs b/crates/zng-wgt-inspector/src/lib.rs
index 595b946a5..d9071f6f0 100644
--- a/crates/zng-wgt-inspector/src/lib.rs
+++ b/crates/zng-wgt-inspector/src/lib.rs
@@ -11,7 +11,7 @@
 
 zng_wgt::enable_widget_macros!();
 
-use zng_wgt::{prelude::*, ICONS};
+use zng_wgt::{ICONS, prelude::*};
 
 pub mod crash_handler;
 pub mod debug;
diff --git a/crates/zng-wgt-inspector/src/live.rs b/crates/zng-wgt-inspector/src/live.rs
index d434fdfb2..2752115c5 100644
--- a/crates/zng-wgt-inspector/src/live.rs
+++ b/crates/zng-wgt-inspector/src/live.rs
@@ -5,7 +5,7 @@ use zng_ext_config::CONFIG;
 use zng_ext_input::{
     gesture::CLICK_EVENT,
     mouse::{MOUSE_HOVERED_EVENT, MOUSE_INPUT_EVENT, MOUSE_MOVE_EVENT, MOUSE_WHEEL_EVENT},
-    touch::{TOUCHED_EVENT, TOUCH_INPUT_EVENT, TOUCH_LONG_PRESS_EVENT, TOUCH_MOVE_EVENT, TOUCH_TAP_EVENT, TOUCH_TRANSFORM_EVENT},
+    touch::{TOUCH_INPUT_EVENT, TOUCH_LONG_PRESS_EVENT, TOUCH_MOVE_EVENT, TOUCH_TAP_EVENT, TOUCH_TRANSFORM_EVENT, TOUCHED_EVENT},
 };
 use zng_ext_window::{WINDOW_Ext as _, WINDOWS};
 use zng_view_api::window::CursorIcon;
diff --git a/crates/zng-wgt-inspector/src/live/data_model.rs b/crates/zng-wgt-inspector/src/live/data_model.rs
index 1ec242b33..4fd8be040 100644
--- a/crates/zng-wgt-inspector/src/live/data_model.rs
+++ b/crates/zng-wgt-inspector/src/live/data_model.rs
@@ -6,7 +6,7 @@ use zng_app::widget::{
     info::WidgetInfoTree,
     inspector::{InspectorInfo, WidgetInfoInspectorExt},
 };
-use zng_var::{types::WeakArcVar, WeakVar};
+use zng_var::{WeakVar, types::WeakArcVar};
 use zng_view_api::window::FrameId;
 use zng_wgt::prelude::*;
 
diff --git a/crates/zng-wgt-inspector/src/live/inspector_window.rs b/crates/zng-wgt-inspector/src/live/inspector_window.rs
index 563140bd1..e05a74212 100644
--- a/crates/zng-wgt-inspector/src/live/inspector_window.rs
+++ b/crates/zng-wgt-inspector/src/live/inspector_window.rs
@@ -1,21 +1,21 @@
 use std::mem;
 
 use zng_app::widget::{
+    OnVarArgs,
     border::{BorderSide, BorderSides},
     builder::{Importance, PropertyArgs, PropertyInfo, WidgetType},
     inspector::{InspectorActualVars, InstanceItem},
-    OnVarArgs,
 };
 use zng_color::Rgba;
 use zng_ext_font::{FontStyle, FontWeight};
 use zng_ext_input::focus::FOCUS;
 use zng_ext_l10n::{l10n, lang};
-use zng_ext_window::{WindowRoot, WINDOWS};
+use zng_ext_window::{WINDOWS, WindowRoot};
 use zng_var::animation::easing;
-use zng_wgt::{border, corner_radius, margin, prelude::*, visibility, Wgt};
+use zng_wgt::{Wgt, border, corner_radius, margin, prelude::*, visibility};
 use zng_wgt_button::Button;
-use zng_wgt_container::{child_align, padding, Container};
-use zng_wgt_dialog::{FileDialogFilters, DIALOG};
+use zng_wgt_container::{Container, child_align, padding};
+use zng_wgt_dialog::{DIALOG, FileDialogFilters};
 use zng_wgt_fill::background_color;
 use zng_wgt_filter::opacity;
 use zng_wgt_input::{focus::focus_shortcut, gesture::click_shortcut, is_hovered};
@@ -24,10 +24,10 @@ use zng_wgt_scroll::{Scroll, ScrollMode};
 use zng_wgt_size_offset::{size, width};
 use zng_wgt_stack::{Stack, StackDirection};
 use zng_wgt_style::Style;
-use zng_wgt_text::{font_family, lang, Text};
+use zng_wgt_text::{Text, font_family, lang};
 use zng_wgt_text_input::TextInput;
 use zng_wgt_toggle::{self as toggle, Toggle};
-use zng_wgt_tooltip::{tooltip, Tip};
+use zng_wgt_tooltip::{Tip, tooltip};
 use zng_wgt_window as window;
 use zng_wgt_wrap::Wrap;
 
diff --git a/crates/zng-wgt-layer/Cargo.toml b/crates/zng-wgt-layer/Cargo.toml
index bcf5fc348..bc4bdb033 100644
--- a/crates/zng-wgt-layer/Cargo.toml
+++ b/crates/zng-wgt-layer/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-layer"
 version = "0.4.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-layer/src/lib.rs b/crates/zng-wgt-layer/src/lib.rs
index 39ceb4f5b..58c5d4ab4 100644
--- a/crates/zng-wgt-layer/src/lib.rs
+++ b/crates/zng-wgt-layer/src/lib.rs
@@ -17,12 +17,12 @@ use zng_app::widget::info::WIDGET_INFO_CHANGED_EVENT;
 use zng_ext_input::mouse::MOUSE;
 use zng_ext_input::touch::TOUCH;
 use zng_ext_window::WINDOW_Ext as _;
-use zng_var::{animation, ContextInitHandle, ReadOnlyContextVar};
+use zng_var::{ContextInitHandle, ReadOnlyContextVar, animation};
 use zng_view_api::window::FrameId;
 use zng_wgt::prelude::*;
 
-use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::Arc;
+use std::sync::atomic::{AtomicBool, Ordering};
 use std::{fmt, mem, ops};
 
 pub mod popup;
@@ -424,11 +424,7 @@ impl LAYERS {
                                         _ => None,
                                     }
                                 } else if let Some(p) = MOUSE.position().get() {
-                                    if p.window_id == WINDOW.id() {
-                                        Some(p.position)
-                                    } else {
-                                        None
-                                    }
+                                    if p.window_id == WINDOW.id() { Some(p.position) } else { None }
                                 } else {
                                     None
                                 };
diff --git a/crates/zng-wgt-layer/src/popup.rs b/crates/zng-wgt-layer/src/popup.rs
index f5871bdd8..92ad46fe4 100644
--- a/crates/zng-wgt-layer/src/popup.rs
+++ b/crates/zng-wgt-layer/src/popup.rs
@@ -2,15 +2,15 @@
 
 use std::time::Duration;
 
-use zng_ext_input::focus::{DirectionalNav, TabNav, FOCUS_CHANGED_EVENT};
+use zng_ext_input::focus::{DirectionalNav, FOCUS_CHANGED_EVENT, TabNav};
 use zng_wgt::{modal_included, prelude::*};
 use zng_wgt_container::Container;
 use zng_wgt_fill::background_color;
 use zng_wgt_filter::drop_shadow;
-use zng_wgt_input::focus::{alt_focus_scope, directional_nav, focus_click_behavior, tab_nav, FocusClickBehavior, FocusableMix};
-use zng_wgt_style::{impl_style_fn, style_fn, Style, StyleMix};
+use zng_wgt_input::focus::{FocusClickBehavior, FocusableMix, alt_focus_scope, directional_nav, focus_click_behavior, tab_nav};
+use zng_wgt_style::{Style, StyleMix, impl_style_fn, style_fn};
 
-use crate::{AnchorMode, AnchorOffset, LayerIndex, LAYERS};
+use crate::{AnchorMode, AnchorOffset, LAYERS, LayerIndex};
 
 /// An overlay container.
 ///
diff --git a/crates/zng-wgt-markdown/Cargo.toml b/crates/zng-wgt-markdown/Cargo.toml
index 6ee7b5703..fadb813bb 100644
--- a/crates/zng-wgt-markdown/Cargo.toml
+++ b/crates/zng-wgt-markdown/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-markdown"
 version = "0.4.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-markdown/src/lib.rs b/crates/zng-wgt-markdown/src/lib.rs
index a0cbf0bac..d2b8dce6b 100644
--- a/crates/zng-wgt-markdown/src/lib.rs
+++ b/crates/zng-wgt-markdown/src/lib.rs
@@ -140,7 +140,7 @@ pub fn markdown_node(md: impl IntoVar<Txt>) -> impl UiNode {
     })
 }
 
-fn markdown_view_fn<'a>(md: &'a str) -> impl UiNode {
+fn markdown_view_fn<'a>(md: &'a str) -> impl UiNode + use<> {
     use pulldown_cmark::*;
     use resolvers::*;
     use view_fn::*;
diff --git a/crates/zng-wgt-markdown/src/resolvers.rs b/crates/zng-wgt-markdown/src/resolvers.rs
index 2b5e9ee94..b768cd3fc 100644
--- a/crates/zng-wgt-markdown/src/resolvers.rs
+++ b/crates/zng-wgt-markdown/src/resolvers.rs
@@ -14,7 +14,7 @@ use zng_wgt_container::Container;
 use zng_wgt_fill::*;
 use zng_wgt_filter::*;
 use zng_wgt_input::focus::on_focus_leave;
-use zng_wgt_layer::{AnchorMode, AnchorOffset, LayerIndex, LAYERS};
+use zng_wgt_layer::{AnchorMode, AnchorOffset, LAYERS, LayerIndex};
 use zng_wgt_scroll::cmd::ScrollToMode;
 use zng_wgt_size_offset::*;
 use zng_wgt_text::{self as text, Text};
@@ -514,11 +514,7 @@ pub fn heading_anchor(header: &str) -> Txt {
 }
 fn slugify(c: char) -> Option<char> {
     if c.is_alphanumeric() || c == '-' || c == '_' {
-        if c.is_ascii() {
-            Some(c.to_ascii_lowercase())
-        } else {
-            Some(c)
-        }
+        if c.is_ascii() { Some(c.to_ascii_lowercase()) } else { Some(c) }
     } else if c.is_whitespace() && c.is_ascii() {
         Some('-')
     } else {
diff --git a/crates/zng-wgt-markdown/src/view_fn.rs b/crates/zng-wgt-markdown/src/view_fn.rs
index 71207e111..6ee626ebd 100644
--- a/crates/zng-wgt-markdown/src/view_fn.rs
+++ b/crates/zng-wgt-markdown/src/view_fn.rs
@@ -5,15 +5,15 @@ use zng_ext_font::*;
 use zng_ext_image::ImageSource;
 use zng_ext_input::gesture::ClickArgs;
 use zng_wgt::*;
-use zng_wgt_access::{self as access, access_role, AccessRole};
+use zng_wgt_access::{self as access, AccessRole, access_role};
 use zng_wgt_button::{Button, LinkStyle};
-use zng_wgt_container::{child_align, padding, Container};
+use zng_wgt_container::{Container, child_align, padding};
 use zng_wgt_fill::background_color;
 use zng_wgt_filter::opacity;
 use zng_wgt_grid::{self as grid, Grid};
 use zng_wgt_size_offset::{offset, size};
 use zng_wgt_stack::{Stack, StackDirection};
-use zng_wgt_text::{font_size, font_weight, Text, FONT_COLOR_VAR, PARAGRAPH_SPACING_VAR};
+use zng_wgt_text::{FONT_COLOR_VAR, PARAGRAPH_SPACING_VAR, Text, font_size, font_weight};
 use zng_wgt_tooltip::*;
 use zng_wgt_transform::scale;
 use zng_wgt_wrap::Wrap;
diff --git a/crates/zng-wgt-material-icons/Cargo.toml b/crates/zng-wgt-material-icons/Cargo.toml
index 175fd6859..3cfef991d 100644
--- a/crates/zng-wgt-material-icons/Cargo.toml
+++ b/crates/zng-wgt-material-icons/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-material-icons"
 version = "0.4.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-material-icons/src/lib.rs b/crates/zng-wgt-material-icons/src/lib.rs
index 3c8873476..899641e84 100644
--- a/crates/zng-wgt-material-icons/src/lib.rs
+++ b/crates/zng-wgt-material-icons/src/lib.rs
@@ -55,7 +55,7 @@ impl zng_app::AppExtension for MaterialIconsManager {
     #[cfg(any(feature = "outlined", feature = "filled", feature = "rounded", feature = "sharp"))]
     fn init(&mut self) {
         use zng_app::widget::node::{NilUiNode, UiNode as _};
-        use zng_wgt::{wgt_fn, IconRequestArgs, ICONS};
+        use zng_wgt::{ICONS, IconRequestArgs, wgt_fn};
         use zng_wgt_text::icon::{GlyphIcon, Icon};
 
         self.register_fonts();
diff --git a/crates/zng-wgt-menu/Cargo.toml b/crates/zng-wgt-menu/Cargo.toml
index b27fbbec8..3ae4381b6 100644
--- a/crates/zng-wgt-menu/Cargo.toml
+++ b/crates/zng-wgt-menu/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-menu"
 version = "0.4.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-menu/src/context.rs b/crates/zng-wgt-menu/src/context.rs
index 57095b07e..f454a2fcd 100644
--- a/crates/zng-wgt-menu/src/context.rs
+++ b/crates/zng-wgt-menu/src/context.rs
@@ -5,8 +5,8 @@ use zng_ext_input::gesture::CLICK_EVENT;
 use zng_wgt::prelude::*;
 use zng_wgt_input::focus::alt_focus_scope;
 use zng_wgt_layer::{
-    popup::{PopupState, CONTEXT_CAPTURE_VAR, POPUP},
     AnchorMode,
+    popup::{CONTEXT_CAPTURE_VAR, POPUP, PopupState},
 };
 use zng_wgt_stack::{Stack, StackDirection};
 use zng_wgt_style::{impl_style_fn, style_fn};
diff --git a/crates/zng-wgt-menu/src/lib.rs b/crates/zng-wgt-menu/src/lib.rs
index deaf771d7..bcbbb742b 100644
--- a/crates/zng-wgt-menu/src/lib.rs
+++ b/crates/zng-wgt-menu/src/lib.rs
@@ -16,15 +16,15 @@ use zng_ext_font::FontNames;
 use zng_ext_input::{focus::FOCUS, mouse::ClickMode};
 use zng_ext_l10n::lang;
 use zng_wgt::{align, base_color, is_disabled, is_mobile, margin, prelude::*};
-use zng_wgt_access::{access_role, AccessRole};
+use zng_wgt_access::{AccessRole, access_role};
 use zng_wgt_button::BUTTON;
 use zng_wgt_container::{child_align, child_end, padding};
 use zng_wgt_fill::{background_color, foreground_highlight};
 use zng_wgt_filter::{opacity, saturate};
+use zng_wgt_input::{CursorIcon, cursor, focus::alt_focus_scope};
 use zng_wgt_input::{click_mode, focus::is_focused, mouse::on_pre_mouse_enter};
-use zng_wgt_input::{cursor, focus::alt_focus_scope, CursorIcon};
 use zng_wgt_size_offset::size;
-use zng_wgt_style::{impl_style_fn, style_fn, Style, StyleMix};
+use zng_wgt_style::{Style, StyleMix, impl_style_fn, style_fn};
 use zng_wgt_text::Text;
 
 pub mod context;
diff --git a/crates/zng-wgt-menu/src/popup.rs b/crates/zng-wgt-menu/src/popup.rs
index 6cfec1e2b..945ea61ef 100644
--- a/crates/zng-wgt-menu/src/popup.rs
+++ b/crates/zng-wgt-menu/src/popup.rs
@@ -4,18 +4,18 @@ use std::sync::Arc;
 
 use colors::BASE_COLOR_VAR;
 use zng_ext_input::{
-    focus::{WidgetInfoFocusExt as _, FOCUS, FOCUS_CHANGED_EVENT},
-    keyboard::{Key, KeyState, KEY_INPUT_EVENT},
+    focus::{FOCUS, FOCUS_CHANGED_EVENT, WidgetInfoFocusExt as _},
+    keyboard::{KEY_INPUT_EVENT, Key, KeyState},
 };
 use zng_layout::unit::Orientation2D;
 use zng_wgt::{base_color, border, prelude::*};
 use zng_wgt_fill::background_color;
-use zng_wgt_input::pointer_capture::{capture_pointer_on_init, CaptureMode};
-use zng_wgt_layer::popup::{PopupCloseMode, POPUP, POPUP_CLOSE_CMD, POPUP_CLOSE_REQUESTED_EVENT};
+use zng_wgt_input::pointer_capture::{CaptureMode, capture_pointer_on_init};
+use zng_wgt_layer::popup::{POPUP, POPUP_CLOSE_CMD, POPUP_CLOSE_REQUESTED_EVENT, PopupCloseMode};
 use zng_wgt_stack::Stack;
 use zng_wgt_style::{impl_style_fn, style_fn};
 
-use super::sub::{SubMenuWidgetInfoExt, HOVER_OPEN_DELAY_VAR};
+use super::sub::{HOVER_OPEN_DELAY_VAR, SubMenuWidgetInfoExt};
 
 /// Sub-menu popup.
 #[widget($crate::popup::SubMenuPopup)]
diff --git a/crates/zng-wgt-menu/src/sub.rs b/crates/zng-wgt-menu/src/sub.rs
index a7bfff382..98bab862b 100644
--- a/crates/zng-wgt-menu/src/sub.rs
+++ b/crates/zng-wgt-menu/src/sub.rs
@@ -6,9 +6,9 @@ use super::ButtonStyle;
 use colors::BASE_COLOR_VAR;
 use zng_ext_font::FontNames;
 use zng_ext_input::{
-    focus::{WidgetInfoFocusExt as _, FOCUS, FOCUS_CHANGED_EVENT},
+    focus::{FOCUS, FOCUS_CHANGED_EVENT, WidgetInfoFocusExt as _},
     gesture::CLICK_EVENT,
-    keyboard::{Key, KeyState, KEY_INPUT_EVENT},
+    keyboard::{KEY_INPUT_EVENT, Key, KeyState},
     mouse::{ClickMode, MOUSE_HOVERED_EVENT},
 };
 use zng_ext_l10n::lang;
@@ -17,18 +17,17 @@ use zng_wgt_container::padding;
 use zng_wgt_fill::{background, background_color, foreground_highlight};
 use zng_wgt_filter::{opacity, saturate};
 use zng_wgt_input::{
-    click_mode, cursor,
-    focus::{focus_click_behavior, focusable, is_focused, FocusClickBehavior},
+    CursorIcon, click_mode, cursor,
+    focus::{FocusClickBehavior, focus_click_behavior, focusable, is_focused},
     is_hovered,
     pointer_capture::capture_pointer,
-    CursorIcon,
 };
 use zng_wgt_layer::{
-    popup::{PopupState, POPUP, POPUP_CLOSE_CMD},
     AnchorMode, AnchorOffset, AnchorSize,
+    popup::{POPUP, POPUP_CLOSE_CMD, PopupState},
 };
 use zng_wgt_size_offset::{size, width};
-use zng_wgt_style::{impl_style_fn, style_fn, Style, StyleMix};
+use zng_wgt_style::{Style, StyleMix, impl_style_fn, style_fn};
 #[doc(hidden)]
 pub use zng_wgt_text::Text;
 
diff --git a/crates/zng-wgt-panel/Cargo.toml b/crates/zng-wgt-panel/Cargo.toml
index 7599dccd2..06b94e26d 100644
--- a/crates/zng-wgt-panel/Cargo.toml
+++ b/crates/zng-wgt-panel/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-panel"
 version = "0.4.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-progress/Cargo.toml b/crates/zng-wgt-progress/Cargo.toml
index 5a874566f..991167245 100644
--- a/crates/zng-wgt-progress/Cargo.toml
+++ b/crates/zng-wgt-progress/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-progress"
 version = "0.2.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-progress/src/lib.rs b/crates/zng-wgt-progress/src/lib.rs
index 26976da78..2220e89f2 100644
--- a/crates/zng-wgt-progress/src/lib.rs
+++ b/crates/zng-wgt-progress/src/lib.rs
@@ -13,10 +13,10 @@ zng_wgt::enable_widget_macros!();
 
 use zng_app::handler::FilterWidgetHandler;
 use zng_wgt::{base_color, prelude::*, visibility};
-use zng_wgt_container::{child_out_bottom, Container};
+use zng_wgt_container::{Container, child_out_bottom};
 use zng_wgt_fill::background_color;
 use zng_wgt_size_offset::{height, width, x};
-use zng_wgt_style::{impl_style_fn, style_fn, Style, StyleMix};
+use zng_wgt_style::{Style, StyleMix, impl_style_fn, style_fn};
 
 pub use zng_task::Progress;
 
diff --git a/crates/zng-wgt-rule-line/Cargo.toml b/crates/zng-wgt-rule-line/Cargo.toml
index b5cd10363..40d97d51d 100644
--- a/crates/zng-wgt-rule-line/Cargo.toml
+++ b/crates/zng-wgt-rule-line/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-rule-line"
 version = "0.4.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-rule-line/src/lib.rs b/crates/zng-wgt-rule-line/src/lib.rs
index 6639c38e2..553b4c864 100644
--- a/crates/zng-wgt-rule-line/src/lib.rs
+++ b/crates/zng-wgt-rule-line/src/lib.rs
@@ -10,7 +10,7 @@
 #![warn(missing_docs)]
 
 use zng_wgt::{margin, prelude::*};
-use zng_wgt_access::{access_role, AccessRole};
+use zng_wgt_access::{AccessRole, access_role};
 
 /// Draws a horizontal or vertical rule line.
 #[widget($crate::RuleLine)]
diff --git a/crates/zng-wgt-scroll/Cargo.toml b/crates/zng-wgt-scroll/Cargo.toml
index a11b8a626..a5e8c9097 100644
--- a/crates/zng-wgt-scroll/Cargo.toml
+++ b/crates/zng-wgt-scroll/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-scroll"
 version = "0.5.10"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-scroll/src/lazy_prop.rs b/crates/zng-wgt-scroll/src/lazy_prop.rs
index 4b04b1e7d..8a7abf561 100644
--- a/crates/zng-wgt-scroll/src/lazy_prop.rs
+++ b/crates/zng-wgt-scroll/src/lazy_prop.rs
@@ -143,11 +143,7 @@ impl LazyMode {
             LazyMode::Disabled => panic!("expected `LazyMode::Enabled`"),
             LazyMode::Enabled { intersect, .. } => {
                 let m = *intersect;
-                if m.is_empty() {
-                    ScrollMode::PAN
-                } else {
-                    m
-                }
+                if m.is_empty() { ScrollMode::PAN } else { m }
             }
         }
     }
diff --git a/crates/zng-wgt-scroll/src/lib.rs b/crates/zng-wgt-scroll/src/lib.rs
index b06a11879..1c728ba8d 100644
--- a/crates/zng-wgt-scroll/src/lib.rs
+++ b/crates/zng-wgt-scroll/src/lib.rs
@@ -37,7 +37,7 @@ pub use scrollbar::Scrollbar;
 pub use thumb::Thumb;
 
 use zng_ext_input::focus::FocusScopeOnFocus;
-use zng_wgt_container::{child_align, Container};
+use zng_wgt_container::{Container, child_align};
 use zng_wgt_input::focus::{focus_scope, focus_scope_behavior};
 
 /// A container that can pan and zoom a child of any size.
diff --git a/crates/zng-wgt-scroll/src/node.rs b/crates/zng-wgt-scroll/src/node.rs
index 37bb4514a..42da5f2d2 100644
--- a/crates/zng-wgt-scroll/src/node.rs
+++ b/crates/zng-wgt-scroll/src/node.rs
@@ -11,16 +11,16 @@ use zng_app::{
 use zng_color::Rgba;
 use zng_ext_input::{
     focus::{FOCUS, FOCUS_CHANGED_EVENT},
-    keyboard::{Key, KeyState, KEY_INPUT_EVENT},
-    mouse::{ButtonState, MouseButton, MouseScrollDelta, MOUSE_INPUT_EVENT, MOUSE_WHEEL_EVENT},
-    touch::{TouchPhase, TOUCH_TRANSFORM_EVENT},
+    keyboard::{KEY_INPUT_EVENT, Key, KeyState},
+    mouse::{ButtonState, MOUSE_INPUT_EVENT, MOUSE_WHEEL_EVENT, MouseButton, MouseScrollDelta},
+    touch::{TOUCH_TRANSFORM_EVENT, TouchPhase},
 };
 use zng_wgt::prelude::{
     gradient::{ExtendMode, RenderGradientStop},
     *,
 };
 use zng_wgt_container::Container;
-use zng_wgt_layer::{AnchorMode, LayerIndex, LAYERS};
+use zng_wgt_layer::{AnchorMode, LAYERS, LayerIndex};
 
 use super::cmd::*;
 use super::scroll_properties::*;
diff --git a/crates/zng-wgt-scroll/src/scrollbar.rs b/crates/zng-wgt-scroll/src/scrollbar.rs
index 1755157cb..1111edac4 100644
--- a/crates/zng-wgt-scroll/src/scrollbar.rs
+++ b/crates/zng-wgt-scroll/src/scrollbar.rs
@@ -3,7 +3,7 @@
 use zng_ext_input::mouse::{ClickMode, MouseClickArgs};
 use zng_ext_window::WINDOW_Ext as _;
 use zng_wgt::{align, prelude::*};
-use zng_wgt_access::{access_role, AccessRole};
+use zng_wgt_access::{AccessRole, access_role};
 use zng_wgt_fill::background_color;
 use zng_wgt_input::{click_mode, mouse::on_mouse_click};
 
diff --git a/crates/zng-wgt-scroll/src/types.rs b/crates/zng-wgt-scroll/src/types.rs
index b150ca4da..cfd5baf32 100644
--- a/crates/zng-wgt-scroll/src/types.rs
+++ b/crates/zng-wgt-scroll/src/types.rs
@@ -5,15 +5,15 @@ use bitflags::bitflags;
 use parking_lot::Mutex;
 use zng_ext_input::touch::TouchPhase;
 use zng_var::{
+    ReadOnlyContextVar, VARS,
     animation::{
-        easing::{self, EasingStep, EasingTime},
         AnimationHandle, ChaseAnimation, Transition,
+        easing::{self, EasingStep, EasingTime},
     },
-    ReadOnlyContextVar, VARS,
 };
 use zng_wgt::prelude::*;
 
-use super::{cmd, SMOOTH_SCROLLING_VAR};
+use super::{SMOOTH_SCROLLING_VAR, cmd};
 
 bitflags! {
     /// What dimensions are scrollable in a widget.
diff --git a/crates/zng-wgt-settings/Cargo.toml b/crates/zng-wgt-settings/Cargo.toml
index 78f5b9beb..cc41762ac 100644
--- a/crates/zng-wgt-settings/Cargo.toml
+++ b/crates/zng-wgt-settings/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-settings"
 version = "0.2.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-settings/src/lib.rs b/crates/zng-wgt-settings/src/lib.rs
index bd65a906a..7ba905951 100644
--- a/crates/zng-wgt-settings/src/lib.rs
+++ b/crates/zng-wgt-settings/src/lib.rs
@@ -14,7 +14,7 @@ use zng_ext_window::{WINDOW_Ext as _, WINDOWS};
 use zng_wgt::prelude::*;
 use zng_wgt_input::cmd::SETTINGS_CMD;
 use zng_wgt_size_offset::actual_width;
-use zng_wgt_window::{save_state_node, SaveState, Window};
+use zng_wgt_window::{SaveState, Window, save_state_node};
 
 /// Settings editor widget.
 #[widget($crate::SettingsEditor)]
diff --git a/crates/zng-wgt-settings/src/view_fn.rs b/crates/zng-wgt-settings/src/view_fn.rs
index f636165e7..321d1b5b1 100644
--- a/crates/zng-wgt-settings/src/view_fn.rs
+++ b/crates/zng-wgt-settings/src/view_fn.rs
@@ -6,13 +6,13 @@ use zng_app::{
     },
 };
 use zng_ext_config::{
-    settings::{Category, CategoryId, Setting, SettingBuilder, SETTINGS},
     ConfigKey,
+    settings::{Category, CategoryId, SETTINGS, Setting, SettingBuilder},
 };
 use zng_ext_font::FontWeight;
 use zng_ext_l10n::l10n;
 use zng_var::{ContextInitHandle, ReadOnlyContextVar};
-use zng_wgt::{node::with_context_var, prelude::*, Wgt, WidgetFn, EDITORS, ICONS};
+use zng_wgt::{EDITORS, ICONS, Wgt, WidgetFn, node::with_context_var, prelude::*};
 use zng_wgt_container::Container;
 use zng_wgt_filter::opacity;
 use zng_wgt_markdown::Markdown;
@@ -23,7 +23,7 @@ use zng_wgt_style::Style;
 use zng_wgt_text::Text;
 use zng_wgt_text_input::TextInput;
 use zng_wgt_toggle::{Selector, Toggle};
-use zng_wgt_tooltip::{disabled_tooltip, tooltip, Tip};
+use zng_wgt_tooltip::{Tip, disabled_tooltip, tooltip};
 
 use crate::SettingsEditor;
 
diff --git a/crates/zng-wgt-size-offset/Cargo.toml b/crates/zng-wgt-size-offset/Cargo.toml
index 05cc81907..bef023d8b 100644
--- a/crates/zng-wgt-size-offset/Cargo.toml
+++ b/crates/zng-wgt-size-offset/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-size-offset"
 version = "0.3.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-slider/Cargo.toml b/crates/zng-wgt-slider/Cargo.toml
index dcab59f11..8c735e043 100644
--- a/crates/zng-wgt-slider/Cargo.toml
+++ b/crates/zng-wgt-slider/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-slider"
 version = "0.2.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-slider/src/lib.rs b/crates/zng-wgt-slider/src/lib.rs
index 6ac8d75a6..3c47edcbb 100644
--- a/crates/zng-wgt-slider/src/lib.rs
+++ b/crates/zng-wgt-slider/src/lib.rs
@@ -20,7 +20,7 @@ use parking_lot::Mutex;
 use zng_var::{AnyVar, AnyVarValue, BoxedAnyVar};
 use zng_wgt::prelude::*;
 use zng_wgt_input::{focus::FocusableMix, pointer_capture::capture_pointer};
-use zng_wgt_style::{impl_style_fn, style_fn, Style, StyleMix};
+use zng_wgt_style::{Style, StyleMix, impl_style_fn, style_fn};
 
 /// Value selector from a range of values.
 #[widget($crate::Slider)]
diff --git a/crates/zng-wgt-slider/src/thumb.rs b/crates/zng-wgt-slider/src/thumb.rs
index 841cb10da..a6e1a70b9 100644
--- a/crates/zng-wgt-slider/src/thumb.rs
+++ b/crates/zng-wgt-slider/src/thumb.rs
@@ -3,9 +3,9 @@
 use zng_ext_input::mouse::MOUSE_MOVE_EVENT;
 use zng_wgt::prelude::*;
 use zng_wgt_input::{focus::FocusableMix, pointer_capture::capture_pointer};
-use zng_wgt_style::{impl_style_fn, style_fn, Style, StyleMix};
+use zng_wgt_style::{Style, StyleMix, impl_style_fn, style_fn};
 
-use crate::{SliderDirection, ThumbValue, WidgetInfoExt as _, SLIDER_DIRECTION_VAR};
+use crate::{SLIDER_DIRECTION_VAR, SliderDirection, ThumbValue, WidgetInfoExt as _};
 
 /// Slider thumb widget.
 #[widget($crate::thumb::Thumb {
diff --git a/crates/zng-wgt-stack/Cargo.toml b/crates/zng-wgt-stack/Cargo.toml
index f79c489ed..8a93e1b05 100644
--- a/crates/zng-wgt-stack/Cargo.toml
+++ b/crates/zng-wgt-stack/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-stack"
 version = "0.4.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-stack/src/lib.rs b/crates/zng-wgt-stack/src/lib.rs
index ae1edf1c3..da2531889 100644
--- a/crates/zng-wgt-stack/src/lib.rs
+++ b/crates/zng-wgt-stack/src/lib.rs
@@ -274,11 +274,7 @@ fn measure(wm: &mut WidgetMeasure, children: &mut PanelList, direction: StackDir
             children.measure_each(
                 wm,
                 |_, c, _, wm| {
-                    if c.is_widget() {
-                        c.measure(wm)
-                    } else {
-                        PxSize::zero()
-                    }
+                    if c.is_widget() { c.measure(wm) } else { PxSize::zero() }
                 },
                 |_, _| PxSize::zero(),
             );
@@ -525,11 +521,7 @@ fn stack_nodes_layout_by_impl(
                     children.measure_each(
                         wm,
                         |i, n, wm| {
-                            if i != index {
-                                n.measure(wm)
-                            } else {
-                                index_size
-                            }
+                            if i != index { n.measure(wm) } else { index_size }
                         },
                         PxSize::max,
                     )
@@ -555,11 +547,7 @@ fn stack_nodes_layout_by_impl(
                     children.layout_each(
                         wl,
                         |i, n, wl| {
-                            if i != index {
-                                n.layout(wl)
-                            } else {
-                                index_size
-                            }
+                            if i != index { n.layout(wl) } else { index_size }
                         },
                         PxSize::max,
                     )
diff --git a/crates/zng-wgt-stack/src/types.rs b/crates/zng-wgt-stack/src/types.rs
index d46bc2edd..d1b878629 100644
--- a/crates/zng-wgt-stack/src/types.rs
+++ b/crates/zng-wgt-stack/src/types.rs
@@ -1,6 +1,6 @@
 use std::{fmt, mem, ops};
 use zng_layout::context::LayoutMask;
-use zng_var::animation::{easing::EasingStep, Transitionable};
+use zng_var::animation::{Transitionable, easing::EasingStep};
 use zng_wgt::prelude::*;
 
 /// Defines a placement point in the previous item and the origin point of the next.
diff --git a/crates/zng-wgt-style/Cargo.toml b/crates/zng-wgt-style/Cargo.toml
index d71af36b3..7c2dab557 100644
--- a/crates/zng-wgt-style/Cargo.toml
+++ b/crates/zng-wgt-style/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-style"
 version = "0.4.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-style/src/lib.rs b/crates/zng-wgt-style/src/lib.rs
index 6cdbaf426..b1b4b5854 100644
--- a/crates/zng-wgt-style/src/lib.rs
+++ b/crates/zng-wgt-style/src/lib.rs
@@ -132,7 +132,7 @@ impl<P> StyleMix<P> {
 
 #[doc(hidden)]
 pub mod __impl_style_context_util {
-    pub use zng_wgt::prelude::{context_var, property, IntoVar, UiNode};
+    pub use zng_wgt::prelude::{IntoVar, UiNode, context_var, property};
 }
 
 /// Implements the contextual `STYLE_FN_VAR` and `style_fn`.
@@ -359,11 +359,7 @@ impl StyleFn {
     pub fn new(func: impl Fn(&StyleArgs) -> StyleBuilder + Send + Sync + 'static) -> Self {
         Self(Some(Arc::new(move |a| {
             let style = func(a);
-            if style.is_empty() {
-                None
-            } else {
-                Some(style)
-            }
+            if style.is_empty() { None } else { Some(style) }
         })))
     }
 
@@ -427,11 +423,7 @@ impl ops::Deref for StyleFn {
     type Target = dyn Fn(&StyleArgs) -> Option<StyleBuilder>;
 
     fn deref(&self) -> &Self::Target {
-        if let Some(func) = &self.0 {
-            &**func
-        } else {
-            &nil_func
-        }
+        if let Some(func) = &self.0 { &**func } else { &nil_func }
     }
 }
 fn nil_func(_: &StyleArgs) -> Option<StyleBuilder> {
diff --git a/crates/zng-wgt-text-input/Cargo.toml b/crates/zng-wgt-text-input/Cargo.toml
index ec6964f8b..6eb9716b0 100644
--- a/crates/zng-wgt-text-input/Cargo.toml
+++ b/crates/zng-wgt-text-input/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-text-input"
 version = "0.5.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-text-input/src/label.rs b/crates/zng-wgt-text-input/src/label.rs
index 38d88260e..6985cccf5 100644
--- a/crates/zng-wgt-text-input/src/label.rs
+++ b/crates/zng-wgt-text-input/src/label.rs
@@ -2,13 +2,13 @@
 
 use zng_app::access::ACCESS_CLICK_EVENT;
 use zng_ext_input::{
-    focus::{FocusInfoBuilder, FOCUS},
+    focus::{FOCUS, FocusInfoBuilder},
     mouse::MOUSE_INPUT_EVENT,
     touch::TOUCH_INPUT_EVENT,
 };
 use zng_wgt::prelude::*;
 use zng_wgt_input::focus::FocusableMix;
-use zng_wgt_style::{impl_style_fn, style_fn, Style, StyleMix};
+use zng_wgt_style::{Style, StyleMix, impl_style_fn, style_fn};
 
 /// Styleable and focusable read-only text widget.
 ///
diff --git a/crates/zng-wgt-text-input/src/selectable.rs b/crates/zng-wgt-text-input/src/selectable.rs
index a462a9320..bccea9c49 100644
--- a/crates/zng-wgt-text-input/src/selectable.rs
+++ b/crates/zng-wgt-text-input/src/selectable.rs
@@ -6,9 +6,9 @@ use zng_wgt_button::Button;
 use zng_wgt_input::focus::FocusableMix;
 use zng_wgt_menu::{
     self as menu,
-    context::{context_menu_fn, ContextMenu},
+    context::{ContextMenu, context_menu_fn},
 };
-use zng_wgt_style::{impl_style_fn, style_fn, Style, StyleMix};
+use zng_wgt_style::{Style, StyleMix, impl_style_fn, style_fn};
 use zng_wgt_text::{self as text, *};
 
 #[doc(hidden)]
diff --git a/crates/zng-wgt-text-input/src/text_input.rs b/crates/zng-wgt-text-input/src/text_input.rs
index b4cd170c6..ebc342aca 100644
--- a/crates/zng-wgt-text-input/src/text_input.rs
+++ b/crates/zng-wgt-text-input/src/text_input.rs
@@ -2,9 +2,9 @@ use colors::{ACCENT_COLOR_VAR, BASE_COLOR_VAR};
 use zng_ext_clipboard::{COPY_CMD, CUT_CMD, PASTE_CMD};
 use zng_wgt::base_color;
 use zng_wgt::{align, is_disabled, margin, prelude::*};
-use zng_wgt_access::{access_role, AccessRole};
+use zng_wgt_access::{AccessRole, access_role};
 use zng_wgt_button::Button;
-use zng_wgt_data::{DataNoteLevel, DataNotes, DATA};
+use zng_wgt_data::{DATA, DataNoteLevel, DataNotes};
 use zng_wgt_fill::foreground_highlight;
 use zng_wgt_filter::{child_opacity, saturate};
 use zng_wgt_input::{
@@ -14,13 +14,13 @@ use zng_wgt_input::{
 use zng_wgt_layer::popup;
 use zng_wgt_menu::{
     self as menu,
-    context::{context_menu_fn, ContextMenu},
+    context::{ContextMenu, context_menu_fn},
 };
 use zng_wgt_rule_line::hr::Hr;
 use zng_wgt_size_offset::{offset, y};
-use zng_wgt_style::{impl_style_fn, style_fn, Style, StyleMix};
+use zng_wgt_style::{Style, StyleMix, impl_style_fn, style_fn};
 use zng_wgt_text::{self as text, *};
-use zng_wgt_undo::{undo_scope, UndoMix};
+use zng_wgt_undo::{UndoMix, undo_scope};
 
 /// Simple text editor widget.
 ///
diff --git a/crates/zng-wgt-text/Cargo.toml b/crates/zng-wgt-text/Cargo.toml
index 9d4e024c3..806abfc75 100644
--- a/crates/zng-wgt-text/Cargo.toml
+++ b/crates/zng-wgt-text/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-text"
 version = "0.5.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-text/src/icon.rs b/crates/zng-wgt-text/src/icon.rs
index 43a2735b1..47fd8b67a 100644
--- a/crates/zng-wgt-text/src/icon.rs
+++ b/crates/zng-wgt-text/src/icon.rs
@@ -3,7 +3,7 @@
 //! Note that no icons are embedded in this crate directly, you can manually create a [`GlyphIcon`]
 //! or use an icon set crate. See the `zng::icon::material` module for an example.
 
-use zng_ext_font::{font_features::FontFeatures, FontName, FontSize};
+use zng_ext_font::{FontName, FontSize, font_features::FontFeatures};
 use zng_wgt::prelude::*;
 
 use std::fmt;
diff --git a/crates/zng-wgt-text/src/node.rs b/crates/zng-wgt-text/src/node.rs
index 4672ce0a8..bf72e4acf 100644
--- a/crates/zng-wgt-text/src/node.rs
+++ b/crates/zng-wgt-text/src/node.rs
@@ -10,17 +10,17 @@ use zng_app_context::{MappedRwLockWriteGuardOwned, RwLockReadGuardOwned, RwLockW
 use zng_ext_font::{CaretIndex, FontFaceList, FontList, SegmentedText, ShapedLine, ShapedText, TextOverflowInfo};
 use zng_ext_input::{
     focus::FOCUS_CHANGED_EVENT,
-    keyboard::{Key, KeyState, KEY_INPUT_EVENT},
+    keyboard::{KEY_INPUT_EVENT, Key, KeyState},
     mouse::MOUSE_INPUT_EVENT,
     touch::{TOUCH_INPUT_EVENT, TOUCH_LONG_PRESS_EVENT},
 };
 use zng_ext_window::WINDOW_Ext as _;
 use zng_view_api::{mouse::ButtonState, touch::TouchPhase};
 use zng_wgt::prelude::*;
-use zng_wgt_data::{DataNoteHandle, DATA};
+use zng_wgt_data::{DATA, DataNoteHandle};
 use zng_wgt_layer::{
-    popup::{ContextCapture, PopupState, POPUP},
     AnchorMode, AnchorTransform,
+    popup::{ContextCapture, POPUP, PopupState},
 };
 
 mod resolve;
diff --git a/crates/zng-wgt-text/src/node/caret.rs b/crates/zng-wgt-text/src/node/caret.rs
index e159b0499..ca86304af 100644
--- a/crates/zng-wgt-text/src/node/caret.rs
+++ b/crates/zng-wgt-text/src/node/caret.rs
@@ -8,12 +8,13 @@ use zng_app::{
     render::FrameValueKey,
     update::UPDATES,
     widget::{
+        WIDGET, WidgetId,
         base::WidgetBase,
-        node::{match_node, match_node_leaf, UiNode, UiNodeOp},
-        property, widget, WidgetId, WIDGET,
+        node::{UiNode, UiNodeOp, match_node, match_node_leaf},
+        property, widget,
     },
 };
-use zng_app_context::{context_local, LocalContext};
+use zng_app_context::{LocalContext, context_local};
 use zng_color::colors;
 use zng_ext_input::{
     focus::{FOCUS, FOCUS_CHANGED_EVENT},
@@ -26,12 +27,12 @@ use zng_layout::{
     unit::{Dip, DipToPx as _, DipVector, Px, PxCornerRadius, PxPoint, PxRect, PxSize, PxTransform, PxVector},
 };
 use zng_view_api::{display_list::FrameValue, touch::TouchId};
-use zng_wgt::{prelude::*, WidgetFn};
-use zng_wgt_layer::{AnchorMode, LayerIndex, LAYERS};
+use zng_wgt::{WidgetFn, prelude::*};
+use zng_wgt_layer::{AnchorMode, LAYERS, LayerIndex};
 
 use crate::{
-    cmd::{TextSelectOp, SELECT_CMD},
-    CaretShape, CARET_COLOR_VAR, INTERACTIVE_CARET_VAR, INTERACTIVE_CARET_VISUAL_VAR, TEXT_EDITABLE_VAR,
+    CARET_COLOR_VAR, CaretShape, INTERACTIVE_CARET_VAR, INTERACTIVE_CARET_VISUAL_VAR, TEXT_EDITABLE_VAR,
+    cmd::{SELECT_CMD, TextSelectOp},
 };
 
 use super::TEXT;
diff --git a/crates/zng-wgt-text/src/node/layout.rs b/crates/zng-wgt-text/src/node/layout.rs
index dc9cb9751..fa0548206 100644
--- a/crates/zng-wgt-text/src/node/layout.rs
+++ b/crates/zng-wgt-text/src/node/layout.rs
@@ -3,17 +3,17 @@ use std::{mem, sync::Arc};
 use atomic::Atomic;
 use parking_lot::RwLock;
 use zng_app::{
+    DInstant,
     event::{AnyEventArgs as _, CommandHandle, EventHandle, EventHandles},
     widget::{
-        node::{match_node, UiNode, UiNodeOp},
         WIDGET,
+        node::{UiNode, UiNodeOp, match_node},
     },
-    DInstant,
 };
-use zng_ext_font::{font_features::FontVariations, CaretIndex, FontFaceList, Hyphens, SegmentedText, ShapedText, TextShapingArgs};
+use zng_ext_font::{CaretIndex, FontFaceList, Hyphens, SegmentedText, ShapedText, TextShapingArgs, font_features::FontVariations};
 use zng_ext_input::{
     focus::FOCUS,
-    keyboard::{KEYBOARD, KEY_INPUT_EVENT},
+    keyboard::{KEY_INPUT_EVENT, KEYBOARD},
     mouse::{MOUSE, MOUSE_INPUT_EVENT, MOUSE_MOVE_EVENT},
     pointer_capture::{POINTER_CAPTURE, POINTER_CAPTURE_EVENT},
     touch::{TOUCH_INPUT_EVENT, TOUCH_LONG_PRESS_EVENT, TOUCH_TAP_EVENT},
@@ -22,25 +22,25 @@ use zng_ext_l10n::LANG_VAR;
 use zng_ext_undo::UNDO;
 use zng_ext_window::WidgetInfoBuilderImeArea as _;
 use zng_layout::{
-    context::{InlineConstraints, InlineConstraintsMeasure, InlineSegment, LayoutMetrics, LAYOUT},
+    context::{InlineConstraints, InlineConstraintsMeasure, InlineSegment, LAYOUT, LayoutMetrics},
     unit::{DipPoint, FactorUnits as _, Px, PxBox, PxConstraints2d, PxRect, PxSize, PxTransform, Rect, Size},
 };
 use zng_view_api::keyboard::{Key, KeyState};
 use zng_wgt::prelude::*;
-use zng_wgt_scroll::{cmd::ScrollToMode, SCROLL};
+use zng_wgt_scroll::{SCROLL, cmd::ScrollToMode};
 
 use crate::{
-    cmd::{TextSelectOp, SELECT_ALL_CMD, SELECT_CMD},
+    ACCEPTS_ENTER_VAR, ACCEPTS_TAB_VAR, AUTO_SELECTION_VAR, AutoSelection, FONT_FAMILY_VAR, FONT_FEATURES_VAR, FONT_SIZE_VAR,
+    FONT_STRETCH_VAR, FONT_STYLE_VAR, FONT_VARIATIONS_VAR, FONT_WEIGHT_VAR, HYPHEN_CHAR_VAR, HYPHENS_VAR, IME_UNDERLINE_THICKNESS_VAR,
+    JUSTIFY_MODE_VAR, LETTER_SPACING_VAR, LINE_BREAK_VAR, LINE_HEIGHT_VAR, LINE_SPACING_VAR, OBSCURE_TXT_VAR, OBSCURING_CHAR_VAR,
+    OVERLINE_THICKNESS_VAR, STRIKETHROUGH_THICKNESS_VAR, TAB_LENGTH_VAR, TEXT_ALIGN_VAR, TEXT_EDITABLE_VAR, TEXT_OVERFLOW_ALIGN_VAR,
+    TEXT_OVERFLOW_VAR, TEXT_SELECTABLE_VAR, TEXT_WRAP_VAR, TextOverflow, UNDERLINE_POSITION_VAR, UNDERLINE_SKIP_VAR,
+    UNDERLINE_THICKNESS_VAR, UnderlinePosition, UnderlineSkip, WORD_BREAK_VAR, WORD_SPACING_VAR,
+    cmd::{SELECT_ALL_CMD, SELECT_CMD, TextSelectOp},
     node::SelectionBy,
-    AutoSelection, TextOverflow, UnderlinePosition, UnderlineSkip, ACCEPTS_ENTER_VAR, ACCEPTS_TAB_VAR, AUTO_SELECTION_VAR, FONT_FAMILY_VAR,
-    FONT_FEATURES_VAR, FONT_SIZE_VAR, FONT_STRETCH_VAR, FONT_STYLE_VAR, FONT_VARIATIONS_VAR, FONT_WEIGHT_VAR, HYPHENS_VAR, HYPHEN_CHAR_VAR,
-    IME_UNDERLINE_THICKNESS_VAR, JUSTIFY_MODE_VAR, LETTER_SPACING_VAR, LINE_BREAK_VAR, LINE_HEIGHT_VAR, LINE_SPACING_VAR, OBSCURE_TXT_VAR,
-    OBSCURING_CHAR_VAR, OVERLINE_THICKNESS_VAR, STRIKETHROUGH_THICKNESS_VAR, TAB_LENGTH_VAR, TEXT_ALIGN_VAR, TEXT_EDITABLE_VAR,
-    TEXT_OVERFLOW_ALIGN_VAR, TEXT_OVERFLOW_VAR, TEXT_SELECTABLE_VAR, TEXT_WRAP_VAR, UNDERLINE_POSITION_VAR, UNDERLINE_SKIP_VAR,
-    UNDERLINE_THICKNESS_VAR, WORD_BREAK_VAR, WORD_SPACING_VAR,
 };
 
-use super::{LaidoutText, PendingLayout, RenderInfo, LAIDOUT_TEXT, TEXT};
+use super::{LAIDOUT_TEXT, LaidoutText, PendingLayout, RenderInfo, TEXT};
 
 /// An UI node that layouts the parent [`ResolvedText`] defined by the text context vars.
 ///
diff --git a/crates/zng-wgt-text/src/node/render.rs b/crates/zng-wgt-text/src/node/render.rs
index 05b1bad95..4915c60dd 100644
--- a/crates/zng-wgt-text/src/node/render.rs
+++ b/crates/zng-wgt-text/src/node/render.rs
@@ -3,9 +3,9 @@ use std::borrow::Cow;
 use zng_app::{
     render::{FontSynthesis, FrameValueKey, ReferenceFrameId},
     widget::{
-        border::{LineOrientation, LineStyle},
-        node::{match_node, match_node_leaf, UiNode, UiNodeOp},
         WIDGET,
+        border::{LineOrientation, LineStyle},
+        node::{UiNode, UiNodeOp, match_node, match_node_leaf},
     },
 };
 use zng_color::Rgba;
@@ -19,9 +19,9 @@ use zng_view_api::{config::FontAntiAliasing, display_list::FrameValue, font::Gly
 use zng_wgt::prelude::*;
 
 use crate::{
-    TextOverflow, FONT_AA_VAR, FONT_COLOR_VAR, FONT_PALETTE_COLORS_VAR, FONT_PALETTE_VAR, IME_UNDERLINE_STYLE_VAR, OVERLINE_COLOR_VAR,
+    FONT_AA_VAR, FONT_COLOR_VAR, FONT_PALETTE_COLORS_VAR, FONT_PALETTE_VAR, IME_UNDERLINE_STYLE_VAR, OVERLINE_COLOR_VAR,
     OVERLINE_STYLE_VAR, SELECTION_COLOR_VAR, STRIKETHROUGH_COLOR_VAR, STRIKETHROUGH_STYLE_VAR, TEXT_EDITABLE_VAR, TEXT_OVERFLOW_VAR,
-    UNDERLINE_COLOR_VAR, UNDERLINE_STYLE_VAR,
+    TextOverflow, UNDERLINE_COLOR_VAR, UNDERLINE_STYLE_VAR,
 };
 
 use super::TEXT;
diff --git a/crates/zng-wgt-text/src/node/resolve.rs b/crates/zng-wgt-text/src/node/resolve.rs
index 415bfcb57..75acb4d54 100644
--- a/crates/zng-wgt-text/src/node/resolve.rs
+++ b/crates/zng-wgt-text/src/node/resolve.rs
@@ -7,33 +7,33 @@ use zng_app::{
     render::FontSynthesis,
     update::{EventUpdate, UpdateOp},
     widget::{
-        info::INTERACTIVITY_CHANGED_EVENT,
-        node::{match_node, UiNode, UiNodeOp},
         WIDGET,
+        info::INTERACTIVITY_CHANGED_EVENT,
+        node::{UiNode, UiNodeOp, match_node},
     },
     window::WINDOW,
 };
 use zng_ext_clipboard::{CLIPBOARD, COPY_CMD, CUT_CMD, PASTE_CMD};
-use zng_ext_font::{CaretIndex, FontFaceList, SegmentedText, FONTS, FONT_CHANGED_EVENT};
+use zng_ext_font::{CaretIndex, FONT_CHANGED_EVENT, FONTS, FontFaceList, SegmentedText};
 use zng_ext_input::{
-    focus::{FocusInfoBuilder, WidgetInfoFocusExt as _, FOCUS, FOCUS_CHANGED_EVENT},
-    keyboard::{KEYBOARD, KEY_INPUT_EVENT},
+    focus::{FOCUS, FOCUS_CHANGED_EVENT, FocusInfoBuilder, WidgetInfoFocusExt as _},
+    keyboard::{KEY_INPUT_EVENT, KEYBOARD},
 };
 use zng_ext_l10n::LANG_VAR;
 use zng_ext_undo::UNDO;
-use zng_ext_window::{cmd::CANCEL_IME_CMD, WINDOW_Ext as _, WindowLoadingHandle, IME_EVENT};
-use zng_layout::context::{LayoutDirection, DIRECTION_VAR};
+use zng_ext_window::{IME_EVENT, WINDOW_Ext as _, WindowLoadingHandle, cmd::CANCEL_IME_CMD};
+use zng_layout::context::{DIRECTION_VAR, LayoutDirection};
 use zng_view_api::keyboard::{Key, KeyState};
 use zng_wgt::prelude::*;
 
 use crate::{
-    cmd::{TextEditOp, TextSelectOp, UndoTextEditOp, EDIT_CMD, SELECT_ALL_CMD, SELECT_CMD},
-    AutoSelection, ACCEPTS_ENTER_VAR, ACCEPTS_TAB_VAR, AUTO_SELECTION_VAR, FONT_FAMILY_VAR, FONT_STRETCH_VAR, FONT_STYLE_VAR,
+    ACCEPTS_ENTER_VAR, ACCEPTS_TAB_VAR, AUTO_SELECTION_VAR, AutoSelection, FONT_FAMILY_VAR, FONT_STRETCH_VAR, FONT_STYLE_VAR,
     FONT_SYNTHESIS_VAR, FONT_WEIGHT_VAR, MAX_CHARS_COUNT_VAR, OBSCURE_TXT_VAR, TEXT_EDITABLE_VAR, TEXT_SELECTABLE_VAR, TEXT_TRANSFORM_VAR,
     WHITE_SPACE_VAR,
+    cmd::{EDIT_CMD, SELECT_ALL_CMD, SELECT_CMD, TextEditOp, TextSelectOp, UndoTextEditOp},
 };
 
-use super::{CaretInfo, ImePreview, PendingLayout, ResolvedText, SelectionBy, RESOLVED_TEXT, TEXT};
+use super::{CaretInfo, ImePreview, PendingLayout, RESOLVED_TEXT, ResolvedText, SelectionBy, TEXT};
 
 /// An UI node that resolves the text context vars, applies the text transform and white space correction and segments the `text`.
 ///
diff --git a/crates/zng-wgt-text/src/text_properties.rs b/crates/zng-wgt-text/src/text_properties.rs
index c4ab8abc3..6c16670ce 100644
--- a/crates/zng-wgt-text/src/text_properties.rs
+++ b/crates/zng-wgt-text/src/text_properties.rs
@@ -3,7 +3,7 @@ use std::{fmt, num::NonZeroU32, time::Duration};
 use zng_app::render::FontSynthesis;
 use zng_color::COLOR_SCHEME_VAR;
 use zng_ext_font::{font_features::*, *};
-use zng_ext_l10n::{Langs, LANG_VAR};
+use zng_ext_l10n::{LANG_VAR, Langs};
 use zng_view_api::config::FontAntiAliasing;
 use zng_wgt::prelude::*;
 use zng_wgt_layer::AnchorOffset;
@@ -291,10 +291,6 @@ context_var! {
     /// Text alignment inside the available space when it overflows.
     pub static TEXT_OVERFLOW_ALIGN_VAR: Align = Align::TOP_START;
 
-    #[doc(hidden)]
-    #[deprecated = "use `JUSTIFY_MODE_VAR`"]
-    pub static JUSTIFY_VAR: Option<Justify> = None;
-
     /// Text justify mode when text align is fill.
     pub static JUSTIFY_MODE_VAR: Justify = Justify::Auto;
 }
@@ -344,18 +340,6 @@ pub fn txt_overflow_align(child: impl UiNode, mode: impl IntoVar<Align>) -> impl
     with_context_var(child, TEXT_OVERFLOW_ALIGN_VAR, mode)
 }
 
-#[doc(hidden)]
-#[deprecated = "use `justify_mode`"]
-#[property(CONTEXT, default(#[allow(deprecated)]JUSTIFY_VAR), widget_impl(TextAlignMix<P>))]
-pub fn justify(child: impl UiNode, mode: impl IntoVar<Option<Justify>>) -> impl UiNode {
-    with_context_var(
-        child,
-        #[allow(deprecated)]
-        JUSTIFY_VAR,
-        mode,
-    )
-}
-
 /// Config the automatic spacing inserted between words and letters when text is aligned to fill.
 ///
 /// Text alignment can be set to [`Align::FILL_X`], if that is the case this config is defines how
diff --git a/crates/zng-wgt-toggle/Cargo.toml b/crates/zng-wgt-toggle/Cargo.toml
index 64d9f804c..aa386f41d 100644
--- a/crates/zng-wgt-toggle/Cargo.toml
+++ b/crates/zng-wgt-toggle/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-toggle"
 version = "0.4.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-toggle/src/lib.rs b/crates/zng-wgt-toggle/src/lib.rs
index 45855b5a7..b494390e3 100644
--- a/crates/zng-wgt-toggle/src/lib.rs
+++ b/crates/zng-wgt-toggle/src/lib.rs
@@ -24,15 +24,15 @@ use zng_ext_input::{
 };
 use zng_ext_l10n::lang;
 use zng_var::{AnyVar, AnyVarValue, BoxedAnyVar, Var, VarIsReadOnlyError};
-use zng_wgt::{align, border, border_align, border_over, corner_radius, hit_test_mode, is_inited, prelude::*, Wgt, ICONS};
-use zng_wgt_access::{access_role, accessible, AccessRole};
+use zng_wgt::{ICONS, Wgt, align, border, border_align, border_over, corner_radius, hit_test_mode, is_inited, prelude::*};
+use zng_wgt_access::{AccessRole, access_role, accessible};
 use zng_wgt_container::{child_align, child_end, child_start, padding};
 use zng_wgt_fill::background_color;
 use zng_wgt_filter::opacity;
 use zng_wgt_input::{click_mode, is_hovered, pointer_capture::capture_pointer_on_init};
-use zng_wgt_layer::popup::{PopupState, POPUP};
+use zng_wgt_layer::popup::{POPUP, PopupState};
 use zng_wgt_size_offset::{size, x, y};
-use zng_wgt_style::{impl_style_fn, style_fn, Style};
+use zng_wgt_style::{Style, impl_style_fn, style_fn};
 
 pub mod cmd;
 
diff --git a/crates/zng-wgt-tooltip/Cargo.toml b/crates/zng-wgt-tooltip/Cargo.toml
index 9ddf1fb58..a3a66c468 100644
--- a/crates/zng-wgt-tooltip/Cargo.toml
+++ b/crates/zng-wgt-tooltip/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-tooltip"
 version = "0.5.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-tooltip/src/lib.rs b/crates/zng-wgt-tooltip/src/lib.rs
index 6c693ab28..83d68f4d3 100644
--- a/crates/zng-wgt-tooltip/src/lib.rs
+++ b/crates/zng-wgt-tooltip/src/lib.rs
@@ -15,7 +15,7 @@ use std::time::Duration;
 
 use zng_app::{
     access::ACCESS_TOOLTIP_EVENT,
-    widget::{info::INTERACTIVITY_CHANGED_EVENT, OnVarArgs},
+    widget::{OnVarArgs, info::INTERACTIVITY_CHANGED_EVENT},
 };
 use zng_ext_input::{
     focus::FOCUS_CHANGED_EVENT,
@@ -23,15 +23,15 @@ use zng_ext_input::{
     keyboard::KEY_INPUT_EVENT,
     mouse::{MOUSE, MOUSE_HOVERED_EVENT, MOUSE_INPUT_EVENT, MOUSE_WHEEL_EVENT},
 };
-use zng_wgt::{base_color, border, corner_radius, hit_test_mode, prelude::*, HitTestMode};
-use zng_wgt_access::{access_role, AccessRole};
+use zng_wgt::{HitTestMode, base_color, border, corner_radius, hit_test_mode, prelude::*};
+use zng_wgt_access::{AccessRole, access_role};
 use zng_wgt_container::padding;
 use zng_wgt_fill::background_color;
 use zng_wgt_layer::{
-    popup::{ContextCapture, Popup, PopupState, POPUP},
     AnchorMode,
+    popup::{ContextCapture, POPUP, Popup, PopupState},
 };
-use zng_wgt_style::{impl_style_fn, style_fn, Style};
+use zng_wgt_style::{Style, impl_style_fn, style_fn};
 
 /// Widget tooltip.
 ///
diff --git a/crates/zng-wgt-transform/Cargo.toml b/crates/zng-wgt-transform/Cargo.toml
index 126a59d67..4e8c6a77b 100644
--- a/crates/zng-wgt-transform/Cargo.toml
+++ b/crates/zng-wgt-transform/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-transform"
 version = "0.3.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-undo-history/Cargo.toml b/crates/zng-wgt-undo-history/Cargo.toml
index 12f893f8f..749dedbfa 100644
--- a/crates/zng-wgt-undo-history/Cargo.toml
+++ b/crates/zng-wgt-undo-history/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-undo-history"
 version = "0.4.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-undo-history/src/lib.rs b/crates/zng-wgt-undo-history/src/lib.rs
index 50af5a5cf..2c5cff77e 100644
--- a/crates/zng-wgt-undo-history/src/lib.rs
+++ b/crates/zng-wgt-undo-history/src/lib.rs
@@ -13,17 +13,17 @@ zng_wgt::enable_widget_macros!();
 
 use colors::BASE_COLOR_VAR;
 use zng_ext_input::gesture::ClickArgs;
-use zng_ext_l10n::{l10n, L10nArgument};
+use zng_ext_l10n::{L10nArgument, l10n};
 use zng_ext_undo::*;
 use zng_wgt::{base_color, margin, prelude::*};
 use zng_wgt_button::Button;
-use zng_wgt_container::{child_align, padding, Container};
+use zng_wgt_container::{Container, child_align, padding};
 use zng_wgt_fill::background_color;
 use zng_wgt_input::{is_cap_hovered, is_pressed};
 use zng_wgt_scroll::{Scroll, ScrollMode};
 use zng_wgt_size_offset::max_height;
 use zng_wgt_stack::{Stack, StackDirection};
-use zng_wgt_style::{style_fn, Style, StyleFn};
+use zng_wgt_style::{Style, StyleFn, style_fn};
 use zng_wgt_text::Text;
 
 use std::fmt;
diff --git a/crates/zng-wgt-undo/Cargo.toml b/crates/zng-wgt-undo/Cargo.toml
index e4279191c..71c25871d 100644
--- a/crates/zng-wgt-undo/Cargo.toml
+++ b/crates/zng-wgt-undo/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-undo"
 version = "0.3.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-webrender-debug/Cargo.toml b/crates/zng-wgt-webrender-debug/Cargo.toml
index d89dfe348..62848b45f 100644
--- a/crates/zng-wgt-webrender-debug/Cargo.toml
+++ b/crates/zng-wgt-webrender-debug/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-webrender-debug"
 version = "0.3.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-window/Cargo.toml b/crates/zng-wgt-window/Cargo.toml
index 407bbc9ed..e93fb57a9 100644
--- a/crates/zng-wgt-window/Cargo.toml
+++ b/crates/zng-wgt-window/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-window"
 version = "0.7.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-window/src/lib.rs b/crates/zng-wgt-window/src/lib.rs
index f38c98bde..dfbed02aa 100644
--- a/crates/zng-wgt-window/src/lib.rs
+++ b/crates/zng-wgt-window/src/lib.rs
@@ -21,9 +21,9 @@ use zng_var::types::ContextualizedVar;
 use zng_wgt::{is_mobile, prelude::*};
 use zng_wgt_fill::background_color;
 use zng_wgt_input::focus::{
-    directional_nav, focus_highlight, focus_scope, focus_scope_behavior, tab_nav, FOCUS_HIGHLIGHT_OFFSETS_VAR, FOCUS_HIGHLIGHT_WIDTHS_VAR,
+    FOCUS_HIGHLIGHT_OFFSETS_VAR, FOCUS_HIGHLIGHT_WIDTHS_VAR, directional_nav, focus_highlight, focus_scope, focus_scope_behavior, tab_nav,
 };
-use zng_wgt_text::{font_color, lang, FONT_SIZE_VAR};
+use zng_wgt_text::{FONT_SIZE_VAR, font_color, lang};
 
 pub mod events;
 mod window_properties;
diff --git a/crates/zng-wgt-window/src/window_properties.rs b/crates/zng-wgt-window/src/window_properties.rs
index a8bc857a1..c38f935ca 100644
--- a/crates/zng-wgt-window/src/window_properties.rs
+++ b/crates/zng-wgt-window/src/window_properties.rs
@@ -1,9 +1,9 @@
 use std::time::Duration;
 
-use zng_ext_config::{AnyConfig as _, ConfigKey, ConfigStatus, ConfigValue, CONFIG};
+use zng_ext_config::{AnyConfig as _, CONFIG, ConfigKey, ConfigStatus, ConfigValue};
 use zng_ext_window::{
-    AutoSize, FrameCaptureMode, MonitorQuery, WINDOW_Ext as _, WindowButton, WindowIcon, WindowLoadingHandle, WindowState, WindowVars,
-    MONITORS, WINDOWS, WINDOW_LOAD_EVENT,
+    AutoSize, FrameCaptureMode, MONITORS, MonitorQuery, WINDOW_Ext as _, WINDOW_LOAD_EVENT, WINDOWS, WindowButton, WindowIcon,
+    WindowLoadingHandle, WindowState, WindowVars,
 };
 use zng_wgt::prelude::*;
 
diff --git a/crates/zng-wgt-wrap/Cargo.toml b/crates/zng-wgt-wrap/Cargo.toml
index 4be526c40..56ecb70fa 100644
--- a/crates/zng-wgt-wrap/Cargo.toml
+++ b/crates/zng-wgt-wrap/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt-wrap"
 version = "0.4.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt-wrap/src/lib.rs b/crates/zng-wgt-wrap/src/lib.rs
index 472ec2b0f..131ec60d1 100644
--- a/crates/zng-wgt-wrap/src/lib.rs
+++ b/crates/zng-wgt-wrap/src/lib.rs
@@ -13,7 +13,7 @@ use std::sync::Arc;
 
 use crate_util::RecycleVec;
 use zng_app::widget::node::PanelListRange;
-use zng_ext_font::{unicode_bidi_levels, unicode_bidi_sort, BidiLevel};
+use zng_ext_font::{BidiLevel, unicode_bidi_levels, unicode_bidi_sort};
 use zng_layout::{
     context::{InlineConstraints, InlineConstraintsMeasure, InlineSegment, InlineSegmentPos, TextSegmentKind},
     unit::{GridSpacing, PxGridSpacing},
diff --git a/crates/zng-wgt/Cargo.toml b/crates/zng-wgt/Cargo.toml
index 98d6d3fea..ae4f8588f 100644
--- a/crates/zng-wgt/Cargo.toml
+++ b/crates/zng-wgt/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-wgt"
 version = "0.6.9"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Part of the zng project."
diff --git a/crates/zng-wgt/src/color_props.rs b/crates/zng-wgt/src/color_props.rs
index 2e095327a..3ddfc983d 100644
--- a/crates/zng-wgt/src/color_props.rs
+++ b/crates/zng-wgt/src/color_props.rs
@@ -1,6 +1,6 @@
 use zng_color::{
-    colors::{ACCENT_COLOR_VAR, BASE_COLOR_VAR},
     COLOR_SCHEME_VAR,
+    colors::{ACCENT_COLOR_VAR, BASE_COLOR_VAR},
 };
 
 use crate::prelude::*;
diff --git a/crates/zng-wgt/src/func.rs b/crates/zng-wgt/src/func.rs
index 29482a397..e969edc6b 100644
--- a/crates/zng-wgt/src/func.rs
+++ b/crates/zng-wgt/src/func.rs
@@ -83,11 +83,7 @@ impl<D> WidgetFn<D> {
     ///
     /// In the example above `a` and `b` are both calls to the widget function.
     pub fn call(&self, data: D) -> BoxedUiNode {
-        if let Some(g) = &self.0 {
-            g(data)
-        } else {
-            NilUiNode.boxed()
-        }
+        if let Some(g) = &self.0 { g(data) } else { NilUiNode.boxed() }
     }
 
     /// Calls the function with `data` argument and only returns a node if is not nil.
@@ -98,11 +94,7 @@ impl<D> WidgetFn<D> {
     /// [`UiNode::is_nil`]: zng_app::widget::node::UiNode::is_nil
     pub fn call_checked(&self, data: D) -> Option<BoxedUiNode> {
         let r = self.0.as_ref()?(data);
-        if r.is_nil() {
-            None
-        } else {
-            Some(r)
-        }
+        if r.is_nil() { None } else { Some(r) }
     }
 
     /// New widget function that returns the same `widget` for every call.
@@ -334,11 +326,7 @@ impl ICONS {
     /// if no handler can handle the request.
     pub fn get_or<U: UiNode>(&self, icon_name: impl IconNames, fallback: impl FnOnce() -> U) -> BoxedUiNode {
         let i = self.get(icon_name);
-        if i.is_nil() {
-            fallback().boxed()
-        } else {
-            i
-        }
+        if i.is_nil() { fallback().boxed() } else { i }
     }
 
     /// Same as [`get`], but also logs an error is there are no available icon for any of the names.
@@ -367,11 +355,7 @@ impl ICONS {
     /// [`get_or`]: Self::get_or
     pub fn req_or<U: UiNode>(&self, icon_name: impl IconNames, fallback: impl FnOnce() -> U) -> BoxedUiNode {
         let i = self.req(icon_name);
-        if i.is_nil() {
-            fallback().boxed()
-        } else {
-            i
-        }
+        if i.is_nil() { fallback().boxed() } else { i }
     }
 }
 
diff --git a/crates/zng-wgt/src/lib.rs b/crates/zng-wgt/src/lib.rs
index f6ad79935..ae04e4702 100644
--- a/crates/zng-wgt/src/lib.rs
+++ b/crates/zng-wgt/src/lib.rs
@@ -29,44 +29,44 @@ pub mod prelude {
 }
 mod __prelude {
     pub use zng_app::{
+        DInstant, Deadline, INSTANT,
         event::{
-            command, event, event_args, AnyEventArgs as _, Command, CommandHandle, CommandInfoExt as _, CommandNameExt as _, Event,
-            EventArgs as _, EventHandle, EventHandles, EventPropagationHandle,
+            AnyEventArgs as _, Command, CommandHandle, CommandInfoExt as _, CommandNameExt as _, Event, EventArgs as _, EventHandle,
+            EventHandles, EventPropagationHandle, command, event, event_args,
         },
-        handler::{app_hn, app_hn_once, async_app_hn, async_app_hn_once, async_hn, async_hn_once, hn, hn_once, AppHandler, WidgetHandler},
+        handler::{AppHandler, WidgetHandler, app_hn, app_hn_once, async_app_hn, async_app_hn_once, async_hn, async_hn_once, hn, hn_once},
         render::{FrameBuilder, FrameUpdate, FrameValue, FrameValueKey, FrameValueUpdate, SpatialFrameId, TransformStyle},
-        shortcut::{shortcut, CommandShortcutExt as _, Shortcut, ShortcutFilter, Shortcuts},
-        timer::{DeadlineHandle, DeadlineVar, TimerHandle, TimerVar, TIMERS},
-        update::{EventUpdate, UpdateDeliveryList, UpdateOp, WidgetUpdates, UPDATES},
+        shortcut::{CommandShortcutExt as _, Shortcut, ShortcutFilter, Shortcuts, shortcut},
+        timer::{DeadlineHandle, DeadlineVar, TIMERS, TimerHandle, TimerVar},
+        update::{EventUpdate, UPDATES, UpdateDeliveryList, UpdateOp, WidgetUpdates},
         widget::{
+            AnyVarSubscribe as _, VarLayout as _, VarSubscribe as _, WIDGET, WidgetId, WidgetUpdateMode,
             base::{WidgetBase, WidgetImpl},
-            border::{BorderSides, BorderStyle, CornerRadius, CornerRadiusFit, LineOrientation, LineStyle, BORDER},
-            builder::{property_id, NestGroup, WidgetBuilder, WidgetBuilding},
+            border::{BORDER, BorderSides, BorderStyle, CornerRadius, CornerRadiusFit, LineOrientation, LineStyle},
+            builder::{NestGroup, WidgetBuilder, WidgetBuilding, property_id},
             easing,
             info::{
                 InteractionPath, Interactivity, Visibility, WidgetBorderInfo, WidgetBoundsInfo, WidgetInfo, WidgetInfoBuilder,
                 WidgetLayout, WidgetMeasure, WidgetPath,
             },
             node::{
-                match_node, match_node_leaf, match_node_list, match_node_typed, match_widget, ui_vec, ArcNode, ArcNodeList, BoxedUiNode,
-                BoxedUiNodeList, EditableUiNodeList, EditableUiNodeListRef, FillUiNode, NilUiNode, PanelList, PanelListData as _,
-                SortingList, UiNode, UiNodeList, UiNodeListChain as _, UiNodeListObserver, UiNodeOp, UiVec, ZIndex, SORTING_LIST,
+                ArcNode, ArcNodeList, BoxedUiNode, BoxedUiNodeList, EditableUiNodeList, EditableUiNodeListRef, FillUiNode, NilUiNode,
+                PanelList, PanelListData as _, SORTING_LIST, SortingList, UiNode, UiNodeList, UiNodeListChain as _, UiNodeListObserver,
+                UiNodeOp, UiVec, ZIndex, match_node, match_node_leaf, match_node_list, match_node_typed, match_widget, ui_vec,
             },
-            property, ui_node, widget, widget_impl, widget_mixin, widget_set, AnyVarSubscribe as _, VarLayout as _, VarSubscribe as _,
-            WidgetId, WidgetUpdateMode, WIDGET,
+            property, ui_node, widget, widget_impl, widget_mixin, widget_set,
         },
-        window::{MonitorId, WindowId, WINDOW},
-        DInstant, Deadline, INSTANT,
+        window::{MonitorId, WINDOW, WindowId},
     };
 
     pub use zng_var::{
-        context_var, expr_var, impl_from_and_into_var, merge_var, response_done_var, response_var, state_var, var, var_from, when_var,
         AnyVar as _, AnyWeakVar as _, ArcVar, BoxedVar, ContextVar, IntoValue, IntoVar, LocalVar, ObservableVec, ReadOnlyArcVar,
-        ResponderVar, ResponseVar, Var, VarCapability, VarHandle, VarHandles, VarUpdateId, VarValue, WeakVar as _,
+        ResponderVar, ResponseVar, Var, VarCapability, VarHandle, VarHandles, VarUpdateId, VarValue, WeakVar as _, context_var, expr_var,
+        impl_from_and_into_var, merge_var, response_done_var, response_var, state_var, var, var_from, when_var,
     };
 
     pub use zng_layout::{
-        context::{LayoutDirection, LayoutMetrics, DIRECTION_VAR, LAYOUT},
+        context::{DIRECTION_VAR, LAYOUT, LayoutDirection, LayoutMetrics},
         unit::{
             Align, AngleDegree, AngleGradian, AngleRadian, AngleUnits as _, ByteUnits as _, Dip, DipBox, DipPoint, DipRect, DipSideOffsets,
             DipSize, DipToPx as _, DipVector, Factor, Factor2d, FactorPercent, FactorSideOffsets, FactorUnits as _, Layout1d as _,
@@ -76,21 +76,21 @@ mod __prelude {
         },
     };
 
-    pub use zng_txt::{formatx, ToTxt, Txt};
+    pub use zng_txt::{ToTxt, Txt, formatx};
 
     pub use zng_clone_move::{async_clmv, async_clmv_fn, async_clmv_fn_once, clmv};
 
     pub use zng_task as task;
 
-    pub use zng_app_context::{app_local, context_local, CaptureFilter, ContextLocal, ContextValueSet, LocalContext, RunOnDrop};
+    pub use zng_app_context::{CaptureFilter, ContextLocal, ContextValueSet, LocalContext, RunOnDrop, app_local, context_local};
 
-    pub use zng_state_map::{state_map, static_id, OwnedStateMap, StateId, StateMapMut, StateMapRef};
+    pub use zng_state_map::{OwnedStateMap, StateId, StateMapMut, StateMapRef, state_map, static_id};
 
     pub use zng_unique_id::{IdEntry, IdMap, IdSet};
 
     pub use zng_color::{
-        colors, gradient, hex, hsl, hsla, hsv, hsva, light_dark, rgb, rgba, web_colors, ColorScheme, Hsla, Hsva, LightDark,
-        LightDarkVarExt as _, MixAdjust as _, MixBlendMode, Rgba,
+        ColorScheme, Hsla, Hsva, LightDark, LightDarkVarExt as _, MixAdjust as _, MixBlendMode, Rgba, colors, gradient, hex, hsl, hsla,
+        hsv, hsva, light_dark, rgb, rgba, web_colors,
     };
 
     pub use crate::node::{
@@ -99,7 +99,7 @@ mod __prelude {
         with_context_local_init, with_context_var, with_context_var_init, with_widget_state, with_widget_state_modify,
     };
 
-    pub use crate::{wgt_fn, CommandIconExt as _, WidgetFn};
+    pub use crate::{CommandIconExt as _, WidgetFn, wgt_fn};
 }
 
 pub mod node;
diff --git a/crates/zng-wgt/src/node.rs b/crates/zng-wgt/src/node.rs
index e8276f754..eba7125ee 100644
--- a/crates/zng-wgt/src/node.rs
+++ b/crates/zng-wgt/src/node.rs
@@ -13,10 +13,10 @@ use zng_app::{
     render::{FrameBuilder, FrameValueKey},
     update::WidgetUpdates,
     widget::{
+        VarLayout, WIDGET, WidgetUpdateMode,
         border::{BORDER, BORDER_ALIGN_VAR, BORDER_OVER_VAR},
         info::Interactivity,
         node::*,
-        VarLayout, WidgetUpdateMode, WIDGET,
     },
     window::WINDOW,
 };
@@ -2356,8 +2356,8 @@ where
     }
 }
 
+use crate::WidgetFn;
 #[doc(inline)]
 pub use crate::command_property;
 #[doc(inline)]
 pub use crate::event_property;
-use crate::WidgetFn;
diff --git a/crates/zng-wgt/src/parallel_prop.rs b/crates/zng-wgt/src/parallel_prop.rs
index da5d15b74..03725cbf1 100644
--- a/crates/zng-wgt/src/parallel_prop.rs
+++ b/crates/zng-wgt/src/parallel_prop.rs
@@ -1,4 +1,4 @@
-use zng_app::widget::base::{Parallel, PARALLEL_VAR};
+use zng_app::widget::base::{PARALLEL_VAR, Parallel};
 
 use crate::prelude::*;
 
diff --git a/crates/zng/Cargo.toml b/crates/zng/Cargo.toml
index 7f3381483..8596798d5 100644
--- a/crates/zng/Cargo.toml
+++ b/crates/zng/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng"
 version = "0.13.12"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 license = "Apache-2.0 OR MIT"
 readme = "README.md"
 description = "Cross-platform GUI framework."
diff --git a/crates/zng/src/access.rs b/crates/zng/src/access.rs
index b153f5c68..356a973d8 100644
--- a/crates/zng/src/access.rs
+++ b/crates/zng/src/access.rs
@@ -133,16 +133,17 @@
 //! See [`zng_app::access`] and [`zng_wgt_access`] for the full API.
 
 pub use zng_app::access::{
-    AccessClickArgs, AccessExpanderArgs, AccessIncrementArgs, AccessInitedArgs, AccessNumberArgs, AccessScrollArgs, AccessSelectionArgs,
-    AccessTextArgs, AccessToolTipArgs, ScrollCmd, ACCESS, ACCESS_CLICK_EVENT, ACCESS_EXPANDER_EVENT, ACCESS_INCREMENT_EVENT,
-    ACCESS_INITED_EVENT, ACCESS_NUMBER_EVENT, ACCESS_SCROLL_EVENT, ACCESS_SELECTION_EVENT, ACCESS_TEXT_EVENT, ACCESS_TOOLTIP_EVENT,
+    ACCESS, ACCESS_CLICK_EVENT, ACCESS_EXPANDER_EVENT, ACCESS_INCREMENT_EVENT, ACCESS_INITED_EVENT, ACCESS_NUMBER_EVENT,
+    ACCESS_SCROLL_EVENT, ACCESS_SELECTION_EVENT, ACCESS_TEXT_EVENT, ACCESS_TOOLTIP_EVENT, AccessClickArgs, AccessExpanderArgs,
+    AccessIncrementArgs, AccessInitedArgs, AccessNumberArgs, AccessScrollArgs, AccessSelectionArgs, AccessTextArgs, AccessToolTipArgs,
+    ScrollCmd,
 };
 pub use zng_wgt_access::{
-    access_commands, access_role, accessible, active_descendant, auto_complete, checked, col_count, col_index, col_span, controls, current,
-    described_by, details, error_message, expanded, flows_to, invalid, item_count, item_index, label, labelled_by, labelled_by_child,
-    level, live, modal, multi_selectable, on_access_click, on_access_expander, on_access_increment, on_access_number, on_access_scroll,
-    on_access_selection, on_access_text, on_access_tooltip, on_pre_access_click, on_pre_access_expander, on_pre_access_increment,
-    on_pre_access_number, on_pre_access_scroll, on_pre_access_selection, on_pre_access_text, on_pre_access_tooltip, orientation, owns,
-    placeholder, popup, read_only, required, row_count, row_index, row_span, scroll_horizontal, scroll_vertical, selected, sort, value,
-    value_max, value_min, AccessCmdName, AccessRole, AutoComplete, CurrentKind, Invalid, LiveIndicator, Orientation, Popup, SortDirection,
+    AccessCmdName, AccessRole, AutoComplete, CurrentKind, Invalid, LiveIndicator, Orientation, Popup, SortDirection, access_commands,
+    access_role, accessible, active_descendant, auto_complete, checked, col_count, col_index, col_span, controls, current, described_by,
+    details, error_message, expanded, flows_to, invalid, item_count, item_index, label, labelled_by, labelled_by_child, level, live, modal,
+    multi_selectable, on_access_click, on_access_expander, on_access_increment, on_access_number, on_access_scroll, on_access_selection,
+    on_access_text, on_access_tooltip, on_pre_access_click, on_pre_access_expander, on_pre_access_increment, on_pre_access_number,
+    on_pre_access_scroll, on_pre_access_selection, on_pre_access_text, on_pre_access_tooltip, orientation, owns, placeholder, popup,
+    read_only, required, row_count, row_index, row_span, scroll_horizontal, scroll_vertical, selected, sort, value, value_max, value_min,
 };
diff --git a/crates/zng/src/app.rs b/crates/zng/src/app.rs
index 0b4e519c1..95cfdca00 100644
--- a/crates/zng/src/app.rs
+++ b/crates/zng/src/app.rs
@@ -400,23 +400,23 @@
 //! may be available at the [`zng_app`], [`zng_app_context`] and [`zng_ext_single_instance`] base crates.
 
 pub use zng_app::{
-    on_app_start, print_tracing, print_tracing_filter, AppControlFlow, AppEventObserver, AppExtended, AppExtension, AppExtensionBoxed,
-    AppExtensionInfo, AppStartArgs, DInstant, Deadline, ExitRequestedArgs, HeadlessApp, InstantMode, EXIT_CMD, EXIT_REQUESTED_EVENT,
-    INSTANT,
+    AppControlFlow, AppEventObserver, AppExtended, AppExtension, AppExtensionBoxed, AppExtensionInfo, AppStartArgs, DInstant, Deadline,
+    EXIT_CMD, EXIT_REQUESTED_EVENT, ExitRequestedArgs, HeadlessApp, INSTANT, InstantMode, on_app_start, print_tracing,
+    print_tracing_filter,
 };
 
 #[cfg(feature = "test_util")]
 pub use zng_app::test_log;
 
 pub use zng_app_context::{
-    app_local, context_local, AppId, AppLocal, AppScope, CaptureFilter, ContextLocal, ContextValueSet, LocalContext,
-    MappedRwLockReadGuardOwned, MappedRwLockWriteGuardOwned, ReadOnlyRwLock, RunOnDrop, RwLockReadGuardOwned, RwLockWriteGuardOwned,
+    AppId, AppLocal, AppScope, CaptureFilter, ContextLocal, ContextValueSet, LocalContext, MappedRwLockReadGuardOwned,
+    MappedRwLockWriteGuardOwned, ReadOnlyRwLock, RunOnDrop, RwLockReadGuardOwned, RwLockWriteGuardOwned, app_local, context_local,
 };
 pub use zng_wgt_input::cmd::{
-    on_new, on_open, on_pre_new, on_pre_open, on_pre_save, on_pre_save_as, on_save, on_save_as, NEW_CMD, OPEN_CMD, SAVE_AS_CMD, SAVE_CMD,
+    NEW_CMD, OPEN_CMD, SAVE_AS_CMD, SAVE_CMD, on_new, on_open, on_pre_new, on_pre_open, on_pre_save, on_pre_save_as, on_save, on_save_as,
 };
 
-pub use zng_app::view_process::raw_events::{LowMemoryArgs, LOW_MEMORY_EVENT};
+pub use zng_app::view_process::raw_events::{LOW_MEMORY_EVENT, LowMemoryArgs};
 
 /// Input device hardware ID and events.
 ///
@@ -425,12 +425,12 @@ pub use zng_app::view_process::raw_events::{LowMemoryArgs, LOW_MEMORY_EVENT};
 /// See [`zng_app::view_process::raw_device_events`] for the full API.
 pub mod raw_device_events {
     pub use zng_app::view_process::raw_device_events::{
-        DeviceArgs, DeviceId, MotionArgs, DEVICE_ADDED_EVENT, DEVICE_REMOVED_EVENT, MOTION_EVENT,
+        DEVICE_ADDED_EVENT, DEVICE_REMOVED_EVENT, DeviceArgs, DeviceId, MOTION_EVENT, MotionArgs,
     };
 }
 
 #[cfg(single_instance)]
-pub use zng_ext_single_instance::{AppInstanceArgs, APP_INSTANCE_EVENT};
+pub use zng_ext_single_instance::{APP_INSTANCE_EVENT, AppInstanceArgs};
 
 /// App-process crash handler.
 ///
@@ -549,7 +549,7 @@ pub use zng_ext_single_instance::{AppInstanceArgs, APP_INSTANCE_EVENT};
 /// See [`zng_app::crash_handler`] and [`zng_wgt_inspector::crash_handler`] for the full API.
 #[cfg(crash_handler)]
 pub mod crash_handler {
-    pub use zng_app::crash_handler::{crash_handler_config, BacktraceFrame, CrashArgs, CrashConfig, CrashError, CrashPanic};
+    pub use zng_app::crash_handler::{BacktraceFrame, CrashArgs, CrashConfig, CrashError, CrashPanic, crash_handler_config};
 
     #[cfg(feature = "crash_handler_debug")]
     pub use zng_wgt_inspector::crash_handler::debug_dialog;
diff --git a/crates/zng/src/button.rs b/crates/zng/src/button.rs
index 253e0db5c..ca96f495d 100644
--- a/crates/zng/src/button.rs
+++ b/crates/zng/src/button.rs
@@ -120,4 +120,4 @@
 //!
 //! See [`zng_wgt_button`] for the full widget API.
 
-pub use zng_wgt_button::{style_fn, Button, DefaultStyle, LightStyle, LinkStyle, PrimaryStyle, BUTTON};
+pub use zng_wgt_button::{BUTTON, Button, DefaultStyle, LightStyle, LinkStyle, PrimaryStyle, style_fn};
diff --git a/crates/zng/src/checkerboard.rs b/crates/zng/src/checkerboard.rs
index ec0f73ffe..c84ad239a 100644
--- a/crates/zng/src/checkerboard.rs
+++ b/crates/zng/src/checkerboard.rs
@@ -25,4 +25,4 @@
 //!
 //! See [`zng_wgt_checkerboard`] for the full widget API.
 
-pub use zng_wgt_checkerboard::{cb_origin, cb_size, colors, Checkerboard, Colors};
+pub use zng_wgt_checkerboard::{Checkerboard, Colors, cb_origin, cb_size, colors};
diff --git a/crates/zng/src/clipboard.rs b/crates/zng/src/clipboard.rs
index f267fb0a1..4318c18c5 100644
--- a/crates/zng/src/clipboard.rs
+++ b/crates/zng/src/clipboard.rs
@@ -107,5 +107,5 @@
 //!
 //! See [`zng_ext_clipboard`] for the full clipboard API.
 
-pub use zng_ext_clipboard::{ClipboardError, CLIPBOARD, COPY_CMD, CUT_CMD, PASTE_CMD};
+pub use zng_ext_clipboard::{CLIPBOARD, COPY_CMD, CUT_CMD, ClipboardError, PASTE_CMD};
 pub use zng_wgt_input::cmd::{on_copy, on_cut, on_paste, on_pre_copy, on_pre_cut, on_pre_paste};
diff --git a/crates/zng/src/color.rs b/crates/zng/src/color.rs
index 52ecb92e0..dd8ba0210 100644
--- a/crates/zng/src/color.rs
+++ b/crates/zng/src/color.rs
@@ -105,9 +105,9 @@
 //! See [`zng_color`], [`zng_wgt_filter`] and [`zng_wgt_fill`] for the full API.
 
 pub use zng_color::{
-    colors, hex, hsl, hsla, hsla_linear_sampler, hsla_sampler, hsv, hsva, lerp_space, light_dark, rgb, rgba, rgba_sampler, web_colors,
-    with_lerp_space, ColorScheme, Hsla, Hsva, LerpSpace, LightDark, LightDarkVarExt, MixAdjust, MixBlendMode, PreMulRgba,
-    RenderMixBlendMode, Rgba, COLOR_SCHEME_VAR,
+    COLOR_SCHEME_VAR, ColorScheme, Hsla, Hsva, LerpSpace, LightDark, LightDarkVarExt, MixAdjust, MixBlendMode, PreMulRgba,
+    RenderMixBlendMode, Rgba, colors, hex, hsl, hsla, hsla_linear_sampler, hsla_sampler, hsv, hsva, lerp_space, light_dark, rgb, rgba,
+    rgba_sampler, web_colors, with_lerp_space,
 };
 
 pub use zng_wgt::{accent_color, base_color, color_scheme};
@@ -130,12 +130,12 @@ pub mod filter {
 /// Color gradient types and nodes.
 pub mod gradient {
     pub use zng_color::gradient::{
-        stops, ColorStop, ExtendMode, GradientRadius, GradientRadiusBase, GradientStop, GradientStops, LinearGradientAxis,
-        RenderExtendMode, RenderGradientStop,
+        ColorStop, ExtendMode, GradientRadius, GradientRadiusBase, GradientStop, GradientStops, LinearGradientAxis, RenderExtendMode,
+        RenderGradientStop, stops,
     };
 
     pub use zng_wgt_fill::node::{
-        conic_gradient, gradient, linear_gradient, radial_gradient, ConicGradient, GradientBuilder, LinearGradient, RadialGradient,
-        TiledConicGradient, TiledLinearGradient, TiledRadialGradient,
+        ConicGradient, GradientBuilder, LinearGradient, RadialGradient, TiledConicGradient, TiledLinearGradient, TiledRadialGradient,
+        conic_gradient, gradient, linear_gradient, radial_gradient,
     };
 }
diff --git a/crates/zng/src/config.rs b/crates/zng/src/config.rs
index 9507d1179..bc586e5cb 100644
--- a/crates/zng/src/config.rs
+++ b/crates/zng/src/config.rs
@@ -90,12 +90,12 @@
 //! See [`zng_ext_config`] for the full config API.
 
 pub use zng_ext_config::{
-    AnyConfig, Config, ConfigKey, ConfigStatus, ConfigValue, FallbackConfig, FallbackConfigReset, JsonConfig, MemoryConfig, RawConfigValue,
-    ReadOnlyConfig, SwapConfig, SwitchConfig, CONFIG,
+    AnyConfig, CONFIG, Config, ConfigKey, ConfigStatus, ConfigValue, FallbackConfig, FallbackConfigReset, JsonConfig, MemoryConfig,
+    RawConfigValue, ReadOnlyConfig, SwapConfig, SwitchConfig,
 };
 
 #[cfg(feature = "window")]
-pub use zng_wgt_window::{save_state_node, SaveState};
+pub use zng_wgt_window::{SaveState, save_state_node};
 
 #[cfg(feature = "ron")]
 pub use zng_ext_config::RonConfig;
@@ -113,9 +113,9 @@ pub use zng_ext_config::YamlConfig;
 /// See [`zng_ext_config::settings`] for the full settings API.
 pub mod settings {
     pub use zng_ext_config::settings::{
-        CategoriesBuilder, Category, CategoryBuilder, CategoryId, Setting, SettingBuilder, SettingsBuilder, SETTINGS,
+        CategoriesBuilder, Category, CategoryBuilder, CategoryId, SETTINGS, Setting, SettingBuilder, SettingsBuilder,
     };
-    pub use zng_wgt_input::cmd::{on_pre_settings, on_settings, SETTINGS_CMD};
+    pub use zng_wgt_input::cmd::{SETTINGS_CMD, on_pre_settings, on_settings};
 
     /// Settings editor widget.
     ///
@@ -125,8 +125,8 @@ pub mod settings {
     #[cfg(feature = "settings_editor")]
     pub mod editor {
         pub use zng_wgt_settings::{
-            categories_list_fn, category_header_fn, category_item_fn, setting_fn, settings_fn, CategoriesListArgs, CategoryHeaderArgs,
-            CategoryItemArgs, SettingArgs, SettingBuilderEditorExt, SettingsArgs, SettingsCtxExt, SettingsEditor,
+            CategoriesListArgs, CategoryHeaderArgs, CategoryItemArgs, SettingArgs, SettingBuilderEditorExt, SettingsArgs, SettingsCtxExt,
+            SettingsEditor, categories_list_fn, category_header_fn, category_item_fn, setting_fn, settings_fn,
         };
     }
 }
diff --git a/crates/zng/src/container.rs b/crates/zng/src/container.rs
index d5625f31e..79f69b705 100644
--- a/crates/zng/src/container.rs
+++ b/crates/zng/src/container.rs
@@ -88,6 +88,6 @@
 //! See [`zng_wgt_container`] for the full widget API.
 
 pub use zng_wgt_container::{
-    child, child_bottom, child_end, child_insert, child_left, child_out_bottom, child_out_end, child_out_insert, child_out_left,
-    child_out_right, child_out_start, child_out_top, child_over, child_right, child_start, child_top, child_under, ChildInsert, Container,
+    ChildInsert, Container, child, child_bottom, child_end, child_insert, child_left, child_out_bottom, child_out_end, child_out_insert,
+    child_out_left, child_out_right, child_out_start, child_out_top, child_over, child_right, child_start, child_top, child_under,
 };
diff --git a/crates/zng/src/data_context.rs b/crates/zng/src/data_context.rs
index d7dd1731e..e3955b13d 100644
--- a/crates/zng/src/data_context.rs
+++ b/crates/zng/src/data_context.rs
@@ -119,8 +119,8 @@
 //! See [`zng_wgt_data`] for the full API.
 
 pub use zng_wgt_data::{
-    data, data_error, data_error_color, data_info, data_info_color, data_note, data_warn, data_warn_color, extend_data_note_colors,
-    get_data_error, get_data_error_txt, get_data_info, get_data_info_txt, get_data_notes, get_data_notes_top, get_data_warn,
-    get_data_warn_txt, has_data_error, has_data_info, has_data_notes, has_data_warn, replace_data_note_colors, with_data_note_color,
-    DataNote, DataNoteHandle, DataNoteLevel, DataNoteValue, DataNotes, DATA,
+    DATA, DataNote, DataNoteHandle, DataNoteLevel, DataNoteValue, DataNotes, data, data_error, data_error_color, data_info,
+    data_info_color, data_note, data_warn, data_warn_color, extend_data_note_colors, get_data_error, get_data_error_txt, get_data_info,
+    get_data_info_txt, get_data_notes, get_data_notes_top, get_data_warn, get_data_warn_txt, has_data_error, has_data_info, has_data_notes,
+    has_data_warn, replace_data_note_colors, with_data_note_color,
 };
diff --git a/crates/zng/src/dialog.rs b/crates/zng/src/dialog.rs
index 0a2d626d6..aad2a24a6 100644
--- a/crates/zng/src/dialog.rs
+++ b/crates/zng/src/dialog.rs
@@ -84,8 +84,8 @@
 //! See [`zng_wgt_dialog`] for the full view API.
 
 pub use zng_wgt_dialog::{
-    native_dialogs, AskStyle, ConfirmStyle, DefaultStyle, Dialog, DialogButtonArgs, DialogKind, ErrorStyle, FileDialogFilters,
-    FileDialogResponse, InfoStyle, Response, Responses, WarnStyle, DIALOG,
+    AskStyle, ConfirmStyle, DIALOG, DefaultStyle, Dialog, DialogButtonArgs, DialogKind, ErrorStyle, FileDialogFilters, FileDialogResponse,
+    InfoStyle, Response, Responses, WarnStyle, native_dialogs,
 };
 
 /// Modal dialog parent widget that fills the window.
@@ -117,5 +117,5 @@ pub use zng_wgt_dialog::{
 ///
 /// See [`zng_wgt_dialog::backdrop`] for the fill view API.
 pub mod backdrop {
-    pub use zng_wgt_dialog::backdrop::{style_fn, DefaultStyle};
+    pub use zng_wgt_dialog::backdrop::{DefaultStyle, style_fn};
 }
diff --git a/crates/zng/src/drag_drop.rs b/crates/zng/src/drag_drop.rs
index d829bbfd4..7b9e8d0a9 100644
--- a/crates/zng/src/drag_drop.rs
+++ b/crates/zng/src/drag_drop.rs
@@ -53,8 +53,8 @@
 //! See [`zng_ext_input::drag_drop`] and [`zng_wgt_input::drag_drop`] for the full drag&drop API.
 
 pub use zng_ext_input::drag_drop::{
-    DragDropData, DragDropEffect, DragEndArgs, DragHandle, DragHoveredArgs, DragMoveArgs, DragStartArgs, DropArgs, WeakDragHandle,
-    DRAG_DROP, DRAG_END_EVENT, DRAG_HOVERED_EVENT, DRAG_MOVE_EVENT, DRAG_START_EVENT, DROP_EVENT,
+    DRAG_DROP, DRAG_END_EVENT, DRAG_HOVERED_EVENT, DRAG_MOVE_EVENT, DRAG_START_EVENT, DROP_EVENT, DragDropData, DragDropEffect,
+    DragEndArgs, DragHandle, DragHoveredArgs, DragMoveArgs, DragStartArgs, DropArgs, WeakDragHandle,
 };
 
 pub use zng_wgt_input::drag_drop::{
diff --git a/crates/zng/src/env.rs b/crates/zng/src/env.rs
index 97c3e8643..1a08296bb 100644
--- a/crates/zng/src/env.rs
+++ b/crates/zng/src/env.rs
@@ -35,8 +35,8 @@
 //! See [`zng_env`] for the full API.
 
 pub use zng_env::{
-    about, bin, cache, clear_cache, config, exit, init, init_cache, init_config, init_res, migrate_cache, migrate_config, on_process_exit,
-    on_process_start, res, About, ProcessExitArgs, ProcessStartArgs,
+    About, ProcessExitArgs, ProcessStartArgs, about, bin, cache, clear_cache, config, exit, init, init_cache, init_config, init_res,
+    migrate_cache, migrate_config, on_process_exit, on_process_start, res,
 };
 
 #[cfg(target_os = "android")]
diff --git a/crates/zng/src/event.rs b/crates/zng/src/event.rs
index 2581e05e8..db19a2e7c 100644
--- a/crates/zng/src/event.rs
+++ b/crates/zng/src/event.rs
@@ -322,8 +322,8 @@
 //! See [`zng_app::event`] for the full event API.
 
 pub use zng_app::event::{
-    command, event, event_args, AnyEvent, AnyEventArgs, AppCommandArgs, Command, CommandArgs, CommandHandle, CommandInfoExt, CommandMeta,
-    CommandMetaVar, CommandMetaVarId, CommandNameExt, CommandParam, CommandScope, Event, EventArgs, EventHandle, EventHandles,
-    EventPropagationHandle, EventReceiver, EVENTS,
+    AnyEvent, AnyEventArgs, AppCommandArgs, Command, CommandArgs, CommandHandle, CommandInfoExt, CommandMeta, CommandMetaVar,
+    CommandMetaVarId, CommandNameExt, CommandParam, CommandScope, EVENTS, Event, EventArgs, EventHandle, EventHandles,
+    EventPropagationHandle, EventReceiver, command, event, event_args,
 };
 pub use zng_wgt::node::{command_property, event_property, on_command, on_event, on_pre_command, on_pre_event};
diff --git a/crates/zng/src/focus.rs b/crates/zng/src/focus.rs
index ebde8384c..8d90f7270 100644
--- a/crates/zng/src/focus.rs
+++ b/crates/zng/src/focus.rs
@@ -131,13 +131,13 @@
 //! See [`zng_ext_input::focus`] and [`zng_wgt_input::focus`] for the full focus API.
 
 pub use zng_ext_input::focus::{
-    cmd, iter, DirectionalNav, FocusChangedArgs, FocusChangedCause, FocusInfo, FocusInfoBuilder, FocusInfoTree, FocusNavAction,
-    FocusRequest, FocusScopeOnFocus, FocusTarget, ReturnFocusChangedArgs, TabIndex, TabNav, WidgetFocusInfo, WidgetInfoFocusExt, FOCUS,
-    FOCUS_CHANGED_EVENT, RETURN_FOCUS_CHANGED_EVENT,
+    DirectionalNav, FOCUS, FOCUS_CHANGED_EVENT, FocusChangedArgs, FocusChangedCause, FocusInfo, FocusInfoBuilder, FocusInfoTree,
+    FocusNavAction, FocusRequest, FocusScopeOnFocus, FocusTarget, RETURN_FOCUS_CHANGED_EVENT, ReturnFocusChangedArgs, TabIndex, TabNav,
+    WidgetFocusInfo, WidgetInfoFocusExt, cmd, iter,
 };
 pub use zng_wgt_input::focus::{
-    alt_focus_scope, directional_nav, focus_click_behavior, focus_highlight, focus_on_init, focus_scope, focus_scope_behavior,
-    focus_shortcut, focusable, is_focus_within, is_focus_within_hgl, is_focused, is_focused_hgl, is_return_focus, is_return_focus_within,
-    on_blur, on_focus, on_focus_changed, on_focus_enter, on_focus_leave, on_pre_blur, on_pre_focus, on_pre_focus_changed,
-    on_pre_focus_enter, on_pre_focus_leave, return_focus_on_deinit, skip_directional, tab_index, tab_nav, FocusClickBehavior, FocusableMix,
+    FocusClickBehavior, FocusableMix, alt_focus_scope, directional_nav, focus_click_behavior, focus_highlight, focus_on_init, focus_scope,
+    focus_scope_behavior, focus_shortcut, focusable, is_focus_within, is_focus_within_hgl, is_focused, is_focused_hgl, is_return_focus,
+    is_return_focus_within, on_blur, on_focus, on_focus_changed, on_focus_enter, on_focus_leave, on_pre_blur, on_pre_focus,
+    on_pre_focus_changed, on_pre_focus_enter, on_pre_focus_leave, return_focus_on_deinit, skip_directional, tab_index, tab_nav,
 };
diff --git a/crates/zng/src/font.rs b/crates/zng/src/font.rs
index b46df702c..6a0db4fa2 100644
--- a/crates/zng/src/font.rs
+++ b/crates/zng/src/font.rs
@@ -160,11 +160,11 @@
 //! See [`zng_ext_font`] for the full font and shaping API.
 
 pub use zng_ext_font::{
-    font_features, unicode_bidi_levels, unicode_bidi_sort, BidiLevel, CaretIndex, ColorGlyph, ColorGlyphs, ColorPalette, ColorPaletteType,
-    ColorPalettes, CustomFont, Font, FontChange, FontChangedArgs, FontColorPalette, FontDataRef, FontFace, FontFaceList, FontFaceMetrics,
-    FontList, FontMetrics, FontName, FontNames, FontSize, FontStretch, FontStyle, FontWeight, HyphenationDataDir, HyphenationDataSource,
-    Hyphens, Justify, LayoutDirections, LetterSpacing, LineBreak, LineHeight, LineSpacing, OutlineSink, ParagraphSpacing, SegmentedText,
+    BidiLevel, CaretIndex, ColorGlyph, ColorGlyphs, ColorPalette, ColorPaletteType, ColorPalettes, CustomFont, FONT_CHANGED_EVENT, FONTS,
+    Font, FontChange, FontChangedArgs, FontColorPalette, FontDataRef, FontFace, FontFaceList, FontFaceMetrics, FontList, FontMetrics,
+    FontName, FontNames, FontSize, FontStretch, FontStyle, FontWeight, HYPHENATION, HyphenationDataDir, HyphenationDataSource, Hyphens,
+    Justify, LayoutDirections, LetterSpacing, LineBreak, LineHeight, LineSpacing, OutlineSink, ParagraphSpacing, SegmentedText,
     SegmentedTextIter, ShapedColoredGlyphs, ShapedLine, ShapedSegment, ShapedText, TabLength, TextLineThickness, TextOverflowInfo,
-    TextSegment, TextSegmentKind, TextShapingArgs, TextTransformFn, UnderlineThickness, WhiteSpace, WordBreak, WordSpacing, FONTS,
-    FONT_CHANGED_EVENT, HYPHENATION,
+    TextSegment, TextSegmentKind, TextShapingArgs, TextTransformFn, UnderlineThickness, WhiteSpace, WordBreak, WordSpacing, font_features,
+    unicode_bidi_levels, unicode_bidi_sort,
 };
diff --git a/crates/zng/src/fs_watcher.rs b/crates/zng/src/fs_watcher.rs
index 47905ef99..3776e1eb9 100644
--- a/crates/zng/src/fs_watcher.rs
+++ b/crates/zng/src/fs_watcher.rs
@@ -61,6 +61,6 @@
 //! See [`zng_ext_fs_watcher`] for the full watcher API.
 
 pub use zng_ext_fs_watcher::{
-    fs_event, FsChange, FsChangeNote, FsChangeNoteHandle, FsChangesArgs, WatchFile, WatcherHandle, WatcherReadStatus, WatcherSyncStatus,
-    WriteFile, FS_CHANGES_EVENT, WATCHER,
+    FS_CHANGES_EVENT, FsChange, FsChangeNote, FsChangeNoteHandle, FsChangesArgs, WATCHER, WatchFile, WatcherHandle, WatcherReadStatus,
+    WatcherSyncStatus, WriteFile, fs_event,
 };
diff --git a/crates/zng/src/gesture.rs b/crates/zng/src/gesture.rs
index f47da024a..623364859 100644
--- a/crates/zng/src/gesture.rs
+++ b/crates/zng/src/gesture.rs
@@ -35,12 +35,12 @@
 //! [`zng_app::shortcut`]: mod@zng_app::shortcut
 
 pub use zng_ext_input::gesture::{
-    ClickArgs, ClickArgsSource, CommandShortcutMatchesExt, HeadlessAppGestureExt, ShortcutActions, ShortcutArgs, ShortcutClick,
-    ShortcutsHandle, WeakShortcutsHandle, CLICK_EVENT, GESTURES, SHORTCUT_EVENT,
+    CLICK_EVENT, ClickArgs, ClickArgsSource, CommandShortcutMatchesExt, GESTURES, HeadlessAppGestureExt, SHORTCUT_EVENT, ShortcutActions,
+    ShortcutArgs, ShortcutClick, ShortcutsHandle, WeakShortcutsHandle,
 };
 
 pub use zng_app::shortcut::{
-    shortcut, CommandShortcutExt, GestureKey, KeyChord, KeyGesture, ModifierGesture, Shortcut, ShortcutFilter, Shortcuts,
+    CommandShortcutExt, GestureKey, KeyChord, KeyGesture, ModifierGesture, Shortcut, ShortcutFilter, Shortcuts, shortcut,
 };
 
 pub use zng_wgt_input::gesture::{
diff --git a/crates/zng/src/grid.rs b/crates/zng/src/grid.rs
index f20a8b60e..759ee7f51 100644
--- a/crates/zng/src/grid.rs
+++ b/crates/zng/src/grid.rs
@@ -84,19 +84,19 @@
 //!
 //! See [`zng_wgt_grid`] for the full widget API.
 
-pub use zng_wgt_grid::{node, AutoGrowFnArgs, AutoGrowMode, Cell, Column, Grid, Row};
+pub use zng_wgt_grid::{AutoGrowFnArgs, AutoGrowMode, Cell, Column, Grid, Row, node};
 
 /// Cell widget and properties.
 pub mod cell {
-    pub use zng_wgt_grid::cell::{at, column, column_span, row, row_span, span, Cell, CellInfo, AT_AUTO};
+    pub use zng_wgt_grid::cell::{AT_AUTO, Cell, CellInfo, at, column, column_span, row, row_span, span};
 }
 
 /// Column widget and properties.
 pub mod column {
-    pub use zng_wgt_grid::column::{get_index, get_index_len, get_rev_index, is_even, is_first, is_last, is_odd, Column};
+    pub use zng_wgt_grid::column::{Column, get_index, get_index_len, get_rev_index, is_even, is_first, is_last, is_odd};
 }
 
 /// Row widget and properties.
 pub mod row {
-    pub use zng_wgt_grid::row::{get_index, get_index_len, get_rev_index, is_even, is_first, is_last, is_odd, Row};
+    pub use zng_wgt_grid::row::{Row, get_index, get_index_len, get_rev_index, is_even, is_first, is_last, is_odd};
 }
diff --git a/crates/zng/src/handler.rs b/crates/zng/src/handler.rs
index 63bbc4577..89bed30bf 100644
--- a/crates/zng/src/handler.rs
+++ b/crates/zng/src/handler.rs
@@ -57,6 +57,6 @@
 //! See [`zng_app::handler`] for the full handler API.
 
 pub use zng_app::handler::{
-    app_hn, app_hn_once, async_app_hn, async_app_hn_once, async_hn, async_hn_once, hn, hn_once, AppHandler, AppHandlerArgs, AppWeakHandle,
-    FilterAppHandler, FilterWidgetHandler, WidgetHandler,
+    AppHandler, AppHandlerArgs, AppWeakHandle, FilterAppHandler, FilterWidgetHandler, WidgetHandler, app_hn, app_hn_once, async_app_hn,
+    async_app_hn_once, async_hn, async_hn_once, hn, hn_once,
 };
diff --git a/crates/zng/src/icon.rs b/crates/zng/src/icon.rs
index 6d85bb3ae..4ddccb749 100644
--- a/crates/zng/src/icon.rs
+++ b/crates/zng/src/icon.rs
@@ -70,8 +70,8 @@
 //!
 //! See [`zng_wgt_text::icon`] for the full widget API.
 
-pub use zng_wgt::{CommandIconExt, IconRequestArgs, ICONS};
-pub use zng_wgt_text::icon::{ico_color, ico_size, GlyphIcon, GlyphSource, Icon};
+pub use zng_wgt::{CommandIconExt, ICONS, IconRequestArgs};
+pub use zng_wgt_text::icon::{GlyphIcon, GlyphSource, Icon, ico_color, ico_size};
 
 /// Material Icons
 ///
diff --git a/crates/zng/src/image.rs b/crates/zng/src/image.rs
index 9774b4336..a7d4f4a02 100644
--- a/crates/zng/src/image.rs
+++ b/crates/zng/src/image.rs
@@ -73,17 +73,17 @@
 //! See [`zng_ext_image`] for the full image API and [`zng_wgt_image`] for the full widget API.
 
 pub use zng_ext_image::{
-    render_retain, ImageCacheMode, ImageDataFormat, ImageDownscale, ImageHash, ImageHasher, ImageLimits, ImagePpi, ImageRenderArgs,
-    ImageSource, ImageSourceFilter, ImageVar, Img, PathFilter, IMAGES, IMAGE_RENDER,
+    IMAGE_RENDER, IMAGES, ImageCacheMode, ImageDataFormat, ImageDownscale, ImageHash, ImageHasher, ImageLimits, ImagePpi, ImageRenderArgs,
+    ImageSource, ImageSourceFilter, ImageVar, Img, PathFilter, render_retain,
 };
 
 #[cfg(feature = "http")]
 pub use zng_ext_image::UriFilter;
 
 pub use zng_wgt_image::{
-    img_align, img_cache, img_crop, img_downscale, img_error_fn, img_fit, img_limits, img_loading_fn, img_offset, img_rendering,
-    img_repeat, img_repeat_spacing, img_scale, img_scale_factor, img_scale_ppi, is_error, is_loaded, on_error, on_load, Image, ImageFit,
-    ImageRepeat, ImgErrorArgs, ImgLoadArgs, ImgLoadingArgs,
+    Image, ImageFit, ImageRepeat, ImgErrorArgs, ImgLoadArgs, ImgLoadingArgs, img_align, img_cache, img_crop, img_downscale, img_error_fn,
+    img_fit, img_limits, img_loading_fn, img_offset, img_rendering, img_repeat, img_repeat_spacing, img_scale, img_scale_factor,
+    img_scale_ppi, is_error, is_loaded, on_error, on_load,
 };
 
 /// Mask image properties.
diff --git a/crates/zng/src/keyboard.rs b/crates/zng/src/keyboard.rs
index 7fac98076..71c807b2b 100644
--- a/crates/zng/src/keyboard.rs
+++ b/crates/zng/src/keyboard.rs
@@ -27,8 +27,8 @@
 pub use zng_app::shortcut::ModifiersState;
 
 pub use zng_ext_input::keyboard::{
-    HeadlessAppKeyboardExt, Key, KeyCode, KeyInputArgs, KeyLocation, KeyRepeatConfig, KeyState, ModifiersChangedArgs, NativeKeyCode,
-    KEYBOARD, KEY_INPUT_EVENT, MODIFIERS_CHANGED_EVENT,
+    HeadlessAppKeyboardExt, KEY_INPUT_EVENT, KEYBOARD, Key, KeyCode, KeyInputArgs, KeyLocation, KeyRepeatConfig, KeyState,
+    MODIFIERS_CHANGED_EVENT, ModifiersChangedArgs, NativeKeyCode,
 };
 
 pub use zng_wgt_input::keyboard::{
@@ -54,5 +54,5 @@ pub use zng_wgt_input::keyboard::{
 /// });
 /// ```
 pub mod raw_device_events {
-    pub use zng_app::view_process::raw_device_events::{KeyArgs, TextArgs, KEY_EVENT, TEXT_EVENT};
+    pub use zng_app::view_process::raw_device_events::{KEY_EVENT, KeyArgs, TEXT_EVENT, TextArgs};
 }
diff --git a/crates/zng/src/l10n.rs b/crates/zng/src/l10n.rs
index 58376bee0..3e3deed61 100644
--- a/crates/zng/src/l10n.rs
+++ b/crates/zng/src/l10n.rs
@@ -156,6 +156,6 @@
 //! See [`zng_ext_l10n`] for the full localization API.
 
 pub use zng_ext_l10n::{
-    l10n, lang, IntoL10nVar, L10nArgument, L10nDir, L10nMessageBuilder, L10nSource, L10nTar, Lang, LangFilePath, LangMap, LangResource,
-    LangResourceStatus, LangResources, Langs, NilL10nSource, SwapL10nSource, L10N, LANG_VAR,
+    IntoL10nVar, L10N, L10nArgument, L10nDir, L10nMessageBuilder, L10nSource, L10nTar, LANG_VAR, Lang, LangFilePath, LangMap, LangResource,
+    LangResourceStatus, LangResources, Langs, NilL10nSource, SwapL10nSource, l10n, lang,
 };
diff --git a/crates/zng/src/label.rs b/crates/zng/src/label.rs
index ab5c46d56..a40a3498a 100644
--- a/crates/zng/src/label.rs
+++ b/crates/zng/src/label.rs
@@ -24,4 +24,4 @@
 //!
 //! See [`zng_wgt_text_input::label`] for the full widget API.
 
-pub use zng_wgt_text_input::label::{style_fn, DefaultStyle, Label};
+pub use zng_wgt_text_input::label::{DefaultStyle, Label, style_fn};
diff --git a/crates/zng/src/layer.rs b/crates/zng/src/layer.rs
index aa5435379..8c3ce26cd 100644
--- a/crates/zng/src/layer.rs
+++ b/crates/zng/src/layer.rs
@@ -43,5 +43,5 @@
 //! See [`zng_wgt_layer`] for the full layers API.
 
 pub use zng_wgt_layer::{
-    adorner, adorner_fn, AnchorMode, AnchorOffset, AnchorSize, AnchorTransform, LayerIndex, LAYERS, LAYERS_INSERT_CMD, LAYERS_REMOVE_CMD,
+    AnchorMode, AnchorOffset, AnchorSize, AnchorTransform, LAYERS, LAYERS_INSERT_CMD, LAYERS_REMOVE_CMD, LayerIndex, adorner, adorner_fn,
 };
diff --git a/crates/zng/src/layout.rs b/crates/zng/src/layout.rs
index 8dcd0e038..cfb5b0d95 100644
--- a/crates/zng/src/layout.rs
+++ b/crates/zng/src/layout.rs
@@ -358,8 +358,8 @@ pub use zng_layout::unit::{
 pub use zng_var::types::{slerp_enabled, slerp_sampler};
 
 pub use zng_layout::context::{
-    InlineConstraints, InlineConstraintsLayout, InlineConstraintsMeasure, InlineSegment, InlineSegmentPos, LayoutDirection, LayoutMask,
-    LayoutMetrics, LayoutMetricsSnapshot, LayoutPassId, TextSegmentKind, DIRECTION_VAR, LAYOUT,
+    DIRECTION_VAR, InlineConstraints, InlineConstraintsLayout, InlineConstraintsMeasure, InlineSegment, InlineSegmentPos, LAYOUT,
+    LayoutDirection, LayoutMask, LayoutMetrics, LayoutMetricsSnapshot, LayoutPassId, TextSegmentKind,
 };
 
 pub use zng_app::widget::info::{WidgetLayout, WidgetMeasure};
@@ -370,12 +370,12 @@ pub use zng_wgt_transform::{
 };
 
 pub use zng_wgt_size_offset::{
-    actual_bounds, actual_height, actual_height_px, actual_size, actual_size_px, actual_transform, actual_width, actual_width_px, baseline,
-    force_height, force_size, force_width, height, max_height, max_size, max_width, min_height, min_size, min_width, offset, size,
-    sticky_height, sticky_size, sticky_width, width, x, y, WidgetLength, WIDGET_SIZE,
+    WIDGET_SIZE, WidgetLength, actual_bounds, actual_height, actual_height_px, actual_size, actual_size_px, actual_transform, actual_width,
+    actual_width_px, baseline, force_height, force_size, force_width, height, max_height, max_size, max_width, min_height, min_size,
+    min_width, offset, size, sticky_height, sticky_size, sticky_width, width, x, y,
 };
 
-pub use zng_wgt::{align, inline, is_ltr, is_rtl, margin, InlineMode};
+pub use zng_wgt::{InlineMode, align, inline, is_ltr, is_rtl, margin};
 
 pub use zng_wgt_container::{child_align, padding};
 
diff --git a/crates/zng/src/lib.rs b/crates/zng/src/lib.rs
index 78a16be34..d0a0a425e 100644
--- a/crates/zng/src/lib.rs
+++ b/crates/zng/src/lib.rs
@@ -572,23 +572,22 @@ mod __prelude {
     };
 
     pub use zng_app::{
+        INSTANT,
         event::{AnyEventArgs as _, CommandInfoExt as _, CommandNameExt as _, CommandParam, EventArgs as _},
         handler::{app_hn, app_hn_once, async_app_hn, async_app_hn_once, async_hn, async_hn_once, hn, hn_once},
-        shortcut::{shortcut, CommandShortcutExt as _},
+        shortcut::{CommandShortcutExt as _, shortcut},
         widget::{
-            easing,
-            node::{ui_vec, UiNode, UiNodeList, UiNodeListChain as _, UiVec},
-            AnyVarSubscribe as _, VarLayout as _, VarSubscribe as _, WidgetId, WIDGET,
+            AnyVarSubscribe as _, VarLayout as _, VarSubscribe as _, WIDGET, WidgetId, easing,
+            node::{UiNode, UiNodeList, UiNodeListChain as _, UiVec, ui_vec},
         },
-        window::{WindowId, WINDOW},
-        INSTANT,
+        window::{WINDOW, WindowId},
     };
 
     pub use zng_app::widget::inspector::WidgetInfoInspectorExt as _;
 
     pub use zng_var::{
-        context_var, expr_var, getter_var, merge_var, state_var, var, var_from, when_var, AnyVar as _, AnyWeakVar as _, IntoValue, IntoVar,
-        Var, VarValue, WeakVar as _,
+        AnyVar as _, AnyWeakVar as _, IntoValue, IntoVar, Var, VarValue, WeakVar as _, context_var, expr_var, getter_var, merge_var,
+        state_var, var, var_from, when_var,
     };
 
     pub use crate::var::animation::easing;
@@ -598,11 +597,11 @@ mod __prelude {
         LineFromTuplesBuilder as _, PxToDip as _, RectFromTuplesBuilder as _, ResolutionUnits as _, TimeUnits as _,
     };
 
-    pub use zng_txt::{formatx, ToTxt as _, Txt};
+    pub use zng_txt::{ToTxt as _, Txt, formatx};
 
     pub use zng_clone_move::{async_clmv, async_clmv_fn, async_clmv_fn_once, clmv};
 
-    pub use zng_color::{colors, hex, hsl, hsla, hsv, hsva, light_dark, rgb, rgba, web_colors, LightDarkVarExt as _, MixAdjust as _};
+    pub use zng_color::{LightDarkVarExt as _, MixAdjust as _, colors, hex, hsl, hsla, hsv, hsva, light_dark, rgb, rgba, web_colors};
 
     #[cfg(feature = "clipboard")]
     pub use zng_ext_clipboard::CLIPBOARD;
@@ -619,13 +618,13 @@ mod __prelude {
     pub use zng_wgt_image::Image;
 
     pub use zng_ext_input::{
-        focus::{cmd::CommandFocusExt as _, iter::IterFocusableExt as _, WidgetInfoFocusExt as _, FOCUS},
+        focus::{FOCUS, WidgetInfoFocusExt as _, cmd::CommandFocusExt as _, iter::IterFocusableExt as _},
         gesture::{CommandShortcutMatchesExt as _, HeadlessAppGestureExt as _},
         keyboard::HeadlessAppKeyboardExt as _,
         mouse::WidgetInfoMouseExt as _,
     };
 
-    pub use zng_ext_l10n::{l10n, lang, L10N};
+    pub use zng_ext_l10n::{L10N, l10n, lang};
 
     pub use zng_wgt_text::lang;
 
@@ -634,17 +633,17 @@ mod __prelude {
 
     #[cfg(feature = "window")]
     pub use zng_ext_window::{
-        AppRunWindowExt as _, HeadlessAppWindowExt as _, WINDOW_Ext as _, WidgetInfoImeArea as _, WindowCloseRequestedArgs, WindowIcon,
-        WINDOWS,
+        AppRunWindowExt as _, HeadlessAppWindowExt as _, WINDOW_Ext as _, WINDOWS, WidgetInfoImeArea as _, WindowCloseRequestedArgs,
+        WindowIcon,
     };
 
-    pub use zng_wgt::{CommandIconExt as _, Wgt, ICONS};
+    pub use zng_wgt::{CommandIconExt as _, ICONS, Wgt};
 
     pub use crate::text;
     pub use zng_wgt_text::Text;
 
     #[cfg(feature = "text_input")]
-    pub use zng_wgt_text_input::{selectable::SelectableText, TextInput};
+    pub use zng_wgt_text_input::{TextInput, selectable::SelectableText};
 
     #[cfg(feature = "window")]
     pub use crate::window;
@@ -657,7 +656,7 @@ mod __prelude {
     pub use zng_wgt_button::Button;
 
     #[cfg(feature = "data_context")]
-    pub use zng_wgt_data::{data, DATA};
+    pub use zng_wgt_data::{DATA, data};
 
     #[cfg(feature = "grid")]
     pub use crate::grid;
@@ -665,7 +664,7 @@ mod __prelude {
     pub use zng_wgt_grid::Grid;
 
     pub use crate::layer;
-    pub use zng_wgt_layer::{AnchorMode, LayerIndex, LAYERS};
+    pub use zng_wgt_layer::{AnchorMode, LAYERS, LayerIndex};
 
     pub use crate::popup;
     pub use zng_wgt_layer::popup::POPUP;
@@ -674,16 +673,16 @@ mod __prelude {
     pub use crate::menu;
     #[cfg(feature = "menu")]
     pub use zng_wgt_menu::{
-        context::{context_menu, context_menu_fn, ContextMenu},
-        sub::SubMenu,
         Menu,
+        context::{ContextMenu, context_menu, context_menu_fn},
+        sub::SubMenu,
     };
 
     #[cfg(feature = "rule_line")]
     pub use zng_wgt_rule_line::hr::Hr;
 
     #[cfg(feature = "scroll")]
-    pub use zng_wgt_scroll::{Scroll, SCROLL};
+    pub use zng_wgt_scroll::{SCROLL, Scroll};
 
     #[cfg(feature = "toggle")]
     pub use crate::toggle;
@@ -693,11 +692,11 @@ mod __prelude {
     #[cfg(feature = "tooltip")]
     pub use crate::tip;
     #[cfg(feature = "tooltip")]
-    pub use zng_wgt_tooltip::{tooltip, tooltip_fn, Tip};
+    pub use zng_wgt_tooltip::{Tip, tooltip, tooltip_fn};
 
-    pub use zng_wgt::{wgt_fn, WidgetFn};
+    pub use zng_wgt::{WidgetFn, wgt_fn};
 
-    pub use zng_wgt_style::{style_fn, Style};
+    pub use zng_wgt_style::{Style, style_fn};
 
     #[cfg(feature = "stack")]
     pub use zng_wgt_stack::{Stack, StackDirection};
@@ -752,44 +751,44 @@ pub mod prelude_wgt {
 }
 mod __prelude_wgt {
     pub use zng_app::{
+        DInstant, Deadline, INSTANT,
         event::{
-            command, event, event_args, AnyEventArgs as _, Command, CommandHandle, CommandInfoExt as _, CommandNameExt as _, CommandParam,
-            Event, EventArgs as _, EventHandle, EventHandles, EventPropagationHandle,
+            AnyEventArgs as _, Command, CommandHandle, CommandInfoExt as _, CommandNameExt as _, CommandParam, Event, EventArgs as _,
+            EventHandle, EventHandles, EventPropagationHandle, command, event, event_args,
         },
-        handler::{app_hn, app_hn_once, async_app_hn, async_app_hn_once, async_hn, async_hn_once, hn, hn_once, AppHandler, WidgetHandler},
+        handler::{AppHandler, WidgetHandler, app_hn, app_hn_once, async_app_hn, async_app_hn_once, async_hn, async_hn_once, hn, hn_once},
         render::{FrameBuilder, FrameUpdate, FrameValue, FrameValueKey, FrameValueUpdate, SpatialFrameId, TransformStyle},
-        shortcut::{shortcut, CommandShortcutExt as _, Shortcut, ShortcutFilter, Shortcuts},
-        timer::{DeadlineHandle, DeadlineVar, TimerHandle, TimerVar, TIMERS},
-        update::{EventUpdate, UpdateDeliveryList, UpdateOp, WidgetUpdates, UPDATES},
+        shortcut::{CommandShortcutExt as _, Shortcut, ShortcutFilter, Shortcuts, shortcut},
+        timer::{DeadlineHandle, DeadlineVar, TIMERS, TimerHandle, TimerVar},
+        update::{EventUpdate, UPDATES, UpdateDeliveryList, UpdateOp, WidgetUpdates},
         widget::{
+            AnyVarSubscribe as _, VarLayout as _, VarSubscribe as _, WIDGET, WidgetId, WidgetUpdateMode,
             base::{WidgetBase, WidgetImpl},
-            border::{BorderSides, BorderStyle, CornerRadius, CornerRadiusFit, LineOrientation, LineStyle, BORDER},
-            builder::{property_id, NestGroup, WidgetBuilder, WidgetBuilding},
+            border::{BORDER, BorderSides, BorderStyle, CornerRadius, CornerRadiusFit, LineOrientation, LineStyle},
+            builder::{NestGroup, WidgetBuilder, WidgetBuilding, property_id},
             easing,
             info::{
                 InteractionPath, Interactivity, Visibility, WidgetBorderInfo, WidgetBoundsInfo, WidgetInfo, WidgetInfoBuilder,
                 WidgetLayout, WidgetMeasure, WidgetPath,
             },
             node::{
-                match_node, match_node_leaf, match_node_list, match_node_typed, match_widget, ui_vec, ArcNode, ArcNodeList, BoxedUiNode,
-                BoxedUiNodeList, EditableUiNodeList, EditableUiNodeListRef, FillUiNode, NilUiNode, PanelList, SortingList, UiNode,
-                UiNodeList, UiNodeListChain as _, UiNodeListObserver, UiNodeOp, UiVec, ZIndex, SORTING_LIST,
+                ArcNode, ArcNodeList, BoxedUiNode, BoxedUiNodeList, EditableUiNodeList, EditableUiNodeListRef, FillUiNode, NilUiNode,
+                PanelList, SORTING_LIST, SortingList, UiNode, UiNodeList, UiNodeListChain as _, UiNodeListObserver, UiNodeOp, UiVec,
+                ZIndex, match_node, match_node_leaf, match_node_list, match_node_typed, match_widget, ui_vec,
             },
-            property, ui_node, widget, widget_impl, widget_mixin, widget_set, AnyVarSubscribe as _, VarLayout as _, VarSubscribe as _,
-            WidgetId, WidgetUpdateMode, WIDGET,
+            property, ui_node, widget, widget_impl, widget_mixin, widget_set,
         },
-        window::{MonitorId, WindowId, WINDOW},
-        DInstant, Deadline, INSTANT,
+        window::{MonitorId, WINDOW, WindowId},
     };
 
     pub use zng_var::{
-        context_var, expr_var, getter_var, impl_from_and_into_var, merge_var, response_done_var, response_var, state_var, var, when_var,
         AnyVar as _, AnyWeakVar as _, ArcVar, BoxedVar, ContextVar, IntoValue, IntoVar, LocalVar, ReadOnlyArcVar, ResponderVar,
-        ResponseVar, Var, VarCapability, VarHandle, VarHandles, VarValue, WeakVar as _,
+        ResponseVar, Var, VarCapability, VarHandle, VarHandles, VarValue, WeakVar as _, context_var, expr_var, getter_var,
+        impl_from_and_into_var, merge_var, response_done_var, response_var, state_var, var, when_var,
     };
 
     pub use zng_layout::{
-        context::{LayoutDirection, LayoutMetrics, DIRECTION_VAR, LAYOUT},
+        context::{DIRECTION_VAR, LAYOUT, LayoutDirection, LayoutMetrics},
         unit::{
             Align, AngleDegree, AngleGradian, AngleRadian, AngleUnits as _, ByteUnits as _, Dip, DipBox, DipPoint, DipRect, DipSideOffsets,
             DipSize, DipToPx as _, DipVector, Factor, Factor2d, FactorPercent, FactorSideOffsets, FactorUnits as _, Layout1d as _,
@@ -799,24 +798,24 @@ mod __prelude_wgt {
         },
     };
 
-    pub use zng_txt::{formatx, ToTxt as _, Txt};
+    pub use zng_txt::{ToTxt as _, Txt, formatx};
 
     pub use zng_clone_move::{async_clmv, async_clmv_fn, async_clmv_fn_once, clmv};
 
     pub use crate::task;
 
-    pub use zng_app_context::{app_local, context_local, CaptureFilter, ContextLocal, ContextValueSet, LocalContext, RunOnDrop};
+    pub use zng_app_context::{CaptureFilter, ContextLocal, ContextValueSet, LocalContext, RunOnDrop, app_local, context_local};
 
     pub use crate::state_map;
-    pub use zng_state_map::{static_id, OwnedStateMap, StateId, StateMapMut, StateMapRef};
+    pub use zng_state_map::{OwnedStateMap, StateId, StateMapMut, StateMapRef, static_id};
 
     pub use zng_wgt::prelude::{IdEntry, IdMap, IdSet};
 
-    pub use zng_wgt::{wgt_fn, WidgetFn};
+    pub use zng_wgt::{WidgetFn, wgt_fn};
 
     pub use zng_color::{
-        colors, gradient, hex, hsl, hsla, hsv, hsva, light_dark, rgb, rgba, web_colors, ColorScheme, Hsla, Hsva, LightDark, MixAdjust as _,
-        MixBlendMode, Rgba,
+        ColorScheme, Hsla, Hsva, LightDark, MixAdjust as _, MixBlendMode, Rgba, colors, gradient, hex, hsl, hsla, hsv, hsva, light_dark,
+        rgb, rgba, web_colors,
     };
 
     pub use zng_wgt::node::{
@@ -1053,8 +1052,8 @@ mod default_editors {
     use zng::{
         prelude::*,
         widget::{
-            node::{BoxedUiNode, NilUiNode},
             EditorRequestArgs,
+            node::{BoxedUiNode, NilUiNode},
         },
     };
 
diff --git a/crates/zng/src/markdown.rs b/crates/zng/src/markdown.rs
index 9f22d612c..9559b60e2 100644
--- a/crates/zng/src/markdown.rs
+++ b/crates/zng/src/markdown.rs
@@ -19,10 +19,10 @@
 //! See [`zng_wgt_markdown`] for the full widget API.
 
 pub use zng_wgt_markdown::{
-    anchor, block_quote_fn, code_block_fn, code_inline_fn, footnote_def_fn, footnote_ref_fn, heading_anchor, heading_fn, image_fn,
-    image_resolver, link_fn, link_resolver, link_scroll_mode, list_fn, list_item_bullet_fn, list_item_fn, on_link, on_pre_link, panel_fn,
-    paragraph_fn, rule_fn, table_fn, text_fn, BlockQuoteFnArgs, CodeBlockFnArgs, CodeInlineFnArgs, FootnoteDefFnArgs, FootnoteRefFnArgs,
-    HeadingFnArgs, HeadingLevel, ImageFnArgs, ImageResolver, LinkArgs, LinkFnArgs, LinkResolver, ListFnArgs, ListItemBulletFnArgs,
-    ListItemFnArgs, Markdown, MarkdownStyle, PanelFnArgs, ParagraphFnArgs, RuleFnArgs, TableCellFnArgs, TableFnArgs, TextFnArgs,
-    WidgetInfoExt, LINK_EVENT,
+    BlockQuoteFnArgs, CodeBlockFnArgs, CodeInlineFnArgs, FootnoteDefFnArgs, FootnoteRefFnArgs, HeadingFnArgs, HeadingLevel, ImageFnArgs,
+    ImageResolver, LINK_EVENT, LinkArgs, LinkFnArgs, LinkResolver, ListFnArgs, ListItemBulletFnArgs, ListItemFnArgs, Markdown,
+    MarkdownStyle, PanelFnArgs, ParagraphFnArgs, RuleFnArgs, TableCellFnArgs, TableFnArgs, TextFnArgs, WidgetInfoExt, anchor,
+    block_quote_fn, code_block_fn, code_inline_fn, footnote_def_fn, footnote_ref_fn, heading_anchor, heading_fn, image_fn, image_resolver,
+    link_fn, link_resolver, link_scroll_mode, list_fn, list_item_bullet_fn, list_item_fn, on_link, on_pre_link, panel_fn, paragraph_fn,
+    rule_fn, table_fn, text_fn,
 };
diff --git a/crates/zng/src/menu.rs b/crates/zng/src/menu.rs
index 47ccb5358..5d8f9cd51 100644
--- a/crates/zng/src/menu.rs
+++ b/crates/zng/src/menu.rs
@@ -87,7 +87,7 @@
 //! See [`zng_wgt_menu`] for the full widget API.
 
 pub use zng_wgt_menu::{
-    icon, icon_fn, panel_fn, shortcut_spacing, shortcut_txt, style_fn, ButtonStyle, DefaultStyle, Menu, ToggleStyle, TouchButtonStyle,
+    ButtonStyle, DefaultStyle, Menu, ToggleStyle, TouchButtonStyle, icon, icon_fn, panel_fn, shortcut_spacing, shortcut_txt, style_fn,
 };
 
 /// Submenu widget and properties.
@@ -95,8 +95,8 @@ pub use zng_wgt_menu::{
 /// See [`zng_wgt_menu::sub`] for the full widget API.
 pub mod sub {
     pub use zng_wgt_menu::sub::{
-        column_width_padding, end_column, end_column_fn, end_column_width, hover_open_delay, is_open, start_column, start_column_fn,
-        start_column_width, DefaultStyle, SubMenu, SubMenuAncestors, SubMenuStyle, SubMenuWidgetInfoExt,
+        DefaultStyle, SubMenu, SubMenuAncestors, SubMenuStyle, SubMenuWidgetInfoExt, column_width_padding, end_column, end_column_fn,
+        end_column_width, hover_open_delay, is_open, start_column, start_column_fn, start_column_width,
     };
 }
 
@@ -105,8 +105,8 @@ pub mod sub {
 /// See [`zng_wgt_menu::context`] for the full widget API.
 pub mod context {
     pub use zng_wgt_menu::context::{
-        context_menu, context_menu_anchor, context_menu_fn, disabled_context_menu, disabled_context_menu_fn, panel_fn, style_fn,
-        ContextMenu, ContextMenuArgs, DefaultStyle, TouchStyle,
+        ContextMenu, ContextMenuArgs, DefaultStyle, TouchStyle, context_menu, context_menu_anchor, context_menu_fn, disabled_context_menu,
+        disabled_context_menu_fn, panel_fn, style_fn,
     };
 }
 
@@ -114,5 +114,5 @@ pub mod context {
 ///
 /// See [`zng_wgt_menu::popup`] for the full widget API.
 pub mod popup {
-    pub use zng_wgt_menu::popup::{panel_fn, style_fn, DefaultStyle, SubMenuPopup};
+    pub use zng_wgt_menu::popup::{DefaultStyle, SubMenuPopup, panel_fn, style_fn};
 }
diff --git a/crates/zng/src/mouse.rs b/crates/zng/src/mouse.rs
index a37f76593..351b60e7c 100644
--- a/crates/zng/src/mouse.rs
+++ b/crates/zng/src/mouse.rs
@@ -37,9 +37,9 @@
 //! See [`zng_ext_input::mouse`] and [`zng_wgt_input::mouse`] for the full mouse API.
 
 pub use zng_ext_input::mouse::{
-    ButtonRepeatConfig, ButtonState, ClickMode, ClickTrigger, MouseButton, MouseClickArgs, MouseHoverArgs, MouseInputArgs, MouseMoveArgs,
-    MousePosition, MouseScrollDelta, MouseWheelArgs, MultiClickConfig, WidgetInfoBuilderMouseExt, WidgetInfoMouseExt, MOUSE,
-    MOUSE_CLICK_EVENT, MOUSE_HOVERED_EVENT, MOUSE_INPUT_EVENT, MOUSE_MOVE_EVENT, MOUSE_WHEEL_EVENT,
+    ButtonRepeatConfig, ButtonState, ClickMode, ClickTrigger, MOUSE, MOUSE_CLICK_EVENT, MOUSE_HOVERED_EVENT, MOUSE_INPUT_EVENT,
+    MOUSE_MOVE_EVENT, MOUSE_WHEEL_EVENT, MouseButton, MouseClickArgs, MouseHoverArgs, MouseInputArgs, MouseMoveArgs, MousePosition,
+    MouseScrollDelta, MouseWheelArgs, MultiClickConfig, WidgetInfoBuilderMouseExt, WidgetInfoMouseExt,
 };
 
 pub use zng_wgt_input::mouse::{
@@ -54,13 +54,13 @@ pub use zng_wgt_input::mouse::{
     on_pre_mouse_wheel, on_pre_mouse_zoom,
 };
 
-pub use zng_wgt_input::{click_mode, cursor, is_cap_mouse_pressed, is_mouse_pressed, CursorIcon, CursorImg, CursorSource};
+pub use zng_wgt_input::{CursorIcon, CursorImg, CursorSource, click_mode, cursor, is_cap_mouse_pressed, is_mouse_pressed};
 
 /// Raw mouse hardware events, received independent of what window is under the pointer.
 ///
 /// You must enable device events in the app to receive this events.
 pub mod raw_device_events {
     pub use zng_app::view_process::raw_device_events::{
-        ButtonArgs, MouseMotionArgs, MouseWheelArgs, BUTTON_EVENT, MOUSE_MOTION_EVENT, MOUSE_WHEEL_EVENT,
+        BUTTON_EVENT, ButtonArgs, MOUSE_MOTION_EVENT, MOUSE_WHEEL_EVENT, MouseMotionArgs, MouseWheelArgs,
     };
 }
diff --git a/crates/zng/src/panel.rs b/crates/zng/src/panel.rs
index 524e35bf6..1c989dac2 100644
--- a/crates/zng/src/panel.rs
+++ b/crates/zng/src/panel.rs
@@ -60,4 +60,4 @@
 //!
 //! See [`zng_wgt_panel`] for the full widget API.
 
-pub use zng_wgt_panel::{node, panel_fn, Panel, PanelArgs};
+pub use zng_wgt_panel::{Panel, PanelArgs, node, panel_fn};
diff --git a/crates/zng/src/pointer_capture.rs b/crates/zng/src/pointer_capture.rs
index 9dd29d0ed..a91cc571d 100644
--- a/crates/zng/src/pointer_capture.rs
+++ b/crates/zng/src/pointer_capture.rs
@@ -40,7 +40,7 @@
 //!
 //! See [`zng_ext_input::pointer_capture`] and [`zng_wgt_input::pointer_capture`] for the full pointer capture API.
 
-pub use zng_ext_input::pointer_capture::{CaptureInfo, CaptureMode, PointerCaptureArgs, POINTER_CAPTURE, POINTER_CAPTURE_EVENT};
+pub use zng_ext_input::pointer_capture::{CaptureInfo, CaptureMode, POINTER_CAPTURE, POINTER_CAPTURE_EVENT, PointerCaptureArgs};
 
 pub use zng_wgt_input::pointer_capture::{
     capture_pointer, capture_pointer_on_init, on_got_pointer_capture, on_lost_pointer_capture, on_pointer_capture_changed,
diff --git a/crates/zng/src/popup.rs b/crates/zng/src/popup.rs
index 16c1b75c5..bd2506766 100644
--- a/crates/zng/src/popup.rs
+++ b/crates/zng/src/popup.rs
@@ -40,7 +40,7 @@
 //! See [`zng_wgt_layer::popup`] for the full widget API.
 
 pub use zng_wgt_layer::popup::{
-    anchor_mode, close_delay, close_on_focus_leave, context_capture, is_close_delaying, on_popup_close_requested,
-    on_pre_popup_close_requested, style_fn, ContextCapture, DefaultStyle, Popup, PopupCloseMode, PopupCloseRequestedArgs, PopupState,
-    POPUP, POPUP_CLOSE_CMD, POPUP_CLOSE_REQUESTED_EVENT,
+    ContextCapture, DefaultStyle, POPUP, POPUP_CLOSE_CMD, POPUP_CLOSE_REQUESTED_EVENT, Popup, PopupCloseMode, PopupCloseRequestedArgs,
+    PopupState, anchor_mode, close_delay, close_on_focus_leave, context_capture, is_close_delaying, on_popup_close_requested,
+    on_pre_popup_close_requested, style_fn,
 };
diff --git a/crates/zng/src/progress.rs b/crates/zng/src/progress.rs
index 0607a6c2a..beac3103f 100644
--- a/crates/zng/src/progress.rs
+++ b/crates/zng/src/progress.rs
@@ -28,4 +28,4 @@
 //!
 //! See [`zng_wgt_progress`] and [`zng_task::Progress`] for the full widget API.
 
-pub use zng_wgt_progress::{is_indeterminate, on_complete, on_progress, DefaultStyle, ProgressView, SimpleBarStyle, PROGRESS_VAR};
+pub use zng_wgt_progress::{DefaultStyle, PROGRESS_VAR, ProgressView, SimpleBarStyle, is_indeterminate, on_complete, on_progress};
diff --git a/crates/zng/src/rule_line.rs b/crates/zng/src/rule_line.rs
index 3df90bad4..c85e5d89a 100644
--- a/crates/zng/src/rule_line.rs
+++ b/crates/zng/src/rule_line.rs
@@ -32,10 +32,10 @@ pub use zng_wgt_rule_line::RuleLine;
 
 /// Horizontal rule line widget and properties.
 pub mod hr {
-    pub use zng_wgt_rule_line::hr::{color, line_style, margin, stroke_thickness, Hr};
+    pub use zng_wgt_rule_line::hr::{Hr, color, line_style, margin, stroke_thickness};
 }
 
 /// Vertical rule line widget and properties.
 pub mod vr {
-    pub use zng_wgt_rule_line::vr::{color, line_style, margin, stroke_thickness, Vr};
+    pub use zng_wgt_rule_line::vr::{Vr, color, line_style, margin, stroke_thickness};
 }
diff --git a/crates/zng/src/scroll.rs b/crates/zng/src/scroll.rs
index 28c782523..83e86e72d 100644
--- a/crates/zng/src/scroll.rs
+++ b/crates/zng/src/scroll.rs
@@ -61,29 +61,29 @@
 //! See [`zng_wgt_scroll`] for the full widget API.
 
 pub use zng_wgt_scroll::{
-    alt_factor, auto_hide_extra, clip_to_viewport, define_viewport_unit, h_line_unit, h_page_unit, h_scrollbar_fn, h_wheel_unit, lazy,
-    line_units, max_zoom, min_zoom, mode, mouse_pan, overscroll_color, page_units, scroll_to_focused_mode, scrollbar_fn,
-    scrollbar_joiner_fn, smooth_scrolling, v_line_unit, v_page_unit, v_scrollbar_fn, v_wheel_unit, wheel_units, zoom_origin,
-    zoom_size_only, zoom_touch_origin, zoom_wheel_origin, zoom_wheel_unit, LazyMode, Scroll, ScrollBarArgs, ScrollFrom, ScrollInfo,
-    ScrollMode, ScrollUnitsMix, Scrollbar, ScrollbarFnMix, SmoothScrolling, Thumb, WidgetInfoExt, SCROLL,
+    LazyMode, SCROLL, Scroll, ScrollBarArgs, ScrollFrom, ScrollInfo, ScrollMode, ScrollUnitsMix, Scrollbar, ScrollbarFnMix,
+    SmoothScrolling, Thumb, WidgetInfoExt, alt_factor, auto_hide_extra, clip_to_viewport, define_viewport_unit, h_line_unit, h_page_unit,
+    h_scrollbar_fn, h_wheel_unit, lazy, line_units, max_zoom, min_zoom, mode, mouse_pan, overscroll_color, page_units,
+    scroll_to_focused_mode, scrollbar_fn, scrollbar_joiner_fn, smooth_scrolling, v_line_unit, v_page_unit, v_scrollbar_fn, v_wheel_unit,
+    wheel_units, zoom_origin, zoom_size_only, zoom_touch_origin, zoom_wheel_origin, zoom_wheel_unit,
 };
 
 /// Scrollbar thumb widget.
 pub mod thumb {
-    pub use zng_wgt_scroll::thumb::{cross_length, offset, viewport_ratio, Thumb};
+    pub use zng_wgt_scroll::thumb::{Thumb, cross_length, offset, viewport_ratio};
 }
 
 /// Scroll widget.
 pub mod scrollbar {
-    pub use zng_wgt_scroll::scrollbar::{orientation, Orientation, Scrollbar, SCROLLBAR};
+    pub use zng_wgt_scroll::scrollbar::{Orientation, SCROLLBAR, Scrollbar, orientation};
 }
 
 /// Scroll commands.
 pub mod cmd {
     pub use zng_wgt_scroll::cmd::{
-        scroll_to, scroll_to_zoom, ScrollRequest, ScrollToMode, ScrollToRequest, ScrollToTarget, PAGE_DOWN_CMD, PAGE_LEFT_CMD,
-        PAGE_RIGHT_CMD, PAGE_UP_CMD, SCROLL_DOWN_CMD, SCROLL_LEFT_CMD, SCROLL_RIGHT_CMD, SCROLL_TO_BOTTOM_CMD, SCROLL_TO_CMD,
-        SCROLL_TO_LEFTMOST_CMD, SCROLL_TO_RIGHTMOST_CMD, SCROLL_TO_TOP_CMD, SCROLL_UP_CMD, ZOOM_IN_CMD, ZOOM_OUT_CMD, ZOOM_RESET_CMD,
-        ZOOM_TO_FIT_CMD,
+        PAGE_DOWN_CMD, PAGE_LEFT_CMD, PAGE_RIGHT_CMD, PAGE_UP_CMD, SCROLL_DOWN_CMD, SCROLL_LEFT_CMD, SCROLL_RIGHT_CMD,
+        SCROLL_TO_BOTTOM_CMD, SCROLL_TO_CMD, SCROLL_TO_LEFTMOST_CMD, SCROLL_TO_RIGHTMOST_CMD, SCROLL_TO_TOP_CMD, SCROLL_UP_CMD,
+        ScrollRequest, ScrollToMode, ScrollToRequest, ScrollToTarget, ZOOM_IN_CMD, ZOOM_OUT_CMD, ZOOM_RESET_CMD, ZOOM_TO_FIT_CMD,
+        scroll_to, scroll_to_zoom,
     };
 }
diff --git a/crates/zng/src/selectable.rs b/crates/zng/src/selectable.rs
index b37aadb31..bd1afe910 100644
--- a/crates/zng/src/selectable.rs
+++ b/crates/zng/src/selectable.rs
@@ -38,4 +38,4 @@
 //!
 //! See [`zng_wgt_text_input::selectable`] for the full widget API.
 
-pub use zng_wgt_text_input::selectable::{style_fn, DefaultStyle, SelectableText};
+pub use zng_wgt_text_input::selectable::{DefaultStyle, SelectableText, style_fn};
diff --git a/crates/zng/src/slider.rs b/crates/zng/src/slider.rs
index 4ef34122f..13658610e 100644
--- a/crates/zng/src/slider.rs
+++ b/crates/zng/src/slider.rs
@@ -25,7 +25,7 @@
 //!
 //! See [`zng_wgt_slider`] for the full widget API.
 
-pub use zng_wgt_slider::{DefaultStyle, Selector, SelectorValue, Slider, SliderDirection, SliderTrack, ThumbArgs, SLIDER_DIRECTION_VAR};
+pub use zng_wgt_slider::{DefaultStyle, SLIDER_DIRECTION_VAR, Selector, SelectorValue, Slider, SliderDirection, SliderTrack, ThumbArgs};
 
 /// Slider thumb widget, styles and properties.
 ///
diff --git a/crates/zng/src/stack.rs b/crates/zng/src/stack.rs
index 99eca7c85..737c6d068 100644
--- a/crates/zng/src/stack.rs
+++ b/crates/zng/src/stack.rs
@@ -48,6 +48,6 @@
 //! See [`zng_wgt_stack`] for the full widget API.
 
 pub use zng_wgt_stack::{
-    get_index, get_index_len, get_rev_index, is_even, is_first, is_last, is_odd, lazy_sample, lazy_size, node, stack_nodes,
-    stack_nodes_layout_by, Stack, StackDirection, WidgetInfoStackExt,
+    Stack, StackDirection, WidgetInfoStackExt, get_index, get_index_len, get_rev_index, is_even, is_first, is_last, is_odd, lazy_sample,
+    lazy_size, node, stack_nodes, stack_nodes_layout_by,
 };
diff --git a/crates/zng/src/state_map.rs b/crates/zng/src/state_map.rs
index 5c86e434f..16d493661 100644
--- a/crates/zng/src/state_map.rs
+++ b/crates/zng/src/state_map.rs
@@ -47,6 +47,6 @@
 //! [`WidgetInfoBuilder::with_meta`]: crate::widget::info::WidgetInfoBuilder::with_meta
 
 pub use zng_state_map::{
-    state_map::{OccupiedStateMapEntry, StateMapEntry, VacantStateMapEntry},
     OwnedStateMap, StateId, StateMapMut, StateMapRef, StateValue,
+    state_map::{OccupiedStateMapEntry, StateMapEntry, VacantStateMapEntry},
 };
diff --git a/crates/zng/src/style.rs b/crates/zng/src/style.rs
index 32aede504..3a5f43ee2 100644
--- a/crates/zng/src/style.rs
+++ b/crates/zng/src/style.rs
@@ -140,4 +140,4 @@
 //! # ;
 //! ```
 
-pub use zng_wgt_style::{impl_style_fn, style_fn, Style, StyleArgs, StyleBuilder, StyleFn, StyleMix};
+pub use zng_wgt_style::{Style, StyleArgs, StyleBuilder, StyleFn, StyleMix, impl_style_fn, style_fn};
diff --git a/crates/zng/src/task.rs b/crates/zng/src/task.rs
index 323d35f98..4f18ee8d8 100644
--- a/crates/zng/src/task.rs
+++ b/crates/zng/src/task.rs
@@ -144,9 +144,9 @@
 //! This module fully re-exports [`zng_task`].
 
 pub use zng_task::{
-    all, all_ok, all_some, any, any_ok, any_some, block_on, channel, deadline, fs, future_fn, io, join, join_context, poll_respond,
-    poll_spawn, respond, run, run_catch, scope, spawn, spawn_wait, wait, wait_catch, wait_respond, with_deadline, yield_now, DeadlineError,
-    McWaker, ParallelIteratorExt, ParallelIteratorWithCtx, Progress, ScopeCtx, SignalOnce, UiTask,
+    DeadlineError, McWaker, ParallelIteratorExt, ParallelIteratorWithCtx, Progress, ScopeCtx, SignalOnce, UiTask, all, all_ok, all_some,
+    any, any_ok, any_some, block_on, channel, deadline, fs, future_fn, io, join, join_context, poll_respond, poll_spawn, respond, run,
+    run_catch, scope, spawn, spawn_wait, wait, wait_catch, wait_respond, with_deadline, yield_now,
 };
 
 #[cfg(any(doc, feature = "test_util"))]
diff --git a/crates/zng/src/text.rs b/crates/zng/src/text.rs
index d402df52e..e323584a7 100644
--- a/crates/zng/src/text.rs
+++ b/crates/zng/src/text.rs
@@ -66,6 +66,8 @@
 pub use zng_txt::*;
 
 pub use zng_wgt_text::{
+    AutoSelection, CaretShape, CaretStatus, ChangeStopArgs, ChangeStopCause, Em, FONT_COLOR_VAR, InteractiveCaretMode, LangMix,
+    LinesWrapCount, ParagraphMix, SelectionToolbarArgs, Strong, Text, TextOverflow, TxtParseValue, UnderlinePosition, UnderlineSkip,
     accepts_enter, accepts_tab, auto_selection, caret_color, change_stop_delay, cmd, direction, font_aa, font_annotation, font_caps,
     font_char_variant, font_cn_variant, font_color, font_common_lig, font_contextual_alt, font_discretionary_lig, font_ea_width,
     font_family, font_features, font_historical_forms, font_historical_lig, font_jp_variant, font_kerning, font_num_fraction,
@@ -74,13 +76,8 @@ pub use zng_wgt_text::{
     get_chars_count, get_lines_len, get_lines_wrap_count, get_overflow, hyphen_char, hyphens, ime_underline, interactive_caret,
     interactive_caret_visual, is_line_overflown, is_overflown, is_parse_pending, justify_mode, lang, letter_spacing, line_break,
     line_height, line_spacing, max_chars_count,
-    node::{set_interactive_caret_spot, TEXT},
+    node::{TEXT, set_interactive_caret_spot},
     obscure_txt, obscuring_char, on_change_stop, overline, overline_color, paragraph_spacing, selection_color, selection_toolbar,
     selection_toolbar_anchor, selection_toolbar_fn, strikethrough, strikethrough_color, tab_length, txt_align, txt_editable, txt_overflow,
-    txt_overflow_align, underline, underline_color, underline_skip, white_space, word_break, word_spacing, AutoSelection, CaretShape,
-    CaretStatus, ChangeStopArgs, ChangeStopCause, Em, InteractiveCaretMode, LangMix, LinesWrapCount, ParagraphMix, SelectionToolbarArgs,
-    Strong, Text, TextOverflow, TxtParseValue, UnderlinePosition, UnderlineSkip, FONT_COLOR_VAR,
+    txt_overflow_align, underline, underline_color, underline_skip, white_space, word_break, word_spacing,
 };
-
-#[allow(deprecated)] // avoid breaking change
-pub use zng_wgt_text::justify;
diff --git a/crates/zng/src/text_input.rs b/crates/zng/src/text_input.rs
index 2c40c9238..a9c273661 100644
--- a/crates/zng/src/text_input.rs
+++ b/crates/zng/src/text_input.rs
@@ -44,5 +44,5 @@
 //! See [`zng_wgt_text_input`] for the full widget API.
 
 pub use zng_wgt_text_input::{
-    data_notes_adorner_fn, field_help, max_chars_count_adorner_fn, style_fn, DefaultStyle, FieldStyle, SearchStyle, TextInput,
+    DefaultStyle, FieldStyle, SearchStyle, TextInput, data_notes_adorner_fn, field_help, max_chars_count_adorner_fn, style_fn,
 };
diff --git a/crates/zng/src/third_party.rs b/crates/zng/src/third_party.rs
index c7316ed40..eae9571ef 100644
--- a/crates/zng/src/third_party.rs
+++ b/crates/zng/src/third_party.rs
@@ -140,7 +140,7 @@
 //! [`cargo-about`]: https://github.com/EmbarkStudios/cargo-about/
 //! [`on_pre_event`]: crate::event::Command::on_pre_event
 
-pub use zng_app::third_party::{License, LicenseUsed, User, UserLicense, LICENSES, OPEN_LICENSES_CMD};
+pub use zng_app::third_party::{LICENSES, License, LicenseUsed, OPEN_LICENSES_CMD, User, UserLicense};
 
 #[cfg(feature = "third_party_default")]
 pub(crate) fn setup_default_view() {
diff --git a/crates/zng/src/timer.rs b/crates/zng/src/timer.rs
index 8610d32d6..bb5f06a0c 100644
--- a/crates/zng/src/timer.rs
+++ b/crates/zng/src/timer.rs
@@ -31,5 +31,5 @@
 //!
 
 pub use zng_app::timer::{
-    DeadlineArgs, DeadlineHandle, DeadlineVar, Timer, TimerArgs, TimerHandle, TimerVar, WeakDeadlineHandle, WeakTimerHandle, TIMERS,
+    DeadlineArgs, DeadlineHandle, DeadlineVar, TIMERS, Timer, TimerArgs, TimerHandle, TimerVar, WeakDeadlineHandle, WeakTimerHandle,
 };
diff --git a/crates/zng/src/tip.rs b/crates/zng/src/tip.rs
index fcbec9965..1f0690340 100644
--- a/crates/zng/src/tip.rs
+++ b/crates/zng/src/tip.rs
@@ -31,6 +31,6 @@
 //! See [`zng_wgt_tooltip`] for the full tooltip API.
 
 pub use zng_wgt_tooltip::{
-    access_tooltip_anchor, access_tooltip_duration, disabled_tooltip, disabled_tooltip_fn, style_fn, tooltip, tooltip_anchor,
-    tooltip_context_capture, tooltip_delay, tooltip_duration, tooltip_fn, tooltip_interval, DefaultStyle, Tip, TooltipArgs,
+    DefaultStyle, Tip, TooltipArgs, access_tooltip_anchor, access_tooltip_duration, disabled_tooltip, disabled_tooltip_fn, style_fn,
+    tooltip, tooltip_anchor, tooltip_context_capture, tooltip_delay, tooltip_duration, tooltip_fn, tooltip_interval,
 };
diff --git a/crates/zng/src/toggle.rs b/crates/zng/src/toggle.rs
index 8b9c8bf61..77c6f5f65 100644
--- a/crates/zng/src/toggle.rs
+++ b/crates/zng/src/toggle.rs
@@ -182,12 +182,12 @@
 //! See [`zng_wgt_toggle`] for the full widget API.
 
 pub use zng_wgt_toggle::{
-    check_spacing, combo_spacing, deselect_on_deinit, deselect_on_new, is_checked, radio_spacing, scroll_on_select, select_on_init,
-    select_on_new, selector, style_fn, switch_spacing, tristate, CheckStyle, ComboStyle, DefaultStyle, LightStyle, RadioStyle, Selector,
-    SelectorError, SelectorImpl, SwitchStyle, Toggle, IS_CHECKED_VAR,
+    CheckStyle, ComboStyle, DefaultStyle, IS_CHECKED_VAR, LightStyle, RadioStyle, Selector, SelectorError, SelectorImpl, SwitchStyle,
+    Toggle, check_spacing, combo_spacing, deselect_on_deinit, deselect_on_new, is_checked, radio_spacing, scroll_on_select, select_on_init,
+    select_on_new, selector, style_fn, switch_spacing, tristate,
 };
 
 /// Toggle commands.
 pub mod cmd {
-    pub use zng_wgt_toggle::cmd::{SelectOp, SELECT_CMD, TOGGLE_CMD};
+    pub use zng_wgt_toggle::cmd::{SELECT_CMD, SelectOp, TOGGLE_CMD};
 }
diff --git a/crates/zng/src/touch.rs b/crates/zng/src/touch.rs
index f416434f5..7d5f4e2c5 100644
--- a/crates/zng/src/touch.rs
+++ b/crates/zng/src/touch.rs
@@ -49,9 +49,9 @@
 //! See [`zng_ext_input::touch`] and [`zng_wgt_input::touch`] for the full touch API.
 
 pub use zng_ext_input::touch::{
-    TouchConfig, TouchForce, TouchId, TouchInputArgs, TouchLongPressArgs, TouchMove, TouchMoveArgs, TouchPhase, TouchPosition,
-    TouchTapArgs, TouchTransformArgs, TouchTransformInfo, TouchTransformMode, TouchUpdate, TouchedArgs, TOUCH, TOUCHED_EVENT,
-    TOUCH_INPUT_EVENT, TOUCH_LONG_PRESS_EVENT, TOUCH_MOVE_EVENT, TOUCH_TAP_EVENT, TOUCH_TRANSFORM_EVENT,
+    TOUCH, TOUCH_INPUT_EVENT, TOUCH_LONG_PRESS_EVENT, TOUCH_MOVE_EVENT, TOUCH_TAP_EVENT, TOUCH_TRANSFORM_EVENT, TOUCHED_EVENT, TouchConfig,
+    TouchForce, TouchId, TouchInputArgs, TouchLongPressArgs, TouchMove, TouchMoveArgs, TouchPhase, TouchPosition, TouchTapArgs,
+    TouchTransformArgs, TouchTransformInfo, TouchTransformMode, TouchUpdate, TouchedArgs,
 };
 
 pub use zng_wgt_input::touch::{
diff --git a/crates/zng/src/undo.rs b/crates/zng/src/undo.rs
index 539825f26..910dd9e42 100644
--- a/crates/zng/src/undo.rs
+++ b/crates/zng/src/undo.rs
@@ -57,12 +57,12 @@
 //! See [`zng_ext_undo`] for the full undo API.
 
 pub use zng_ext_undo::{
-    CommandUndoExt, RedoAction, UndoAction, UndoActionMergeArgs, UndoFullOp, UndoInfo, UndoOp, UndoSelect, UndoSelectInterval,
-    UndoSelectLtEq, UndoSelector, UndoStackInfo, UndoTransaction, UndoVarModifyTag, WidgetInfoUndoExt, WidgetUndoScope, CLEAR_HISTORY_CMD,
-    REDO_CMD, UNDO, UNDO_CMD,
+    CLEAR_HISTORY_CMD, CommandUndoExt, REDO_CMD, RedoAction, UNDO, UNDO_CMD, UndoAction, UndoActionMergeArgs, UndoFullOp, UndoInfo, UndoOp,
+    UndoSelect, UndoSelectInterval, UndoSelectLtEq, UndoSelector, UndoStackInfo, UndoTransaction, UndoVarModifyTag, WidgetInfoUndoExt,
+    WidgetUndoScope,
 };
 
-pub use zng_wgt_undo::{undo_enabled, undo_interval, undo_limit, undo_scope, UndoMix};
+pub use zng_wgt_undo::{UndoMix, undo_enabled, undo_interval, undo_limit, undo_scope};
 
 /// Undo history widget.
 ///
@@ -71,7 +71,7 @@ pub use zng_wgt_undo::{undo_enabled, undo_interval, undo_limit, undo_scope, Undo
 /// See [`zng_wgt_undo_history`] for the full undo API.
 pub mod history {
     pub use zng_wgt_undo_history::{
-        group_by_undo_interval, is_cap_hovered_timestamp, undo_button_style_fn, UndoEntryArgs, UndoHistory, UndoPanelArgs,
-        UndoRedoButtonStyle, UndoStackArgs,
+        UndoEntryArgs, UndoHistory, UndoPanelArgs, UndoRedoButtonStyle, UndoStackArgs, group_by_undo_interval, is_cap_hovered_timestamp,
+        undo_button_style_fn,
     };
 }
diff --git a/crates/zng/src/update.rs b/crates/zng/src/update.rs
index 0b8f50d34..b37912880 100644
--- a/crates/zng/src/update.rs
+++ b/crates/zng/src/update.rs
@@ -28,6 +28,6 @@
 //! See [`zng_app::update`] for the full update API.
 
 pub use zng_app::update::{
-    ContextUpdates, EventUpdate, InfoUpdates, LayoutUpdates, OnUpdateHandle, RenderUpdates, UpdateArgs, UpdateDeliveryList, UpdateOp,
-    UpdateSubscribers, UpdatesTraceUiNodeExt, WeakOnUpdateHandle, WidgetUpdates, UPDATES,
+    ContextUpdates, EventUpdate, InfoUpdates, LayoutUpdates, OnUpdateHandle, RenderUpdates, UPDATES, UpdateArgs, UpdateDeliveryList,
+    UpdateOp, UpdateSubscribers, UpdatesTraceUiNodeExt, WeakOnUpdateHandle, WidgetUpdates,
 };
diff --git a/crates/zng/src/var.rs b/crates/zng/src/var.rs
index 98cb1aa1e..68be9dafb 100644
--- a/crates/zng/src/var.rs
+++ b/crates/zng/src/var.rs
@@ -316,11 +316,11 @@ pub use zng_var::types::{
     WeakReadOnlyVar, WeakWhenVar,
 };
 pub use zng_var::{
+    AnyVar, AnyVarValue, AnyWeakVar, ArcEq, ArcVar, BoxedAnyVar, BoxedAnyWeakVar, BoxedVar, BoxedWeakVar, ContextInitHandle, ContextVar,
+    IntoValue, IntoVar, LocalVar, MergeVarBuilder, ObservableVec, ReadOnlyArcVar, ReadOnlyContextVar, ResponderVar, ResponseVar,
+    TraceValueArgs, VARS, Var, VarCapability, VarHandle, VarHandles, VarHookArgs, VarModify, VarPtr, VarUpdateId, VarValue, WeakVar,
     context_var, expr_var, getter_var, impl_from_and_into_var, merge_var, response_done_var, response_var, state_var, var, var_default,
-    var_from, when_var, AnyVar, AnyVarValue, AnyWeakVar, ArcEq, ArcVar, BoxedAnyVar, BoxedAnyWeakVar, BoxedVar, BoxedWeakVar,
-    ContextInitHandle, ContextVar, IntoValue, IntoVar, LocalVar, MergeVarBuilder, ObservableVec, ReadOnlyArcVar, ReadOnlyContextVar,
-    ResponderVar, ResponseVar, TraceValueArgs, Var, VarCapability, VarHandle, VarHandles, VarHookArgs, VarModify, VarPtr, VarUpdateId,
-    VarValue, WeakVar, VARS,
+    var_from, when_var,
 };
 
 pub use zng_app::widget::{AnyVarSubscribe, OnVarArgs, VarLayout, VarSubscribe};
@@ -335,8 +335,8 @@ pub mod animation {
     /// Common easing functions.
     pub mod easing {
         pub use zng_var::animation::easing::{
-            back, bounce, circ, cubic, cubic_bezier, ease_in, ease_in_out, ease_out, ease_out_in, elastic, expo, linear, none, quad, quart,
-            quint, reverse, reverse_out, sine, step_ceil, step_floor, Bezier, EasingFn, EasingStep, EasingTime,
+            Bezier, EasingFn, EasingStep, EasingTime, back, bounce, circ, cubic, cubic_bezier, ease_in, ease_in_out, ease_out, ease_out_in,
+            elastic, expo, linear, none, quad, quart, quint, reverse, reverse_out, sine, step_ceil, step_floor,
         };
     }
 }
diff --git a/crates/zng/src/widget.rs b/crates/zng/src/widget.rs
index f907bce2c..412fddc25 100644
--- a/crates/zng/src/widget.rs
+++ b/crates/zng/src/widget.rs
@@ -37,12 +37,12 @@
 //!
 //! See [`zng_app::widget`] for the full API.
 
-pub use zng_app::widget::base::{HitTestMode, NonWidgetBase, Parallel, WidgetBase, WidgetExt, WidgetImpl, PARALLEL_VAR};
+pub use zng_app::widget::base::{HitTestMode, NonWidgetBase, PARALLEL_VAR, Parallel, WidgetBase, WidgetExt, WidgetImpl};
 
-pub use zng_app::widget::{widget_impl, widget_set, WidgetId, WidgetUpdateMode, WIDGET};
+pub use zng_app::widget::{WIDGET, WidgetId, WidgetUpdateMode, widget_impl, widget_set};
 
 pub use zng_app::widget::border::{
-    BorderSide, BorderSides, BorderStyle, CornerRadius, CornerRadiusFit, LineOrientation, LineStyle, BORDER,
+    BORDER, BorderSide, BorderSides, BorderStyle, CornerRadius, CornerRadiusFit, LineOrientation, LineStyle,
 };
 pub use zng_app::widget::info::Visibility;
 pub use zng_app::widget::node::ZIndex;
@@ -50,19 +50,19 @@ pub use zng_app::widget::node::ZIndex;
 pub use zng_app::render::RepeatMode;
 
 pub use zng_wgt::{
-    auto_hide, border, border_align, border_over, clip_to_bounds, corner_radius, corner_radius_fit, enabled, hit_test_mode, inline,
-    interactive, is_collapsed, is_disabled, is_enabled, is_hidden, is_hit_testable, is_inited, is_mobile, is_visible, modal,
-    modal_included, modal_includes, on_block, on_blocked_changed, on_collapse, on_deinit, on_disable, on_enable, on_enabled_changed,
-    on_hide, on_info_init, on_init, on_interactivity_changed, on_move, on_node_op, on_pre_block, on_pre_blocked_changed, on_pre_collapse,
-    on_pre_deinit, on_pre_disable, on_pre_enable, on_pre_enabled_changed, on_pre_hide, on_pre_init, on_pre_interactivity_changed,
-    on_pre_move, on_pre_node_op, on_pre_show, on_pre_transform_changed, on_pre_unblock, on_pre_update, on_pre_vis_disable,
-    on_pre_vis_enable, on_pre_vis_enabled_changed, on_pre_visibility_changed, on_show, on_transform_changed, on_unblock, on_update,
-    on_vis_disable, on_vis_enable, on_vis_enabled_changed, on_visibility_changed, parallel, visibility, wgt_fn, z_index, EditorRequestArgs,
-    OnNodeOpArgs, WeakWidgetFn, Wgt, WidgetFn, EDITORS, IS_MOBILE_VAR,
+    EDITORS, EditorRequestArgs, IS_MOBILE_VAR, OnNodeOpArgs, WeakWidgetFn, Wgt, WidgetFn, auto_hide, border, border_align, border_over,
+    clip_to_bounds, corner_radius, corner_radius_fit, enabled, hit_test_mode, inline, interactive, is_collapsed, is_disabled, is_enabled,
+    is_hidden, is_hit_testable, is_inited, is_mobile, is_visible, modal, modal_included, modal_includes, on_block, on_blocked_changed,
+    on_collapse, on_deinit, on_disable, on_enable, on_enabled_changed, on_hide, on_info_init, on_init, on_interactivity_changed, on_move,
+    on_node_op, on_pre_block, on_pre_blocked_changed, on_pre_collapse, on_pre_deinit, on_pre_disable, on_pre_enable,
+    on_pre_enabled_changed, on_pre_hide, on_pre_init, on_pre_interactivity_changed, on_pre_move, on_pre_node_op, on_pre_show,
+    on_pre_transform_changed, on_pre_unblock, on_pre_update, on_pre_vis_disable, on_pre_vis_enable, on_pre_vis_enabled_changed,
+    on_pre_visibility_changed, on_show, on_transform_changed, on_unblock, on_update, on_vis_disable, on_vis_enable, on_vis_enabled_changed,
+    on_visibility_changed, parallel, visibility, wgt_fn, z_index,
 };
 
 #[cfg(feature = "image")]
-pub use zng_wgt_image::border::{border_img, border_img_fill, border_img_repeat, BorderRepeats};
+pub use zng_wgt_image::border::{BorderRepeats, border_img, border_img_fill, border_img_repeat};
 
 pub use zng_wgt_fill::{
     background, background_color, background_conic, background_fn, background_gradient, background_radial, foreground, foreground_color,
@@ -129,11 +129,11 @@ pub use zng_wgt_fill::{
 /// See [`zng_app::widget::builder`] for the full API.
 pub mod builder {
     pub use zng_app::widget::builder::{
-        property_args, property_id, property_info, property_input_types, source_location, widget_type, AnyWhenArcWidgetHandlerBuilder,
-        ArcWidgetHandler, BuilderProperty, BuilderPropertyMut, BuilderPropertyRef, Importance, InputKind, NestGroup, NestPosition,
-        PropertyArgs, PropertyBuildAction, PropertyBuildActionArgs, PropertyBuildActions, PropertyBuildActionsWhenData, PropertyId,
-        PropertyInfo, PropertyInput, PropertyInputTypes, PropertyNewArgs, SourceLocation, WhenBuildAction, WhenInfo, WhenInput,
-        WhenInputMember, WhenInputVar, WidgetBuilder, WidgetBuilderProperties, WidgetBuilding, WidgetType,
+        AnyWhenArcWidgetHandlerBuilder, ArcWidgetHandler, BuilderProperty, BuilderPropertyMut, BuilderPropertyRef, Importance, InputKind,
+        NestGroup, NestPosition, PropertyArgs, PropertyBuildAction, PropertyBuildActionArgs, PropertyBuildActions,
+        PropertyBuildActionsWhenData, PropertyId, PropertyInfo, PropertyInput, PropertyInputTypes, PropertyNewArgs, SourceLocation,
+        WhenBuildAction, WhenInfo, WhenInput, WhenInputMember, WhenInputVar, WidgetBuilder, WidgetBuilderProperties, WidgetBuilding,
+        WidgetType, property_args, property_id, property_info, property_input_types, source_location, widget_type,
     };
 }
 
@@ -193,11 +193,11 @@ pub mod builder {
 /// ```
 pub mod info {
     pub use zng_app::widget::info::{
-        iter, HitInfo, HitTestInfo, InlineSegmentInfo, InteractionPath, Interactivity, InteractivityChangedArgs, InteractivityFilterArgs,
-        ParallelBuilder, RelativeHitZ, TransformChangedArgs, TreeFilter, VisibilityChangedArgs, WidgetBorderInfo, WidgetBoundsInfo,
+        HitInfo, HitTestInfo, INTERACTIVITY_CHANGED_EVENT, InlineSegmentInfo, InteractionPath, Interactivity, InteractivityChangedArgs,
+        InteractivityFilterArgs, ParallelBuilder, RelativeHitZ, TRANSFORM_CHANGED_EVENT, TransformChangedArgs, TreeFilter,
+        VISIBILITY_CHANGED_EVENT, VisibilityChangedArgs, WIDGET_INFO_CHANGED_EVENT, WidgetBorderInfo, WidgetBoundsInfo,
         WidgetDescendantsRange, WidgetInfo, WidgetInfoBuilder, WidgetInfoChangedArgs, WidgetInfoMeta, WidgetInfoTree, WidgetInfoTreeStats,
-        WidgetInlineInfo, WidgetInlineMeasure, WidgetPath, INTERACTIVITY_CHANGED_EVENT, TRANSFORM_CHANGED_EVENT, VISIBILITY_CHANGED_EVENT,
-        WIDGET_INFO_CHANGED_EVENT,
+        WidgetInlineInfo, WidgetInlineMeasure, WidgetPath, iter,
     };
 
     /// Accessibility metadata types.
@@ -219,11 +219,11 @@ pub mod info {
 /// [`UiNodeList`]: crate::prelude::UiNodeList
 pub mod node {
     pub use zng_app::widget::node::{
-        extend_widget, match_node, match_node_leaf, match_node_list, match_node_typed, match_widget, ui_vec, AdoptiveChildNode,
-        AdoptiveNode, ArcNode, ArcNodeList, BoxedUiNode, BoxedUiNodeList, DefaultPanelListData, EditableUiNodeList, EditableUiNodeListRef,
-        FillUiNode, MatchNodeChild, MatchNodeChildren, MatchWidgetChild, NilUiNode, OffsetUiListObserver, PanelList, PanelListData,
-        PanelListRange, SortingList, UiNode, UiNodeList, UiNodeListChain, UiNodeListChainImpl, UiNodeListObserver, UiNodeOp,
-        UiNodeOpMethod, UiVec, WeakNode, WeakNodeList, WhenUiNodeBuilder, WhenUiNodeListBuilder, SORTING_LIST, Z_INDEX,
+        AdoptiveChildNode, AdoptiveNode, ArcNode, ArcNodeList, BoxedUiNode, BoxedUiNodeList, DefaultPanelListData, EditableUiNodeList,
+        EditableUiNodeListRef, FillUiNode, MatchNodeChild, MatchNodeChildren, MatchWidgetChild, NilUiNode, OffsetUiListObserver, PanelList,
+        PanelListData, PanelListRange, SORTING_LIST, SortingList, UiNode, UiNodeList, UiNodeListChain, UiNodeListChainImpl,
+        UiNodeListObserver, UiNodeOp, UiNodeOpMethod, UiVec, WeakNode, WeakNodeList, WhenUiNodeBuilder, WhenUiNodeListBuilder, Z_INDEX,
+        extend_widget, match_node, match_node_leaf, match_node_list, match_node_typed, match_widget, ui_vec,
     };
 
     pub use zng_wgt::node::{
@@ -308,7 +308,7 @@ pub mod node {
 ///
 /// impl Foo {
 ///     /// Custom build.
-///     pub fn widget_build(&mut self) -> impl UiNode {
+///     pub fn widget_build(&mut self) -> impl UiNode + use<> {
 ///         println!("on build!");
 ///         WidgetBase::widget_build(self)
 ///     }
diff --git a/crates/zng/src/window.rs b/crates/zng/src/window.rs
index 8b0504624..e28d28f0e 100644
--- a/crates/zng/src/window.rs
+++ b/crates/zng/src/window.rs
@@ -100,15 +100,15 @@
 //!
 //! See [`zng_ext_window`], [`zng_app::window`] and [`zng_wgt_window`] for the full window API.
 
-pub use zng_app::window::{MonitorId, WindowId, WindowMode, WINDOW};
+pub use zng_app::window::{MonitorId, WINDOW, WindowId, WindowMode};
 
 pub use zng_ext_window::{
-    AppRunWindowExt, AutoSize, CloseWindowResult, FocusIndicator, FrameCaptureMode, FrameImageReadyArgs, HeadlessAppWindowExt,
-    HeadlessMonitor, ImeArgs, MonitorInfo, MonitorQuery, MonitorsChangedArgs, ParallelWin, RenderMode, StartPosition, VideoMode,
-    WINDOW_Ext, WidgetInfoBuilderImeArea, WidgetInfoImeArea, WindowButton, WindowChangedArgs, WindowCloseArgs, WindowCloseRequestedArgs,
-    WindowIcon, WindowLoadingHandle, WindowOpenArgs, WindowRoot, WindowRootExtenderArgs, WindowState, WindowStateAllowed, WindowVars,
-    FRAME_IMAGE_READY_EVENT, IME_EVENT, MONITORS, MONITORS_CHANGED_EVENT, WINDOWS, WINDOW_CHANGED_EVENT, WINDOW_CLOSE_EVENT,
-    WINDOW_CLOSE_REQUESTED_EVENT, WINDOW_LOAD_EVENT, WINDOW_OPEN_EVENT,
+    AppRunWindowExt, AutoSize, CloseWindowResult, FRAME_IMAGE_READY_EVENT, FocusIndicator, FrameCaptureMode, FrameImageReadyArgs,
+    HeadlessAppWindowExt, HeadlessMonitor, IME_EVENT, ImeArgs, MONITORS, MONITORS_CHANGED_EVENT, MonitorInfo, MonitorQuery,
+    MonitorsChangedArgs, ParallelWin, RenderMode, StartPosition, VideoMode, WINDOW_CHANGED_EVENT, WINDOW_CLOSE_EVENT,
+    WINDOW_CLOSE_REQUESTED_EVENT, WINDOW_Ext, WINDOW_LOAD_EVENT, WINDOW_OPEN_EVENT, WINDOWS, WidgetInfoBuilderImeArea, WidgetInfoImeArea,
+    WindowButton, WindowChangedArgs, WindowCloseArgs, WindowCloseRequestedArgs, WindowIcon, WindowLoadingHandle, WindowOpenArgs,
+    WindowRoot, WindowRootExtenderArgs, WindowState, WindowStateAllowed, WindowVars,
 };
 
 /// Window commands.
@@ -143,7 +143,7 @@ pub use zng_wgt_window::events::{
 /// [`cmd::INSPECT_CMD`]: crate::window::cmd::INSPECT_CMD
 #[cfg(feature = "inspector")]
 pub mod inspector {
-    pub use zng_wgt_inspector::debug::{show_bounds, show_center_points, show_directional_query, show_hit_test, show_rows, InspectMode};
+    pub use zng_wgt_inspector::debug::{InspectMode, show_bounds, show_center_points, show_directional_query, show_hit_test, show_rows};
 }
 
 /// Default handler registered in mobile platforms.
diff --git a/crates/zng/src/wrap.rs b/crates/zng/src/wrap.rs
index e0f507cdb..55b576984 100644
--- a/crates/zng/src/wrap.rs
+++ b/crates/zng/src/wrap.rs
@@ -37,5 +37,5 @@
 //! See [`zng_wgt_wrap`] for the full view API.
 
 pub use zng_wgt_wrap::{
-    get_index, get_index_len, get_rev_index, is_even, is_first, is_last, is_odd, lazy_sample, lazy_size, node, WidgetInfoWrapExt, Wrap,
+    WidgetInfoWrapExt, Wrap, get_index, get_index_len, get_rev_index, is_even, is_first, is_last, is_odd, lazy_sample, lazy_size, node,
 };
diff --git a/docs/contribute-example.md b/docs/contribute-example.md
index 47882037c..6f8026e47 100644
--- a/docs/contribute-example.md
+++ b/docs/contribute-example.md
@@ -9,7 +9,7 @@ To contribute an example, add the new example crate in `examples/<example-name>`
 name = "zng-example-<example-name>"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt"] }
diff --git a/examples/animation/Cargo.toml b/examples/animation/Cargo.toml
index 61f83f26c..eddf0d66f 100644
--- a/examples/animation/Cargo.toml
+++ b/examples/animation/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-animation"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt"] }
diff --git a/examples/animation/src/main.rs b/examples/animation/src/main.rs
index 5703cafed..1eb87dcbc 100644
--- a/examples/animation/src/main.rs
+++ b/examples/animation/src/main.rs
@@ -5,8 +5,8 @@ use zng::{
     color::Rgba,
     layout::{margin, size},
     prelude::*,
-    var::animation::easing::EasingFn,
     var::VARS,
+    var::animation::easing::EasingFn,
     widget::{background_color, corner_radius},
 };
 
diff --git a/examples/border/Cargo.toml b/examples/border/Cargo.toml
index 329cea4ab..fbd43725d 100644
--- a/examples/border/Cargo.toml
+++ b/examples/border/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-border"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt"] }
diff --git a/examples/button/Cargo.toml b/examples/button/Cargo.toml
index b29491fcc..f9cec11df 100644
--- a/examples/button/Cargo.toml
+++ b/examples/button/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-button"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt", "material_icons"] }
diff --git a/examples/button/src/main.rs b/examples/button/src/main.rs
index aad14ecc9..7c1585646 100644
--- a/examples/button/src/main.rs
+++ b/examples/button/src/main.rs
@@ -8,7 +8,7 @@ use zng::{
     prelude::*,
     stack,
     var::ObservableVec,
-    widget::{node::EditableUiNodeList, LineStyle},
+    widget::{LineStyle, node::EditableUiNodeList},
 };
 
 fn main() {
diff --git a/examples/calculator/Cargo.toml b/examples/calculator/Cargo.toml
index 8cf6e2ca7..7d5d6d319 100644
--- a/examples/calculator/Cargo.toml
+++ b/examples/calculator/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-calculator"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt"] }
diff --git a/examples/calculator/src/main.rs b/examples/calculator/src/main.rs
index 5dcb87bc5..fa8b7de32 100644
--- a/examples/calculator/src/main.rs
+++ b/examples/calculator/src/main.rs
@@ -2,7 +2,7 @@
 
 use std::convert::TryInto;
 use zng::{
-    gesture::{click_shortcut, Shortcuts},
+    gesture::{Shortcuts, click_shortcut},
     prelude::*,
 };
 
diff --git a/examples/config/Cargo.toml b/examples/config/Cargo.toml
index 75398e71b..64e97772a 100644
--- a/examples/config/Cargo.toml
+++ b/examples/config/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-config"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt", "material_icons"] }
diff --git a/examples/countdown/Cargo.toml b/examples/countdown/Cargo.toml
index c02de56e2..20cee2be2 100644
--- a/examples/countdown/Cargo.toml
+++ b/examples/countdown/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-countdown"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view"] }
diff --git a/examples/cursor/Cargo.toml b/examples/cursor/Cargo.toml
index fc23dec9f..bbba24770 100644
--- a/examples/cursor/Cargo.toml
+++ b/examples/cursor/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-cursor"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt"] }
diff --git a/examples/extend-view/Cargo.toml b/examples/extend-view/Cargo.toml
index da9db428e..e0340ec3b 100644
--- a/examples/extend-view/Cargo.toml
+++ b/examples/extend-view/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-extend-view"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view"] }
diff --git a/examples/extend-view/src/using_blob.rs b/examples/extend-view/src/using_blob.rs
index ef8ae33b4..b96941f40 100644
--- a/examples/extend-view/src/using_blob.rs
+++ b/examples/extend-view/src/using_blob.rs
@@ -31,9 +31,9 @@ pub mod view_side {
         extensions::{AsyncBlobRasterizer, BlobExtension, RenderItemArgs, RenderUpdateArgs, RendererExtension},
         webrender::{
             api::{
-                units::{BlobDirtyRect, DeviceIntRect, DeviceIntSize, LayoutRect},
                 BlobImageError, BlobImageKey, BlobImageParams, BlobImageResult, ColorF, CommonItemProperties, ImageDescriptor,
                 ImageDescriptorFlags, ImageFormat, RasterizedBlobImage,
+                units::{BlobDirtyRect, DeviceIntRect, DeviceIntSize, LayoutRect},
             },
             euclid,
         },
diff --git a/examples/extend-view/src/using_display_items.rs b/examples/extend-view/src/using_display_items.rs
index 647341a48..dcb4c2429 100644
--- a/examples/extend-view/src/using_display_items.rs
+++ b/examples/extend-view/src/using_display_items.rs
@@ -128,8 +128,8 @@ pub mod view_side {
         extensions::{PxToWr as _, RenderItemArgs, RenderUpdateArgs, RendererExtension},
         webrender::{
             api::{
-                units::{LayoutPoint, LayoutRect},
                 ColorF, CommonItemProperties,
+                units::{LayoutPoint, LayoutRect},
             },
             euclid,
         },
diff --git a/examples/extend-view/src/using_gl_texture.rs b/examples/extend-view/src/using_gl_texture.rs
index 2bbb1ee26..8f67ffd95 100644
--- a/examples/extend-view/src/using_gl_texture.rs
+++ b/examples/extend-view/src/using_gl_texture.rs
@@ -27,9 +27,9 @@ pub mod view_side {
         extensions::{PxToWr as _, RenderItemArgs, RendererExtension},
         gleam::gl,
         webrender::api::{
-            units::{DeviceIntSize, TexelRect},
             AlphaType, ColorF, CommonItemProperties, ExternalImageData, ExternalImageId, ExternalImageType, ImageDescriptor,
             ImageDescriptorFlags, ImageFormat, ImageKey, ImageRendering,
+            units::{DeviceIntSize, TexelRect},
         },
     };
     use zng_view_api::api_extension::ApiExtensionId;
diff --git a/examples/focus/Cargo.toml b/examples/focus/Cargo.toml
index 4fc28dd9d..79b2560a9 100644
--- a/examples/focus/Cargo.toml
+++ b/examples/focus/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-focus"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt"] }
diff --git a/examples/focus/src/main.rs b/examples/focus/src/main.rs
index bf0c48958..e43bcbd15 100644
--- a/examples/focus/src/main.rs
+++ b/examples/focus/src/main.rs
@@ -4,9 +4,9 @@ use zng::{
     button,
     color::filter::drop_shadow,
     focus::{
+        DirectionalNav, FOCUS_CHANGED_EVENT, FocusChangedArgs, FocusClickBehavior, FocusRequest, FocusTarget, TabIndex, TabNav,
         alt_focus_scope, directional_nav, focus_click_behavior, focus_scope, focus_shortcut, focusable, is_focused, is_return_focus,
-        return_focus_on_deinit, tab_index, tab_nav, DirectionalNav, FocusChangedArgs, FocusClickBehavior, FocusRequest, FocusTarget,
-        TabIndex, TabNav, FOCUS_CHANGED_EVENT,
+        return_focus_on_deinit, tab_index, tab_nav,
     },
     font::FontName,
     gesture::ClickArgs,
diff --git a/examples/gradient/Cargo.toml b/examples/gradient/Cargo.toml
index c1a2a1bd4..f2c932c8d 100644
--- a/examples/gradient/Cargo.toml
+++ b/examples/gradient/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-gradient"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt"] }
diff --git a/examples/gradient/src/main.rs b/examples/gradient/src/main.rs
index 9ffd68079..4d0853a4c 100644
--- a/examples/gradient/src/main.rs
+++ b/examples/gradient/src/main.rs
@@ -3,9 +3,9 @@
 use zng::{
     color::{
         self,
-        gradient::{linear_gradient, stops, GradientStops},
+        gradient::{GradientStops, linear_gradient, stops},
     },
-    layout::{size, Line},
+    layout::{Line, size},
     prelude::*,
     stack::stack_nodes,
     text::ToTxt,
diff --git a/examples/headless/Cargo.toml b/examples/headless/Cargo.toml
index 2277ae63d..bbc93f9fa 100644
--- a/examples/headless/Cargo.toml
+++ b/examples/headless/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-headless"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt"] }
diff --git a/examples/headless/src/headless.rs b/examples/headless/src/headless.rs
index e312e65e3..9ee1dc4e0 100644
--- a/examples/headless/src/headless.rs
+++ b/examples/headless/src/headless.rs
@@ -2,7 +2,7 @@ use std::io::Write as _;
 use zng::{
     color::{
         self,
-        gradient::{linear_gradient, GradientStops},
+        gradient::{GradientStops, linear_gradient},
     },
     prelude::*,
     stack::stack_nodes,
diff --git a/examples/hot-reload-lib/Cargo.toml b/examples/hot-reload-lib/Cargo.toml
index 57a24c94a..dd3f726b8 100644
--- a/examples/hot-reload-lib/Cargo.toml
+++ b/examples/hot-reload-lib/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "zng-example-hot-reload-lib"
 version = "0.0.0"
-edition = "2021"
+edition = "2024"
 publish = false
 description = "Hot reload library example for `hot_reload` example"
 
diff --git a/examples/hot-reload/Cargo.toml b/examples/hot-reload/Cargo.toml
index a20e198a9..fd087c5ab 100644
--- a/examples/hot-reload/Cargo.toml
+++ b/examples/hot-reload/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-hot-reload"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 hot-reload-lib = { path = "../hot-reload-lib", package = "zng-example-hot-reload-lib" }
diff --git a/examples/icon/Cargo.toml b/examples/icon/Cargo.toml
index af46ab074..d6a831d5e 100644
--- a/examples/icon/Cargo.toml
+++ b/examples/icon/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-icon"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt", "material_icons"] }
diff --git a/examples/icon/src/main.rs b/examples/icon/src/main.rs
index 9e4735434..5c44c0fb0 100644
--- a/examples/icon/src/main.rs
+++ b/examples/icon/src/main.rs
@@ -8,13 +8,13 @@ use zng::{
     color::filter::{backdrop_blur, drop_shadow, opacity},
     container,
     data_view::{DataView, DataViewArgs},
-    focus::{directional_nav, focus_scope, focus_shortcut, tab_nav, DirectionalNav, TabNav},
+    focus::{DirectionalNav, TabNav, directional_nav, focus_scope, focus_shortcut, tab_nav},
     font::FontName,
-    gesture::{on_click, ClickArgs},
+    gesture::{ClickArgs, on_click},
     icon::{self, GlyphIcon, Icon},
     layout::{align, margin, padding},
     prelude::*,
-    scroll::{lazy, LazyMode, ScrollMode},
+    scroll::{LazyMode, ScrollMode, lazy},
     widget::{background_color, corner_radius},
     wrap,
 };
diff --git a/examples/image/Cargo.toml b/examples/image/Cargo.toml
index 93a3004ff..f711c2e9d 100644
--- a/examples/image/Cargo.toml
+++ b/examples/image/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-image"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt", "http", "svg"] }
diff --git a/examples/image/src/main.rs b/examples/image/src/main.rs
index af653f1e7..3cc67e401 100644
--- a/examples/image/src/main.rs
+++ b/examples/image/src/main.rs
@@ -7,16 +7,16 @@ use zng::{
     checkerboard::Checkerboard,
     clipboard,
     color::{
-        filter::{drop_shadow, filter, mix_blend, Filter},
+        filter::{Filter, drop_shadow, filter, mix_blend},
         gradient::stops,
     },
-    image::{self, img_error_fn, img_loading_fn, mask::mask_image, ImageDownscale, ImageFit, ImageLimits, ImgErrorArgs, IMAGES},
+    image::{self, IMAGES, ImageDownscale, ImageFit, ImageLimits, ImgErrorArgs, img_error_fn, img_loading_fn, mask::mask_image},
     layout::{align, margin, padding, size},
     mouse,
     prelude::*,
     scroll::ScrollMode,
     task::http,
-    widget::{background_color, border, BorderSides},
+    widget::{BorderSides, background_color, border},
     window::{RenderMode, WindowState},
 };
 use zng_wgt_webrender_debug as wr;
diff --git a/examples/layer/Cargo.toml b/examples/layer/Cargo.toml
index dcdb84d0d..016112725 100644
--- a/examples/layer/Cargo.toml
+++ b/examples/layer/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-layer"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt"] }
diff --git a/examples/layer/src/main.rs b/examples/layer/src/main.rs
index 89f9051ef..70b0b074e 100644
--- a/examples/layer/src/main.rs
+++ b/examples/layer/src/main.rs
@@ -3,11 +3,11 @@
 use zng::{
     button,
     color::filter::opacity,
-    focus::{directional_nav, focus_scope, tab_nav, DirectionalNav, TabNav},
+    focus::{DirectionalNav, TabNav, directional_nav, focus_scope, tab_nav},
     layer::AnchorOffset,
     layout::{align, margin, offset},
     prelude::*,
-    widget::{background_color, border, hit_test_mode, HitTestMode},
+    widget::{HitTestMode, background_color, border, hit_test_mode},
 };
 
 fn main() {
diff --git a/examples/localize/Cargo.toml b/examples/localize/Cargo.toml
index db33c1f0a..ba00d5adb 100644
--- a/examples/localize/Cargo.toml
+++ b/examples/localize/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-localize"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt"] }
diff --git a/examples/localize/src/main.rs b/examples/localize/src/main.rs
index db6d4267c..f8e06aff0 100644
--- a/examples/localize/src/main.rs
+++ b/examples/localize/src/main.rs
@@ -8,7 +8,7 @@ use std::sync::Arc;
 use zng::{
     clipboard::{COPY_CMD, PASTE_CMD},
     color::filter::drop_shadow,
-    focus::{alt_focus_scope, focus_click_behavior, FocusClickBehavior},
+    focus::{FocusClickBehavior, alt_focus_scope, focus_click_behavior},
     image,
     l10n::{LangFilePath, LangMap},
     layout::align,
diff --git a/examples/markdown/Cargo.toml b/examples/markdown/Cargo.toml
index 1b0e1779e..ff935702b 100644
--- a/examples/markdown/Cargo.toml
+++ b/examples/markdown/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-markdown"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt", "http", "material_icons"] }
diff --git a/examples/multi/Cargo.toml b/examples/multi/Cargo.toml
index 0c84c7296..ef1cf59c7 100644
--- a/examples/multi/Cargo.toml
+++ b/examples/multi/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-multi"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [lib]
 # "cdylib" required by Android and Wasm builds
diff --git a/examples/multi/src/lib.rs b/examples/multi/src/lib.rs
index dae02dc6b..7de1c81ee 100644
--- a/examples/multi/src/lib.rs
+++ b/examples/multi/src/lib.rs
@@ -40,7 +40,7 @@ mod android {
     use super::app;
     use zng::view_process::default::*;
 
-    #[no_mangle]
+    #[unsafe(no_mangle)]
     fn android_main(app: android::AndroidApp) {
         zng::env::init!();
 
@@ -59,7 +59,7 @@ mod android {
 mod ios {
     use zng::view_process::default::{run_same_process, *};
 
-    #[no_mangle]
+    #[unsafe(no_mangle)]
     pub extern "C" fn ios_main() {
         zng::env::init!();
 
diff --git a/examples/respawn/Cargo.toml b/examples/respawn/Cargo.toml
index e432c9b2a..a249b6e1c 100644
--- a/examples/respawn/Cargo.toml
+++ b/examples/respawn/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-respawn"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view"] }
diff --git a/examples/scroll/Cargo.toml b/examples/scroll/Cargo.toml
index 10c02785b..132500fb7 100644
--- a/examples/scroll/Cargo.toml
+++ b/examples/scroll/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-scroll"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt", "material_icons_outlined"] }
diff --git a/examples/scroll/src/main.rs b/examples/scroll/src/main.rs
index d5ad865c3..e2043c4a1 100644
--- a/examples/scroll/src/main.rs
+++ b/examples/scroll/src/main.rs
@@ -1,7 +1,7 @@
 //! Demonstrates the `Scroll!` widget and scroll commands.
 
 use zng::{
-    mouse::{cursor, CursorIcon},
+    mouse::{CursorIcon, cursor},
     prelude::*,
     scroll::cmd::ScrollToMode,
 };
diff --git a/examples/shortcut/Cargo.toml b/examples/shortcut/Cargo.toml
index 50d4dd7ef..33248f0d0 100644
--- a/examples/shortcut/Cargo.toml
+++ b/examples/shortcut/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-shortcut"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt"] }
diff --git a/examples/text/Cargo.toml b/examples/text/Cargo.toml
index 83b19e82f..432465c63 100644
--- a/examples/text/Cargo.toml
+++ b/examples/text/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-text"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt", "material_icons"] }
diff --git a/examples/text/src/editor.rs b/examples/text/src/editor.rs
index 8e32d9a47..9add262c4 100644
--- a/examples/text/src/editor.rs
+++ b/examples/text/src/editor.rs
@@ -5,16 +5,16 @@ use zng::{
     button,
     clipboard::{COPY_CMD, CUT_CMD, PASTE_CMD},
     color::filter::opacity,
-    focus::{alt_focus_scope, focus_click_behavior, FocusClickBehavior},
+    focus::{FocusClickBehavior, alt_focus_scope, focus_click_behavior},
     gesture::click_shortcut,
     icon::{self, ICONS},
-    layout::{align, margin, padding, Dip},
+    layout::{Dip, align, margin, padding},
     prelude::*,
     rule_line,
     scroll::ScrollMode,
     undo::UNDO_CMD,
     var::ArcVar,
-    widget::{corner_radius, enabled, visibility, Visibility},
+    widget::{Visibility, corner_radius, enabled, visibility},
     window::WindowRoot,
 };
 
diff --git a/examples/text/src/main.rs b/examples/text/src/main.rs
index da99dc65c..46a715ff7 100644
--- a/examples/text/src/main.rs
+++ b/examples/text/src/main.rs
@@ -6,9 +6,9 @@ use zng::{
     gesture::{click_shortcut, is_hovered},
     layout::{align, margin, padding},
     prelude::*,
-    text::{font_family, font_weight, UnderlinePosition, UnderlineSkip},
+    text::{UnderlinePosition, UnderlineSkip, font_family, font_weight},
     var::ArcVar,
-    widget::{background_color, corner_radius, LineStyle},
+    widget::{LineStyle, background_color, corner_radius},
 };
 
 mod editor;
diff --git a/examples/transform/Cargo.toml b/examples/transform/Cargo.toml
index 14e39a36c..4ce07a78b 100644
--- a/examples/transform/Cargo.toml
+++ b/examples/transform/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-transform"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt"] }
diff --git a/examples/transform/src/main.rs b/examples/transform/src/main.rs
index ef7b9cb6a..b5f42477f 100644
--- a/examples/transform/src/main.rs
+++ b/examples/transform/src/main.rs
@@ -9,7 +9,7 @@ use zng::{
     text::font_size,
     toggle,
     var::animation::{self, easing::EasingStep},
-    widget::{background_color, border, corner_radius, z_index, BorderStyle, ZIndex},
+    widget::{BorderStyle, ZIndex, background_color, border, corner_radius, z_index},
     window::WindowState,
 };
 
diff --git a/examples/window/Cargo.toml b/examples/window/Cargo.toml
index 8ad5d2d18..2f41dfbc3 100644
--- a/examples/window/Cargo.toml
+++ b/examples/window/Cargo.toml
@@ -2,7 +2,7 @@
 name = "zng-example-window"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 zng = { path = "../../crates/zng", features = ["view_prebuilt", "inspector", "material_icons"] }
diff --git a/examples/window/src/main.rs b/examples/window/src/main.rs
index d73e7318f..7156448ab 100644
--- a/examples/window/src/main.rs
+++ b/examples/window/src/main.rs
@@ -9,7 +9,7 @@ use zng::{
     layout::*,
     prelude::*,
     scroll::ScrollMode,
-    widget::{background_color, corner_radius, enabled, visibility, LineStyle},
+    widget::{LineStyle, background_color, corner_radius, enabled, visibility},
     window::{FocusIndicator, FrameCaptureMode, FrameImageReadyArgs, WindowChangedArgs, WindowState},
 };
 
diff --git a/tools/cargo-do/Cargo.toml b/tools/cargo-do/Cargo.toml
index f75b3e6b4..3abd00780 100644
--- a/tools/cargo-do/Cargo.toml
+++ b/tools/cargo-do/Cargo.toml
@@ -2,7 +2,7 @@
 name = "cargo-do"
 version = "0.0.0"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 description = "Run tasks for managing this project. Implemented in \"./tools/cargo-do\"."
 
 [dependencies]
diff --git a/tools/cargo-do/src/util.rs b/tools/cargo-do/src/util.rs
index 6039380b8..f7c80341b 100644
--- a/tools/cargo-do/src/util.rs
+++ b/tools/cargo-do/src/util.rs
@@ -146,11 +146,7 @@ pub fn take_option<'a>(args: &mut Vec<&'a str>, option: &[&str], value_name: &st
         i += 1;
     }
 
-    if values.is_empty() {
-        None
-    } else {
-        Some(values)
-    }
+    if values.is_empty() { None } else { Some(values) }
 }
 
 // Parses the initial input. Returns ("task-name", ["task", "args"]).
@@ -374,11 +370,7 @@ pub fn c_w() -> &'static str {
     color("\x1B[0m")
 }
 fn color(color: &str) -> &str {
-    if TaskInfo::dump() || !ansi_enabled() {
-        ""
-    } else {
-        color
-    }
+    if TaskInfo::dump() || !ansi_enabled() { "" } else { color }
 }
 #[allow(unreachable_code)]
 fn ansi_enabled() -> bool {
diff --git a/tools/color-gen/Cargo.toml b/tools/color-gen/Cargo.toml
index e1abbfea6..c92495aec 100644
--- a/tools/color-gen/Cargo.toml
+++ b/tools/color-gen/Cargo.toml
@@ -2,7 +2,7 @@
 name = "color-gen"
 version = "0.1.0"
 authors = ["The Zng Project Developers"]
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 serde = { version = "1.0", features = ["derive"] }


Test patch:
diff --git a/crates/zng-app/src/tests/ui_node.rs b/crates/zng-app/src/tests/ui_node.rs
index 5b877b595..30613b162 100644
--- a/crates/zng-app/src/tests/ui_node.rs
+++ b/crates/zng-app/src/tests/ui_node.rs
@@ -2,19 +2,18 @@
 //!
 //! Note: Compile error tests are in the integration tests folder: `tests/macro-tests/ui_node`
 
-use util::{assert_did_not_trace, assert_only_traced, TestTraceNode};
+use util::{TestTraceNode, assert_did_not_trace, assert_only_traced};
 use zng_app_proc_macros::ui_node;
 use zng_layout::unit::{Px, PxConstraints2d};
 
 use crate::{
-    ui_vec,
+    APP, ui_vec,
     update::WidgetUpdates,
     widget::{
+        WIDGET, WidgetUpdateMode,
         node::{UiNode, UiNodeList},
-        WidgetUpdateMode, WIDGET,
     },
     window::WINDOW,
-    APP,
 };
 
 #[test]
@@ -203,7 +202,7 @@ mod util {
     use std::sync::Arc;
     use zng_app_proc_macros::ui_node;
     use zng_layout::unit::{Px, PxSize};
-    use zng_state_map::{static_id, StateId};
+    use zng_state_map::{StateId, static_id};
 
     static_id! {
         pub(super) static ref TRACE_ID: StateId<Vec<TraceRef>>;
@@ -266,9 +265,9 @@ mod util {
         render::{FrameBuilder, FrameUpdate},
         update::{EventUpdate, UpdateDeliveryList, WidgetUpdates},
         widget::{
+            WIDGET, WidgetId, WidgetUpdateMode,
             info::{WidgetInfoBuilder, WidgetLayout, WidgetMeasure},
             node::UiNode,
-            WidgetId, WidgetUpdateMode, WIDGET,
         },
         window::WINDOW,
     };
diff --git a/crates/zng-app/src/tests/ui_node_list.rs b/crates/zng-app/src/tests/ui_node_list.rs
index f269f0ea5..814f9801f 100644
--- a/crates/zng-app/src/tests/ui_node_list.rs
+++ b/crates/zng-app/src/tests/ui_node_list.rs
@@ -4,14 +4,13 @@ use zng_app_proc_macros::{property, widget};
 use zng_var::ContextInitHandle;
 
 use crate::{
-    ui_vec,
+    APP, ui_vec,
     widget::{
+        WidgetUpdateMode,
         base::PARALLEL_VAR,
         node::{PanelList, UiNode, UiNodeList, UiVec},
-        WidgetUpdateMode,
     },
     window::WINDOW,
-    APP,
 };
 
 use super::widget::EmptyWgt;
@@ -119,15 +118,15 @@ mod util {
         thread::{self, ThreadId},
     };
 
-    use zng_app_context::{context_local, ContextLocal};
+    use zng_app_context::{ContextLocal, context_local};
     use zng_app_proc_macros::property;
     use zng_state_map::StateId;
     use zng_unique_id::static_id;
     use zng_var::IntoValue;
 
     use crate::widget::{
-        node::{match_node, match_node_list, UiNode, UiNodeList, UiNodeOp},
-        WidgetUpdateMode, WIDGET,
+        WIDGET, WidgetUpdateMode,
+        node::{UiNode, UiNodeList, UiNodeOp, match_node, match_node_list},
     };
 
     pub use super::super::widget::util::*;
diff --git a/crates/zng-app/src/tests/widget.rs b/crates/zng-app/src/tests/widget.rs
index 0ae02badb..91c90faf0 100644
--- a/crates/zng-app/src/tests/widget.rs
+++ b/crates/zng-app/src/tests/widget.rs
@@ -6,10 +6,10 @@ use zng_app_proc_macros::{property, widget};
 use zng_var::{IntoValue, Var};
 
 use crate::{
-    widget::{builder::WidgetBuilder, node::UiNode, WidgetId, WidgetUpdateMode, WIDGET},
+    APP,
+    widget::{WIDGET, WidgetId, WidgetUpdateMode, builder::WidgetBuilder, node::UiNode},
     widget_set,
     window::WINDOW,
-    APP,
 };
 
 use self::util::Position;
@@ -1131,8 +1131,8 @@ pub mod util {
     use zng_var::{IntoValue, IntoVar, Var};
 
     use crate::widget::{
-        node::{match_node, UiNode, UiNodeOp},
-        WidgetUpdateMode, WIDGET,
+        WIDGET, WidgetUpdateMode,
+        node::{UiNode, UiNodeOp, match_node},
     };
 
     /// Insert `trace` in the widget state. Can be probed using [`traced`].
diff --git a/crates/zng-wgt/src/hit_test_props.rs b/crates/zng-wgt/src/hit_test_props.rs
index 66c396664..c13d547d1 100644
--- a/crates/zng-wgt/src/hit_test_props.rs
+++ b/crates/zng-wgt/src/hit_test_props.rs
@@ -1,5 +1,5 @@
-pub use zng_app::widget::base::HitTestMode;
 use zng_app::widget::base::HIT_TEST_MODE_VAR;
+pub use zng_app::widget::base::HitTestMode;
 
 use crate::prelude::*;
 
diff --git a/tests/Cargo.toml b/tests/Cargo.toml
index 670f67e22..d30e5a1a8 100644
--- a/tests/Cargo.toml
+++ b/tests/Cargo.toml
@@ -2,7 +2,7 @@
 name = "integration-tests"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [features]
 default = ["ipc"]
diff --git a/tests/cargo-zng-res-tests/custom/tools/cargo-zng-res-tool-crate/Cargo.toml b/tests/cargo-zng-res-tests/custom/tools/cargo-zng-res-tool-crate/Cargo.toml
index ff90942e7..21e52b999 100644
--- a/tests/cargo-zng-res-tests/custom/tools/cargo-zng-res-tool-crate/Cargo.toml
+++ b/tests/cargo-zng-res-tests/custom/tools/cargo-zng-res-tool-crate/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "cargo-zng-res-tool-crate"
 version = "0.0.0"
-edition = "2021"
+edition = "2024"
 publish = false
 
 [dependencies]
diff --git a/tests/cargo-zng-res-tests/custom/tools/cargo-zng-res/Cargo.toml b/tests/cargo-zng-res-tests/custom/tools/cargo-zng-res/Cargo.toml
index 4ea861f8b..169f18d90 100644
--- a/tests/cargo-zng-res-tests/custom/tools/cargo-zng-res/Cargo.toml
+++ b/tests/cargo-zng-res-tests/custom/tools/cargo-zng-res/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "cargo-zng-res"
 version = "0.0.0"
-edition = "2021"
+edition = "2024"
 publish = false
 
 [dependencies]
diff --git a/tests/cargo_zng.rs b/tests/cargo_zng.rs
index 21663e146..726737472 100644
--- a/tests/cargo_zng.rs
+++ b/tests/cargo_zng.rs
@@ -287,14 +287,16 @@ fn zng_new<S: AsRef<OsStr>>(args: &[S], target: &Path, template: &Path) -> Resul
 }
 
 fn zng(setup: impl FnOnce(&mut Command) -> &mut Command, cleanup: impl FnOnce(&mut StdioStr)) -> Result<StdioStr, (io::Error, StdioStr)> {
-    assert!(Command::new("cargo")
-        .arg("build")
-        .arg("-p")
-        .arg("cargo-zng")
-        .output()
-        .expect("cannot build cargo-zng")
-        .status
-        .success());
+    assert!(
+        Command::new("cargo")
+            .arg("build")
+            .arg("-p")
+            .arg("cargo-zng")
+            .output()
+            .expect("cannot build cargo-zng")
+            .status
+            .success()
+    );
 
     let cargo_zng = dunce::canonicalize(Path::new("../target/debug").join(format!("cargo-zng{}", std::env::consts::EXE_SUFFIX))).unwrap();
 
diff --git a/tests/focus.rs b/tests/focus.rs
index 01a26c9e9..0625a2dda 100644
--- a/tests/focus.rs
+++ b/tests/focus.rs
@@ -4,14 +4,14 @@ use zng::{
     data_view::{DataView, DataViewArgs},
     event::EventReceiver,
     focus::{
-        alt_focus_scope,
+        DirectionalNav, FOCUS_CHANGED_EVENT, FocusChangedArgs, FocusChangedCause, RETURN_FOCUS_CHANGED_EVENT, ReturnFocusChangedArgs,
+        TabIndex, TabNav, alt_focus_scope,
         cmd::{FOCUS_NEXT_CMD, FOCUS_PREV_CMD},
-        directional_nav, focus_scope, focusable, tab_index, tab_nav, DirectionalNav, FocusChangedArgs, FocusChangedCause,
-        ReturnFocusChangedArgs, TabIndex, TabNav, FOCUS_CHANGED_EVENT, RETURN_FOCUS_CHANGED_EVENT,
+        directional_nav, focus_scope, focusable, tab_index, tab_nav,
     },
     keyboard::{Key, KeyCode, KeyState},
     prelude::*,
-    widget::{info::InteractionPath, interactive, node::ArcNode, visibility, Visibility, WidgetUpdateMode},
+    widget::{Visibility, WidgetUpdateMode, info::InteractionPath, interactive, node::ArcNode, visibility},
 };
 
 #[test]
diff --git a/tests/image.rs b/tests/image.rs
index 0254c6e2f..5ff6baddd 100644
--- a/tests/image.rs
+++ b/tests/image.rs
@@ -1,6 +1,6 @@
 use std::sync::{
-    atomic::{AtomicBool, Ordering},
     Arc,
+    atomic::{AtomicBool, Ordering},
 };
 
 use zng::{image::Img, prelude::*, widget::parallel};
diff --git a/tests/macro-tests/Cargo.toml b/tests/macro-tests/Cargo.toml
index 6e804707b..ed076a07e 100644
--- a/tests/macro-tests/Cargo.toml
+++ b/tests/macro-tests/Cargo.toml
@@ -2,7 +2,7 @@
 name = "macro-tests"
 version = "0.0.0"
 publish = false
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 trybuild = "1.0"
diff --git a/tests/macro-tests/cases/widget_new/incorrect_when_expr_type1.stderr b/tests/macro-tests/cases/widget_new/incorrect_when_expr_type1.stderr
index acc66288b..f91187998 100644
--- a/tests/macro-tests/cases/widget_new/incorrect_when_expr_type1.stderr
+++ b/tests/macro-tests/cases/widget_new/incorrect_when_expr_type1.stderr
@@ -8,8 +8,7 @@ error[E0277]: the trait bound `impl zng::var::Var<SideOffsets>: zng::var::Var<bo
 13 | |
 14 | |         when *#margin {
    | |              ^ the trait `zng::var::Var<bool>` is not implemented for `impl zng::var::Var<SideOffsets>`
-15 | |             background_color = colors::WHITE;
-16 | |         }
+...  |
 17 | |     };
    | |_____- required by a bound introduced by this call
    |
diff --git a/tests/macro-tests/cases/widget_new/missing_field_all_multi.stderr b/tests/macro-tests/cases/widget_new/missing_field_all_multi.stderr
index ec91198fe..3d2df50cf 100644
--- a/tests/macro-tests/cases/widget_new/missing_field_all_multi.stderr
+++ b/tests/macro-tests/cases/widget_new/missing_field_all_multi.stderr
@@ -21,9 +21,7 @@ error[E0061]: this method takes 2 arguments but 1 argument was supplied
    |
 8  |       let _ = Wgt! {
    |  _____________-
-9  | |         // background_gradient has two fields
-10 | |         // this is interpreted as an unnamed assign `{ }` is the value
-11 | |         // and the second value is missing
+...  |
 12 | |         background_gradient = {}
    | |         ^^^^^^^^^^^^^^^^^^^
 13 | |     };
diff --git a/tests/macro-tests/cases/widget_new/missing_field_multi.stderr b/tests/macro-tests/cases/widget_new/missing_field_multi.stderr
index 5f155d3ea..8cdbb472b 100644
--- a/tests/macro-tests/cases/widget_new/missing_field_multi.stderr
+++ b/tests/macro-tests/cases/widget_new/missing_field_multi.stderr
@@ -3,9 +3,7 @@ error[E0061]: this method takes 2 arguments but 1 argument was supplied
    |
 9  |       let _ = Wgt! {
    |  _____________-
-10 | |         // background_gradient has two fields
-11 | |         // the error highlights the property
-12 | |         // in a struct initializer the struct name is highlighted
+...  |
 13 | |         background_gradient = { axis: 0.deg() }
    | |         ^^^^^^^^^^^^^^^^^^^
 14 | |     };
diff --git a/tests/macro-tests/cases/widget_new/missing_value3.stderr b/tests/macro-tests/cases/widget_new/missing_value3.stderr
index 54932dafc..ddf8a60e9 100644
--- a/tests/macro-tests/cases/widget_new/missing_value3.stderr
+++ b/tests/macro-tests/cases/widget_new/missing_value3.stderr
@@ -6,8 +6,7 @@ error[E0061]: this method takes 1 argument but 0 arguments were supplied
 6  | |         // we expected an error here.
 7  | |         cursor = ;
    | |         ^^^^^^
-8  | |         // we expect margin to be used here.
-9  | |         margin = 0;
+...  |
 10 | |     };
    | |_____- argument #1 is missing
    |
diff --git a/tests/macro-tests/cases/widget_new/missing_value5.stderr b/tests/macro-tests/cases/widget_new/missing_value5.stderr
index d799100e6..e5c9357ec 100644
--- a/tests/macro-tests/cases/widget_new/missing_value5.stderr
+++ b/tests/macro-tests/cases/widget_new/missing_value5.stderr
@@ -6,8 +6,7 @@ error: expected expression, found `)`
 6  | |         cursor = #[allow(unused_imports)]
 7  | |         margin = {
 8  | |             use zng::layout::PxPoint;
-9  | |             0
-10 | |         }
+...  |
 11 | |     };
    | |_____^ expected expression
    |
diff --git a/tests/macro-tests/cases/widget_new/not_allowed_in_when1.stderr b/tests/macro-tests/cases/widget_new/not_allowed_in_when1.stderr
index fae8dcfe6..843618379 100644
--- a/tests/macro-tests/cases/widget_new/not_allowed_in_when1.stderr
+++ b/tests/macro-tests/cases/widget_new/not_allowed_in_when1.stderr
@@ -10,7 +10,6 @@ error[E0599]: no method named `allowed_in_when_expr` found for struct `foo_` in
 18 | |         when {
 19 | |             let node = #foo;
 ...  |
-23 | |         }
 24 | |     };
    | |_____^
    |
diff --git a/tests/macro-tests/cases/widget_new/not_allowed_in_when2.stderr b/tests/macro-tests/cases/widget_new/not_allowed_in_when2.stderr
index 8cfe67308..123103cf2 100644
--- a/tests/macro-tests/cases/widget_new/not_allowed_in_when2.stderr
+++ b/tests/macro-tests/cases/widget_new/not_allowed_in_when2.stderr
@@ -9,7 +9,6 @@ error[E0599]: no method named `allowed_in_when_assign` found for struct `foo_` i
 20 | |         foo = false;
 21 | |         margin = 0;
 ...  |
-26 | |         }
 27 | |     };
    | |_____^
    |
diff --git a/tests/render-tests/Cargo.toml b/tests/render-tests/Cargo.toml
index 7d17ddbc7..5beb67409 100644
--- a/tests/render-tests/Cargo.toml
+++ b/tests/render-tests/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "render-tests"
 version = "0.0.0"
-edition = "2021"
+edition = "2024"
 publish = false
 
 [dependencies]
diff --git a/tests/render-tests/src/main.rs b/tests/render-tests/src/main.rs
index a12e1c2ed..3e9816109 100644
--- a/tests/render-tests/src/main.rs
+++ b/tests/render-tests/src/main.rs
@@ -8,11 +8,11 @@ use std::{
 
 use color_print::cstr;
 use zng::{
+    APP,
     app::HeadlessApp,
     layout::{FactorUnits as _, TimeUnits as _},
-    text::{formatx, Txt},
+    text::{Txt, formatx},
     window::RenderMode,
-    APP,
 };
 
 mod tests;
diff --git a/tests/render-tests/src/tests.rs b/tests/render-tests/src/tests.rs
index c350fdec6..486f8cf30 100644
--- a/tests/render-tests/src/tests.rs
+++ b/tests/render-tests/src/tests.rs
@@ -1,5 +1,5 @@
 use zng::{
-    image::{Img, IMAGES},
+    image::{IMAGES, Img},
     layout::LayoutPassId,
     prelude::*,
     prelude_wgt::*,