collective

Browse / github.com/storytold/craft-libs / patch

craft-ui: update egui to 0.37

craft-ui: update egui to 0.37 FilmCraft is moving to egui 0.37, because eframe 0.37 (emilk/egui#8631) fixes FilmCraft's control channel going unanswered while its window is on another Wayland workspace (storytold/filmcraft#1584). craft-ui pins egui 0.36, so it has to move first. - egui 0.37 replaces `WidgetType` with accesskit's `Role` and renames a few methods. Mapped per egui's own table: Checkbox is CheckBox, SelectableLabel is Button, Other is Unknown; `UiBuilder::id` and `Ui::id` are `scope_id`; `Id::new` is `Id::unique` (the same hash). No behaviour change. - egui's test harness now panics on a glyph no installed fo

Status
open
Score
0.00
Adopters
0 other operators
Author
adventurelands (imported from pull request #172, open)
Base
82a24b006eefa036b43c09a67fb9a3fbd17ffe63
Size
+129 −489 in 13 files
Review
pending
Shared
2026-10-28
Id
1c071ac13568a34d5510d373

How it went

No other operator has reported using it yet.

Diff

raw · Cargo.lock Cargo.toml crates/ui/Cargo.toml crates/ui/src/buttons/mod.rs crates/ui/src/docking/surface.rs crates/ui/src/docking/tests.rs crates/ui/src/layout/resize.rs crates/ui/src/layout/tests.rs crates/ui/src/printing/tests.rs crates/ui/src/tabs/mod.rs crates/ui/src/tabs/tests.rs crates/ui/tests/docking_workflows.rs crates/ui/tests/visual/fixtures.rs

diff --git a/Cargo.lock b/Cargo.lock--- a/Cargo.lock+++ b/Cargo.lock@@ -4,21 +4,21 @@ version = 4  [[package]] name = "accesskit"-version = "0.24.1"+version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "d3b7f7f85a7e5f68090000ed7622545829afd484d210358702ae4cb97dd0c320"+checksum = "ad442f58ee04714aaa0ba0a2768c1ea1935b29507bb22ddece8cbbc76db02932" dependencies = [  "uuid", ]  [[package]] name = "accesskit_consumer"-version = "0.35.0"+version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "53cf47daed85312e763fbf85ceca136e0d7abc68e0a7e12abe11f48172bc3b10"+checksum = "8a45e2bb300bea6d5f33a82c3e051c3ddc6f41c209750f68a0acbe991a284344" dependencies = [  "accesskit",- "hashbrown 0.16.1",+ "hashbrown 0.17.1", ]  [[package]]@@ -94,26 +94,6 @@ dependencies = [  "libc", ] -[[package]]-name = "arboard"-version = "3.6.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "0348a1c054491f4bfe6ab86a7b6ab1e44e45d899005de92f58b3df180b36ddaf"-dependencies = [- "clipboard-win",- "image",- "log",- "objc2 0.6.5",- "objc2-app-kit 0.3.2",- "objc2-core-foundation",- "objc2-core-graphics",- "objc2-foundation 0.3.2",- "parking_lot",- "percent-encoding",- "windows-sys 0.60.2",- "x11rb",-]- [[package]] name = "arrayref" version = "0.3.9"@@ -327,30 +307,6 @@ dependencies = [  "thiserror 1.0.69", ] -[[package]]-name = "calloop"-version = "0.14.5"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "43b32313e937c8721c9d17ee9bf60699a6402b4b7c2cb6ac1bee0ffcaa4b4e5e"-dependencies = [- "bitflags 2.13.2",- "polling",- "rustix 1.1.5",- "tracing",-]--[[package]]-name = "calloop-wayland-source"-version = "0.4.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "138efcf0940a02ebf0cc8d1eff41a1682a46b431630f4c52450d6265876021fa"-dependencies = [- "calloop 0.14.5",- "rustix 1.1.5",- "wayland-backend",- "wayland-client",-]- [[package]] name = "cast" version = "0.3.0"@@ -406,15 +362,6 @@ dependencies = [  "windows-link", ] -[[package]]-name = "clipboard-win"-version = "5.4.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4"-dependencies = [- "error-code",-]- [[package]] name = "cmake" version = "0.1.58"@@ -862,12 +809,6 @@ dependencies = [  "litrs", ] -[[package]]-name = "downcast-rs"-version = "1.2.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"- [[package]] name = "dpi" version = "0.1.2"@@ -882,9 +823,9 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"  [[package]] name = "ecolor"-version = "0.36.2"+version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "0656a7530b9e2841ee7a5f983965bdd9840c32f4012f759cfd44b912cced6b34"+checksum = "31bcbef0d4263a63eb32c4834e5d711613035ce1333468e107d928923e21e6e2" dependencies = [  "bytemuck",  "emath",@@ -892,9 +833,9 @@ dependencies = [  [[package]] name = "eframe"-version = "0.36.2"+version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "55ad41fac6e3149abb4866e93df37dbd33baa95db525c3368c944584e95a5dc2"+checksum = "9c5642501a65ca657d05f00c643a5c14ff2346cb3818032bfe23d58e1f8e5f84" dependencies = [  "ahash",  "bytemuck",@@ -913,6 +854,7 @@ dependencies = [  "pollster",  "profiling",  "raw-window-handle",+ "send_wrapper",  "static_assertions",  "wasm-bindgen",  "web-sys",@@ -924,9 +866,9 @@ dependencies = [  [[package]] name = "egui"-version = "0.36.2"+version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "dc938cc27cd911415e1e4d151bc56ff9df063d8db081374e87aeb805ea74b2ba"+checksum = "bec9144f49b7a28b5f395d3147e325b4fe3e77ba686eac11d1bdf0a7da3f375f" dependencies = [  "accesskit",  "ahash",@@ -944,9 +886,9 @@ dependencies = [  [[package]] name = "egui-wgpu"-version = "0.36.2"+version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "5cef1f6d1bba40b09a4d0d62cb822b81030922cfbf65c5373398c3a3caafc5bd"+checksum = "0309cbe1febed48af5b974e4bcc424b35e9664863a4d402697147b57a488c864" dependencies = [  "ahash",  "bytemuck",@@ -964,29 +906,29 @@ dependencies = [  [[package]] name = "egui-winit"-version = "0.36.2"+version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "98466000559d66ba4db786a30448b01483946add4188e7f10f522a27b4fb89cc"+checksum = "e4e449f4c4a2a60c7ccb4ba7fa4078417bfe1f9ddc03b5e05ce75748e33a70de" dependencies = [- "arboard",- "bytemuck",+ "block2 0.6.2",  "egui",  "log",  "objc2 0.6.5",+ "objc2-app-kit 0.3.2",  "objc2-foundation 0.3.2",  "objc2-ui-kit 0.3.2",  "profiling",  "raw-window-handle",- "smithay-clipboard",  "web-time",+ "windows-sys 0.61.2",  "winit", ]  [[package]] name = "egui_extras"-version = "0.36.2"+version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "05cbdc785020861553f230f23d330ba1fb72613b9d8e0e457f3bdc8ba6db6dcf"+checksum = "def286cf47194f3fe45b8e37c503ada7a20a64b59a903b4bc704baec943b1827" dependencies = [  "ahash",  "egui",@@ -999,9 +941,9 @@ dependencies = [  [[package]] name = "egui_kittest"-version = "0.36.2"+version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "5eb3f3effb2726fee23449293e67acbf6cc6ce35525b1722bd5743bb348114d5"+checksum = "0979c2e37860fcf13a2bea77508607f067a9a6a84ba9bd47b5e298582fb59b86" dependencies = [  "eframe",  "egui",@@ -1023,9 +965,9 @@ checksum = "0e9c71c2167ca323c882b99918929403426e2373ea17242ff5653e0d5e1058be"  [[package]] name = "emath"-version = "0.36.2"+version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "52c8d4141cf0f60fb2f7aefaf352d3ffa5171ef0ab09731c64391801e95e48f1"+checksum = "e73ce90f54750be8672c02be0743fe47530e6f251e066f0ee2869b59eb297af5" dependencies = [  "bytemuck", ]@@ -1046,29 +988,29 @@ dependencies = [  [[package]] name = "enum-map"-version = "2.7.3"+version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9"+checksum = "d4532960034c15ba2f55e9eee631040ecc473c32e6c4b200828c759840f13a06" dependencies = [  "enum-map-derive", ]  [[package]] name = "enum-map-derive"-version = "0.17.0"+version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb"+checksum = "7127272f64b3e098f7d81f350d672081b879bff896d219c42370dc858b1af9ff" dependencies = [  "proc-macro2",  "quote",- "syn 2.0.119",+ "syn 3.0.6", ]  [[package]] name = "epaint"-version = "0.36.2"+version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "a0ec0308dc23130fc1a7d4623a8534c2ed069c6dc84e258ee4f3de99615aa1a3"+checksum = "97bac86ae3dde93fc3951e790951caea739ff39a6c89d909cdaf1d9278dbb1bd" dependencies = [  "ahash",  "bytemuck",@@ -1085,15 +1027,16 @@ dependencies = [  "skrifa 0.44.0",  "smallvec",  "unicode-general-category",+ "unicode-properties",  "unicode-segmentation",- "vello_cpu 0.1.0",+ "vello_cpu 0.2.0", ]  [[package]] name = "epaint_default_fonts"-version = "0.36.2"+version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "773fa9c96dd0dbef887e39d0ed6177f141cce4d68e6041df77570aa3702dfa13"+checksum = "cfc1cc505827f4c23eedc297975a0fd038268d41293f389dd8ff3b574aefab19"  [[package]] name = "equivalent"@@ -1111,12 +1054,6 @@ dependencies = [  "windows-sys 0.61.2", ] -[[package]]-name = "error-code"-version = "3.4.0"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "0b5343afd4a8365a643ac588dab4cf234a190c7f6c88c9f6dd6ffe00837661b7"- [[package]] name = "euclid" version = "0.22.14"@@ -1132,12 +1069,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" -[[package]]-name = "fax"-version = "0.2.7"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "caf1079563223d5d59d83c85886a56e586cfd5c1a26292e971a0fa266531ac5a"- [[package]] name = "fdeflate" version = "0.3.7"@@ -1348,16 +1279,6 @@ dependencies = [  "version_check", ] -[[package]]-name = "gethostname"-version = "1.1.0"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8"-dependencies = [- "rustix 1.1.5",- "windows-link",-]- [[package]] name = "getrandom" version = "0.2.17"@@ -1425,9 +1346,9 @@ dependencies = [  [[package]] name = "glifo"-version = "0.2.0"+version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "ed4a1bb24121291d27230c1b1b44e07d6a9b28cefdb32fe1581dfb84e14f940a"+checksum = "282a26c1e23de04bdab3e34a21b6f877a479b96737792516b9b8b8f69b6661be" dependencies = [  "bytemuck",  "foldhash",@@ -1436,7 +1357,7 @@ dependencies = [  "peniko",  "skrifa 0.44.0",  "smallvec",- "vello_common 0.1.0",+ "vello_common 0.2.0", ]  [[package]]@@ -1899,7 +1820,6 @@ dependencies = [  "moxcms",  "num-traits",  "png 0.18.1",- "tiff", ]  [[package]]@@ -2063,9 +1983,9 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"  [[package]] name = "kittest"-version = "0.4.0"+version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "90ceaa75eb0036a32b6b9833962eb18137449e9817e2e586006471925b727fd5"+checksum = "0bb81a721ba76aa095b7f45deb180504f786904e56ca4b8e141f66eb89a78b75" dependencies = [  "accesskit",  "accesskit_consumer",@@ -2212,15 +2132,6 @@ version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" -[[package]]-name = "memmap2"-version = "0.9.11"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0"-dependencies = [- "libc",-]- [[package]] name = "mime" version = "0.3.17"@@ -2465,9 +2376,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [  "bitflags 2.13.2",+ "block2 0.6.2",  "objc2 0.6.5",  "objc2-core-foundation",- "objc2-core-graphics",  "objc2-foundation 0.3.2", ] @@ -2524,7 +2435,6 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [- "bitflags 2.13.2",  "dispatch2",  "objc2 0.6.5",  "objc2-core-foundation",@@ -3084,15 +2994,6 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" -[[package]]-name = "quick-xml"-version = "0.41.0"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1"-dependencies = [- "memchr",-]- [[package]] name = "quinn" version = "0.11.12"@@ -3578,12 +3479,6 @@ dependencies = [  "windows-sys 0.61.2", ] -[[package]]-name = "scoped-tls"-version = "1.0.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"- [[package]] name = "scopeguard" version = "1.2.0"@@ -3625,6 +3520,12 @@ version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +[[package]]+name = "send_wrapper"+version = "0.6.0"+source = "registry+https://github.com/rust-lang/crates.io-index"+checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73"+ [[package]] name = "serde" version = "1.0.229"@@ -3985,44 +3886,6 @@ version = "1.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9395f0f0eee849a9b707b2f06bb92a6a422090e2123bb2ef8e87a0e61892a8e" -[[package]]-name = "smithay-client-toolkit"-version = "0.20.0"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "0512da38f5e2b31201a93524adb8d3136276fa4fe4aafab4e1f727a82b534cc0"-dependencies = [- "bitflags 2.13.2",- "calloop 0.14.5",- "calloop-wayland-source",- "cursor-icon",- "libc",- "log",- "memmap2",- "rustix 1.1.5",- "thiserror 2.0.21",- "wayland-backend",- "wayland-client",- "wayland-csd-frame",- "wayland-cursor",- "wayland-protocols",- "wayland-protocols-experimental",- "wayland-protocols-misc",- "wayland-protocols-wlr",- "wayland-scanner",- "xkeysym",-]--[[package]]-name = "smithay-clipboard"-version = "0.7.3"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "71704c03f739f7745053bde45fa203a46c58d25bc5c4efba1d9a60e9dba81226"-dependencies = [- "libc",- "smithay-client-toolkit",- "wayland-backend",-]- [[package]] name = "smol_str" version = "0.2.2"@@ -4288,20 +4151,6 @@ dependencies = [  "syn 3.0.6", ] -[[package]]-name = "tiff"-version = "0.11.3"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "b63feaf3343d35b6ca4d50483f94843803b0f51634937cc2ec519fc32232bc52"-dependencies = [- "fax",- "flate2",- "half",- "quick-error",- "weezl",- "zune-jpeg",-]- [[package]] name = "tiny-skia" version = "0.11.4"@@ -4517,7 +4366,6 @@ version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [- "log",  "pin-project-lite",  "tracing-attributes",  "tracing-core",@@ -4730,9 +4578,9 @@ dependencies = [  [[package]] name = "vello_common"-version = "0.1.0"+version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "b2e9aed918117e8152c9eddfd8362d73c465c23f26c44786aa331707b8a64fa2"+checksum = "bbb2141a2bca6e6d598e471fd4d1d7eed8e020aad6a28187edda07f091a325dd" dependencies = [  "bytemuck",  "fearless_simd",@@ -4758,14 +4606,14 @@ dependencies = [  [[package]] name = "vello_cpu"-version = "0.1.0"+version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "ac7349e1f55f6b801c7c277958df4ea53e7f20f21e8014910ad888b2ecda93ea"+checksum = "ace506ca414548966fcf3c283be94eb1cad8254de488791ee698bf438b0890a9" dependencies = [  "bytemuck",- "glifo 0.2.0",+ "glifo 0.3.0",  "hashbrown 0.17.1",- "vello_common 0.1.0",+ "vello_common 0.2.0", ]  [[package]]@@ -4894,116 +4742,6 @@ version = "0.2.129" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f692aa943ccd88363733b77063f32cfed5bc6cbea8e6e8b251b302f881606fe" -[[package]]-name = "wayland-backend"-version = "0.3.17"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "38a91b4eaddff87b1cd1074985e3713da4af2c49742d1b356b2c01670a67a078"-dependencies = [- "cc",- "downcast-rs",- "rustix 1.1.5",- "scoped-tls",- "smallvec",- "wayland-sys",-]--[[package]]-name = "wayland-client"-version = "0.31.15"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "e3c36a0f861ad76d0901f2800b46321410d9f73f2ea88aac0650d86c32688073"-dependencies = [- "bitflags 2.13.2",- "rustix 1.1.5",- "wayland-backend",- "wayland-scanner",-]--[[package]]-name = "wayland-csd-frame"-version = "0.3.0"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e"-dependencies = [- "bitflags 2.13.2",- "cursor-icon",- "wayland-backend",-]--[[package]]-name = "wayland-cursor"-version = "0.31.14"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "4a52d18780be9b1314328a3de5f930b73d2200112e3849ca6cb11822793fb34d"-dependencies = [- "rustix 1.1.5",- "wayland-client",- "xcursor",-]--[[package]]-name = "wayland-protocols"-version = "0.32.13"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "23d0c813de3daa2ed6520af85a3bd49b0e722a3078506899aa9686fea58dc4b6"-dependencies = [- "bitflags 2.13.2",- "wayland-backend",- "wayland-client",- "wayland-scanner",-]--[[package]]-name = "wayland-protocols-experimental"-version = "20250721.0.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "40a1f863128dcaaec790d7b4b396cc9b9a7a079e878e18c47e6c2d2c5a8dcbb1"-dependencies = [- "bitflags 2.13.2",- "wayland-backend",- "wayland-client",- "wayland-protocols",- "wayland-scanner",-]--[[package]]-name = "wayland-protocols-misc"-version = "0.3.12"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "6e9567599ef23e09b8dad6e429e5738d4509dfc46b3b21f32841a304d16b29c8"-dependencies = [- "bitflags 2.13.2",- "wayland-backend",- "wayland-client",- "wayland-protocols",- "wayland-scanner",-]--[[package]]-name = "wayland-protocols-wlr"-version = "0.3.12"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234"-dependencies = [- "bitflags 2.13.2",- "wayland-backend",- "wayland-client",- "wayland-protocols",- "wayland-scanner",-]--[[package]]-name = "wayland-scanner"-version = "0.31.11"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "338e30461b3a2b67d70eb30a6d89f8e0c93a833e07d2ae89085cd070c4a00ac0"-dependencies = [- "proc-macro2",- "quick-xml",- "quote",-]- [[package]] name = "wayland-sys" version = "0.31.11"@@ -5361,7 +5099,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [- "windows-targets 0.52.6",+ "windows-targets", ]  [[package]]@@ -5370,16 +5108,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [- "windows-targets 0.52.6",-]--[[package]]-name = "windows-sys"-version = "0.60.2"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"-dependencies = [- "windows-targets 0.53.5",+ "windows-targets", ]  [[package]]@@ -5397,31 +5126,14 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [- "windows_aarch64_gnullvm 0.52.6",- "windows_aarch64_msvc 0.52.6",- "windows_i686_gnu 0.52.6",- "windows_i686_gnullvm 0.52.6",- "windows_i686_msvc 0.52.6",- "windows_x86_64_gnu 0.52.6",- "windows_x86_64_gnullvm 0.52.6",- "windows_x86_64_msvc 0.52.6",-]--[[package]]-name = "windows-targets"-version = "0.53.5"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"-dependencies = [- "windows-link",- "windows_aarch64_gnullvm 0.53.1",- "windows_aarch64_msvc 0.53.1",- "windows_i686_gnu 0.53.1",- "windows_i686_gnullvm 0.53.1",- "windows_i686_msvc 0.53.1",- "windows_x86_64_gnu 0.53.1",- "windows_x86_64_gnullvm 0.53.1",- "windows_x86_64_msvc 0.53.1",+ "windows_aarch64_gnullvm",+ "windows_aarch64_msvc",+ "windows_i686_gnu",+ "windows_i686_gnullvm",+ "windows_i686_msvc",+ "windows_x86_64_gnu",+ "windows_x86_64_gnullvm",+ "windows_x86_64_msvc", ]  [[package]]@@ -5439,96 +5151,48 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]]-name = "windows_aarch64_gnullvm"-version = "0.53.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"- [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]]-name = "windows_aarch64_msvc"-version = "0.53.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"- [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]]-name = "windows_i686_gnu"-version = "0.53.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"- [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]]-name = "windows_i686_gnullvm"-version = "0.53.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"- [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]]-name = "windows_i686_msvc"-version = "0.53.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"- [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]]-name = "windows_x86_64_gnu"-version = "0.53.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"- [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]]-name = "windows_x86_64_gnullvm"-version = "0.53.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"- [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]]-name = "windows_x86_64_msvc"-version = "0.53.1"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"- [[package]] name = "winit" version = "0.30.13"@@ -5539,7 +5203,7 @@ dependencies = [  "atomic-waker",  "bitflags 2.13.2",  "block2 0.5.1",- "calloop 0.13.0",+ "calloop",  "cfg_aliases",  "concurrent-queue",  "core-foundation 0.9.4",@@ -5624,23 +5288,6 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" -[[package]]-name = "x11rb"-version = "0.13.2"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414"-dependencies = [- "gethostname",- "rustix 1.1.5",- "x11rb-protocol",-]--[[package]]-name = "x11rb-protocol"-version = "0.13.2"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd"- [[package]] name = "x509-cert" version = "0.2.5"@@ -5676,12 +5323,6 @@ dependencies = [  "rustix 1.1.5", ] -[[package]]-name = "xcursor"-version = "0.3.11"-source = "registry+https://github.com/rust-lang/crates.io-index"-checksum = "163b33ed8786455e2fa5d72f554057ce3f3182425434f756cd39c99839d88e23"- [[package]] name = "xkbcommon-dl" version = "0.4.2"diff --git a/Cargo.toml b/Cargo.toml--- a/Cargo.toml+++ b/Cargo.toml@@ -27,7 +27,7 @@ craft-print = { path = "crates/print" } craft-quit = { path = "crates/quit" } craft-settings = { path = "crates/settings" } craft-ui = { path = "crates/ui" }-egui = { version = "0.36", default-features = false }+egui = { version = "0.37", default-features = false } rayon = "1" serde = { version = "1", features = ["derive"] } serde_json = "1"diff --git a/crates/ui/Cargo.toml b/crates/ui/Cargo.toml--- a/crates/ui/Cargo.toml+++ b/crates/ui/Cargo.toml@@ -20,6 +20,6 @@ serde = ["dep:serde"] [dev-dependencies] egui = { workspace = true, features = ["default_fonts"] } serde_json = "1"-egui_extras = { version = "0.36", default-features = false, features = ["svg"] }-egui_kittest = { version = "0.36", features = ["wgpu"] }+egui_extras = { version = "0.37", default-features = false, features = ["svg"] }+egui_kittest = { version = "0.37", features = ["wgpu"] } image = { version = "0.25", default-features = false, features = ["png"] }diff --git a/crates/ui/src/buttons/mod.rs b/crates/ui/src/buttons/mod.rs--- a/crates/ui/src/buttons/mod.rs+++ b/crates/ui/src/buttons/mod.rs@@ -81,7 +81,7 @@ impl<'a> IconButton<'a> {         let valid = self.size.is_finite() && self.size.x > 0.0 && self.size.y > 0.0 && self.size.x <= 4096.0 && self.size.y <= 4096.0;         let (rect, response) =             ui.allocate_exact_size(if valid { self.size } else { Vec2::ZERO }, if valid { Sense::click() } else { Sense::hover() });-        response.widget_info(|| egui::WidgetInfo::selected(egui::WidgetType::Button, valid && ui.is_enabled(), self.selected, self.label));+        response.widget_info(|| egui::WidgetInfo::selected(egui::Role::Button, valid && ui.is_enabled(), self.selected, self.label));         if !valid {             return response;         }diff --git a/crates/ui/src/docking/surface.rs b/crates/ui/src/docking/surface.rs--- a/crates/ui/src/docking/surface.rs+++ b/crates/ui/src/docking/surface.rs@@ -213,14 +213,14 @@ impl<P: Clone + Eq + Hash + Debug + Send + Sync + 'static> DockArea<P> {         while let Some((node, path)) = nodes.pop() {             match node {                 Node::Tabs { panels, .. } if group(panels) => return true,-                Node::Stack { entries } => {+                Node::Stack { entries }                     if entries.iter().any(|entry| {                         matches(self.id.with(("tab", &entry.panel)))                             || matches(self.id.with(("collapse", &entry.panel)))                             || matches(self.id.with(("stack-resize", &entry.panel)))-                    }) {-                        return true;-                    }+                    }) =>+                {+                    return true;                 }                 Node::Split { first, second, .. } => {                     if matches(self.id.with(("split", &path))) {@@ -416,9 +416,8 @@ impl<P: Clone + Eq + Hash + Debug + Send + Sync + 'static> Renderer<'_, P> {                     self.tab(ui, &entry.panel, title_rect, entry.open, panel_rect);                     let collapse = Rect::from_min_max(pos2((title_rect.right() - 18.0).max(title_rect.left()), title_rect.top()), title_rect.max);                     let response = ui.interact(collapse, self.id.with(("collapse", &entry.panel)), Sense::click());-                    response.widget_info(|| {-                        egui::WidgetInfo::selected(egui::WidgetType::Checkbox, ui.is_enabled(), entry.open, (self.label)(&entry.panel))-                    });+                    response+                        .widget_info(|| egui::WidgetInfo::selected(egui::Role::CheckBox, ui.is_enabled(), entry.open, (self.label)(&entry.panel)));                     ui.painter().with_clip_rect(collapse).text(                         collapse.center(),                         egui::Align2::CENTER_CENTER,@@ -536,7 +535,7 @@ impl<P: Clone + Eq + Hash + Debug + Send + Sync + 'static> Renderer<'_, P> {         }         ui.painter().rect_filled(rect, 0.0, self.style.background);         let mut child =-            ui.new_child(UiBuilder::new().id(self.id.with(("body", panel))).max_rect(rect).layout(egui::Layout::top_down(egui::Align::Min)));+            ui.new_child(UiBuilder::new().scope_id(self.id.with(("body", panel))).max_rect(rect).layout(egui::Layout::top_down(egui::Align::Min)));         child.set_clip_rect(rect.intersect(ui.clip_rect()));         self.content.body(&mut child, panel);         if child.rect_contains_pointer(rect) && child.input(|i| i.pointer.primary_pressed()) {@@ -566,7 +565,7 @@ impl<P: Clone + Eq + Hash + Debug + Send + Sync + 'static> Renderer<'_, P> {             let grip = Rect::from_min_max(strip.min, pos2((strip.left() + 12.0).min(strip.right()), strip.bottom()));             let response = ui.interact(grip, self.id.with(("move-group", panels.first())), Sense::drag()).on_hover_cursor(egui::CursorIcon::Grab);             self.register_interaction(ui.ctx(), response.id);-            response.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Button, ui.is_enabled(), &self.style.move_label));+            response.widget_info(|| egui::WidgetInfo::labeled(egui::Role::Button, ui.is_enabled(), &self.style.move_label));             if panels.iter().all(|p| (self.permissions)(p).movable)                 && response.drag_started()                 && let Some(first) = panels.first()@@ -597,7 +596,7 @@ impl<P: Clone + Eq + Hash + Debug + Send + Sync + 'static> Renderer<'_, P> {         let header_width = if requested.is_finite() { requested.clamp(0.0, strip.width()) } else { 0.0 };         if header_width > 0.0 {             let header = Rect::from_min_max(pos2(strip.right() - header_width, strip.top()), strip.max);-            let mut child = ui.new_child(UiBuilder::new().id(self.id.with(("header", selected))).max_rect(header));+            let mut child = ui.new_child(UiBuilder::new().scope_id(self.id.with(("header", selected))).max_rect(header));             child.set_clip_rect(header.intersect(ui.clip_rect()));             self.content.group_header(&mut child, panels, selected, floating);         }@@ -625,7 +624,7 @@ impl<P: Clone + Eq + Hash + Debug + Send + Sync + 'static> Renderer<'_, P> {         if !fit.overflow.is_empty() && fit.overflow_width > 0.0 {             let overflow = Rect::from_min_size(pos2(x, strip.top()), vec2(fit.overflow_width, strip.height()));             let response = ui.interact(overflow, self.id.with(("overflow", selected)), Sense::click());-            response.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Button, ui.is_enabled(), &self.style.panels_label));+            response.widget_info(|| egui::WidgetInfo::labeled(egui::Role::Button, ui.is_enabled(), &self.style.panels_label));             ui.painter().with_clip_rect(overflow).text(overflow.center(), egui::Align2::CENTER_CENTER, "…", self.style.font.clone(), self.style.text);             egui::Popup::menu(&response).show(|ui| {                 egui::ScrollArea::vertical().max_height(360.0).show(ui, |ui| {@@ -663,7 +662,7 @@ impl<P: Clone + Eq + Hash + Debug + Send + Sync + 'static> Renderer<'_, P> {         let logical = (self.label)(panel);         let text = self.content.label(ui, panel, &logical, &self.style.font, self.style.text);         let response = ui.button(text);-        response.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Button, ui.is_enabled(), &logical));+        response.widget_info(|| egui::WidgetInfo::labeled(egui::Role::Button, ui.is_enabled(), &logical));         response     } @@ -698,7 +697,7 @@ impl<P: Clone + Eq + Hash + Debug + Send + Sync + 'static> Renderer<'_, P> {             if policy.movable && policy.floatable {                 let text = self.content.action_label(ui, &self.style.float_label, &self.style.font, self.style.text);                 let response = ui.button(text);-                response.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Button, ui.is_enabled(), &self.style.float_label));+                response.widget_info(|| egui::WidgetInfo::labeled(egui::Role::Button, ui.is_enabled(), &self.style.float_label));                 if response.clicked() {                     let rect = clamp_float(group.translate(vec2(24.0, 24.0)), ui.ctx().content_rect());                     self.output.actions.push(Action::Float { panel: panel.clone(), rect: [rect.left(), rect.top(), rect.width(), rect.height()] });@@ -721,12 +720,12 @@ impl<P: Clone + Eq + Hash + Debug + Send + Sync + 'static> Renderer<'_, P> {                         }                     });                 });-                response.response.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Button, ui.is_enabled(), &self.style.move_label));+                response.response.widget_info(|| egui::WidgetInfo::labeled(egui::Role::Button, ui.is_enabled(), &self.style.move_label));             }             if policy.closable {                 let text = self.content.action_label(ui, &self.style.close_label, &self.style.font, self.style.text);                 let response = ui.button(text);-                response.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Button, ui.is_enabled(), &self.style.close_label));+                response.widget_info(|| egui::WidgetInfo::labeled(egui::Role::Button, ui.is_enabled(), &self.style.close_label));                 if response.clicked() {                     self.output.actions.push(Action::Close { panel: panel.clone() });                     ui.close();@@ -766,7 +765,7 @@ impl<P: Clone + Eq + Hash + Debug + Send + Sync + 'static> Renderer<'_, P> {                 let corner = Rect::from_min_max((rect.max - vec2(12.0, 12.0)).max(rect.min), rect.max);                 let response = ui.interact(corner, id.with("resize"), Sense::drag()).on_hover_cursor(egui::CursorIcon::ResizeNwSe);                 self.register_interaction(ui.ctx(), response.id);-                response.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Button, ui.is_enabled(), &self.style.resize_window_label));+                response.widget_info(|| egui::WidgetInfo::labeled(egui::Role::Button, ui.is_enabled(), &self.style.resize_window_label));                 if response.drag_started() {                     response.request_focus();                 }diff --git a/crates/ui/src/docking/tests.rs b/crates/ui/src/docking/tests.rs--- a/crates/ui/src/docking/tests.rs+++ b/crates/ui/src/docking/tests.rs@@ -305,14 +305,14 @@ fn frame(ctx: &Context, layout: &Layout<u32>, events: Vec<Event>, focused: bool)     let input = RawInput { screen_rect: Some(Rect::from_min_size(pos2(0.0, 0.0), vec2(800.0, 600.0))), events, focused, ..Default::default() };     ctx.run_ui(input, |ui| {         let style = DockStyle::from_ui(ui);-        output = DockArea::new(Id::new("test-area")).show(+        output = DockArea::new(Id::unique("test-area")).show(             ui,             layout,             &style,             |p| format!("Panel {p}"),             |_| Permissions::default(),             |ui, _| {-                ids.push(ui.id());+                ids.push(ui.scope_id());                 ui.label("Actual panel content");             },         );@@ -341,7 +341,7 @@ fn cancelling_or_losing_focus_during_a_drag_does_not_move_panels() {     let source = Rect::from_min_size(pos2(0.0, 0.0), vec2(200.0, 200.0));     let press = Event::PointerButton { pos: pos2(30.0, 30.0), button: PointerButton::Primary, pressed: true, modifiers: Modifiers::NONE };     frame(&ctx, &layout, vec![Event::PointerMoved(pos2(30.0, 30.0)), press], true);-    assert!(begin_drag(&ctx, Id::new("test-area"), 2u32, source));+    assert!(begin_drag(&ctx, Id::unique("test-area"), 2u32, source));     let (out, _) = frame(         &ctx,         &layout,@@ -349,7 +349,7 @@ fn cancelling_or_losing_focus_during_a_drag_does_not_move_panels() {         true,     );     assert!(out.actions.is_empty());-    assert!(begin_drag(&ctx, Id::new("test-area"), 2u32, source));+    assert!(begin_drag(&ctx, Id::unique("test-area"), 2u32, source));     let (out, _) = frame(&ctx, &layout, Vec::new(), false);     assert!(out.actions.is_empty());     let (out, _) = frame(@@ -381,8 +381,8 @@ fn actual_pointer_drag_docks_a_floating_panel_into_the_main_tab_strip() {     for _ in 0..3 {         step(&ctx, &mut layout, Vec::new());     }-    let source = ctx.read_response(Id::new("test-area").with(("tab", &5u32))).unwrap().rect.center();-    let target = ctx.read_response(Id::new("test-area").with(("tab", &3u32))).unwrap().rect.center();+    let source = ctx.read_response(Id::unique("test-area").with(("tab", &5u32))).unwrap().rect.center();+    let target = ctx.read_response(Id::unique("test-area").with(("tab", &3u32))).unwrap().rect.center();     step(&ctx, &mut layout, vec![Event::PointerMoved(source), pointer_button(source, true)]);     step(&ctx, &mut layout, vec![Event::PointerMoved(source + vec2(8.0, 0.0))]);     step(&ctx, &mut layout, vec![Event::PointerMoved(target)]);@@ -418,7 +418,7 @@ fn panel_size_limits_clamp_geometry_without_overwriting_preferred_widths() {         let mut rects = std::collections::BTreeMap::new();         let mut out = DockOutput::default();         ctx.run_ui(RawInput { screen_rect: Some(Rect::from_min_size(pos2(0.0, 0.0), vec2(width, 600.0))), ..Default::default() }, |ui| {-            out = DockArea::new(Id::new("bounds")).show_with_limits(+            out = DockArea::new(Id::unique("bounds")).show_with_limits(                 ui,                 &layout,                 &DockStyle::from_ui(ui),@@ -460,7 +460,7 @@ fn focused_floating_resize_grip_accepts_both_arrow_axes_and_releases_tab() {     for _ in 0..3 {         step(&ctx, &mut layout, Vec::new());     }-    let id = Id::new("test-area").with(("floating", &5u32)).with("resize");+    let id = Id::unique("test-area").with(("floating", &5u32)).with("resize");     ctx.memory_mut(|memory| memory.request_focus(id));     let key = |key| Event::Key { key, physical_key: None, pressed: true, repeat: false, modifiers: Modifiers::NONE };     step(&ctx, &mut layout, vec![key(egui::Key::ArrowRight), key(egui::Key::ArrowDown)]);@@ -486,7 +486,7 @@ fn stack_dividers_resize_adjacent_open_bodies_by_pointer_and_keyboard() {     for _ in 0..3 {         step(&ctx, &mut layout, Vec::new());     }-    let id = Id::new("test-area").with(("stack-resize", &1u32));+    let id = Id::unique("test-area").with(("stack-resize", &1u32));     let start = ctx.read_response(id).unwrap().rect.center();     step(&ctx, &mut layout, vec![Event::PointerMoved(start), pointer_button(start, true)]);     step(&ctx, &mut layout, vec![Event::PointerMoved(start + vec2(0.0, 24.0))]);@@ -525,7 +525,7 @@ fn split_inner_edge_remains_draggable_beside_a_scrollbar() {         let mut output = DockOutput::default();         let mut sidebar = Rect::NOTHING;         ctx.run_ui(RawInput { screen_rect: Some(Rect::from_min_size(pos2(0.0, 0.0), vec2(800.0, 600.0))), events, ..Default::default() }, |ui| {-            output = DockArea::new(Id::new("scrolling-dock")).show(+            output = DockArea::new(Id::unique("scrolling-dock")).show(                 ui,                 layout,                 &DockStyle::from_ui(ui),@@ -597,7 +597,7 @@ fn floating_only_surface_does_not_allocate_the_callers_document_region() {     let layout = Layout { root: None, floating: vec![Floating { panels: vec![1u32], active: 0, rect: [30.0, 40.0, 200.0, 200.0] }] };     ctx.run_ui(RawInput { screen_rect: Some(Rect::from_min_size(pos2(0.0, 0.0), vec2(800.0, 600.0))), ..Default::default() }, |ui| {         let before = ui.available_rect_before_wrap();-        let out = DockArea::new(Id::new("float-only")).show(+        let out = DockArea::new(Id::unique("float-only")).show(             ui,             &layout,             &DockStyle::from_ui(ui),@@ -633,7 +633,7 @@ fn floating_group_grip_moves_every_member_while_tab_drag_detaches_one() {     for _ in 0..2 {         step(&ctx, &mut layout, vec![]);     }-    let tab = ctx.read_response(Id::new("test-area").with(("tab", &5u32))).unwrap().rect.center();+    let tab = ctx.read_response(Id::unique("test-area").with(("tab", &5u32))).unwrap().rect.center();     step(&ctx, &mut layout, vec![Event::PointerMoved(tab), pointer_button(tab, true)]);     step(&ctx, &mut layout, vec![Event::PointerMoved(tab + vec2(8.0, 0.0))]);     step(&ctx, &mut layout, vec![Event::PointerMoved(tab + vec2(100.0, 100.0))]);@@ -663,7 +663,7 @@ fn host_cancel_discards_group_drag_before_workspace_replacement() {     let actions = step(&ctx, &mut layout, vec![Event::PointerMoved(moved)]);     assert!(actions.iter().any(|action| matches!(action, Action::MoveFloating { .. }))); -    cancel_drag::<u32>(&ctx, Id::new("test-area"));+    cancel_drag::<u32>(&ctx, Id::unique("test-area"));     layout = sample();     let replacement = layout.clone();     let actions = step(&ctx, &mut layout, vec![Event::PointerMoved(moved + vec2(20.0, 10.0))]);@@ -696,7 +696,7 @@ impl DockContent<u32> for CustomContent {     fn group_header(&mut self, ui: &mut egui::Ui, _: &[u32], _: &u32, _: bool) {         self.headers += 1;         assert!(ui.max_rect().width() <= 40.0);-        ui.label("⋮");+        ui.label("…");     } } @@ -711,7 +711,7 @@ fn custom_frame(     let mut out = DockOutput::default();     ctx.run_ui(RawInput { screen_rect: Some(Rect::from_min_size(pos2(0.0, 0.0), vec2(800.0, 600.0))), events, ..Default::default() }, |ui| {         let style = DockStyle::from_ui(ui);-        let mut area = DockArea::new(Id::new("test-area")).blocked_rects(blockers);+        let mut area = DockArea::new(Id::unique("test-area")).blocked_rects(blockers);         if raise {             area = area.raise_panel(5);         }@@ -762,7 +762,7 @@ fn overlay_appearing_mid_drag_blocks_release_and_float_fallback() {     let mut content = CustomContent { labels: vec![], headers: 0, menus: 0, bodies: 0 };     let source = Rect::from_min_size(pos2(80.0, 70.0), vec2(300.0, 220.0));     custom_frame(&ctx, &layout, &mut content, vec![Event::PointerMoved(pos2(130.0, 82.0)), pointer_button(pos2(130.0, 82.0), true)], &[], false);-    assert!(begin_drag(&ctx, Id::new("test-area"), 5, source));+    assert!(begin_drag(&ctx, Id::unique("test-area"), 5, source));     let at = pos2(700.0, 400.0);     let blocker = Rect::from_min_size(pos2(650.0, 350.0), vec2(100.0, 100.0));     let out = custom_frame(&ctx, &layout, &mut content, vec![Event::PointerMoved(at), pointer_button(at, false)], &[blocker], false);@@ -801,7 +801,7 @@ fn custom_headers_and_labels_render_at_small_and_large_scales() {         let mut out = DockOutput::default();         ctx.run_ui(RawInput { screen_rect: Some(Rect::from_min_size(pos2(0.0, 0.0), vec2(120.0 * scale, 160.0))), ..Default::default() }, |ui| {             let style = DockStyle::from_ui(ui);-            out = DockArea::new(Id::new("scaled")).show_customized(+            out = DockArea::new(Id::unique("scaled")).show_customized(                 ui,                 &layout,                 &style,@@ -834,7 +834,7 @@ fn protected_group_member_blocks_whole_group_gesture_and_host_drop() {         let mut out = DockOutput::default();         ctx.run_ui(RawInput { screen_rect: Some(Rect::from_min_size(pos2(0.0, 0.0), vec2(800.0, 600.0))), events, ..Default::default() }, |ui| {             let style = DockStyle::from_ui(ui);-            out = DockArea::new(Id::new("test-area")).show(+            out = DockArea::new(Id::unique("test-area")).show(                 ui,                 &layout,                 &style,@@ -856,13 +856,13 @@ fn protected_group_member_blocks_whole_group_gesture_and_host_drop() { fn chrome_focus_classifies_rendered_tab_but_excludes_body_text_field_and_invalid_layout() {     let ctx = Context::default();     let layout = sample();-    let tab = Id::new("focus-area").with(("tab", 3u32));-    let text = Id::new("body-text");+    let tab = Id::unique("focus-area").with(("tab", 3u32));+    let text = Id::unique("body-text");     let mut value = String::new();     let mut paint = |focus: Id| {         let mut output =             ctx.run_ui(RawInput { screen_rect: Some(Rect::from_min_size(pos2(0.0, 0.0), vec2(800.0, 600.0))), ..Default::default() }, |ui| {-                DockArea::new(Id::new("focus-area")).show(+                DockArea::new(Id::unique("focus-area")).show(                     ui,                     &layout,                     &DockStyle::from_ui(ui),@@ -879,22 +879,22 @@ fn chrome_focus_classifies_rendered_tab_but_excludes_body_text_field_and_invalid         output.textures_delta.clear();     };     paint(tab);-    assert!(DockArea::new(Id::new("focus-area")).chrome_has_focus(&ctx, &layout));+    assert!(DockArea::new(Id::unique("focus-area")).chrome_has_focus(&ctx, &layout));     paint(text);-    assert!(!DockArea::new(Id::new("focus-area")).chrome_has_focus(&ctx, &layout));+    assert!(!DockArea::new(Id::unique("focus-area")).chrome_has_focus(&ctx, &layout));     paint(tab);     let mut invalid = layout.clone();     invalid.floating.push(Floating { panels: vec![3], active: 0, rect: [10.0, 10.0, 100.0, 100.0] });-    assert!(!DockArea::new(Id::new("focus-area")).chrome_has_focus(&ctx, &invalid));-    assert!(!DockArea::<u32>::new(Id::new("focus-area")).chrome_has_focus(&ctx, &Layout::default()));-    ctx.memory_mut(|memory| memory.request_focus(Id::new("unrendered")));-    assert!(!DockArea::new(Id::new("focus-area")).chrome_has_focus(&ctx, &layout));+    assert!(!DockArea::new(Id::unique("focus-area")).chrome_has_focus(&ctx, &invalid));+    assert!(!DockArea::<u32>::new(Id::unique("focus-area")).chrome_has_focus(&ctx, &Layout::default()));+    ctx.memory_mut(|memory| memory.request_focus(Id::unique("unrendered")));+    assert!(!DockArea::new(Id::unique("focus-area")).chrome_has_focus(&ctx, &layout)); }  #[test] fn chrome_focus_classifies_rendered_accordion_and_split_and_floating_resizers() {     let ctx = Context::default();-    let area = Id::new("focus-chrome-controls");+    let area = Id::unique("focus-chrome-controls");     let accordion = Layout {         root: Some(Node::Stack {             entries: vec![StackEntry { panel: 1u32, open: true, height: Some(150.0) }, StackEntry { panel: 2u32, open: true, height: Some(150.0) }],@@ -930,7 +930,7 @@ fn chrome_focus_classifies_rendered_accordion_and_split_and_floating_resizers()  #[test] fn workspace_cancel_stops_owned_resize_controls_until_new_press() {-    let area = Id::new("test-area");+    let area = Id::unique("test-area");     let fixtures = [         (sample(), area.with(("split", Vec::<bool>::new())), vec2(24.0, 0.0)),         (@@ -978,8 +978,8 @@ fn workspace_cancel_stops_owned_resize_controls_until_new_press() { fn workspace_cancel_preserves_other_area_and_body_drag_ownership() {     for body_drag in [false, true] {         let ctx = Context::default();-        let area = Id::new("cancel-area");-        let other = Id::new("other-area");+        let area = Id::unique("cancel-area");+        let other = Id::unique("other-area");         let layout = Layout {             root: Some(Node::Split {                 axis: SplitAxis::Horizontal,@@ -989,7 +989,7 @@ fn workspace_cancel_preserves_other_area_and_body_drag_ownership() {             }),             floating: vec![],         };-        let body_id = Id::new("application-body-drag");+        let body_id = Id::unique("application-body-drag");         let mut value = 0.0;         let mut run = |events: Vec<Event>| {             let mut outputs = Vec::new();@@ -1052,7 +1052,7 @@ fn popup_action_labels_use_custom_visual_text_and_logical_accessibility() {     let layout = sample();     let mut h = Harness::builder().with_size(vec2(800.0, 600.0)).build_ui_state(         move |ui, content: &mut CustomContent| {-            DockArea::new(Id::new("action-label-test")).show_customized(+            DockArea::new(Id::unique("action-label-test")).show_customized(                 ui,                 &layout,                 &DockStyle::from_ui(ui),@@ -1065,7 +1065,7 @@ fn popup_action_labels_use_custom_visual_text_and_logical_accessibility() {         CustomContent { labels: vec![], headers: 0, menus: 0, bodies: 0 },     );     h.run_steps(2);-    let tab = Id::new("action-label-test").with(("tab", &5_u32));+    let tab = Id::unique("action-label-test").with(("tab", &5_u32));     let at = h.ctx.read_response(tab).unwrap().rect.center();     h.input_mut().events.extend([         Event::PointerMoved(at),diff --git a/crates/ui/src/layout/resize.rs b/crates/ui/src/layout/resize.rs--- a/crates/ui/src/layout/resize.rs+++ b/crates/ui/src/layout/resize.rs@@ -151,7 +151,7 @@ impl<'a> ResizeHandle<'a> {             {                 egui::WidgetInfo::slider(enabled, f64::from(*value), self.label)             } else {-                egui::WidgetInfo::labeled(egui::WidgetType::Other, enabled, self.label)+                egui::WidgetInfo::labeled(egui::Role::Unknown, enabled, self.label)             }         });         ui.ctx().accesskit_node_builder(response.id, |node| {diff --git a/crates/ui/src/layout/tests.rs b/crates/ui/src/layout/tests.rs--- a/crates/ui/src/layout/tests.rs+++ b/crates/ui/src/layout/tests.rs@@ -127,7 +127,7 @@ impl HandleTest {             ctx.run_ui(RawInput { screen_rect: Some(Rect::from_min_size(Pos2::ZERO, vec2(400.0, 200.0))), events, ..Default::default() }, |ui| {                 result = Some(                     ui.add_enabled_ui(self.enabled, |ui| {-                        ResizeHandle::new(Id::new("divider"), self.axis, self.rect, &self.label, handle_style())+                        ResizeHandle::new(Id::unique("divider"), self.axis, self.rect, &self.label, handle_style())                             .value(self.value, 0.0..=300.0)                             .show(ui)                     })diff --git a/crates/ui/src/printing/tests.rs b/crates/ui/src/printing/tests.rs--- a/crates/ui/src/printing/tests.rs+++ b/crates/ui/src/printing/tests.rs@@ -99,7 +99,7 @@ fn discovery_and_controls_do_not_submit_a_job() {         grayscale: "Graustufen",     };     let ctx = egui::Context::default();-    let mut output = ctx.run_ui(egui::RawInput::default(), |ui| state.show(ui, egui::Id::new("print"), &discover, &labels));+    let mut output = ctx.run_ui(egui::RawInput::default(), |ui| state.show(ui, egui::Id::unique("print"), &discover, &labels));     output.textures_delta.clear();     assert_eq!(state.settings.printer, "Office");     assert!(state.ready());@@ -134,7 +134,7 @@ fn localized_controls_fit_narrow_ui_and_disable_while_submitting() {     let frame = |state: &mut State, events| {         let mut output = ctx.run_ui(             egui::RawInput { screen_rect: Some(egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(220.0, 360.0))), events, ..Default::default() },-            |ui| state.show(ui, egui::Id::new("print"), &discover, &labels),+            |ui| state.show(ui, egui::Id::unique("print"), &discover, &labels),         );         output.textures_delta.clear();         outputdiff --git a/crates/ui/src/tabs/mod.rs b/crates/ui/src/tabs/mod.rs--- a/crates/ui/src/tabs/mod.rs+++ b/crates/ui/src/tabs/mod.rs@@ -139,7 +139,7 @@ impl<'a> Tab<'a> {         let valid = rect.is_finite() && size.x > 0.0 && size.y > 0.0 && size.x <= MAX_EXTENT && size.y <= MAX_EXTENT;         let safe_rect = if valid { rect } else { Rect::from_min_size(egui::Pos2::ZERO, Vec2::ZERO) };         let response = ui.interact(safe_rect, self.id, if valid { self.sense } else { Sense::hover() });-        response.widget_info(|| egui::WidgetInfo::selected(egui::WidgetType::SelectableLabel, valid && ui.is_enabled(), self.selected, self.label));+        response.widget_info(|| egui::WidgetInfo::selected(egui::Role::Button, valid && ui.is_enabled(), self.selected, self.label));         ui.ctx().accesskit_node_builder(self.id, |node| {             node.set_role(egui::accesskit::Role::Tab);             node.clear_toggled();diff --git a/crates/ui/src/tabs/tests.rs b/crates/ui/src/tabs/tests.rs--- a/crates/ui/src/tabs/tests.rs+++ b/crates/ui/src/tabs/tests.rs@@ -112,7 +112,7 @@ impl TabTest {         let mut output = ctx.run_ui(raw, |ui| {             ui.add_enabled_ui(self.enabled, |ui| {                 for (i, label) in self.labels.iter().enumerate() {-                    let r = Tab::new(ui.id().with(("tab", i)), label, self.selected == i)+                    let r = Tab::new(ui.scope_id().with(("tab", i)), label, self.selected == i)                         .sense(self.sense)                         .focus_stroke(Stroke::new(1.0, Color32::LIGHT_BLUE))                         .show_at(ui, self.rect.translate(vec2(i as f32 * 100.0, 0.0)), |ui, response| {diff --git a/crates/ui/tests/docking_workflows.rs b/crates/ui/tests/docking_workflows.rs--- a/crates/ui/tests/docking_workflows.rs+++ b/crates/ui/tests/docking_workflows.rs@@ -90,14 +90,14 @@ impl Harness {         let mut actions = Vec::new();         self.output = self.ctx.run_ui(input, |ui| {             let style = DockStyle::from_ui(ui);-            let out = DockArea::new(Id::new("workflow")).show(+            let out = DockArea::new(Id::unique("workflow")).show(                 ui,                 &self.layout,                 &style,                 label,                 |panel| if *panel == CANVAS { Permissions::PROTECTED } else { Permissions::default() },                 |ui, panel| {-                    self.body_ids.insert(*panel, ui.id());+                    self.body_ids.insert(*panel, ui.scope_id());                     if *panel == CANVAS {                         let rect = ui.available_rect_before_wrap();                         ui.painter().rect_filled(rect, 0.0, Color32::from_rgb(44, 53, 66));@@ -181,7 +181,7 @@ impl Harness {     }      fn tab(&self, panel: u32) -> Rect {-        self.ctx.read_response(Id::new("workflow").with(("tab", &panel))).unwrap().rect+        self.ctx.read_response(Id::unique("workflow").with(("tab", &panel))).unwrap().rect     }      fn drag(&mut self, from: Pos2, to: Pos2) {diff --git a/crates/ui/tests/visual/fixtures.rs b/crates/ui/tests/visual/fixtures.rs--- a/crates/ui/tests/visual/fixtures.rs+++ b/crates/ui/tests/visual/fixtures.rs@@ -221,7 +221,7 @@ pub fn actual(ui: &mut Ui, case: Case, mutation: Mutation) -> Vec<Response> {         let response = ui             .add_enabled_ui(case.state.enabled(), |ui| {                 ResizeHandle::new(-                    Id::new("visual-divider"),+                    Id::unique("visual-divider"),                     axis,                     split.divider,                     "Resize panes",@@ -252,7 +252,7 @@ pub fn actual(ui: &mut Ui, case: Case, mutation: Mutation) -> Vec<Response> {                     let selected = index == 0 && case.state.selected();                     let response = if matches!(case.component, Component::Tab) {                         let rect = Rect::from_min_size(pos2(12.0 + index as f32 * (case.size().x + spacing), 12.0), case.size());-                        Tab::new(Id::new(("visual-tab", index)), "Tab", selected)+                        Tab::new(Id::unique(("visual-tab", index)), "Tab", selected)                             .focus_stroke(style.focus_stroke)                             .show_at(ui, rect, |ui, r| tab_body(ui, r, selected, p, case.compact))                     } else {