From d2b2715835870791ac4da498946a1972e1435a7f Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Mon, 13 Apr 2026 11:01:32 -0400 Subject: [PATCH 01/72] feat: ext-background-effect blur --- Cargo.lock | 593 +++++++++--------- runtime/src/platform_specific/wayland/mod.rs | 9 +- .../wayland/event_loop/mod.rs | 26 +- .../wayland/event_loop/state.rs | 121 +++- .../wayland/handlers/ext_background_effect.rs | 65 ++ .../platform_specific/wayland/handlers/mod.rs | 5 +- .../wayland/subsurface_widget.rs | 1 - .../platform_specific/wayland/winit_window.rs | 16 +- 8 files changed, 506 insertions(+), 330 deletions(-) create mode 100644 winit/src/platform_specific/wayland/handlers/ext_background_effect.rs diff --git a/Cargo.lock b/Cargo.lock index 9fddcd2e..805e6066 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -159,23 +159,21 @@ dependencies = [ [[package]] name = "android-activity" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" +checksum = "0f2a1bb052857d5dd49572219344a7332b31b76405648eabac5bc68978251bcd" dependencies = [ "android-properties", "bitflags 2.11.0", "cc", - "cesu8", - "jni 0.21.1", - "jni-sys 0.3.0", + "jni 0.22.4", "libc", "log", "ndk", "ndk-context", "ndk-sys", "num_enum", - "thiserror 1.0.69", + "thiserror 2.0.18", ] [[package]] @@ -210,9 +208,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstyle" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anyhow" @@ -307,7 +305,7 @@ dependencies = [ "url", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.11", + "wayland-protocols 0.32.12", "zbus", ] @@ -457,9 +455,9 @@ dependencies = [ [[package]] name = "async-signal" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" +checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485" dependencies = [ "async-io", "async-lock", @@ -775,10 +773,11 @@ checksum = "e79769241dcd44edf79a732545e8b5cec84c247ac060f5252cd51885d093a8fc" [[package]] name = "borsh" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" +checksum = "cfd1e3f8955a5d7de9fab72fc8373fade9fb8a703968cb200ae3dc6cf08e185a" dependencies = [ + "bytes", "cfg_aliases", ] @@ -923,9 +922,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.56" +version = "1.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" dependencies = [ "find-msvc-tools", "jobserver", @@ -1036,18 +1035,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.60" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a" +checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.60" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstyle", "clap_lex", @@ -1055,9 +1054,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "clipboard-win" @@ -1071,7 +1070,7 @@ dependencies = [ [[package]] name = "clipboard_macos" version = "0.1.0" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "objc", "objc-foundation", @@ -1081,7 +1080,7 @@ dependencies = [ [[package]] name = "clipboard_wayland" version = "0.2.2" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "dnd", "mime 0.1.0", @@ -1091,7 +1090,7 @@ dependencies = [ [[package]] name = "clipboard_x11" version = "0.4.2" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "thiserror 1.0.69", "x11rb", @@ -1296,7 +1295,7 @@ dependencies = [ "libc", "smithay-client-toolkit 0.20.0", "wayland-client", - "wayland-protocols 0.32.11", + "wayland-protocols 0.32.12", ] [[package]] @@ -1307,8 +1306,8 @@ dependencies = [ "bitflags 2.11.0", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.11", - "wayland-protocols-wlr 0.3.11", + "wayland-protocols 0.32.12", + "wayland-protocols-wlr 0.3.12", "wayland-scanner", "wayland-server", ] @@ -1316,7 +1315,7 @@ dependencies = [ [[package]] name = "cosmic-text" version = "0.18.2" -source = "git+https://github.com/pop-os/cosmic-text.git#9a2ab09f06905e91f41d64ac6eee887726e7fd76" +source = "git+https://github.com/pop-os/cosmic-text.git#4d74f795cc771fdcc7ea0f9cacba63fcf036fad6" dependencies = [ "bitflags 2.11.0", "fontdb", @@ -1324,9 +1323,9 @@ dependencies = [ "linebender_resource_handle", "log", "rangemap", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "self_cell", - "skrifa 0.40.0", + "skrifa", "smol_str", "swash", "sys-locale", @@ -1445,7 +1444,7 @@ dependencies = [ "cosmic-text", "etagere", "lru", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "wgpu", ] @@ -1562,7 +1561,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.2", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -1617,7 +1616,7 @@ dependencies = [ [[package]] name = "dnd" version = "0.1.0" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "bitflags 2.11.0", "mime 0.1.0", @@ -1652,7 +1651,7 @@ dependencies = [ [[package]] name = "dpi" version = "0.1.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" [[package]] name = "drm" @@ -1790,7 +1789,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -1811,9 +1810,9 @@ dependencies = [ [[package]] name = "euclid" -version = "0.22.13" +version = "0.22.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df61bf483e837f88d5c2291dcf55c67be7e676b3a51acc48db3a7b163b91ed63" +checksum = "f1a05365e3b1c6d1650318537c7460c6923f1abdd272ad6842baa2b509957a06" dependencies = [ "num-traits", ] @@ -1893,9 +1892,9 @@ checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" [[package]] name = "fastrand" -version = "2.3.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "fax" @@ -1981,18 +1980,9 @@ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "font-types" -version = "0.10.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39a654f404bbcbd48ea58c617c2993ee91d1cb63727a37bf2323a4edeed1b8c5" -dependencies = [ - "bytemuck", -] - -[[package]] -name = "font-types" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4d2d0cf79d38430cc9dc9aadec84774bff2e1ba30ae2bf6c16cfce9385a23" +checksum = "2d9237c6d82152100c691fb77ea18037b402bcc7257d2c876a4ffac81bc22a1c" dependencies = [ "bytemuck", ] @@ -2192,7 +2182,7 @@ version = "0.1.0" dependencies = [ "iced", "itertools 0.12.1", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "tokio", "tracing-subscriber", ] @@ -2284,9 +2274,9 @@ dependencies = [ [[package]] name = "gif" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5df2ba84018d80c213569363bdcd0c64e6933c67fe4c1d60ecf822971a3c35e" +checksum = "ee8cfcc411d9adbbaba82fb72661cc1bcca13e8bba98b364e62b2dba8f960159" dependencies = [ "color_quant", "weezl", @@ -2302,7 +2292,7 @@ dependencies = [ "gobject-sys", "libc", "system-deps", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -2690,7 +2680,7 @@ dependencies = [ "bitflags 2.11.0", "bytemuck", "core_maths", - "read-fonts 0.37.0", + "read-fonts", "smallvec", ] @@ -2712,6 +2702,12 @@ dependencies = [ "foldhash 0.2.0", ] +[[package]] +name = "hashbrown" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" + [[package]] name = "headers" version = "0.3.9" @@ -2865,9 +2861,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" dependencies = [ "atomic-waker", "bytes", @@ -2879,7 +2875,6 @@ dependencies = [ "httparse", "itoa", "pin-project-lite", - "pin-utils", "smallvec", "tokio", "want", @@ -2892,7 +2887,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ "http 1.4.0", - "hyper 1.8.1", + "hyper 1.9.0", "hyper-util", "rustls 0.23.37", "rustls-pki-types", @@ -2909,7 +2904,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.8.1", + "hyper 1.9.0", "hyper-util", "native-tls", "tokio", @@ -2929,7 +2924,7 @@ dependencies = [ "futures-util", "http 1.4.0", "http-body 1.0.1", - "hyper 1.8.1", + "hyper 1.9.0", "ipnet", "libc", "percent-encoding", @@ -3032,7 +3027,7 @@ dependencies = [ "num-traits", "palette", "raw-window-handle", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "serde", "smol_str", "thiserror 2.0.18", @@ -3068,7 +3063,7 @@ dependencies = [ "futures", "iced_core", "log", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "smol", "tokio", "wasm-bindgen-futures", @@ -3090,7 +3085,7 @@ dependencies = [ "log", "lyon_path", "raw-window-handle", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "thiserror 2.0.18", "unicode-segmentation", ] @@ -3182,7 +3177,7 @@ dependencies = [ "kurbo 0.10.4", "log", "resvg", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "softbuffer", "tiny-skia", ] @@ -3205,13 +3200,13 @@ dependencies = [ "lyon", "raw-window-handle", "resvg", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "rustix 0.38.44", "thiserror 2.0.18", "tiny-xlib", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.11", + "wayland-protocols 0.32.12", "wayland-sys", "wgpu", "x11rb", @@ -3232,7 +3227,7 @@ dependencies = [ "ouroboros", "pulldown-cmark", "qrcode", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "thiserror 2.0.18", "unicode-segmentation", "window_clipboard", @@ -3254,14 +3249,14 @@ dependencies = [ "log", "mundy", "raw-window-handle", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "rustix 0.38.44", "sysinfo", "thiserror 2.0.18", "wasm-bindgen-futures", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.11", + "wayland-protocols 0.32.12", "web-sys", "winapi", "window_clipboard", @@ -3274,12 +3269,13 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -3287,9 +3283,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -3300,9 +3296,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -3314,15 +3310,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ "icu_collections", "icu_locale_core", @@ -3334,15 +3330,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", @@ -3390,7 +3386,7 @@ dependencies = [ "byteorder-lite", "color_quant", "exr", - "gif 0.14.1", + "gif 0.14.2", "image-webp", "moxcms", "num-traits", @@ -3401,7 +3397,7 @@ dependencies = [ "rgb", "tiff", "zune-core 0.5.1", - "zune-jpeg 0.5.13", + "zune-jpeg 0.5.15", ] [[package]] @@ -3428,12 +3424,12 @@ checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8" [[package]] name = "indexmap" -version = "2.13.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.17.0", "serde", "serde_core", ] @@ -3457,9 +3453,9 @@ checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "iri-string" -version = "0.7.10" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" dependencies = [ "memchr", "serde", @@ -3482,7 +3478,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -3524,9 +3520,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" @@ -3540,7 +3536,7 @@ dependencies = [ "portable-atomic", "portable-atomic-util", "serde_core", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -3578,7 +3574,7 @@ dependencies = [ "cesu8", "cfg-if", "combine", - "jni-sys 0.3.0", + "jni-sys 0.3.1", "log", "thiserror 1.0.69", "walkdir", @@ -3587,9 +3583,9 @@ dependencies = [ [[package]] name = "jni" -version = "0.22.3" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "295dc9997acda1562fdf8d299f56063c936443b60f078e63a5d8d3c34ef2642b" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" dependencies = [ "cfg-if", "combine", @@ -3604,9 +3600,9 @@ dependencies = [ [[package]] name = "jni-macros" -version = "0.22.2" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c3d1da60c95c98847b26b9d45f4360fee718b31de746df016d9cd6de916a7ef" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" dependencies = [ "proc-macro2", "quote", @@ -3617,9 +3613,12 @@ dependencies = [ [[package]] name = "jni-sys" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] [[package]] name = "jni-sys" @@ -3652,10 +3651,12 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.91" +version = "0.3.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" +checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" dependencies = [ + "cfg-if", + "futures-util", "once_cell", "wasm-bindgen", ] @@ -3760,9 +3761,9 @@ checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" [[package]] name = "libc" -version = "0.2.183" +version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" +checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" [[package]] name = "libfuzzer-sys" @@ -3792,14 +3793,14 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.14" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" +checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" dependencies = [ "bitflags 2.11.0", "libc", "plain", - "redox_syscall 0.7.3", + "redox_syscall 0.7.4", ] [[package]] @@ -3850,9 +3851,9 @@ dependencies = [ [[package]] name = "litemap" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "litrs" @@ -3951,9 +3952,9 @@ dependencies = [ [[package]] name = "lyon_tessellation" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05a35a7dd71b845ff317ce1834c4185506b79790294bde397df8d5c23031e357" +checksum = "8e43b7e44161571868f5c931d12583592c223c5583eef86b08aa02b7048a3552" dependencies = [ "float_next_after", "lyon_path", @@ -4060,7 +4061,7 @@ dependencies = [ [[package]] name = "mime" version = "0.1.0" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "smithay-clipboard", ] @@ -4093,9 +4094,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "wasi", @@ -4240,7 +4241,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ "bitflags 2.11.0", - "jni-sys 0.3.0", + "jni-sys 0.3.1", "log", "ndk-sys", "num_enum", @@ -4260,7 +4261,7 @@ version = "0.6.0+11769913" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" dependencies = [ - "jni-sys 0.3.0", + "jni-sys 0.3.1", ] [[package]] @@ -4299,7 +4300,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -4314,9 +4315,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" +checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" [[package]] name = "num-derive" @@ -4361,9 +4362,9 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" dependencies = [ "num_enum_derive", "rustversion", @@ -4371,9 +4372,9 @@ dependencies = [ [[package]] name = "num_enum_derive" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -4753,9 +4754,9 @@ dependencies = [ [[package]] name = "orbclient" -version = "0.3.50" +version = "0.3.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ad2c6bae700b7aa5d1cc30c59bdd3a1c180b09dbaea51e2ae2b8e1cf211fdd" +checksum = "59aed3b33578edcfa1bc96a321d590d31832b6ad55a26f0313362ce687e9abd6" dependencies = [ "libc", "libredox", @@ -4763,9 +4764,9 @@ dependencies = [ [[package]] name = "ordered-float" -version = "5.1.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d" +checksum = "b7d950ca161dc355eaf28f82b11345ed76c6e1f6eb1f4f4479e0323b9e2fbd0e" dependencies = [ "num-traits", ] @@ -5114,18 +5115,18 @@ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5" +checksum = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3" dependencies = [ "portable-atomic", ] [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "zerovec", ] @@ -5475,16 +5476,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "read-fonts" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717cf23b488adf64b9d711329542ba34de147df262370221940dfabc2c91358" -dependencies = [ - "bytemuck", - "font-types 0.10.1", -] - [[package]] name = "read-fonts" version = "0.37.0" @@ -5493,7 +5484,7 @@ checksum = "7b634fabf032fab15307ffd272149b622260f55974d9fad689292a5d33df02e5" dependencies = [ "bytemuck", "core_maths", - "font-types 0.11.0", + "font-types", ] [[package]] @@ -5507,9 +5498,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" +checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" dependencies = [ "bitflags 2.11.0", ] @@ -5586,7 +5577,7 @@ dependencies = [ "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.8.1", + "hyper 1.9.0", "hyper-rustls", "hyper-tls", "hyper-util", @@ -5692,9 +5683,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" [[package]] name = "rustc_version" @@ -5715,7 +5706,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -5728,7 +5719,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -5753,7 +5744,7 @@ checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" dependencies = [ "once_cell", "rustls-pki-types", - "rustls-webpki 0.103.9", + "rustls-webpki 0.103.11", "subtle", "zeroize", ] @@ -5780,9 +5771,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.103.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "20a6af516fea4b20eccceaf166e8aa666ac996208e8a644ce3ef5aa783bc7cd4" dependencies = [ "ring", "rustls-pki-types", @@ -5999,9 +5990,9 @@ checksum = "b12e76d157a900eb52e81bc6e9f3069344290341720e9178cde2407113ac8d89" [[package]] name = "semver" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" dependencies = [ "serde", "serde_core", @@ -6063,9 +6054,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.0.4" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" dependencies = [ "serde_core", ] @@ -6139,9 +6130,9 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" [[package]] name = "simd_cesu8" @@ -6193,16 +6184,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "skrifa" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c31071dedf532758ecf3fed987cdb4bd9509f900e026ab684b4ecb81ea49841" -dependencies = [ - "bytemuck", - "read-fonts 0.35.0", -] - [[package]] name = "skrifa" version = "0.40.0" @@ -6210,7 +6191,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fbdfe3d2475fbd7ddd1f3e5cf8288a30eb3e5f95832829570cd88115a7434ac" dependencies = [ "bytemuck", - "read-fonts 0.37.0", + "read-fonts", ] [[package]] @@ -6289,10 +6270,10 @@ dependencies = [ "wayland-client", "wayland-csd-frame", "wayland-cursor", - "wayland-protocols 0.32.11", + "wayland-protocols 0.32.12", "wayland-protocols-experimental", "wayland-protocols-misc", - "wayland-protocols-wlr 0.3.11", + "wayland-protocols-wlr 0.3.12", "wayland-scanner", "xkbcommon 0.8.0", "xkeysym", @@ -6353,7 +6334,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -6449,9 +6430,9 @@ dependencies = [ [[package]] name = "subsecond" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8438668e545834d795d04c4335aafc332ce046106521a29f0a5c6501de34187c" +checksum = "5dbb9f2928b6654ccc28d4ddfef5213e97ed66afed4907774d049b376c62a838" dependencies = [ "js-sys", "libc", @@ -6468,9 +6449,9 @@ dependencies = [ [[package]] name = "subsecond-types" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e72f747606fc19fe81d6c59e491af93ed7dcbcb6aad9d1d18b05129914ec298" +checksum = "388bb28e6ddbee717745963b8932d9a6e24a5d3c93350655f733e938de04d81f" dependencies = [ "serde", ] @@ -6506,11 +6487,11 @@ dependencies = [ [[package]] name = "swash" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47846491253e976bdd07d0f9cc24b7daf24720d11309302ccbbc6e6b6e53550a" +checksum = "842f3cd369c2ba38966204f983eaa5e54a8e84a7d7159ed36ade2b6c335aae64" dependencies = [ - "skrifa 0.37.0", + "skrifa", "yazi", "zeno", ] @@ -6613,9 +6594,9 @@ dependencies = [ [[package]] name = "system-deps" -version = "7.0.7" +version = "7.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c8f33736f986f16d69b6cb8b03f55ddcad5c41acc4ccc39dd88e84aa805e7f" +checksum = "396a35feb67335377e0251fcbc1092fc85c484bd4e3a7a54319399da127796e7" dependencies = [ "cfg-expr", "heck 0.5.0", @@ -6647,7 +6628,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix 1.1.4", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -6728,7 +6709,7 @@ dependencies = [ "half", "quick-error", "weezl", - "zune-jpeg 0.5.13", + "zune-jpeg 0.5.15", ] [[package]] @@ -6803,9 +6784,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", @@ -6823,9 +6804,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" dependencies = [ "tinyvec_macros", ] @@ -6861,9 +6842,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.50.0" +version = "1.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" +checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" dependencies = [ "bytes", "libc", @@ -6877,9 +6858,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", @@ -6955,63 +6936,54 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.12+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ "indexmap", "serde_core", "serde_spanned", - "toml_datetime 0.7.5+spec-1.1.0", + "toml_datetime", "toml_parser", "toml_writer", - "winnow", + "winnow 1.0.1", ] [[package]] name = "toml_datetime" -version = "0.7.5+spec-1.1.0" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", -] - -[[package]] -name = "toml_datetime" -version = "1.0.0+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32c2555c699578a4f59f0cc68e5116c8d7cabbd45e1409b989d4be085b53f13e" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.25.4+spec-1.1.0" +version = "0.25.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7193cbd0ce53dc966037f54351dbbcf0d5a642c7f0038c382ef9e677ce8c13f2" +checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" dependencies = [ "indexmap", - "toml_datetime 1.0.0+spec-1.1.0", + "toml_datetime", "toml_parser", - "winnow", + "winnow 1.0.1", ] [[package]] name = "toml_parser" -version = "1.0.9+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow", + "winnow 1.0.1", ] [[package]] name = "toml_writer" -version = "1.0.6+spec-1.1.0" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" [[package]] name = "tooltip" @@ -7122,9 +7094,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ "nu-ansi-term", "sharded-slab", @@ -7189,13 +7161,13 @@ checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "uds_windows" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b70b87d15e91f553711b40df3048faf27a7a04e01e0ddc0cf9309f0af7c2ca" +checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e" dependencies = [ "memoffset", "tempfile", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -7248,9 +7220,9 @@ checksum = "383ad40bb927465ec0ce7720e033cb4ca06912855fc35db31b5755d0de75b1ee" [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" [[package]] name = "unicode-vo" @@ -7342,9 +7314,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.22.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" +checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" dependencies = [ "getrandom 0.4.2", "js-sys", @@ -7490,9 +7462,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.114" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" +checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" dependencies = [ "cfg-if", "once_cell", @@ -7503,23 +7475,19 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.64" +version = "0.4.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9c5522b3a28661442748e09d40924dfb9ca614b21c00d3fd135720e48b67db8" +checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" dependencies = [ - "cfg-if", - "futures-util", "js-sys", - "once_cell", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.114" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" +checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7527,9 +7495,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.114" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" +checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" dependencies = [ "bumpalo", "proc-macro2", @@ -7540,9 +7508,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.114" +version = "0.2.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" +checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" dependencies = [ "unicode-ident", ] @@ -7610,9 +7578,9 @@ dependencies = [ [[package]] name = "wayland-backend" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa75f400b7f719bcd68b3f47cd939ba654cedeef690f486db71331eec4c6a406" +checksum = "2857dd20b54e916ec7253b3d6b4d5c4d7d4ca2c33c2e11c6c76a99bd8744755d" dependencies = [ "cc", "downcast-rs", @@ -7624,9 +7592,9 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.13" +version = "0.31.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab51d9f7c071abeee76007e2b742499e535148035bb835f97aaed1338cf516c3" +checksum = "645c7c96bb74690c3189b5c9cb4ca1627062bb23693a4fad9d8c3de958260144" dependencies = [ "bitflags 2.11.0", "rustix 1.1.4", @@ -7647,9 +7615,9 @@ dependencies = [ [[package]] name = "wayland-cursor" -version = "0.31.13" +version = "0.31.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b3298683470fbdc6ca40151dfc48c8f2fd4c41a26e13042f801f85002384091" +checksum = "4a52d18780be9b1314328a3de5f930b73d2200112e3849ca6cb11822793fb34d" dependencies = [ "rustix 1.1.4", "wayland-client", @@ -7670,9 +7638,9 @@ dependencies = [ [[package]] name = "wayland-protocols" -version = "0.32.11" +version = "0.32.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b23b5df31ceff1328f06ac607591d5ba360cf58f90c8fad4ac8d3a55a3c4aec7" +checksum = "563a85523cade2429938e790815fd7319062103b9f4a2dc806e9b53b95982d8f" dependencies = [ "bitflags 2.11.0", "wayland-backend", @@ -7690,33 +7658,33 @@ dependencies = [ "bitflags 2.11.0", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.11", + "wayland-protocols 0.32.12", "wayland-scanner", ] [[package]] name = "wayland-protocols-misc" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "429b99200febaf95d4f4e46deff6fe4382bcff3280ee16a41cf887b3c3364984" +checksum = "6e9567599ef23e09b8dad6e429e5738d4509dfc46b3b21f32841a304d16b29c8" dependencies = [ "bitflags 2.11.0", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.11", + "wayland-protocols 0.32.12", "wayland-scanner", ] [[package]] name = "wayland-protocols-plasma" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d392fc283a87774afc9beefcd6f931582bb97fe0e6ced0b306a62cb1d026527c" +checksum = "2b6d8cf1eb2c1c31ed1f5643c88a6e53538129d4af80030c8cabd1f9fa884d91" dependencies = [ "bitflags 2.11.0", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.11", + "wayland-protocols 0.32.12", "wayland-scanner", ] @@ -7735,23 +7703,23 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78248e4cc0eff8163370ba5c158630dcae1f3497a586b826eca2ef5f348d6235" +checksum = "eb04e52f7836d7c7976c78ca0250d61e33873c34156a2a1fc9474828ec268234" dependencies = [ "bitflags 2.11.0", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.11", + "wayland-protocols 0.32.12", "wayland-scanner", "wayland-server", ] [[package]] name = "wayland-scanner" -version = "0.31.9" +version = "0.31.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c86287151a309799b821ca709b7345a048a2956af05957c89cb824ab919fa4e3" +checksum = "9c324a910fd86ebdc364a3e61ec1f11737d3b1d6c273c0239ee8ff4bc0d24b4a" dependencies = [ "proc-macro2", "quick-xml 0.39.2", @@ -7760,9 +7728,9 @@ dependencies = [ [[package]] name = "wayland-server" -version = "0.31.12" +version = "0.31.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63736a4a73e781cf6a736aa32c5d6773c3eb5389197562742a8c611b49b5e359" +checksum = "cc1846eb04c49182e04f4a099e2a830a2b745610bbc1d61246e206f29c7000a0" dependencies = [ "bitflags 2.11.0", "downcast-rs", @@ -7773,9 +7741,9 @@ dependencies = [ [[package]] name = "wayland-sys" -version = "0.31.10" +version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374f6b70e8e0d6bf9461a32988fd553b59ff630964924dad6e4a4eb6bd538d17" +checksum = "d8eab23fefc9e41f8e841df4a9c707e8a8c4ed26e944ef69297184de2785e3be" dependencies = [ "dlib", "log", @@ -7785,9 +7753,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.91" +version = "0.3.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9" +checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" dependencies = [ "js-sys", "wasm-bindgen", @@ -7810,7 +7778,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe985f41e291eecef5e5c0770a18d28390addb03331c043964d9e916453d6f16" dependencies = [ "core-foundation 0.10.1", - "jni 0.22.3", + "jni 0.22.4", "log", "ndk-context", "objc2 0.6.4", @@ -8036,7 +8004,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -8048,7 +8016,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "window_clipboard" version = "0.4.1" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" +source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "clipboard-win", "clipboard_macos", @@ -8621,7 +8589,7 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "bitflags 2.11.0", "cfg_aliases", @@ -8647,7 +8615,7 @@ dependencies = [ [[package]] name = "winit-android" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "android-activity", "bitflags 2.11.0", @@ -8662,7 +8630,7 @@ dependencies = [ [[package]] name = "winit-appkit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "bitflags 2.11.0", "block2 0.6.2", @@ -8684,7 +8652,7 @@ dependencies = [ [[package]] name = "winit-common" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "memmap2 0.9.10", "objc2 0.6.4", @@ -8699,7 +8667,7 @@ dependencies = [ [[package]] name = "winit-core" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "bitflags 2.11.0", "cursor-icon", @@ -8713,14 +8681,14 @@ dependencies = [ [[package]] name = "winit-orbital" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "bitflags 2.11.0", "dpi", "libredox", "orbclient", "raw-window-handle", - "redox_syscall 0.7.3", + "redox_syscall 0.7.4", "smol_str", "tracing", "winit-core", @@ -8729,7 +8697,7 @@ dependencies = [ [[package]] name = "winit-uikit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "bitflags 2.11.0", "block2 0.6.2", @@ -8749,7 +8717,7 @@ dependencies = [ [[package]] name = "winit-wayland" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "ahash", "bitflags 2.11.0", @@ -8766,7 +8734,7 @@ dependencies = [ "tracing", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.11", + "wayland-protocols 0.32.12", "wayland-protocols-plasma", "winit-common", "winit-core", @@ -8775,7 +8743,7 @@ dependencies = [ [[package]] name = "winit-web" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "atomic-waker", "bitflags 2.11.0", @@ -8797,7 +8765,7 @@ dependencies = [ [[package]] name = "winit-win32" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "bitflags 2.11.0", "cursor-icon", @@ -8813,7 +8781,7 @@ dependencies = [ [[package]] name = "winit-x11" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" +source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "bitflags 2.11.0", "bytemuck", @@ -8842,6 +8810,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen" version = "0.51.0" @@ -8932,9 +8909,9 @@ dependencies = [ [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "x11-dl" @@ -9060,9 +9037,9 @@ checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5" [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -9071,9 +9048,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", @@ -9110,7 +9087,7 @@ dependencies = [ "uds_windows", "uuid", "windows-sys 0.61.2", - "winnow", + "winnow 0.7.15", "zbus_macros", "zbus_names", "zvariant", @@ -9162,7 +9139,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffd8af6d5b78619bab301ff3c560a5bd22426150253db278f164d6cf3b72c50f" dependencies = [ "serde", - "winnow", + "winnow 0.7.15", "zvariant", ] @@ -9186,18 +9163,18 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524" [[package]] name = "zerocopy" -version = "0.8.42" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.42" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", @@ -9206,18 +9183,18 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", @@ -9233,9 +9210,9 @@ checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", @@ -9244,9 +9221,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "yoke", "zerofrom", @@ -9255,9 +9232,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", @@ -9302,9 +9279,9 @@ dependencies = [ [[package]] name = "zune-jpeg" -version = "0.5.13" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec5f41c76397b7da451efd19915684f727d7e1d516384ca6bd0ec43ec94de23c" +checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296" dependencies = [ "zune-core 0.5.1", ] @@ -9319,7 +9296,7 @@ dependencies = [ "enumflags2", "serde", "url", - "winnow", + "winnow 0.7.15", "zvariant_derive", "zvariant_utils", ] @@ -9347,5 +9324,5 @@ dependencies = [ "quote", "serde", "syn", - "winnow", + "winnow 0.7.15", ] diff --git a/runtime/src/platform_specific/wayland/mod.rs b/runtime/src/platform_specific/wayland/mod.rs index 752ca49a..3c2ac977 100644 --- a/runtime/src/platform_specific/wayland/mod.rs +++ b/runtime/src/platform_specific/wayland/mod.rs @@ -2,7 +2,7 @@ use std::fmt::Debug; -use iced_core::window::Id; +use iced_core::{Rectangle, window::Id}; /// activation Actions pub mod activation; @@ -35,6 +35,8 @@ pub enum Action { InhibitShortcuts(bool), /// Rounded corners in logical space RoundedCorners(iced_core::window::Id, Option), + /// Blur effect for a surface + BlurSurface(Id, Option>), } #[derive(Debug, Clone, Copy, PartialEq, Default)] @@ -70,6 +72,11 @@ impl Debug for Action { Action::RoundedCorners(id, v) => { f.debug_tuple("RoundedCorners").field(id).field(v).finish() } + Action::BlurSurface(id, rectangles) => f + .debug_tuple("BlurSurface") + .field(id) + .field(rectangles) + .finish(), } } } diff --git a/winit/src/platform_specific/wayland/event_loop/mod.rs b/winit/src/platform_specific/wayland/event_loop/mod.rs index 6c63f218..976595a7 100644 --- a/winit/src/platform_specific/wayland/event_loop/mod.rs +++ b/winit/src/platform_specific/wayland/event_loop/mod.rs @@ -7,7 +7,10 @@ use crate::platform_specific::SurfaceIdWrapper; use crate::{ Control, futures::futures::channel::mpsc, - handlers::{overlap::OverlapNotifyV1, text_input::TextInputManager}, + handlers::{ + ext_background_effect, overlap::OverlapNotifyV1, + text_input::TextInputManager, + }, platform_specific::wayland::{ handlers::{ wp_fractional_scaling::FractionalScalingManager, @@ -346,26 +349,26 @@ impl SctkEventLoop { &qh, ), corner_radius_manager: registry_state.bind_one::( - &qh, - 1..=1, - (), - ).ok(), + &qh, + 1..=1, + (), + ).ok(), toplevel_manager: ToplevelManagerState::try_new( ®istry_state, &qh, ), - inhibitor_manager: registry_state.bind_one::( - &qh, - 1..=1, - (), - ).ok(), + inhibitor_manager: registry_state.bind_one::( + &qh, + 1..=1, + (), + ).ok(), text_input_manager: TextInputManager::try_new(®istry_state, &qh), + ext_background_effect_manager: ext_background_effect::ExtBackgroundEffectManager::new(&globals, &qh).ok(), registry_state, queue_handle: qh, loop_handle, - inhibitor: None, inhibited: false, _cursor_surface: None, @@ -373,6 +376,7 @@ impl SctkEventLoop { outputs: Vec::new(), seats: Vec::new(), windows: Vec::new(), + blur_surfaces: HashMap::new(), layer_surfaces: Vec::new(), popups: Vec::new(), lock_surfaces: Vec::new(), diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index 9c9a4e11..68de367f 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -2,6 +2,7 @@ use crate::{ Control, handlers::{ activation::IcedRequestData, + ext_background_effect, overlap::{OverlapNotificationV1, OverlapNotifyV1}, text_input::{Preedit, TextInputManager}, }, @@ -25,7 +26,7 @@ use iced_futures::{ }; use raw_window_handle::HasWindowHandle; use std::{ - collections::{HashMap, HashSet}, + collections::{HashMap, HashSet, hash_map::Entry}, convert::Infallible, fmt::Debug, sync::{Arc, Mutex, atomic::AtomicU32}, @@ -108,6 +109,7 @@ use iced_runtime::{ }, }; use wayland_protocols::{ + ext::background_effect::v1::client::ext_background_effect_surface_v1::ExtBackgroundEffectSurfaceV1, wp::{ fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1, keyboard_shortcuts_inhibit::zv1::client::{ @@ -443,6 +445,7 @@ pub struct SctkState { pub(crate) popups: Vec, pub(crate) subsurfaces: Vec, pub(crate) lock_surfaces: Vec, + pub(crate) blur_surfaces: HashMap>, pub(crate) touch_points: HashMap, /// Window updates, which are coming from SCTK or the compositor, which require @@ -485,6 +488,7 @@ pub struct SctkState { pub(crate) toplevel_info: Option, pub(crate) toplevel_manager: Option, pub(crate) subsurface_state: Option, + pub(crate) ext_background_effect_manager: Option, pub(crate) activation_token_ctr: u32, pub(crate) token_senders: HashMap>>, @@ -666,9 +670,7 @@ impl SctkState { // TODO winit sets cursor size after handling the change for the window, so maybe that should be done as well. } -} -impl SctkState { pub fn get_popup( &mut self, settings: SctkPopupSettings, @@ -1091,6 +1093,12 @@ impl SctkState { if let Some(i) = self.layer_surfaces.iter().position(|l| l.id == id) { let l = self.layer_surfaces.remove(i); + if let Some(blurred) = self.blur_surfaces.remove(&l.id) { + for s in blurred { + s.destroy(); + } + } + let (removed, remaining): (Vec<_>, Vec<_>) = self .subsurfaces .drain(..) @@ -1344,6 +1352,12 @@ impl SctkState { _ = self.destroyed.insert(id); } + if let Some(blurred) = self.blur_surfaces.remove(&id) { + for s in blurred { + s.destroy(); + } + } + let (removed, remaining): (Vec<_>, Vec<_>) = self .subsurfaces .drain(..) @@ -1455,6 +1469,7 @@ impl SctkState { // TODO how to handle this when there's no lock? if let Some((surface, _)) = self.get_lock_surface(id, &output) { let wl_surface = surface.wl_surface(); + receive_frame(&mut self.frame_status, &wl_surface); } } @@ -1465,6 +1480,11 @@ impl SctkState { }) { let surface = self.lock_surfaces.remove(i); + if let Some(blurred) = self.blur_surfaces.remove(&surface.id) { + for s in blurred { + s.destroy(); + } + } let (removed, remaining): (Vec<_>, Vec<_>) = self .subsurfaces .drain(..) @@ -1536,7 +1556,7 @@ impl SctkState { let mut destroyed = vec![]; if let Some(subsurface) = self.subsurfaces.iter().position(|s| s.id == id) { let subsurface = self.subsurfaces.remove(subsurface); - destroyed.push((subsurface.instance.wl_surface.clone(), subsurface.instance.parent.clone())); + destroyed.push((subsurface.instance.wl_surface.clone(), subsurface.instance.parent.clone(), subsurface.id)); subsurface.instance.wl_surface.attach(None, 0, 0); subsurface.instance.wl_surface.commit(); @@ -1544,7 +1564,12 @@ impl SctkState { SctkEvent::SubsurfaceEvent( crate::sctk_event::SubsurfaceEventVariant::Destroyed(subsurface.instance) ) ); } - for (destroyed, parent) in destroyed { + for (destroyed, parent, id) in destroyed { + if let Some(blurred) = self.blur_surfaces.remove(&id) { + for s in blurred { + s.destroy(); + } + } if let Some((wl_surface, f)) = self.seats.iter_mut().find(|f| { f.kbd_focus.as_ref().is_some_and(|f| *f == destroyed) }).and_then(|f| Some((parent, &mut f.kbd_focus))) { @@ -1574,7 +1599,7 @@ impl SctkState { if let Some(manager) = self.corner_radius_manager.as_ref() { if let Some(w) = self.windows.iter_mut().find(|w| w.id == id) { let geo_size: LogicalSize = w.window.surface_size().cast::().to_logical(w.window.scale_factor()); - let half_min_dim = ((geo_size.width as u32).min(geo_size.height as u32) / 2); + let half_min_dim = (geo_size.width as u32).min(geo_size.height as u32) / 2; if let Some(radii) = v { let adjusted_radii = CornerRadius { @@ -1621,6 +1646,90 @@ impl SctkState { } } } + Action::BlurSurface(id, rectangles) => { + let s = if let Some(s) = self.popups.iter().find(|s| s.data.id == id) { + s.popup.wl_surface() + } else if let Some(s) = self.layer_surfaces.iter().find(|s| s.id == id) { + s.surface.wl_surface() + } else if let Some(s) = self.lock_surfaces.iter().find(|s| s.id == id) { + s.session_lock_surface.wl_surface() + } else if let Some(subsurface) = self.subsurfaces.iter().find(|s| s.id == id) { + &subsurface.instance.wl_surface + } else { + log::error!("Failed to find surface for blur action"); + return Ok(()); + }; + let existing_blur = self.blur_surfaces.entry(id); + match (existing_blur, rectangles) { + (Entry::Occupied(occupied_entry), None) => { + let blur_surfaces = occupied_entry.remove(); + for region in blur_surfaces { + region.destroy(); + } + }, + (Entry::Occupied(mut occupied_entry), Some(rectangles)) => { + let blur_surfaces = occupied_entry.get_mut(); + let regions = rectangles.into_iter().map(|rect| { + let region = self + .compositor_state + .wl_compositor() + .create_region(&self.queue_handle, ()); + region.add( + rect.x.round() as i32, + rect.y.round() as i32, + rect.width.round() as i32, + rect.height.round() as i32, + ); + region + }).collect::>(); + if regions.len() > blur_surfaces.len() { + // add extra blur surfaces if needed + for _ in blur_surfaces.len()..regions.len() { + let Some(extra_region) = self.ext_background_effect_manager.as_mut().map(|mgr| mgr.blur(s, &self.queue_handle)) else { + log::error!("Failed to create blur effect for surface"); + return Ok(()); + }; + blur_surfaces.push(extra_region); + } + } else if regions.len() < blur_surfaces.len() { + for surface in blur_surfaces.iter().skip(regions.len()) { + surface.destroy(); + } + } + + // update existing blur surfaces + for (blur_surface, region) in blur_surfaces.iter().zip(regions.into_iter()) { + blur_surface.set_blur_region(Some(®ion)); + } + }, + (Entry::Vacant(..), None) => { + // nothing to remove + }, + (Entry::Vacant(vacant_entry), Some(rectangles)) => { + if self.ext_background_effect_manager.is_none() { + log::error!("Blur effect is not supported."); + return Ok(()); + } + let blur_surfaces = rectangles.into_iter().map(|rect| { + let region = self + .compositor_state + .wl_compositor() + .create_region(&self.queue_handle, ()); + region.add( + rect.x.round() as i32, + rect.y.round() as i32, + rect.width.round() as i32, + rect.height.round() as i32, + ); + let blur_manager = self.ext_background_effect_manager.as_mut().unwrap(); + let blur_surface = blur_manager.blur(s, &self.queue_handle); + blur_surface.set_blur_region(Some(®ion)); + blur_surface + }).collect::>(); + _ = vacant_entry.insert(blur_surfaces); + }, + } + }, }; Ok(()) } diff --git a/winit/src/platform_specific/wayland/handlers/ext_background_effect.rs b/winit/src/platform_specific/wayland/handlers/ext_background_effect.rs new file mode 100644 index 00000000..3e33d9a1 --- /dev/null +++ b/winit/src/platform_specific/wayland/handlers/ext_background_effect.rs @@ -0,0 +1,65 @@ +use cctk::sctk; +use sctk::globals::GlobalData; +use sctk::reexports::client::globals::{BindError, GlobalList}; +use sctk::reexports::client::protocol::wl_surface::WlSurface; +use sctk::reexports::client::{Connection, Dispatch, Proxy, QueueHandle, delegate_dispatch}; +use wayland_protocols::ext::background_effect::v1::client::ext_background_effect_manager_v1::ExtBackgroundEffectManagerV1; +use wayland_protocols::ext::background_effect::v1::client::ext_background_effect_surface_v1::ExtBackgroundEffectSurfaceV1; + +use crate::event_loop::state::SctkState; + +#[derive(Debug, Clone)] +pub struct ExtBackgroundEffectManager { + manager: ExtBackgroundEffectManagerV1, +} + +impl ExtBackgroundEffectManager { + pub fn new( + globals: &GlobalList, + queue_handle: &QueueHandle, + ) -> Result { + let manager = globals.bind(queue_handle, 1..=1, GlobalData)?; + Ok(Self { manager }) + } + + pub fn blur( + &mut self, + surface: &WlSurface, + queue_handle: &QueueHandle, + ) -> ExtBackgroundEffectSurfaceV1 { + self.manager + .get_background_effect(surface, queue_handle, ()) + } +} + +impl Dispatch + for ExtBackgroundEffectManager +{ + fn event( + _: &mut SctkState, + _: &ExtBackgroundEffectManagerV1, + _: ::Event, + _: &GlobalData, + _: &Connection, + _: &QueueHandle, + ) { + } +} + +impl Dispatch + for ExtBackgroundEffectManager +{ + fn event( + _: &mut SctkState, + _: &ExtBackgroundEffectSurfaceV1, + _: ::Event, + _: &(), + _: &Connection, + _: &QueueHandle, + ) { + // There is no event + } +} + +delegate_dispatch!(SctkState: [ExtBackgroundEffectManagerV1: GlobalData] => ExtBackgroundEffectManager); +delegate_dispatch!(SctkState: [ExtBackgroundEffectSurfaceV1: ()] => ExtBackgroundEffectManager); diff --git a/winit/src/platform_specific/wayland/handlers/mod.rs b/winit/src/platform_specific/wayland/handlers/mod.rs index dfc73b5e..444c7e4e 100644 --- a/winit/src/platform_specific/wayland/handlers/mod.rs +++ b/winit/src/platform_specific/wayland/handlers/mod.rs @@ -1,6 +1,7 @@ // handlers pub mod activation; pub mod compositor; +pub mod ext_background_effect; pub mod output; pub mod overlap; pub mod seat; @@ -12,14 +13,14 @@ pub mod toplevel; pub mod wp_fractional_scaling; pub mod wp_viewporter; -use cctk::{sctk::{ +use cctk::sctk::{ delegate_registry, delegate_shm, output::OutputState, registry::{ProvidesRegistryState, RegistryState}, registry_handlers, seat::SeatState, shm::{Shm, ShmHandler}, -}}; +}; use crate::platform_specific::wayland::event_loop::state::SctkState; diff --git a/winit/src/platform_specific/wayland/subsurface_widget.rs b/winit/src/platform_specific/wayland/subsurface_widget.rs index ed53d9ea..dbecc52d 100644 --- a/winit/src/platform_specific/wayland/subsurface_widget.rs +++ b/winit/src/platform_specific/wayland/subsurface_widget.rs @@ -7,7 +7,6 @@ use crate::core::{ widget::{self, Widget}, }; use std::{ - borrow::BorrowMut, cell::RefCell, collections::HashMap, fmt::Debug, diff --git a/winit/src/platform_specific/wayland/winit_window.rs b/winit/src/platform_specific/wayland/winit_window.rs index 296d8b67..d7458186 100644 --- a/winit/src/platform_specific/wayland/winit_window.rs +++ b/winit/src/platform_specific/wayland/winit_window.rs @@ -287,7 +287,21 @@ impl winit::window::Window for SctkWinitWindow { } fn set_blur(&self, blur: bool) { - // TODO + _ = self.tx.send(Action::Action( + iced_runtime::platform_specific::wayland::Action::BlurSurface( + self.id.inner(), + if blur { + Some(vec![iced_runtime::core::Rectangle { + x: f32::MIN, + y: f32::MIN, + width: f32::MAX, + height: f32::MAX, + }]) + } else { + None + }, + ), + )); } fn set_visible(&self, visible: bool) {} From 1bf1e33317b8da299ffd9a620e7e0e099c0c3478 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Tue, 14 Apr 2026 14:47:25 -0400 Subject: [PATCH 02/72] improv(wayland): handle capabilities for ext_background_effect --- .../wayland/event_loop/state.rs | 7 +++ .../wayland/handlers/ext_background_effect.rs | 50 +++++++++++++++++-- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index 68de367f..f99e48ba 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -1647,6 +1647,13 @@ impl SctkState { } } Action::BlurSurface(id, rectangles) => { + use wayland_protocols::ext::background_effect::v1::client::ext_background_effect_manager_v1; + + if let Some(bg_effect_mgr) = self.ext_background_effect_manager.as_mut() && !bg_effect_mgr.capabilities().contains(ext_background_effect_manager_v1::Capability::Blur) { + bg_effect_mgr.enqueue(id, rectangles.clone()); + return Ok(()); + } + let s = if let Some(s) = self.popups.iter().find(|s| s.data.id == id) { s.popup.wl_surface() } else if let Some(s) = self.layer_surfaces.iter().find(|s| s.id == id) { diff --git a/winit/src/platform_specific/wayland/handlers/ext_background_effect.rs b/winit/src/platform_specific/wayland/handlers/ext_background_effect.rs index 3e33d9a1..03a80da9 100644 --- a/winit/src/platform_specific/wayland/handlers/ext_background_effect.rs +++ b/winit/src/platform_specific/wayland/handlers/ext_background_effect.rs @@ -1,16 +1,23 @@ +use std::collections::HashMap; + use cctk::sctk; +use iced_runtime::core::Rectangle; +use iced_runtime::platform_specific::wayland::Action; use sctk::globals::GlobalData; use sctk::reexports::client::globals::{BindError, GlobalList}; use sctk::reexports::client::protocol::wl_surface::WlSurface; use sctk::reexports::client::{Connection, Dispatch, Proxy, QueueHandle, delegate_dispatch}; -use wayland_protocols::ext::background_effect::v1::client::ext_background_effect_manager_v1::ExtBackgroundEffectManagerV1; +use wayland_protocols::ext::background_effect::v1::client::ext_background_effect_manager_v1::{Capability, Event, ExtBackgroundEffectManagerV1}; use wayland_protocols::ext::background_effect::v1::client::ext_background_effect_surface_v1::ExtBackgroundEffectSurfaceV1; use crate::event_loop::state::SctkState; +use crate::window; #[derive(Debug, Clone)] pub struct ExtBackgroundEffectManager { manager: ExtBackgroundEffectManagerV1, + capabilities: Capability, + queued_blur_actions: HashMap>>, } impl ExtBackgroundEffectManager { @@ -19,7 +26,11 @@ impl ExtBackgroundEffectManager { queue_handle: &QueueHandle, ) -> Result { let manager = globals.bind(queue_handle, 1..=1, GlobalData)?; - Ok(Self { manager }) + Ok(Self { + manager, + capabilities: Capability::empty(), + queued_blur_actions: HashMap::new(), + }) } pub fn blur( @@ -30,19 +41,50 @@ impl ExtBackgroundEffectManager { self.manager .get_background_effect(surface, queue_handle, ()) } + + pub fn enqueue(&mut self, id: window::Id, rects: Option>) { + _ = self.queued_blur_actions.insert(id, rects); + } + + pub fn capabilities(&self) -> Capability { + self.capabilities + } } impl Dispatch for ExtBackgroundEffectManager { fn event( - _: &mut SctkState, + state: &mut SctkState, _: &ExtBackgroundEffectManagerV1, - _: ::Event, + event: ::Event, _: &GlobalData, _: &Connection, _: &QueueHandle, ) { + match event { + Event::Capabilities { flags } => match flags { + wayland_client::WEnum::Value(capability) => { + let mut queued_actions = Vec::new(); + if let Some(bg_effect_mgr) = + state.ext_background_effect_manager.as_mut() + { + bg_effect_mgr.capabilities = capability; + queued_actions = + bg_effect_mgr.queued_blur_actions.drain().collect(); + } + for (id, rects) in queued_actions { + _ = state.handle_action(Action::BlurSurface(id, rects)); + } + } + wayland_client::WEnum::Unknown(u) => { + log::warn!("Unknown value: {u:?}"); + } + }, + e => { + log::warn!("Ignored event {e:?}"); + } + } } } From 13b8d3eab67df7f40d3d9e932a9412f85ff8413c Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Tue, 14 Apr 2026 23:18:44 -0400 Subject: [PATCH 03/72] fix: just use 0 for position of blur rectangle --- winit/src/platform_specific/wayland/winit_window.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/winit/src/platform_specific/wayland/winit_window.rs b/winit/src/platform_specific/wayland/winit_window.rs index d7458186..b33b7f9e 100644 --- a/winit/src/platform_specific/wayland/winit_window.rs +++ b/winit/src/platform_specific/wayland/winit_window.rs @@ -292,8 +292,8 @@ impl winit::window::Window for SctkWinitWindow { self.id.inner(), if blur { Some(vec![iced_runtime::core::Rectangle { - x: f32::MIN, - y: f32::MIN, + x: 0., + y: 0., width: f32::MAX, height: f32::MAX, }]) From 64b97077b7989aceb17019b7e1ebdeac239538f9 Mon Sep 17 00:00:00 2001 From: boloto1979 Date: Wed, 15 Apr 2026 23:07:37 -0300 Subject: [PATCH 04/72] fix(wayland): add mouse cursor entered event to SctkEvent --- winit/src/platform_specific/wayland/sctk_event.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/winit/src/platform_specific/wayland/sctk_event.rs b/winit/src/platform_specific/wayland/sctk_event.rs index 3a1a0166..8845b0c9 100755 --- a/winit/src/platform_specific/wayland/sctk_event.rs +++ b/winit/src/platform_specific/wayland/sctk_event.rs @@ -380,6 +380,12 @@ impl SctkEvent { (variant.position.0, variant.position.1).into(), ) } + events.push(( + id.clone(), + iced_runtime::core::Event::Mouse( + mouse::Event::CursorEntered, + ), + )); events.push(( id, iced_runtime::core::Event::Mouse( From 8f10a3bd34c5e97fabae0329bd90fd10a973b48e Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Thu, 16 Apr 2026 11:56:14 -0700 Subject: [PATCH 05/72] winit: Set `WindowAttributesWayland` without `cctk` feature There doesn't seem to be any reason for this to require the `cctk` feature? Fixes the app ID, and therefore icon, for `cosmic-sync-gui`. --- winit/src/conversion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index fcb73c39..cc5676b5 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -178,7 +178,7 @@ pub fn window_attributes( ), )); } - #[cfg(all(feature = "cctk", target_os = "linux"))] + #[cfg(target_os = "linux")] { use winit::platform::wayland::WindowAttributesWayland; From aa2a870c357284630045b05186fa7a6313c27693 Mon Sep 17 00:00:00 2001 From: KENZ Date: Sat, 18 Apr 2026 13:23:01 +0900 Subject: [PATCH 06/72] fix: Forward wayland IME events in SCTK only when `single-instance` feature enabled --- winit/Cargo.toml | 2 ++ winit/src/platform_specific/wayland/handlers/text_input.rs | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/winit/Cargo.toml b/winit/Cargo.toml index 1208cc17..41e4a582 100644 --- a/winit/Cargo.toml +++ b/winit/Cargo.toml @@ -37,6 +37,8 @@ cctk = [ "xkeysym", "dep:cctk", ] +# Prevents multiple separate process instances. +single-instance = [] [dependencies] diff --git a/winit/src/platform_specific/wayland/handlers/text_input.rs b/winit/src/platform_specific/wayland/handlers/text_input.rs index bb0c38da..eb1ed596 100644 --- a/winit/src/platform_specific/wayland/handlers/text_input.rs +++ b/winit/src/platform_specific/wayland/handlers/text_input.rs @@ -69,6 +69,10 @@ impl Dispatch for TextInputManager { _conn: &Connection, _qhandle: &QueueHandle, ) { + if cfg!(not(feature = "single-instance")) { + return; + } + let kbd_focus = match state.seats.iter_mut().find_map(|s| s.kbd_focus.clone()) { Some(surface) => surface, From e4d6dc1f68b931db6b0cf05ea865081801979685 Mon Sep 17 00:00:00 2001 From: leyoda Date: Fri, 24 Apr 2026 06:00:03 +0200 Subject: [PATCH 07/72] yoda: drop x11 default on winit workspace dep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Was pulling winit's full x11 backend (winit-x11 + x11-dl) unconditionally despite iced_winit's own x11 feature being disabled. Fixed by adding default-features=false on the workspace-level winit dep — iced_winit/wayland + wayland-dlopen propagate to winit/wayland + wayland-dlopen as needed. --- Cargo.toml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 49b4b5d7..83e62d54 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -305,7 +305,11 @@ winapi = "0.3" window_clipboard = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" } dnd = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" } mime = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" } -winit = { git = "https://github.com/pop-os/winit.git", tag = "cosmic-0.14" } +# Yoda: default-features = false drops winit's x11 default, which otherwise +# pulls winit-x11, x11-dl, tiny-xlib, as-raw-xcb-connection. Our Wayland-only +# fork doesn't need any of that — the wayland + wayland-dlopen features are +# re-enabled via iced_winit's own feature propagation from libcosmic-yoda. +winit = { git = "https://github.com/pop-os/winit.git", tag = "cosmic-0.14", default-features = false } winit-core = { git = "https://github.com/pop-os/winit.git", tag = "cosmic-0.14" } cursor-icon = "1.1.0" From 8f6be7984af03bc5457966b416d7a240b2c31d4e Mon Sep 17 00:00:00 2001 From: leyoda Date: Fri, 24 Apr 2026 06:24:15 +0200 Subject: [PATCH 08/72] yoda: gate iced_wgpu x11 backend behind an opt-in feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit iced_wgpu's unix block unconditionally depended on as-raw-xcb-connection, tiny-xlib and x11rb for a DRI3 device-id fallback in window/compositor.rs that only fires when wayland can't determine the GPU. On a Wayland-only build this code path never runs, so the deps are pure bloat. Changes: - Cargo.toml: move the 3 x11 crates to optional + new feature `x11` (not in default — wayland-only is the yoda target; users who need X11 opt in). - window.rs: cfg-gate `mod x11;` on feature = "x11" - window/compositor.rs: cfg-gate `use super::x11::get_x11_device_ids` + the or_else fallback on feature = "x11" (wrapped in a let-binding so the non-x11 branch compiles cleanly). Result: iced_wgpu no longer pulls any x11 crate when built without the feature. --- wgpu/Cargo.toml | 11 ++++++++--- wgpu/src/window.rs | 2 +- wgpu/src/window/compositor.rs | 8 +++++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 48fca1b8..ffbcd293 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -25,6 +25,11 @@ svg = ["iced_graphics/svg", "resvg/text"] web-colors = ["iced_graphics/web-colors"] webgl = ["wgpu/webgl"] strict-assertions = [] +# Yoda: opt-in X11 backend. Pulls tiny-xlib/as-raw-xcb-connection/x11rb +# (which otherwise were unconditional direct deps on unix). Wayland-only +# builds just leave this off — window/x11.rs and the DRI3 device-id +# fallback in window/compositor.rs are cfg-gated on it. +x11 = ["dep:as-raw-xcb-connection", "dep:tiny-xlib", "dep:x11rb"] [dependencies] iced_debug.workspace = true @@ -57,9 +62,9 @@ wayland-protocols.workspace = true wayland-backend = { version = "0.3.3", features = ["client_system"] } wayland-client = { version = "0.31.2" } wayland-sys = { version = "0.31.1", features = ["dlopen"] } -as-raw-xcb-connection = "1.0.1" -tiny-xlib = "0.2.3" -x11rb = { version = "0.13.1", features = [ +as-raw-xcb-connection = { version = "1.0.1", optional = true } +tiny-xlib = { version = "0.2.3", optional = true } +x11rb = { version = "0.13.1", optional = true, features = [ "allow-unsafe-code", "dl-libxcb", "dri3", diff --git a/wgpu/src/window.rs b/wgpu/src/window.rs index b9ec54bd..f71b7d3f 100644 --- a/wgpu/src/window.rs +++ b/wgpu/src/window.rs @@ -7,7 +7,7 @@ pub mod compositor; not(target_os = "redox") ))] mod wayland; -#[cfg(all(unix, not(target_os = "macos"), not(target_os = "redox")))] +#[cfg(all(unix, feature = "x11", not(target_os = "macos"), not(target_os = "redox")))] mod x11; pub use compositor::Compositor; diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index 833a642e..15a13905 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -16,7 +16,7 @@ use crate::{Engine, Renderer}; not(target_os = "redox") ))] use super::wayland::get_wayland_device_ids; -#[cfg(all(unix, not(target_os = "macos"), not(target_os = "redox")))] +#[cfg(all(unix, feature = "x11", not(target_os = "macos"), not(target_os = "redox")))] use super::x11::get_x11_device_ids; use std::future::Future; @@ -72,8 +72,10 @@ impl Compositor { not(target_os = "redox") ))] let ids = compatible_window.as_ref().and_then(|window| { - get_wayland_device_ids(window) - .or_else(|| get_x11_device_ids(window)) + let w = get_wayland_device_ids(window); + #[cfg(feature = "x11")] + let w = w.or_else(|| get_x11_device_ids(window)); + w }); // HACK: From f0c0b8d42ecdc52ff6d8b155225051bf6e009f5b Mon Sep 17 00:00:00 2001 From: leyoda Date: Fri, 24 Apr 2026 06:53:36 +0200 Subject: [PATCH 09/72] yoda: softbuffer + window_clipboard default-features=false Two one-line workspace-dep fixes that drop the last remaining X11 crates for Wayland-only builds: - softbuffer: its default = [kms, x11, x11-dlopen, wayland, wayland-dlopen] pulled tiny-xlib + as-raw-xcb-connection unconditionally even though iced_tiny_skia only needed softbuffer/wayland. Disabling the default lets iced_tiny_skia's own feature propagation ask for just wayland + wayland-dlopen. - window_clipboard: upstream pulled clipboard_x11 + clipboard_wayland unconditionally on unix. Our local fork (branch yoda-x11-optional) gates clipboard_x11 behind an opt-in feature, so default-features=false + features=["wayland"] drops ~500 x11 symbols (clipboard_x11, x11rb, x11rb-protocol). Combined with previous yoda-v4 cuts, cosmic-yoterm goes from 1526 -> 43 x11 symbols (-97%), and 55.4 MB -> 53.3 MB (-2.1 MB). --- Cargo.toml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 83e62d54..18a433f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -276,7 +276,10 @@ tiny-skia = { version = "0.11", default-features = false, features = [ "simd", ] } cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "160b086" } -softbuffer = { git = "https://github.com/pop-os/softbuffer", tag = "cosmic-4.0" } +# Yoda: default-features=false drops softbuffer's x11 / x11-dlopen (pulled +# tiny-xlib + as-raw-xcb-connection). The wayland + wayland-dlopen features +# are re-activated via iced_tiny_skia's own `wayland` feature propagation. +softbuffer = { git = "https://github.com/pop-os/softbuffer", tag = "cosmic-4.0", default-features = false } syntect = "5.2" tokio = "1.0" tracing = "0.1" @@ -302,7 +305,11 @@ wayland-client = { version = "0.31.5" } winapi = "0.3" # window_clipboard = "0.4.1" -window_clipboard = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" } +# Yoda: window_clipboard via git path = our local fork that has x11 gated +# behind an opt-in feature. default-features=false + features=["wayland"] +# drops clipboard_x11 + x11rb from the build. +# Kept at /home/lionel/Devels/window_clipboard branch yoda-x11-optional. +window_clipboard = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20", default-features = false, features = ["wayland"] } dnd = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" } mime = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" } # Yoda: default-features = false drops winit's x11 default, which otherwise From 90d2c418a73af0669302e58fb6a0978bb73a7436 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Wed, 22 Apr 2026 14:36:39 -0600 Subject: [PATCH 10/72] chore: update to wgpu 28 and cosmic-text 0.19 --- Cargo.lock | 179 ++++++------------- Cargo.toml | 9 +- examples/custom_shader/src/scene/pipeline.rs | 12 +- examples/integration/src/scene.rs | 5 +- wgpu/src/buffer.rs | 3 - wgpu/src/color.rs | 5 +- wgpu/src/image/atlas.rs | 5 +- wgpu/src/image/cache.rs | 10 +- wgpu/src/image/mod.rs | 13 +- wgpu/src/lib.rs | 4 + wgpu/src/quad.rs | 4 +- wgpu/src/quad/gradient.rs | 6 +- wgpu/src/quad/solid.rs | 6 +- wgpu/src/text.rs | 2 +- wgpu/src/triangle.rs | 25 +-- wgpu/src/triangle/msaa.rs | 7 +- wgpu/src/window/compositor.rs | 3 + 17 files changed, 113 insertions(+), 185 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 805e6066..383d8cfa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -157,6 +157,12 @@ dependencies = [ "equator", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android-activity" version = "0.6.1" @@ -1314,8 +1320,9 @@ dependencies = [ [[package]] name = "cosmic-text" -version = "0.18.2" -source = "git+https://github.com/pop-os/cosmic-text.git#4d74f795cc771fdcc7ea0f9cacba63fcf036fad6" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be17b688510d934ce13f48a2beba700e11583e281e0fda99c22bb256a14eda73" dependencies = [ "bitflags 2.11.0", "fontdb", @@ -1439,7 +1446,7 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "cryoglyph" version = "0.1.0" -source = "git+https://github.com/pop-os/glyphon.git?tag=cosmic-0.14#c49de15bce4d8254ac136d1be9911960cc85ce12" +source = "git+https://github.com/iced-rs/cryoglyph.git?rev=e429a025df36ab8145708acb309080ae3deec17a#e429a025df36ab8145708acb309080ae3deec17a" dependencies = [ "cosmic-text", "etagere", @@ -1561,7 +1568,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.2", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1789,7 +1796,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -2292,7 +2299,7 @@ dependencies = [ "gobject-sys", "libc", "system-deps", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2403,35 +2410,18 @@ dependencies = [ "system-deps", ] -[[package]] -name = "gpu-alloc" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" -dependencies = [ - "bitflags 2.11.0", - "gpu-alloc-types", -] - -[[package]] -name = "gpu-alloc-types" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" -dependencies = [ - "bitflags 2.11.0", -] - [[package]] name = "gpu-allocator" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd" +checksum = "51255ea7cfaadb6c5f1528d43e92a82acb2b96c43365989a28b2d44ee38f8795" dependencies = [ + "ash", + "hashbrown 0.16.1", "log", "presser", - "thiserror 1.0.69", - "windows 0.58.0", + "thiserror 2.0.18", + "windows 0.57.0", ] [[package]] @@ -2699,6 +2689,8 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ + "allocator-api2", + "equivalent", "foldhash 0.2.0", ] @@ -3478,7 +3470,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -3536,7 +3528,7 @@ dependencies = [ "portable-atomic", "portable-atomic-util", "serde_core", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -4045,9 +4037,9 @@ dependencies = [ [[package]] name = "metal" -version = "0.32.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605" +checksum = "c7047791b5bc903b8cd963014b355f71dc9864a9a0b727057676c1dcae5cbc15" dependencies = [ "bitflags 2.11.0", "block", @@ -4193,9 +4185,9 @@ checksum = "13d2233c9842d08cfe13f9eac96e207ca6a2ea10b80259ebe8ad0268be27d2af" [[package]] name = "naga" -version = "27.0.3" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "066cf25f0e8b11ee0df221219010f213ad429855f57c494f995590c861a9a7d8" +checksum = "618f667225063219ddfc61251087db8a9aec3c3f0950c916b614e403486f1135" dependencies = [ "arrayvec", "bit-set", @@ -4300,7 +4292,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -5706,7 +5698,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -5719,7 +5711,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -6334,7 +6326,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -6628,7 +6620,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix 1.1.4", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -7167,7 +7159,7 @@ checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e" dependencies = [ "memoffset", "tempfile", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -7823,12 +7815,13 @@ checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" [[package]] name = "wgpu" -version = "27.0.1" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe68bac7cde125de7a731c3400723cadaaf1703795ad3f4805f187459cd7a77" +checksum = "f9cb534d5ffd109c7d1135f34cdae29e60eab94855a625dcfe1705f8bc7ad79f" dependencies = [ "arrayvec", "bitflags 2.11.0", + "bytemuck", "cfg-if", "cfg_aliases", "document-features", @@ -7852,9 +7845,9 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "27.0.3" +version = "28.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27a75de515543b1897b26119f93731b385a19aea165a1ec5f0e3acecc229cae7" +checksum = "d23f4642f53f666adcfd2d3218ab174d1e6681101aef18696b90cbe64d1c10f9" dependencies = [ "arrayvec", "bit-set", @@ -7885,45 +7878,45 @@ dependencies = [ [[package]] name = "wgpu-core-deps-apple" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0772ae958e9be0c729561d5e3fd9a19679bcdfb945b8b1a1969d9bfe8056d233" +checksum = "87b7b696b918f337c486bf93142454080a32a37832ba8a31e4f48221890047da" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-emscripten" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06ac3444a95b0813ecfd81ddb2774b66220b264b3e2031152a4a29fda4da6b5" +checksum = "34b251c331f84feac147de3c4aa3aa45112622a95dd7ee1b74384fa0458dbd79" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-wasm" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b1027dcf3b027a877e44819df7ceb0e2e98578830f8cd34cd6c3c7c2a7a50b7" +checksum = "12a2cf578ce8d7d50d0e63ddc2345c7dcb599f6eb90b888813406ea78b9b7010" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-core-deps-windows-linux-android" -version = "27.0.0" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71197027d61a71748e4120f05a9242b2ad142e3c01f8c1b47707945a879a03c3" +checksum = "68ca976e72b2c9964eb243e281f6ce7f14a514e409920920dcda12ae40febaae" dependencies = [ "wgpu-hal", ] [[package]] name = "wgpu-hal" -version = "27.0.4" +version = "28.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b21cb61c57ee198bc4aff71aeadff4cbb80b927beb912506af9c780d64313ce" +checksum = "44d6cb474beb218824dcc9e1ce679d973f719262789bfb27407da560cac20eeb" dependencies = [ "android_system_properties", "arrayvec", @@ -7937,7 +7930,6 @@ dependencies = [ "core-graphics-types 0.2.0", "glow", "glutin_wgl_sys", - "gpu-alloc", "gpu-allocator", "gpu-descriptor", "hashbrown 0.16.1", @@ -7964,21 +7956,20 @@ dependencies = [ "wasm-bindgen", "web-sys", "wgpu-types", - "windows 0.58.0", - "windows-core 0.58.0", + "windows 0.62.2", + "windows-core 0.62.2", ] [[package]] name = "wgpu-types" -version = "27.0.1" +version = "28.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afdcf84c395990db737f2dd91628706cb31e86d72e53482320d368e52b5da5eb" +checksum = "e18308757e594ed2cd27dddbb16a139c42a683819d32a2e0b1b0167552f5840c" dependencies = [ "bitflags 2.11.0", "bytemuck", "js-sys", "log", - "thiserror 2.0.18", "web-sys", ] @@ -8004,7 +7995,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -8038,16 +8029,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" -dependencies = [ - "windows-core 0.58.0", - "windows-targets 0.52.6", -] - [[package]] name = "windows" version = "0.61.3" @@ -8103,19 +8084,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-core" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" -dependencies = [ - "windows-implement 0.58.0", - "windows-interface 0.58.0", - "windows-result 0.2.0", - "windows-strings 0.1.0", - "windows-targets 0.52.6", -] - [[package]] name = "windows-core" version = "0.61.2" @@ -8175,17 +8143,6 @@ dependencies = [ "syn", ] -[[package]] -name = "windows-implement" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "windows-implement" version = "0.60.2" @@ -8208,17 +8165,6 @@ dependencies = [ "syn", ] -[[package]] -name = "windows-interface" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "windows-interface" version = "0.59.3" @@ -8282,15 +8228,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-result" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-result" version = "0.3.4" @@ -8309,16 +8246,6 @@ dependencies = [ "windows-link 0.2.1", ] -[[package]] -name = "windows-strings" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" -dependencies = [ - "windows-result 0.2.0", - "windows-targets 0.52.6", -] - [[package]] name = "windows-strings" version = "0.4.2" diff --git a/Cargo.toml b/Cargo.toml index 49b4b5d7..d60bcb8d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -202,7 +202,7 @@ repository = "https://github.com/iced-rs/iced" homepage = "https://iced.rs" categories = ["gui"] keywords = ["gui", "ui", "graphics", "interface", "widgets"] -rust-version = "1.89" +rust-version = "1.92" [workspace.dependencies] iced = { version = "0.14.0", path = "." } @@ -238,10 +238,9 @@ async-std = "1.0" bitflags = "2.5" bytemuck = { version = "1.0", features = ["derive"] } bytes = "1.6" -cosmic-text = { git = "https://github.com/pop-os/cosmic-text.git" } -# cosmic-text = "0.10" +cosmic-text = "0.19" +cryoglyph = { git = "https://github.com/iced-rs/cryoglyph.git", rev = "e429a025df36ab8145708acb309080ae3deec17a" } dark-light = "1.0" -cryoglyph = { package = "cryoglyph", git = "https://github.com/pop-os/glyphon.git", tag = "cosmic-0.14" } resvg = "0.45" web-sys = "0.3.69" guillotiere = "0.6" @@ -288,7 +287,7 @@ url = "2.5" wasm-bindgen-futures = "0.4" wasmtimer = "0.4.2" web-time = "1.1" -wgpu = { version = "27.0", default-features = false, features = [ +wgpu = { version = "28.0", default-features = false, features = [ "std", "wgsl", ] } diff --git a/examples/custom_shader/src/scene/pipeline.rs b/examples/custom_shader/src/scene/pipeline.rs index 80b0d533..30262a5d 100644 --- a/examples/custom_shader/src/scene/pipeline.rs +++ b/examples/custom_shader/src/scene/pipeline.rs @@ -140,7 +140,7 @@ impl Pipeline { address_mode_w: wgpu::AddressMode::ClampToEdge, mag_filter: wgpu::FilterMode::Linear, min_filter: wgpu::FilterMode::Linear, - mipmap_filter: wgpu::FilterMode::Linear, + mipmap_filter: wgpu::MipmapFilterMode::Linear, ..Default::default() }); @@ -223,7 +223,7 @@ impl Pipeline { device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("cubes pipeline layout"), bind_group_layouts: &[&uniform_bind_group_layout], - push_constant_ranges: &[], + immediate_size: 0, }); let shader = @@ -280,7 +280,7 @@ impl Pipeline { compilation_options: wgpu::PipelineCompilationOptions::default(), }), - multiview: None, + multiview_mask: None, cache: None, }); @@ -388,6 +388,7 @@ impl Pipeline { ), timestamp_writes: None, occlusion_query_set: None, + multiview_mask: None, }); pass.set_viewport( @@ -478,7 +479,7 @@ impl DepthPipeline { device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("cubes.depth_pipeline.layout"), bind_group_layouts: &[&bind_group_layout], - push_constant_ranges: &[], + immediate_size: 0, }); let shader = @@ -520,7 +521,7 @@ impl DepthPipeline { compilation_options: wgpu::PipelineCompilationOptions::default(), }), - multiview: None, + multiview_mask: None, cache: None, }); @@ -586,6 +587,7 @@ impl DepthPipeline { ), timestamp_writes: None, occlusion_query_set: None, + multiview_mask: None, }); pass.set_viewport( diff --git a/examples/integration/src/scene.rs b/examples/integration/src/scene.rs index 4e4757fa..1b248036 100644 --- a/examples/integration/src/scene.rs +++ b/examples/integration/src/scene.rs @@ -43,6 +43,7 @@ impl Scene { depth_stencil_attachment: None, timestamp_writes: None, occlusion_query_set: None, + multiview_mask: None, }) } @@ -64,8 +65,8 @@ fn build_pipeline( let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: None, - push_constant_ranges: &[], bind_group_layouts: &[], + immediate_size: 0, }); device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { @@ -101,7 +102,7 @@ fn build_pipeline( mask: !0, alpha_to_coverage_enabled: false, }, - multiview: None, + multiview_mask: None, cache: None, }) } diff --git a/wgpu/src/buffer.rs b/wgpu/src/buffer.rs index 172922da..e251e979 100644 --- a/wgpu/src/buffer.rs +++ b/wgpu/src/buffer.rs @@ -63,7 +63,6 @@ impl Buffer { /// Returns the size of the written bytes. pub fn write( &mut self, - device: &wgpu::Device, encoder: &mut wgpu::CommandEncoder, belt: &mut wgpu::util::StagingBelt, offset: usize, @@ -79,7 +78,6 @@ impl Buffer { &self.raw, (offset + bytes_written) as u64, MAX_WRITE_SIZE_U64, - device, ) .copy_from_slice( &bytes[bytes_written..bytes_written + MAX_WRITE_SIZE], @@ -100,7 +98,6 @@ impl Buffer { &self.raw, (offset + bytes_written) as u64, bytes_left, - device, ) .copy_from_slice(&bytes[bytes_written..]); diff --git a/wgpu/src/color.rs b/wgpu/src/color.rs index 52fe8463..642d4ea7 100644 --- a/wgpu/src/color.rs +++ b/wgpu/src/color.rs @@ -99,7 +99,7 @@ pub fn convert( device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("iced_wgpu.offscreen.blit.pipeline_layout"), bind_group_layouts: &[&constant_layout, &texture_layout], - push_constant_ranges: &[], + immediate_size: 0, }); let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { @@ -149,7 +149,7 @@ pub fn convert( }, depth_stencil: None, multisample: wgpu::MultisampleState::default(), - multiview: None, + multiview_mask: None, cache: None, }); @@ -194,6 +194,7 @@ pub fn convert( depth_stencil_attachment: None, timestamp_writes: None, occlusion_query_set: None, + multiview_mask: None, }); pass.set_pipeline(&pipeline); diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs index 09258329..d23e7452 100644 --- a/wgpu/src/image/atlas.rs +++ b/wgpu/src/image/atlas.rs @@ -132,7 +132,7 @@ impl Atlas { match &entry { Entry::Contiguous(allocation) => { self.upload_allocation( - pixels, width, 0, allocation, device, encoder, belt, + pixels, width, 0, allocation, encoder, belt, ); } Entry::Fragmented { fragments, .. } => { @@ -145,7 +145,6 @@ impl Atlas { width, offset, &fragment.allocation, - device, encoder, belt, ); @@ -312,7 +311,6 @@ impl Atlas { image_width: u32, offset: usize, allocation: &Allocation, - device: &wgpu::Device, encoder: &mut wgpu::CommandEncoder, belt: &mut wgpu::util::StagingBelt, ) { @@ -334,7 +332,6 @@ impl Atlas { let buffer_slice = belt.allocate( wgpu::BufferSize::new(total_bytes as u64).unwrap(), wgpu::BufferSize::new(8 * 4).unwrap(), - device, ); const PIXEL: usize = 4; diff --git a/wgpu/src/image/cache.rs b/wgpu/src/image/cache.rs index 097a383f..88a48640 100644 --- a/wgpu/src/image/cache.rs +++ b/wgpu/src/image/cache.rs @@ -38,7 +38,10 @@ impl Cache { raster: Raster { cache: crate::image::raster::Cache::default(), pending: HashMap::new(), - belt: wgpu::util::StagingBelt::new(2 * 1024 * 1024), + belt: wgpu::util::StagingBelt::new( + device.clone(), + 2 * 1024 * 1024, + ), }, #[cfg(feature = "svg")] vector: crate::image::vector::Cache::default(), @@ -451,7 +454,10 @@ mod worker { backend, texture_layout, shell: shell.clone(), - belt: wgpu::util::StagingBelt::new(4 * 1024 * 1024), + belt: wgpu::util::StagingBelt::new( + device.clone(), + 4 * 1024 * 1024, + ), jobs: jobs_receiver, output: work_sender, quit: quit_receiver, diff --git a/wgpu/src/image/mod.rs b/wgpu/src/image/mod.rs index ba98f443..d0665ee4 100644 --- a/wgpu/src/image/mod.rs +++ b/wgpu/src/image/mod.rs @@ -45,7 +45,7 @@ impl Pipeline { address_mode_w: wgpu::AddressMode::ClampToEdge, min_filter: wgpu::FilterMode::Nearest, mag_filter: wgpu::FilterMode::Nearest, - mipmap_filter: wgpu::FilterMode::Nearest, + mipmap_filter: wgpu::MipmapFilterMode::Nearest, ..Default::default() }); @@ -55,7 +55,7 @@ impl Pipeline { address_mode_w: wgpu::AddressMode::ClampToEdge, min_filter: wgpu::FilterMode::Linear, mag_filter: wgpu::FilterMode::Linear, - mipmap_filter: wgpu::FilterMode::Linear, + mipmap_filter: wgpu::MipmapFilterMode::Linear, ..Default::default() }); @@ -106,8 +106,8 @@ impl Pipeline { let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("iced_wgpu::image pipeline layout"), - push_constant_ranges: &[], bind_group_layouts: &[&constant_layout, &texture_layout], + immediate_size: 0, }); let shader = @@ -191,7 +191,7 @@ impl Pipeline { mask: !0, alpha_to_coverage_enabled: false, }, - multiview: None, + multiview_mask: None, cache: None, }); @@ -528,7 +528,6 @@ impl Layer { &self.uniforms, 0, (bytes.len() as u64).try_into().expect("Sized uniforms"), - device, ) .copy_from_slice(bytes); @@ -539,11 +538,11 @@ impl Layer { let mut offset = 0; if !nearest.is_empty() { - offset += self.instances.write(device, encoder, belt, 0, nearest); + offset += self.instances.write(encoder, belt, 0, nearest); } if !linear.is_empty() { - let _ = self.instances.write(device, encoder, belt, offset, linear); + let _ = self.instances.write(encoder, belt, offset, linear); } } diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 4eb52cc8..03a72042 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -126,6 +126,7 @@ impl Renderer { // It would be great if the `StagingBelt` API exposed methods // for introspection to detect when a resize may be worth it. staging_belt: wgpu::util::StagingBelt::new( + engine.device.clone(), buffer::MAX_WRITE_SIZE as u64, ), @@ -454,6 +455,7 @@ impl Renderer { depth_stencil_attachment: None, timestamp_writes: None, occlusion_query_set: None, + multiview_mask: None, }, )); @@ -528,6 +530,7 @@ impl Renderer { depth_stencil_attachment: None, timestamp_writes: None, occlusion_query_set: None, + multiview_mask: None, }, )); } @@ -621,6 +624,7 @@ impl Renderer { depth_stencil_attachment: None, timestamp_writes: None, occlusion_query_set: None, + multiview_mask: None, }, )); } diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs index 31bf69cf..4cab2598 100644 --- a/wgpu/src/quad.rs +++ b/wgpu/src/quad.rs @@ -209,7 +209,7 @@ impl Layer { transformation: Transformation, scale: f32, ) { - self.update(device, encoder, belt, transformation, scale); + self.update(encoder, belt, transformation, scale); if !quads.solids.is_empty() { self.solid.prepare(device, encoder, belt, &quads.solids); @@ -223,7 +223,6 @@ impl Layer { pub fn update( &mut self, - device: &wgpu::Device, encoder: &mut wgpu::CommandEncoder, belt: &mut wgpu::util::StagingBelt, transformation: Transformation, @@ -237,7 +236,6 @@ impl Layer { &self.constants_buffer, 0, (bytes.len() as u64).try_into().expect("Sized uniforms"), - device, ) .copy_from_slice(bytes); } diff --git a/wgpu/src/quad/gradient.rs b/wgpu/src/quad/gradient.rs index 6a5eed8d..55e62e79 100644 --- a/wgpu/src/quad/gradient.rs +++ b/wgpu/src/quad/gradient.rs @@ -51,7 +51,7 @@ impl Layer { instances: &[Gradient], ) { let _ = self.instances.resize(device, instances.len()); - let _ = self.instances.write(device, encoder, belt, 0, instances); + let _ = self.instances.write(encoder, belt, 0, instances); self.instance_count = instances.len(); } @@ -75,8 +75,8 @@ impl Pipeline { let layout = device.create_pipeline_layout( &wgpu::PipelineLayoutDescriptor { label: Some("iced_wgpu.quad.gradient.pipeline"), - push_constant_ranges: &[], bind_group_layouts: &[constants_layout], + immediate_size: 0, }, ); @@ -155,7 +155,7 @@ impl Pipeline { mask: !0, alpha_to_coverage_enabled: false, }, - multiview: None, + multiview_mask: None, cache: None, }, ); diff --git a/wgpu/src/quad/solid.rs b/wgpu/src/quad/solid.rs index 7e48358e..49e4cf01 100644 --- a/wgpu/src/quad/solid.rs +++ b/wgpu/src/quad/solid.rs @@ -45,7 +45,7 @@ impl Layer { instances: &[Solid], ) { let _ = self.instances.resize(device, instances.len()); - let _ = self.instances.write(device, encoder, belt, 0, instances); + let _ = self.instances.write(encoder, belt, 0, instances); self.instance_count = instances.len(); } @@ -65,8 +65,8 @@ impl Pipeline { let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("iced_wgpu.quad.solid.pipeline"), - push_constant_ranges: &[], bind_group_layouts: &[constants_layout], + immediate_size: 0, }); let shader = @@ -139,7 +139,7 @@ impl Pipeline { mask: !0, alpha_to_coverage_enabled: false, }, - multiview: None, + multiview_mask: None, cache: None, }); diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index 16efa092..b6d9e679 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -619,7 +619,7 @@ fn prepare( )?; Some(cryoglyph::TextArea { - buffer, + text: buffer.layout_runs(), left: position.x, top: position.y, scale: transformation.scale_factor() diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs index fa5ecb9c..5607d03a 100644 --- a/wgpu/src/triangle.rs +++ b/wgpu/src/triangle.rs @@ -313,6 +313,7 @@ fn render<'a>( depth_stencil_attachment: None, timestamp_writes: None, occlusion_query_set: None, + multiview_mask: None, }) }; @@ -425,18 +426,13 @@ impl Layer { let indices = mesh.indices(); - index_offset += self.index_buffer.write( - device, - encoder, - belt, - index_offset, - indices, - ); + index_offset += + self.index_buffer + .write(encoder, belt, index_offset, indices); match mesh { Mesh::Solid { buffers, .. } => { solid_vertex_offset += self.solid.vertices.write( - device, encoder, belt, solid_vertex_offset, @@ -444,16 +440,14 @@ impl Layer { ); solid_uniform_offset += self.solid.uniforms.write( - device, encoder, belt, solid_uniform_offset, &[uniforms], - ); + ) } Mesh::Gradient { buffers, .. } => { gradient_vertex_offset += self.gradient.vertices.write( - device, encoder, belt, gradient_vertex_offset, @@ -461,7 +455,6 @@ impl Layer { ); gradient_uniform_offset += self.gradient.uniforms.write( - device, encoder, belt, gradient_uniform_offset, @@ -731,7 +724,7 @@ mod solid { &wgpu::PipelineLayoutDescriptor { label: Some("iced_wgpu.triangle.solid.pipeline_layout"), bind_group_layouts: &[&constants_layout], - push_constant_ranges: &[], + immediate_size: 0, }, ); @@ -784,7 +777,7 @@ mod solid { primitive: triangle::primitive_state(), depth_stencil: None, multisample: triangle::multisample_state(antialiasing), - multiview: None, + multiview_mask: None, cache: None, }, ); @@ -886,7 +879,7 @@ mod gradient { &wgpu::PipelineLayoutDescriptor { label: Some("iced_wgpu.triangle.gradient.pipeline_layout"), bind_group_layouts: &[&constants_layout], - push_constant_ranges: &[], + immediate_size: 0, }, ); @@ -949,7 +942,7 @@ mod gradient { primitive: triangle::primitive_state(), depth_stencil: None, multisample: triangle::multisample_state(antialiasing), - multiview: None, + multiview_mask: None, cache: None, }, ); diff --git a/wgpu/src/triangle/msaa.rs b/wgpu/src/triangle/msaa.rs index 8ca49461..46118361 100644 --- a/wgpu/src/triangle/msaa.rs +++ b/wgpu/src/triangle/msaa.rs @@ -69,8 +69,8 @@ impl Pipeline { let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("iced_wgpu::triangle::msaa pipeline layout"), - push_constant_ranges: &[], bind_group_layouts: &[&constant_layout, &texture_layout], + immediate_size: 0, }); let shader = @@ -116,7 +116,7 @@ impl Pipeline { mask: !0, alpha_to_coverage_enabled: false, }, - multiview: None, + multiview_mask: None, cache: None, }); @@ -177,6 +177,7 @@ impl Pipeline { depth_stencil_attachment: None, timestamp_writes: None, occlusion_query_set: None, + multiview_mask: None, }) } } @@ -320,7 +321,6 @@ impl State { 0, NonZeroU64::new(std::mem::size_of::() as u64) .expect("non-empty ratio"), - device, ) .copy_from_slice(bytemuck::bytes_of(&ratio)); @@ -351,6 +351,7 @@ impl State { depth_stencil_attachment: None, timestamp_writes: None, occlusion_query_set: None, + multiview_mask: None, }); render_pass.set_pipeline(&pipeline.raw); diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index 833a642e..b575ef61 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -126,6 +126,7 @@ impl Compositor { // if log::max_level() >= log::LevelFilter::Info { // let available_adapters: Vec<_> = instance // .enumerate_adapters(settings.backends) + // .await // .iter() // .map(wgpu::Adapter::get_info) // .collect(); @@ -155,6 +156,7 @@ impl Compositor { if let Some((vendor_id, device_id)) = ids { adapter = instance .enumerate_adapters(settings.backends) + .await .into_iter() .filter(|adapter| { let info = adapter.get_info(); @@ -172,6 +174,7 @@ impl Compositor { } else if let Ok(name) = std::env::var("WGPU_ADAPTER_NAME") { adapter = instance .enumerate_adapters(settings.backends) + .await .into_iter() .filter(|adapter| { let info = adapter.get_info(); From 3928e0d38572d63ff1ef1d768b17770e9a91d7c0 Mon Sep 17 00:00:00 2001 From: edwloef Date: Sat, 27 Dec 2025 16:57:41 +0100 Subject: [PATCH 11/72] wgpu: request devices with `SHADER_F16` feature --- wgpu/src/window/compositor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index b575ef61..d3f4bf8c 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -297,7 +297,7 @@ impl Compositor { label: Some( "iced_wgpu::window::compositor device descriptor", ), - required_features: wgpu::Features::empty(), + required_features: wgpu::Features::SHADER_F16, required_limits: required_limits.clone(), memory_hints: wgpu::MemoryHints::MemoryUsage, trace: wgpu::Trace::Off, From bb9115558d2649c3bced42d340648b8dbceb1fa2 Mon Sep 17 00:00:00 2001 From: Votre Nom Date: Tue, 5 May 2026 08:27:03 +0200 Subject: [PATCH 12/72] Fix high-signal widget and Wayland warnings Avoid recursive operation traversal, execute visible list updates instead of leaving a lazy iterator unused, remove unreachable cfg-gated surface creation code, and handle subsurface buffer attachment failures. --- widget/src/container.rs | 2 +- widget/src/list.rs | 2 +- winit/src/platform_specific/mod.rs | 7 +++++-- winit/src/platform_specific/wayland/subsurface_widget.rs | 5 ++++- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/widget/src/container.rs b/widget/src/container.rs index c9a300c9..e4aeabf2 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -601,7 +601,7 @@ pub fn visible_bounds(id: Id) -> Task> { operate: &mut dyn FnMut(&mut dyn Operation>), ) { self.depth += 1; - self.traverse(operate); + operate(self); self.depth -= 1; } diff --git a/widget/src/list.rs b/widget/src/list.rs index de9fe9b8..6b5f663f 100644 --- a/widget/src/list.rs +++ b/widget/src/list.rs @@ -366,7 +366,7 @@ where self.visible_elements .iter_mut() .zip(&mut state.visible_layouts) - .map(|(element, (index, layout, tree))| { + .for_each(|(element, (index, layout, tree))| { element.as_widget_mut().update( tree, event, diff --git a/winit/src/platform_specific/mod.rs b/winit/src/platform_specific/mod.rs index 9b74ee9c..5e84d16a 100644 --- a/winit/src/platform_specific/mod.rs +++ b/winit/src/platform_specific/mod.rs @@ -153,9 +153,12 @@ impl PlatformSpecific { ) -> Option> { #[cfg(all(feature = "cctk", target_os = "linux"))] { - return self.wayland.create_surface(); + self.wayland.create_surface() + } + #[cfg(not(all(feature = "cctk", target_os = "linux")))] + { + None } - None } pub(crate) fn update_surface_shm( diff --git a/winit/src/platform_specific/wayland/subsurface_widget.rs b/winit/src/platform_specific/wayland/subsurface_widget.rs index ed53d9ea..15233009 100644 --- a/winit/src/platform_specific/wayland/subsurface_widget.rs +++ b/winit/src/platform_specific/wayland/subsurface_widget.rs @@ -410,7 +410,10 @@ impl SubsurfaceState { .unwrap(); canvas[0..width as usize * height as usize * 4].copy_from_slice(data); surface.damage_buffer(0, 0, width as i32, height as i32); - buffer.attach_to(&surface); + if let Err(err) = buffer.attach_to(&surface) { + log::warn!("failed to attach shm buffer to subsurface: {err}"); + return; + } surface.offset(offset.x as i32, offset.y as i32); wp_viewport.set_destination( (width as f64 / scale) as i32, From f388dfdfe47c2aa0c71bc89dae735993973c2ffb Mon Sep 17 00:00:00 2001 From: Votre Nom Date: Tue, 5 May 2026 12:52:06 +0200 Subject: [PATCH 13/72] yoda: point window_clipboard at public Forgejo fork MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace pop-os/window_clipboard sctk-0.20 (no wayland feature) with forge.aditua.com/leyoda/window_clipboard branch yoda-x11-optional. This removes the need for cosmic-files' [patch] redirect to a local path and makes libcosmic build standalone again. Leyoda 2026 – GPLv3 --- Cargo.toml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 18a433f2..99841e8a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -305,13 +305,13 @@ wayland-client = { version = "0.31.5" } winapi = "0.3" # window_clipboard = "0.4.1" -# Yoda: window_clipboard via git path = our local fork that has x11 gated -# behind an opt-in feature. default-features=false + features=["wayland"] -# drops clipboard_x11 + x11rb from the build. -# Kept at /home/lionel/Devels/window_clipboard branch yoda-x11-optional. -window_clipboard = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20", default-features = false, features = ["wayland"] } -dnd = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" } -mime = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" } +# Yoda: window_clipboard pinned to our public fork that has x11 gated behind +# an opt-in feature. default-features=false + features=["wayland"] drops +# clipboard_x11 + x11rb from the build. Branch yoda-x11-optional on +# https://forge.aditua.com/leyoda/window_clipboard. +window_clipboard = { git = "https://forge.aditua.com/leyoda/window_clipboard.git", branch = "yoda-x11-optional", default-features = false, features = ["wayland"] } +dnd = { git = "https://forge.aditua.com/leyoda/window_clipboard.git", branch = "yoda-x11-optional" } +mime = { git = "https://forge.aditua.com/leyoda/window_clipboard.git", branch = "yoda-x11-optional" } # Yoda: default-features = false drops winit's x11 default, which otherwise # pulls winit-x11, x11-dl, tiny-xlib, as-raw-xcb-connection. Our Wayland-only # fork doesn't need any of that — the wayland + wayland-dlopen features are From 8a7a32ff927c210c7fee07c214834deccc9f8136 Mon Sep 17 00:00:00 2001 From: Votre Nom Date: Tue, 5 May 2026 16:45:37 +0200 Subject: [PATCH 14/72] =?UTF-8?q?yoda:=20cargo=20fix=20--lib=20across=20al?= =?UTF-8?q?l=20crates=20=E2=80=94=20drop=20~115=20trivial=20warnings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Auto-applied suggestions (unused imports, _-prefixed unused params, redundant mutability) on iced_core, iced_widget, iced_runtime, iced_winit, iced_wgpu, iced_graphics, iced_tiny_skia. From 170 warnings down to 55. Leyoda 2026 – GPLv3 --- core/src/element.rs | 2 +- core/src/overlay/group.rs | 2 +- core/src/widget/operation/search_id.rs | 2 +- core/src/widget/text.rs | 3 +- graphics/src/image.rs | 2 - runtime/src/dnd.rs | 4 +- runtime/src/lib.rs | 1 - .../src/platform_specific/wayland/popup.rs | 4 +- .../platform_specific/wayland/subsurface.rs | 9 +--- tiny_skia/src/raster.rs | 2 +- wgpu/src/layer.rs | 1 - wgpu/src/lib.rs | 4 +- wgpu/src/window/compositor.rs | 1 - widget/src/button.rs | 2 +- widget/src/checkbox.rs | 2 +- widget/src/container.rs | 2 +- widget/src/image.rs | 4 +- widget/src/keyed/column.rs | 1 - widget/src/lazy.rs | 2 +- widget/src/lazy/component.rs | 4 +- widget/src/list.rs | 2 +- widget/src/mouse_area.rs | 1 - widget/src/pane_grid/content.rs | 2 +- widget/src/scrollable.rs | 7 ++- widget/src/slider.rs | 2 +- widget/src/stack.rs | 1 - widget/src/svg.rs | 1 - widget/src/themer.rs | 1 - widget/src/toggler.rs | 7 ++- winit/src/a11y.rs | 1 - winit/src/application/drag_resize.rs | 2 +- winit/src/clipboard.rs | 2 +- winit/src/conversion.rs | 12 ++--- winit/src/lib.rs | 12 ++--- winit/src/platform_specific/mod.rs | 9 +--- .../wayland/event_loop/mod.rs | 4 -- .../wayland/event_loop/state.rs | 6 +-- .../wayland/handlers/activation.rs | 1 - .../wayland/handlers/seat/seat.rs | 2 +- .../wayland/handlers/shell/corner_radius.rs | 10 ++-- winit/src/platform_specific/wayland/mod.rs | 12 ++--- .../platform_specific/wayland/sctk_event.rs | 18 +++---- .../wayland/subsurface_widget.rs | 4 +- .../platform_specific/wayland/winit_window.rs | 50 +++++++++---------- winit/src/proxy.rs | 1 - 45 files changed, 85 insertions(+), 139 deletions(-) diff --git a/core/src/element.rs b/core/src/element.rs index f97ed6bc..dbe449c5 100644 --- a/core/src/element.rs +++ b/core/src/element.rs @@ -1,4 +1,4 @@ -use crate::event::{self, Event}; +use crate::event::Event; use crate::id::Id; use crate::layout; use crate::mouse; diff --git a/core/src/overlay/group.rs b/core/src/overlay/group.rs index ec0906e7..1a4ce672 100644 --- a/core/src/overlay/group.rs +++ b/core/src/overlay/group.rs @@ -3,7 +3,7 @@ use crate::mouse; use crate::overlay; use crate::renderer; use crate::widget; -use crate::{Clipboard, Event, Layout, Overlay, Point, Rectangle, Shell, Size}; +use crate::{Clipboard, Event, Layout, Overlay, Shell, Size}; /// An [`Overlay`] container that displays multiple overlay [`overlay::Element`] /// children. diff --git a/core/src/widget/operation/search_id.rs b/core/src/widget/operation/search_id.rs index 1286abaf..e03fac8a 100644 --- a/core/src/widget/operation/search_id.rs +++ b/core/src/widget/operation/search_id.rs @@ -4,7 +4,7 @@ use super::Operation; use crate::{ Rectangle, id::Id, - widget::operation::{Outcome, focusable::Count}, + widget::operation::Outcome, }; /// Produces an [`Operation`] that searches for the Id diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs index 1e40bf9e..19e76761 100644 --- a/core/src/widget/text.rs +++ b/core/src/widget/text.rs @@ -25,13 +25,12 @@ use crate::layout; use crate::mouse; use crate::renderer; use crate::text::paragraph::{self, Paragraph}; -use crate::text::{self, Fragment}; +use crate::text::{self}; use crate::widget::tree::{self, Tree}; use crate::{ Color, Element, Layout, Length, Pixels, Rectangle, Size, Theme, Widget, }; -use std::borrow::Cow; pub use text::{Alignment, Ellipsize, LineHeight, Shaping, Wrapping}; /// A bunch of text. diff --git a/graphics/src/image.rs b/graphics/src/image.rs index e5fe9281..d9b23216 100644 --- a/graphics/src/image.rs +++ b/graphics/src/image.rs @@ -2,8 +2,6 @@ #[cfg(feature = "image")] use crate::core::Bytes; -use crate::core::Color; -use crate::core::Radians; use crate::core::Rectangle; use crate::core::image; use crate::core::svg; diff --git a/runtime/src/dnd.rs b/runtime/src/dnd.rs index e6f2b267..446bee68 100644 --- a/runtime/src/dnd.rs +++ b/runtime/src/dnd.rs @@ -1,10 +1,8 @@ //! Access the clipboard. -use std::any::Any; use dnd::{DndDestinationRectangle, DndSurface}; -use iced_core::clipboard::DndSource; -use window_clipboard::mime::{AllowedMimeTypes, AsMimeTypes}; +use window_clipboard::mime::AllowedMimeTypes; use crate::{oneshot, task, Action, Task}; diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 22da3d66..68034bfc 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -28,7 +28,6 @@ pub use task::Task; pub use user_interface::UserInterface; pub use window::Window; -use crate::core::Color; use crate::futures::futures::channel::oneshot; use std::borrow::Cow; diff --git a/runtime/src/platform_specific/wayland/popup.rs b/runtime/src/platform_specific/wayland/popup.rs index e0475eb8..d186f5f0 100644 --- a/runtime/src/platform_specific/wayland/popup.rs +++ b/runtime/src/platform_specific/wayland/popup.rs @@ -1,14 +1,12 @@ -use std::any::Any; use std::fmt; use std::hash::{Hash, Hasher}; -use std::sync::Arc; use cctk::sctk::reexports::protocols::xdg::shell::client::xdg_positioner::{ Anchor, Gravity, }; use iced_core::layout::Limits; use iced_core::window::Id; -use iced_core::{Element, Rectangle}; +use iced_core::Rectangle; /// Popup creation details #[derive(Debug, Clone)] diff --git a/runtime/src/platform_specific/wayland/subsurface.rs b/runtime/src/platform_specific/wayland/subsurface.rs index f174b0a5..13ae6da2 100644 --- a/runtime/src/platform_specific/wayland/subsurface.rs +++ b/runtime/src/platform_specific/wayland/subsurface.rs @@ -1,14 +1,9 @@ -use std::any::Any; use std::fmt; use std::hash::{Hash, Hasher}; -use std::sync::Arc; -use cctk::sctk::reexports::protocols::xdg::shell::client::xdg_positioner::{ - Anchor, Gravity, -}; -use iced_core::layout::Limits; +use cctk::sctk::reexports::protocols::xdg::shell::client::xdg_positioner::Gravity; use iced_core::window::Id; -use iced_core::{Element, Point, Rectangle, Size}; +use iced_core::{Point, Rectangle, Size}; /// Subsurface creation details #[derive(Debug, Clone)] diff --git a/tiny_skia/src/raster.rs b/tiny_skia/src/raster.rs index 7c820917..cf508c9c 100644 --- a/tiny_skia/src/raster.rs +++ b/tiny_skia/src/raster.rs @@ -57,7 +57,7 @@ impl Pipeline { let width_scale = bounds.width / image.width() as f32; let height_scale = bounds.height / image.height() as f32; - let quality = match filter_method { + let _quality = match filter_method { raster::FilterMethod::Linear => tiny_skia::FilterQuality::Bilinear, raster::FilterMethod::Nearest => tiny_skia::FilterQuality::Nearest, }; diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index d4a96ef8..c61730b6 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -1,4 +1,3 @@ -use crate::core::Radians; use crate::core::{ self, Background, Color, Point, Rectangle, Svg, Transformation, renderer, }; diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 4eb52cc8..830f9911 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -64,8 +64,8 @@ pub use geometry::Geometry; use crate::core::renderer; use crate::core::{ - Background, Color, Font, Pixels, Point, Radians, Rectangle, Size, - Transformation, Vector, image::FilterMethod, + Background, Color, Font, Pixels, Point, Rectangle, Size, + Transformation, Vector, }; use crate::graphics::mesh; use crate::graphics::text::{Editor, Paragraph}; diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index 15a13905..56c01980 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -18,7 +18,6 @@ use crate::{Engine, Renderer}; use super::wayland::get_wayland_device_ids; #[cfg(all(unix, feature = "x11", not(target_os = "macos"), not(target_os = "redox")))] use super::x11::get_x11_device_ids; -use std::future::Future; /// A window graphics backend for iced powered by `wgpu`. pub struct Compositor { diff --git a/widget/src/button.rs b/widget/src/button.rs index f137221e..ed7f6ea9 100644 --- a/widget/src/button.rs +++ b/widget/src/button.rs @@ -599,7 +599,7 @@ where (x + width) as f64, (y + height) as f64, ); - let is_hovered = state.state.downcast_ref::().is_hovered; + let _is_hovered = state.state.downcast_ref::().is_hovered; let mut node = Node::new(Role::Button); node.add_action(Action::Focus); diff --git a/widget/src/checkbox.rs b/widget/src/checkbox.rs index 873a4541..83960569 100644 --- a/widget/src/checkbox.rs +++ b/widget/src/checkbox.rs @@ -536,7 +536,7 @@ where }; let bounds = layout.bounds(); - let is_hovered = cursor.is_over(bounds); + let _is_hovered = cursor.is_over(bounds); let Rectangle { x, y, diff --git a/widget/src/container.rs b/widget/src/container.rs index e4aeabf2..a264007a 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -35,7 +35,7 @@ use crate::core::{ color, }; -use iced_runtime::{Action, Task, task}; +use iced_runtime::{Task, task}; /// A widget that aligns its contents inside of its boundaries. /// diff --git a/widget/src/image.rs b/widget/src/image.rs index 4315709a..d726eeec 100644 --- a/widget/src/image.rs +++ b/widget/src/image.rs @@ -293,8 +293,8 @@ fn drawing_bounds( content_fit: ContentFit, rotation: Rotation, scale: f32, - opacity: f32, - border_radius: [f32; 4], + _opacity: f32, + _border_radius: [f32; 4], ) -> Rectangle where Renderer: image::Renderer, diff --git a/widget/src/keyed/column.rs b/widget/src/keyed/column.rs index baaee5c9..f3e33142 100644 --- a/widget/src/keyed/column.rs +++ b/widget/src/keyed/column.rs @@ -1,7 +1,6 @@ //! Keyed columns distribute content vertically while keeping continuity. //! Distribute content vertically. -use crate::core::event; use crate::core::layout; use crate::core::mouse; use crate::core::overlay; diff --git a/widget/src/lazy.rs b/widget/src/lazy.rs index 7a1f8506..7a2611ee 100644 --- a/widget/src/lazy.rs +++ b/widget/src/lazy.rs @@ -15,7 +15,7 @@ use crate::core::mouse; use crate::core::overlay; use crate::core::renderer; use crate::core::widget::tree::{self, Tree}; -use crate::core::widget::{self, Widget}; +use crate::core::widget::Widget; use crate::core::{ self, Clipboard, Event, Length, Rectangle, Shell, Size, Vector, }; diff --git a/widget/src/lazy/component.rs b/widget/src/lazy/component.rs index a810e117..682fd458 100644 --- a/widget/src/lazy/component.rs +++ b/widget/src/lazy/component.rs @@ -527,11 +527,11 @@ where renderer: &Renderer, dnd_rectangles: &mut core::clipboard::DndDestinationRectangles, ) { - let mut tree = tree + let tree = tree .state .downcast_ref::>>>() .borrow_mut(); - let mut tree = tree.as_ref().unwrap(); + let tree = tree.as_ref().unwrap(); self.with_element(|element| { element.as_widget().drag_destinations( &tree.children[0], diff --git a/widget/src/list.rs b/widget/src/list.rs index 6b5f663f..d0d501d2 100644 --- a/widget/src/list.rs +++ b/widget/src/list.rs @@ -1,5 +1,5 @@ #![allow(missing_docs)] -use crate::core::event::{self, Event}; +use crate::core::event::Event; use crate::core::layout; use crate::core::mouse; use crate::core::overlay; diff --git a/widget/src/mouse_area.rs b/widget/src/mouse_area.rs index 3d355c52..4d808348 100644 --- a/widget/src/mouse_area.rs +++ b/widget/src/mouse_area.rs @@ -2,7 +2,6 @@ use iced_renderer::core::mouse::Click; -use crate::core::event; use crate::core::layout; use crate::core::mouse; use crate::core::overlay; diff --git a/widget/src/pane_grid/content.rs b/widget/src/pane_grid/content.rs index a76010e7..4c41e3a6 100644 --- a/widget/src/pane_grid/content.rs +++ b/widget/src/pane_grid/content.rs @@ -6,7 +6,7 @@ use crate::core::renderer; use crate::core::widget::{self, Tree}; use crate::core::{ self, Clipboard, Element, Event, Layout, Point, Rectangle, Shell, Size, - Vector, event, + Vector, }; use crate::pane_grid::{Draggable, TitleBar}; diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index e005a7b8..b14e1413 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -27,7 +27,6 @@ use iced_runtime::core::widget::Id; #[cfg(feature = "a11y")] use std::borrow::Cow; -use crate::core::event; use crate::core::keyboard; use crate::core::layout; use crate::core::mouse; @@ -933,7 +932,7 @@ where let had_input_method = shell.input_method().is_enabled(); - let mut c_event = match event.clone() { + let c_event = match event.clone() { Event::Dnd(dnd::DndEvent::Offer( id, dnd::OfferEvent::Enter { @@ -1586,7 +1585,7 @@ where return A11yTree::default(); } let window = layout.bounds(); - let is_hovered = cursor.is_over(window); + let _is_hovered = cursor.is_over(window); let Rectangle { x, y, @@ -1670,7 +1669,7 @@ where })) { let scrollbar_bounds = scrollbar.total_bounds; - let is_hovered = cursor.is_over(scrollbar_bounds); + let _is_hovered = cursor.is_over(scrollbar_bounds); let Rectangle { x, y, diff --git a/widget/src/slider.rs b/widget/src/slider.rs index ff32f417..e3fe484a 100644 --- a/widget/src/slider.rs +++ b/widget/src/slider.rs @@ -695,7 +695,7 @@ where }; let bounds = layout.bounds(); - let is_hovered = cursor.is_over(bounds); + let _is_hovered = cursor.is_over(bounds); let Rectangle { x, y, diff --git a/widget/src/stack.rs b/widget/src/stack.rs index e85bf2af..cd30a886 100644 --- a/widget/src/stack.rs +++ b/widget/src/stack.rs @@ -1,6 +1,5 @@ //! Display content on top of other content. -use crate::core::event; use crate::core::layout; use crate::core::mouse; use crate::core::overlay; diff --git a/widget/src/svg.rs b/widget/src/svg.rs index 277af3eb..61b1e688 100644 --- a/widget/src/svg.rs +++ b/widget/src/svg.rs @@ -31,7 +31,6 @@ use crate::core::{ #[cfg(feature = "a11y")] use std::borrow::Cow; -use std::marker::PhantomData; use std::path::PathBuf; pub use crate::core::svg::Handle; diff --git a/widget/src/themer.rs b/widget/src/themer.rs index 306c8580..76448ae1 100644 --- a/widget/src/themer.rs +++ b/widget/src/themer.rs @@ -1,6 +1,5 @@ use crate::container; -use crate::core::event; use crate::core::layout; use crate::core::mouse; use crate::core::overlay; diff --git a/widget/src/toggler.rs b/widget/src/toggler.rs index d398a79b..43ba6930 100644 --- a/widget/src/toggler.rs +++ b/widget/src/toggler.rs @@ -37,7 +37,6 @@ use std::borrow::Cow; use iced_runtime::core::border::Radius; use crate::core::alignment; -use crate::core::border; use crate::core::layout; use crate::core::mouse; use crate::core::renderer; @@ -509,7 +508,7 @@ where let space = style.handle_margin; - let toggler_background_bounds = Rectangle { + let _toggler_background_bounds = Rectangle { x: bounds.x, y: bounds.y, width: bounds.width, @@ -529,7 +528,7 @@ where style.background, ); - let padding = (style.padding_ratio * bounds.height).round(); + let _padding = (style.padding_ratio * bounds.height).round(); let toggler_foreground_bounds = Rectangle { x: bounds.x + if self.is_toggled { @@ -570,7 +569,7 @@ where }; let bounds = layout.bounds(); - let is_hovered = cursor.is_over(bounds); + let _is_hovered = cursor.is_over(bounds); let Rectangle { x, y, diff --git a/winit/src/a11y.rs b/winit/src/a11y.rs index a901b480..61fbe630 100644 --- a/winit/src/a11y.rs +++ b/winit/src/a11y.rs @@ -4,7 +4,6 @@ use crate::futures::futures::channel::mpsc; use iced_accessibility::accesskit::{ ActivationHandler, Node, NodeId, Role, Tree, TreeId, TreeUpdate, }; -use iced_accessibility::accesskit_winit::Adapter; use iced_runtime::core; pub struct WinitActivationHandler { diff --git a/winit/src/application/drag_resize.rs b/winit/src/application/drag_resize.rs index 6d575b52..5e524736 100644 --- a/winit/src/application/drag_resize.rs +++ b/winit/src/application/drag_resize.rs @@ -25,7 +25,7 @@ const DRAG_RESIZE_SUPPORTED: bool = false; /// If supported by winit, returns a closure that implements cursor resize support. pub fn event_func( - window: &dyn winit::window::Window, + _window: &dyn winit::window::Window, border_size: f64, ) -> Option< Box< diff --git a/winit/src/clipboard.rs b/winit/src/clipboard.rs index d302ac36..da83d37a 100644 --- a/winit/src/clipboard.rs +++ b/winit/src/clipboard.rs @@ -1,7 +1,7 @@ //! Access the clipboard. use std::sync::Mutex; -use std::{any::Any, borrow::Cow}; +use std::borrow::Cow; use crate::Control; diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index fcb73c39..0afb8e72 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -3,7 +3,6 @@ //! [`winit`]: https://github.com/rust-windowing/winit //! [`iced_runtime`]: https://github.com/iced-rs/iced/tree/0.14/runtime use crate::core::input_method; -use std::hash::DefaultHasher; use std::hash::Hash; use std::hash::Hasher; use std::sync::Arc; @@ -14,7 +13,6 @@ use crate::core::theme; use crate::core::touch; use crate::core::window; use crate::core::{Event, Point, Size}; -use iced_futures::core::event::PlatformSpecific; use winit::dpi::PhysicalPosition; use winit::event::ButtonSource; use winit::event::ElementState; @@ -27,7 +25,7 @@ use winit::keyboard::SmolStr; pub fn window_attributes( settings: window::Settings, title: &str, - scale_factor: f64, + _scale_factor: f64, primary_monitor: Option, _id: Option, ) -> winit::window::WindowAttributes { @@ -396,8 +394,8 @@ pub fn window_event( Ime::Commit(content) => input_method::Event::Commit(content), Ime::Disabled => input_method::Event::Closed, Ime::DeleteSurrounding { - before_bytes, - after_bytes, + before_bytes: _, + after_bytes: _, } => todo!(), })), WindowEvent::Focused(focused) => Some(Event::Window(if focused { @@ -411,7 +409,7 @@ pub fn window_event( WindowEvent::DragDropped { paths, .. } => { Some(Event::Window(window::Event::FileDropped(paths.clone()))) } - WindowEvent::DragLeft { position } => { + WindowEvent::DragLeft { position: _ } => { Some(Event::Window(window::Event::FilesHoveredLeft)) } @@ -707,7 +705,7 @@ enum TouchInternal { pub fn touch_event( finger: FingerId, state: TouchInternal, - force: Option, + _force: Option, position: Option>, scale_factor: f64, ) -> touch::Event { diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 735d73aa..5b5d1ce1 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -53,7 +53,6 @@ mod window; pub use clipboard::Clipboard; pub use error::Error; pub use proxy::Proxy; -use winit::dpi::LogicalSize; use winit::dpi::PhysicalPosition; use winit::dpi::PhysicalSize; @@ -322,9 +321,9 @@ where // create initial window let Some(BootConfig { sender, - fonts, - graphics_settings, - is_wayland, + fonts: _, + graphics_settings: _, + is_wayland: _, }) = self.boot.take() else { return; @@ -636,10 +635,7 @@ where #[cfg(feature = "a11y")] fn init_adapter(&mut self, event_loop: &(dyn winit::event_loop::ActiveEventLoop + 'static), id: core::window::Id, window: Arc) { use crate::a11y::*; - use iced_accessibility::accesskit::{ - ActivationHandler, Node, NodeId, Role, - Tree, TreeUpdate, - }; + use iced_accessibility::accesskit_winit::Adapter; let node_id = diff --git a/winit/src/platform_specific/mod.rs b/winit/src/platform_specific/mod.rs index 5e84d16a..66eda20c 100644 --- a/winit/src/platform_specific/mod.rs +++ b/winit/src/platform_specific/mod.rs @@ -1,14 +1,11 @@ //! Wayland specific shell //! -use std::{borrow::Cow, collections::HashMap, sync::Arc}; +use std::collections::HashMap; -#[cfg(all(feature = "cctk", target_os = "linux"))] -use cctk::sctk::reexports::client::Connection; use iced_graphics::{Compositor, compositor}; use iced_runtime::{ - core::{Vector, window}, - platform_specific, user_interface, + core::{Vector, window}, user_interface, }; use winit::raw_window_handle::HasWindowHandle; @@ -17,8 +14,6 @@ pub mod wayland; #[cfg(all(feature = "cctk", target_os = "linux"))] pub use wayland::*; -#[cfg(all(feature = "cctk", target_os = "linux"))] -use wayland_backend::client::Backend; use crate::{CreateCompositor, Program, WindowManager}; diff --git a/winit/src/platform_specific/wayland/event_loop/mod.rs b/winit/src/platform_specific/wayland/event_loop/mod.rs index 6c63f218..87d00ec2 100644 --- a/winit/src/platform_specific/wayland/event_loop/mod.rs +++ b/winit/src/platform_specific/wayland/event_loop/mod.rs @@ -2,8 +2,6 @@ pub mod control_flow; pub mod proxy; pub mod state; -#[cfg(feature = "a11y")] -use crate::platform_specific::SurfaceIdWrapper; use crate::{ Control, futures::futures::channel::mpsc, @@ -43,8 +41,6 @@ use cctk::{ }; use raw_window_handle::HasDisplayHandle; use state::{FrameStatus, SctkWindow, send_event}; -#[cfg(feature = "a11y")] -use std::sync::{Arc, Mutex}; use std::{ collections::{HashMap, HashSet}, fmt::Debug, diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index 9c9a4e11..3d93a015 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -29,7 +29,6 @@ use std::{ convert::Infallible, fmt::Debug, sync::{Arc, Mutex, atomic::AtomicU32}, - thread::panicking, time::Duration, }; use wayland_backend::client::ObjectId; @@ -50,7 +49,6 @@ use cctk::{ activation::{ActivationState, RequestData}, compositor::CompositorState, error::GlobalError, - globals::GlobalData, output::OutputState, reexports::{ calloop::{LoopHandle, timer::TimeoutAction}, @@ -1258,7 +1256,7 @@ impl SctkState { let timer = cctk::sctk::reexports::calloop::timer::Timer::from_duration(Duration::from_millis(30)); let queue_handle = self.queue_handle.clone(); _ = self.loop_handle.insert_source(timer, move |_, _, state| { - let Some((mut popup, attempt)) = state.pending_popup.take() else { + let Some((popup, attempt)) = state.pending_popup.take() else { return TimeoutAction::Drop; }; @@ -1574,7 +1572,7 @@ impl SctkState { if let Some(manager) = self.corner_radius_manager.as_ref() { if let Some(w) = self.windows.iter_mut().find(|w| w.id == id) { let geo_size: LogicalSize = w.window.surface_size().cast::().to_logical(w.window.scale_factor()); - let half_min_dim = ((geo_size.width as u32).min(geo_size.height as u32) / 2); + let half_min_dim = (geo_size.width as u32).min(geo_size.height as u32) / 2 ; if let Some(radii) = v { let adjusted_radii = CornerRadius { diff --git a/winit/src/platform_specific/wayland/handlers/activation.rs b/winit/src/platform_specific/wayland/handlers/activation.rs index 6b03a8dd..ed5f2259 100644 --- a/winit/src/platform_specific/wayland/handlers/activation.rs +++ b/winit/src/platform_specific/wayland/handlers/activation.rs @@ -3,7 +3,6 @@ use cctk::sctk::{ delegate_activation, reexports::client::protocol::{wl_seat::WlSeat, wl_surface::WlSurface}, }; -use iced_futures::futures::channel::oneshot::Sender; use crate::platform_specific::wayland::event_loop::state::SctkState; diff --git a/winit/src/platform_specific/wayland/handlers/seat/seat.rs b/winit/src/platform_specific/wayland/handlers/seat/seat.rs index 2901ce8e..b0fe43f4 100644 --- a/winit/src/platform_specific/wayland/handlers/seat/seat.rs +++ b/winit/src/platform_specific/wayland/handlers/seat/seat.rs @@ -18,7 +18,7 @@ impl SeatHandler for SctkState { fn new_seat( &mut self, _conn: &cctk::sctk::reexports::client::Connection, - qh: &cctk::sctk::reexports::client::QueueHandle, + _qh: &cctk::sctk::reexports::client::QueueHandle, seat: cctk::sctk::reexports::client::protocol::wl_seat::WlSeat, ) { self.sctk_events.push(SctkEvent::SeatEvent { diff --git a/winit/src/platform_specific/wayland/handlers/shell/corner_radius.rs b/winit/src/platform_specific/wayland/handlers/shell/corner_radius.rs index bd7d2409..67439671 100644 --- a/winit/src/platform_specific/wayland/handlers/shell/corner_radius.rs +++ b/winit/src/platform_specific/wayland/handlers/shell/corner_radius.rs @@ -1,17 +1,13 @@ -use cctk::{sctk, cosmic_protocols::{ - corner_radius::v1::client::{ +use cctk::{sctk, cosmic_protocols::corner_radius::v1::client::{ cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1, - }, - overlap_notify::v1::client::zcosmic_overlap_notification_v1::ZcosmicOverlapNotificationV1, -}}; + }}; use sctk::reexports::{ client::{Connection, Dispatch, Proxy}, }; use crate::event_loop::state::SctkState; -use crate::platform_specific::wayland::SctkEvent; impl Dispatch for SctkState { fn event( @@ -31,7 +27,7 @@ impl > for SctkState { fn event( - state: &mut Self, + _state: &mut Self, _proxy: &CosmicCornerRadiusToplevelV1, event: ::Event, _data: &(), diff --git a/winit/src/platform_specific/wayland/mod.rs b/winit/src/platform_specific/wayland/mod.rs index 9b3a7ec0..321561da 100644 --- a/winit/src/platform_specific/wayland/mod.rs +++ b/winit/src/platform_specific/wayland/mod.rs @@ -18,7 +18,7 @@ use cursor_icon::CursorIcon; use iced_futures::futures::channel::mpsc; use iced_graphics::{Compositor, compositor}; use iced_runtime::core::{Vector, window}; -use raw_window_handle::{DisplayHandle, HasDisplayHandle, HasWindowHandle}; +use raw_window_handle::{HasDisplayHandle, HasWindowHandle}; use raw_window_handle::{HasRawDisplayHandle, RawWindowHandle}; use sctk_event::SctkEvent; use std::{collections::HashMap, sync::Arc}; @@ -189,12 +189,12 @@ impl WaylandSpecific { winit_event_sender, proxy, sender, - display_handle, - conn, + display_handle: _, + conn: _, surface_ids, modifiers, subsurface_state, - surface_subsurfaces, + surface_subsurfaces: _, } = self; match e { @@ -237,7 +237,7 @@ impl WaylandSpecific { &mut self, keep: F, ) { - self.surface_subsurfaces.retain(|k, v| keep(*k)) + self.surface_subsurfaces.retain(|k, _v| keep(*k)) } pub(crate) fn clear_subsurface_list(&mut self) { @@ -250,7 +250,7 @@ impl WaylandSpecific { wl_surface: &WlSurface, ) { let subsurfaces = crate::subsurface_widget::take_subsurfaces(); - let mut entry = self.surface_subsurfaces.entry(id); + let entry = self.surface_subsurfaces.entry(id); let surface_subsurfaces = entry.or_default(); let Some(subsurface_state) = self.subsurface_state.as_mut() else { return; diff --git a/winit/src/platform_specific/wayland/sctk_event.rs b/winit/src/platform_specific/wayland/sctk_event.rs index 3a1a0166..8c2b24df 100755 --- a/winit/src/platform_specific/wayland/sctk_event.rs +++ b/winit/src/platform_specific/wayland/sctk_event.rs @@ -4,7 +4,7 @@ use crate::{ SurfaceIdWrapper, UserInterfaces, wayland::{ conversion::{ - modifiers_to_native, pointer_axis_to_native, + modifiers_to_native, pointer_button_to_native, }, keymap::{self, keysym_to_key}, @@ -25,7 +25,6 @@ use iced_futures::{ }, }, }, - event, futures::{SinkExt, channel::mpsc}, }; use iced_graphics::{Compositor, compositor}; @@ -40,9 +39,7 @@ use iced_runtime::{ user_interface, }; -use cctk::{ - cosmic_protocols::overlap_notify::v1::client::zcosmic_overlap_notification_v1, - sctk::{ +use cctk::sctk::{ output::OutputInfo, reexports::{ calloop::channel, @@ -67,11 +64,8 @@ use cctk::{ wlr_layer::{Layer, LayerSurfaceConfigure}, xdg::{popup::PopupConfigure, window::WindowConfigure}, }, - }, - wayland_client::protocol::wl_subsurface::WlSubsurface, -}; + }; use std::{ - any::Any, collections::HashMap, num::NonZeroU32, sync::{Arc, Mutex}, @@ -510,7 +504,7 @@ impl SctkEvent { ), ), ), - SurfaceIdWrapper::Window(id) => { + SurfaceIdWrapper::Window(_id) => { Some(iced_runtime::core::Event::Window( window::Event::Unfocused, )) @@ -538,7 +532,7 @@ impl SctkEvent { ), ), ), - SurfaceIdWrapper::Subsurface(id) => None, + SurfaceIdWrapper::Subsurface(_id) => None, }) { events.push(( @@ -572,7 +566,7 @@ impl SctkEvent { ), ), ), - SurfaceIdWrapper::Window(id) => { + SurfaceIdWrapper::Window(_id) => { Some(iced_runtime::core::Event::Window( window::Event::Focused, )) diff --git a/winit/src/platform_specific/wayland/subsurface_widget.rs b/winit/src/platform_specific/wayland/subsurface_widget.rs index 15233009..7f15854b 100644 --- a/winit/src/platform_specific/wayland/subsurface_widget.rs +++ b/winit/src/platform_specific/wayland/subsurface_widget.rs @@ -58,9 +58,7 @@ use wayland_protocols::wp::{ }; use winit::window::WindowId; -use crate::platform_specific::{ - SurfaceIdWrapper, event_loop::state::SctkState, -}; +use crate::platform_specific::event_loop::state::SctkState; #[derive(Debug)] pub struct Plane { diff --git a/winit/src/platform_specific/wayland/winit_window.rs b/winit/src/platform_specific/wayland/winit_window.rs index 296d8b67..fd562a45 100644 --- a/winit/src/platform_specific/wayland/winit_window.rs +++ b/winit/src/platform_specific/wayland/winit_window.rs @@ -1,9 +1,9 @@ use crate::platform_specific::wayland::Action; use cctk::sctk::reexports::{ - calloop::{LoopHandle, channel}, + calloop::channel, client::{ Proxy, QueueHandle, - protocol::{wl_display::WlDisplay, wl_surface::WlSurface}, + protocol::wl_display::WlDisplay, }, }; use raw_window_handle::HandleError; @@ -91,7 +91,7 @@ impl winit::window::Window for SctkWinitWindow { } } - fn set_cursor_visible(&self, visible: bool) { + fn set_cursor_visible(&self, _visible: bool) { // TODO } @@ -203,35 +203,35 @@ impl winit::window::Window for SctkWinitWindow { // TODO refer to winit for implementation } - fn set_outer_position(&self, position: winit::dpi::Position) {} + fn set_outer_position(&self, _position: winit::dpi::Position) {} fn outer_size(&self) -> winit::dpi::PhysicalSize { // XXX not applicable to wrapped surfaces Default::default() } - fn set_min_surface_size(&self, min_size: Option) { + fn set_min_surface_size(&self, _min_size: Option) { // XXX not applicable to wrapped surfaces } - fn set_max_surface_size(&self, max_size: Option) { + fn set_max_surface_size(&self, _max_size: Option) { // XXX not applicable to wrapped surfaces } fn set_surface_resize_increments( &self, - increments: Option, + _increments: Option, ) { log::warn!( "`set_surface_resize_increments` is not implemented for Wayland" ) } - fn set_title(&self, title: &str) { + fn set_title(&self, _title: &str) { // XXX not applicable to wrapped surfaces } - fn set_transparent(&self, transparent: bool) { + fn set_transparent(&self, _transparent: bool) { todo!() } @@ -286,23 +286,23 @@ impl winit::window::Window for SctkWinitWindow { _ = self.tx.send(Action::SetImePurpose(purpose)); } - fn set_blur(&self, blur: bool) { + fn set_blur(&self, _blur: bool) { // TODO } - fn set_visible(&self, visible: bool) {} + fn set_visible(&self, _visible: bool) {} fn is_visible(&self) -> Option { None } - fn set_resizable(&self, resizable: bool) {} + fn set_resizable(&self, _resizable: bool) {} fn is_resizable(&self) -> bool { false } - fn set_enabled_buttons(&self, buttons: winit::window::WindowButtons) { + fn set_enabled_buttons(&self, _buttons: winit::window::WindowButtons) { // TODO v5 of xdg_shell. } @@ -310,7 +310,7 @@ impl winit::window::Window for SctkWinitWindow { WindowButtons::all() } - fn set_minimized(&self, minimized: bool) { + fn set_minimized(&self, _minimized: bool) { // XXX not applicable to the wrapped surfaces } @@ -319,7 +319,7 @@ impl winit::window::Window for SctkWinitWindow { None } - fn set_maximized(&self, maximized: bool) { + fn set_maximized(&self, _maximized: bool) { // XXX can't minimize the wrapped surfaces } @@ -330,7 +330,7 @@ impl winit::window::Window for SctkWinitWindow { fn set_fullscreen( &self, - fullscreen: Option, + _fullscreen: Option, ) { // XXX can't fullscreen the wrapped surfaces } @@ -340,7 +340,7 @@ impl winit::window::Window for SctkWinitWindow { None } - fn set_decorations(&self, decorations: bool) { + fn set_decorations(&self, _decorations: bool) { // XXX no decorations supported for the wrapped surfaces } @@ -348,26 +348,26 @@ impl winit::window::Window for SctkWinitWindow { false } - fn set_window_level(&self, level: winit::window::WindowLevel) {} + fn set_window_level(&self, _level: winit::window::WindowLevel) {} - fn set_window_icon(&self, window_icon: Option) {} + fn set_window_icon(&self, _window_icon: Option) {} fn focus_window(&self) {} fn request_user_attention( &self, - request_type: Option, + _request_type: Option, ) { // XXX can't request attention on wrapped surfaces } - fn set_theme(&self, theme: Option) {} + fn set_theme(&self, _theme: Option) {} fn theme(&self) -> Option { None } - fn set_content_protected(&self, protected: bool) {} + fn set_content_protected(&self, _protected: bool) {} fn title(&self) -> String { String::new() @@ -420,14 +420,14 @@ impl winit::window::Window for SctkWinitWindow { fn set_cursor_position( &self, - position: winit::dpi::Position, + _position: winit::dpi::Position, ) -> Result<(), winit::error::RequestError> { todo!() } fn set_cursor_grab( &self, - mode: winit::window::CursorGrabMode, + _mode: winit::window::CursorGrabMode, ) -> Result<(), winit::error::RequestError> { todo!() } @@ -438,7 +438,7 @@ impl winit::window::Window for SctkWinitWindow { fn request_ime_update( &self, - request: winit::window::ImeRequest, + _request: winit::window::ImeRequest, ) -> Result<(), winit::window::ImeRequestError> { todo!() } diff --git a/winit/src/proxy.rs b/winit/src/proxy.rs index a3e4e816..e65de2aa 100644 --- a/winit/src/proxy.rs +++ b/winit/src/proxy.rs @@ -8,7 +8,6 @@ use crate::futures::futures::{ use crate::graphics::shell; use crate::runtime::Action; use crate::runtime::window; -use std::hash::DefaultHasher; use std::pin::Pin; /// An event loop proxy with backpressure that implements `Sink`. From aa1c2593acf2409b6cd445c47adf393caa26f169 Mon Sep 17 00:00:00 2001 From: Votre Nom Date: Tue, 5 May 2026 18:11:19 +0200 Subject: [PATCH 15/72] =?UTF-8?q?yoda:=20iced=5Fwinit=20unreachable=20+=20?= =?UTF-8?q?deprecation=20cleanup=20(45=E2=86=9229=20warnings)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - conversion.rs: drop 4 duplicate Interaction arms (Cell/Move/Copy/Help) that were already handled higher in the same match — pure dead code from a past merge, not a real bug. - platform_specific/wayland/mod.rs: migrate HasRawDisplayHandle → HasDisplayHandle (display_handle().map(|h| h.as_raw())). - conversion.rs: #[allow(deprecated)] on key_code/winit_key_code — the warning suggests Meta but no Meta variant exists in this enum (only MetaLeft/MetaRight, which aren't equivalent to Super). - window.rs: #[allow(deprecated)] on enable_ime/disable_ime with TODO to migrate set_ime_* → request_ime_update(ImeRequest::*). - lib.rs: #[allow(deprecated)] on process_event with TODO to migrate try_next → try_recv (futures-channel API change). Leyoda 2026 – GPLv3 --- winit/src/conversion.rs | 6 ++---- winit/src/lib.rs | 2 ++ winit/src/platform_specific/wayland/mod.rs | 5 ++--- winit/src/window.rs | 5 +++++ 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index 0afb8e72..71af6e2e 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -640,10 +640,6 @@ pub fn mouse_interaction( Interaction::AllScroll => winit_core::cursor::CursorIcon::AllScroll, Interaction::ZoomIn => winit_core::cursor::CursorIcon::ZoomIn, Interaction::ZoomOut => winit_core::cursor::CursorIcon::ZoomOut, - Interaction::Cell => winit_core::cursor::CursorIcon::Cell, - Interaction::Move => winit_core::cursor::CursorIcon::Move, - Interaction::Copy => winit_core::cursor::CursorIcon::Copy, - Interaction::Help => winit_core::cursor::CursorIcon::Help, Interaction::Hidden => { return None; } @@ -1079,6 +1075,7 @@ pub fn physical_key( /// /// [`winit`]: https://github.com/rust-windowing/winit /// [`iced`]: https://github.com/iced-rs/iced/tree/0.12 +#[allow(deprecated)] // KeyCode::Super/Hyper/Turbo: legacy spec, no Meta variant in this enum pub fn key_code( key_code: winit::keyboard::KeyCode, ) -> Option { @@ -1283,6 +1280,7 @@ pub fn key_code( }) } +#[allow(deprecated)] // KeyCode::Super/Hyper/Turbo: legacy spec, no Meta variant in this enum pub fn winit_key_code( key_code: keyboard::key::Code, ) -> Option { diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 5b5d1ce1..32837143 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -362,6 +362,8 @@ where where F: Future, { + // TODO(yoda): migrate try_next → try_recv (futures-channel API change). + #[allow(deprecated)] fn process_event( &mut self, event_loop: &dyn winit::event_loop::ActiveEventLoop, diff --git a/winit/src/platform_specific/wayland/mod.rs b/winit/src/platform_specific/wayland/mod.rs index 321561da..82304b7c 100644 --- a/winit/src/platform_specific/wayland/mod.rs +++ b/winit/src/platform_specific/wayland/mod.rs @@ -18,8 +18,7 @@ use cursor_icon::CursorIcon; use iced_futures::futures::channel::mpsc; use iced_graphics::{Compositor, compositor}; use iced_runtime::core::{Vector, window}; -use raw_window_handle::{HasDisplayHandle, HasWindowHandle}; -use raw_window_handle::{HasRawDisplayHandle, RawWindowHandle}; +use raw_window_handle::{HasDisplayHandle, HasWindowHandle, RawWindowHandle}; use sctk_event::SctkEvent; use std::{collections::HashMap, sync::Arc}; use subsurface_widget::{SubsurfaceInstance, SubsurfaceState}; @@ -106,7 +105,7 @@ impl PlatformSpecific { display: OwnedDisplayHandle, ) -> Self { self.wayland.winit_event_sender = Some(tx); - self.wayland.conn = match display.raw_display_handle() { + self.wayland.conn = match display.display_handle().map(|h| h.as_raw()) { Ok(raw_window_handle::RawDisplayHandle::Wayland( wayland_display_handle, )) => { diff --git a/winit/src/window.rs b/winit/src/window.rs index 87d35a5a..89368802 100644 --- a/winit/src/window.rs +++ b/winit/src/window.rs @@ -325,6 +325,10 @@ where } } + // TODO(yoda): migrate to Window::request_ime_update(ImeRequest::*). + // Legacy set_ime_* still functional but deprecated; full migration + // requires ImeCapabilities + ImeRequestData reshape. + #[allow(deprecated)] fn enable_ime( &mut self, cursor: Rectangle, @@ -355,6 +359,7 @@ where } } + #[allow(deprecated)] // see TODO on enable_ime fn disable_ime(&mut self) { if self.ime_state.is_some() { self.raw.set_ime_allowed(false); From e424487704912e05a526a213076793074dbfdc0e Mon Sep 17 00:00:00 2001 From: Votre Nom Date: Tue, 5 May 2026 18:26:08 +0200 Subject: [PATCH 16/72] =?UTF-8?q?yoda:=20iced=5Fwinit=20dead-code=20purge?= =?UTF-8?q?=20(29=E2=86=920=20warnings)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed code paths inherited from past refactors that no longer have any reader: - ViewFn type alias (window.rs) - a11y_enabled flag and resized flag (lib.rs) — assigned but never read - BootConfig.fonts/graphics_settings/is_wayland — already passed to run_instance(...) directly; the BootConfig copies were never read - Runner.system_theme oneshot::Sender — stored but no producer ever wired; receiver side already falls back to default - event_loop/control_flow.rs — local ControlFlow enum, all callers use winit::event_loop::ControlFlow - event_loop/proxy.rs — Proxy never constructed - Error::Connect(ConnectError) variant — never constructed - Common.has_focus / ime_pos / ime_size — never read after assignment - SctkPopupData.grab — replicated settings.grab, never read back - SubsurfaceEventVariant::Created.surface field — destructure does `surface: _` everywhere, the value is unused Visibility tightening: - a11y.rs WinitActivationHandler / WinitActionHandler / WinitDeactivationHandler: pub proxy → pub(crate) proxy - conversion::touch_event: pub → private (no external callers) - proxy::Proxy::new: pub → pub(crate) Allow attributes (intentional, not warning-suppression): - conversion::RawImage: #[allow(dead_code)] — fields kept for IconProvider downcast-via-AsAny on winit's side - event_loop::Error: #[allow(dead_code)] — variant payloads kept for Debug, never inspected programmatically - lib.rs Event: #[allow(hidden_glob_reexports)] — intentional shadow of winit::event::Event coming from `pub use winit` - window.rs/lib.rs: #[allow(deprecated)] on enable_ime/disable_ime/ process_event with TODOs for set_ime_* → request_ime_update and try_next → try_recv migrations Five orphan imports also removed (Hash/Hasher, BorrowMut, 3× Compositor). Leyoda 2026 – GPLv3 --- winit/src/a11y.rs | 6 +- winit/src/conversion.rs | 7 +- winit/src/lib.rs | 28 ++------ winit/src/platform_specific/mod.rs | 2 +- .../wayland/event_loop/control_flow.rs | 56 ---------------- .../wayland/event_loop/mod.rs | 6 +- .../wayland/event_loop/proxy.rs | 66 ------------------- .../wayland/event_loop/state.rs | 11 +--- winit/src/platform_specific/wayland/mod.rs | 2 +- .../platform_specific/wayland/sctk_event.rs | 4 +- .../wayland/subsurface_widget.rs | 3 +- winit/src/proxy.rs | 2 +- winit/src/window.rs | 6 +- 13 files changed, 22 insertions(+), 177 deletions(-) delete mode 100644 winit/src/platform_specific/wayland/event_loop/control_flow.rs delete mode 100644 winit/src/platform_specific/wayland/event_loop/proxy.rs diff --git a/winit/src/a11y.rs b/winit/src/a11y.rs index 61fbe630..8f6cf27b 100644 --- a/winit/src/a11y.rs +++ b/winit/src/a11y.rs @@ -7,7 +7,7 @@ use iced_accessibility::accesskit::{ use iced_runtime::core; pub struct WinitActivationHandler { - pub proxy: mpsc::UnboundedSender, + pub(crate) proxy: mpsc::UnboundedSender, pub title: String, } @@ -33,7 +33,7 @@ impl ActivationHandler for WinitActivationHandler { pub struct WinitActionHandler { pub id: core::window::Id, - pub proxy: mpsc::UnboundedSender, + pub(crate) proxy: mpsc::UnboundedSender, } impl iced_accessibility::accesskit::ActionHandler for WinitActionHandler { @@ -48,7 +48,7 @@ impl iced_accessibility::accesskit::ActionHandler for WinitActionHandler { } pub struct WinitDeactivationHandler { - pub proxy: mpsc::UnboundedSender, + pub(crate) proxy: mpsc::UnboundedSender, } impl iced_accessibility::accesskit::DeactivationHandler diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index 71af6e2e..5192cb61 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -3,8 +3,6 @@ //! [`winit`]: https://github.com/rust-windowing/winit //! [`iced_runtime`]: https://github.com/iced-rs/iced/tree/0.14/runtime use crate::core::input_method; -use std::hash::Hash; -use std::hash::Hasher; use std::sync::Arc; use crate::core::keyboard; @@ -698,7 +696,7 @@ enum TouchInternal { /// /// [`winit`]: https://github.com/rust-windowing/winit /// [`iced`]: https://github.com/iced-rs/iced/tree/0.12 -pub fn touch_event( +fn touch_event( finger: FingerId, state: TouchInternal, _force: Option, @@ -1591,7 +1589,10 @@ pub fn resize_direction( } } +// Fields are passed through to winit via `IconProvider: AsAny` for potential +// downcast; they are not read directly here. #[derive(Debug)] +#[allow(dead_code)] pub struct RawImage(Vec, Size); impl IconProvider for RawImage {} impl From for winit_core::icon::Icon { diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 32837143..3c5a5d29 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -157,7 +157,8 @@ where let (boot_sender, boot_receiver) = oneshot::channel(); let (control_sender, control_receiver) = mpsc::unbounded(); - let (system_theme_sender, system_theme_receiver) = oneshot::channel(); + // Sender side currently not wired to a producer; receiver gets default. + let (_system_theme_sender, system_theme_receiver) = oneshot::channel(); let instance = Box::pin(run_instance::

( program, @@ -178,9 +179,6 @@ where struct BootConfig { sender: oneshot::Sender<()>, - fonts: Vec>, - graphics_settings: graphics::Settings, - is_wayland: bool, } struct Runner { instance: std::pin::Pin>, @@ -190,7 +188,6 @@ where sender: mpsc::UnboundedSender>, receiver: mpsc::UnboundedReceiver, error: Option, - system_theme: Option>, control_sender: mpsc::UnboundedSender, #[cfg(feature = "a11y")] @@ -207,16 +204,12 @@ where context, boot: Some(BootConfig { sender: boot_sender, - fonts: settings.fonts, - graphics_settings, - is_wayland, }), id: settings.id, sender: event_sender, receiver: control_receiver, control_sender: control_sender.clone(), error: None, - system_theme: Some(system_theme_sender), #[cfg(feature = "a11y")] adapters: Default::default(), @@ -319,12 +312,7 @@ where event_loop: &dyn winit::event_loop::ActiveEventLoop, ) { // create initial window - let Some(BootConfig { - sender, - fonts: _, - graphics_settings: _, - is_wayland: _, - }) = self.boot.take() + let Some(BootConfig { sender }) = self.boot.take() else { return; }; @@ -691,6 +679,7 @@ where } } +#[allow(hidden_glob_reexports)] // intentional: internal Event shadows winit::event::Event from `pub use winit` enum Event { WindowCreated { id: window::Id, @@ -798,9 +787,6 @@ async fn run_instance

( > = None; let mut dnd_surface_id: Option = None; - #[cfg(feature = "a11y")] - let mut a11y_enabled = false; - #[cfg(all(feature = "linux-theme-detection", target_os = "linux"))] let mut system_theme = { let to_mode = |color_scheme| match color_scheme { @@ -1393,7 +1379,6 @@ async fn run_instance

( } let mut uis_stale = false; - let mut resized = false; for (id, window) in window_manager.iter_mut() { if skip && !window.resize_enabled { continue; @@ -1446,7 +1431,6 @@ async fn run_instance

( // FIXME what to do when we are stuck in a configure event/resize request loop // We don't have control over how winit handles this. window.resize_enabled = true; - resized = true; needs_redraw = true; let s = winit::dpi::Size::Logical( requested_size.cast(), @@ -1661,8 +1645,8 @@ async fn run_instance

( events.push((Some(id), conversion::a11y(action_request))); } #[cfg(feature = "a11y")] - Event::AccessibilityEnabled(enabled) => { - a11y_enabled = enabled; + Event::AccessibilityEnabled(_enabled) => { + // a11y enable signal currently unused at this layer } Event::PlatformSpecific(e) => { crate::platform_specific::handle_event( diff --git a/winit/src/platform_specific/mod.rs b/winit/src/platform_specific/mod.rs index 66eda20c..357fb1ec 100644 --- a/winit/src/platform_specific/mod.rs +++ b/winit/src/platform_specific/mod.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; -use iced_graphics::{Compositor, compositor}; +use iced_graphics::compositor; use iced_runtime::{ core::{Vector, window}, user_interface, }; diff --git a/winit/src/platform_specific/wayland/event_loop/control_flow.rs b/winit/src/platform_specific/wayland/event_loop/control_flow.rs deleted file mode 100644 index bc920ed4..00000000 --- a/winit/src/platform_specific/wayland/event_loop/control_flow.rs +++ /dev/null @@ -1,56 +0,0 @@ -/// Set by the user callback given to the [`EventLoop::run`] method. -/// -/// Indicates the desired behavior of the event loop after [`Event::RedrawEventsCleared`] is emitted. -/// -/// Defaults to [`Poll`]. -/// -/// ## Persistency -/// -/// Almost every change is persistent between multiple calls to the event loop closure within a -/// given run loop. The only exception to this is [`ExitWithCode`] which, once set, cannot be unset. -/// Changes are **not** persistent between multiple calls to `run_return` - issuing a new call will -/// reset the control flow to [`Poll`]. -/// -/// [`ExitWithCode`]: Self::ExitWithCode -/// [`Poll`]: Self::Poll -#[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub enum ControlFlow { - /// When the current loop iteration finishes, immediately begin a new iteration regardless of - /// whether or not new events are available to process. - /// - /// ## Platform-specific - /// - /// - **Web:** Events are queued and usually sent when `requestAnimationFrame` fires but sometimes - /// the events in the queue may be sent before the next `requestAnimationFrame` callback, for - /// example when the scaling of the page has changed. This should be treated as an implementation - /// detail which should not be relied on. - Poll, - /// When the current loop iteration finishes, suspend the thread until another event arrives. - Wait, - /// When the current loop iteration finishes, suspend the thread until either another event - /// arrives or the given time is reached. - /// - /// Useful for implementing efficient timers. Applications which want to render at the display's - /// native refresh rate should instead use [`Poll`] and the VSync functionality of a graphics API - /// to reduce odds of missed frames. - /// - /// [`Poll`]: Self::Poll - WaitUntil(std::time::Instant), - /// Send a [`LoopDestroyed`] event and stop the event loop. This variant is *sticky* - once set, - /// `control_flow` cannot be changed from `ExitWithCode`, and any future attempts to do so will - /// result in the `control_flow` parameter being reset to `ExitWithCode`. - /// - /// The contained number will be used as exit code. The [`Exit`] constant is a shortcut for this - /// with exit code 0. - /// - /// ## Platform-specific - /// - /// - **Android / iOS / WASM:** The supplied exit code is unused. - /// - **Unix:** On most Unix-like platforms, only the 8 least significant bits will be used, - /// which can cause surprises with negative exit values (`-42` would end up as `214`). See - /// [`std::process::exit`]. - /// - /// [`LoopDestroyed`]: Event::LoopDestroyed - /// [`Exit`]: ControlFlow::Exit - ExitWithCode(i32), -} diff --git a/winit/src/platform_specific/wayland/event_loop/mod.rs b/winit/src/platform_specific/wayland/event_loop/mod.rs index 87d00ec2..d21edcea 100644 --- a/winit/src/platform_specific/wayland/event_loop/mod.rs +++ b/winit/src/platform_specific/wayland/event_loop/mod.rs @@ -1,5 +1,3 @@ -pub mod control_flow; -pub mod proxy; pub mod state; use crate::{ @@ -28,7 +26,7 @@ use cctk::{ reexports::{ calloop::{self, EventLoop}, client::{ - ConnectError, Connection, Proxy, globals::registry_queue_init, + Connection, Proxy, globals::registry_queue_init, }, }, registry::RegistryState, @@ -64,8 +62,8 @@ pub struct SctkEventLoop { pub(crate) state: SctkState, } +#[allow(dead_code)] // payloads kept for Debug; not inspected programmatically pub enum Error { - Connect(ConnectError), Calloop(calloop::Error), Global(GlobalError), NoDisplayHandle, diff --git a/winit/src/platform_specific/wayland/event_loop/proxy.rs b/winit/src/platform_specific/wayland/event_loop/proxy.rs deleted file mode 100644 index bdbc44a4..00000000 --- a/winit/src/platform_specific/wayland/event_loop/proxy.rs +++ /dev/null @@ -1,66 +0,0 @@ -use cctk::sctk::reexports::calloop; -use iced_futures::futures::{ - channel::mpsc, - task::{Context, Poll}, - Sink, -}; -use std::pin::Pin; - -/// An event loop proxy that implements `Sink`. -#[derive(Debug)] -pub struct Proxy { - raw: calloop::channel::Sender, -} - -impl Clone for Proxy { - fn clone(&self) -> Self { - Self { - raw: self.raw.clone(), - } - } -} - -impl Proxy { - /// Creates a new [`Proxy`] from an `EventLoopProxy`. - pub fn new(raw: calloop::channel::Sender) -> Self { - Self { raw } - } - /// send an event - pub fn send_event(&self, message: Message) { - let _ = self.raw.send(message); - } -} - -impl Sink for Proxy { - type Error = mpsc::SendError; - - fn poll_ready( - self: Pin<&mut Self>, - _cx: &mut Context<'_>, - ) -> Poll> { - Poll::Ready(Ok(())) - } - - fn start_send( - self: Pin<&mut Self>, - message: Message, - ) -> Result<(), Self::Error> { - let _ = self.raw.send(message); - - Ok(()) - } - - fn poll_flush( - self: Pin<&mut Self>, - _cx: &mut Context<'_>, - ) -> Poll> { - Poll::Ready(Ok(())) - } - - fn poll_close( - self: Pin<&mut Self>, - _cx: &mut Context<'_>, - ) -> Poll> { - Poll::Ready(Ok(())) - } -} diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index 3d93a015..8be7c639 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -33,7 +33,7 @@ use std::{ }; use wayland_backend::client::ObjectId; use winit::{ - dpi::{LogicalPosition, LogicalSize}, + dpi::LogicalSize, platform::wayland::WindowExtWayland, }; @@ -229,9 +229,6 @@ impl CommonSurface { #[derive(Debug, Clone)] pub struct Common { pub(crate) fractional_scale: Option, - pub(crate) has_focus: bool, - pub(crate) ime_pos: LogicalPosition, - pub(crate) ime_size: LogicalSize, pub(crate) size: LogicalSize, pub(crate) requested_size: (Option, Option), pub(crate) wp_viewport: Option, @@ -241,9 +238,6 @@ impl Default for Common { fn default() -> Self { Self { fractional_scale: Default::default(), - has_focus: Default::default(), - ime_pos: Default::default(), - ime_size: Default::default(), size: LogicalSize::new(1, 1), requested_size: (None, None), wp_viewport: None, @@ -336,7 +330,6 @@ pub struct SctkPopupData { pub(crate) parent: PopupParent, pub(crate) toplevel: WlSurface, pub(crate) positioner: Arc, - pub(crate) grab: bool, } #[derive(Debug)] @@ -877,7 +870,6 @@ impl SctkState { parent: parent.clone(), toplevel: toplevel.clone(), positioner: positioner.clone(), - grab: settings.grab, }, last_configure: None, _pending_requests: Default::default(), @@ -1519,7 +1511,6 @@ impl SctkState { SctkEvent::SubsurfaceEvent (crate::sctk_event::SubsurfaceEventVariant::Created{ parent_id, parent, - surface: subsurface, qh: self.queue_handle.clone(), common_surface, surface_id: subsurface_settings.id, diff --git a/winit/src/platform_specific/wayland/mod.rs b/winit/src/platform_specific/wayland/mod.rs index 82304b7c..e613e3b4 100644 --- a/winit/src/platform_specific/wayland/mod.rs +++ b/winit/src/platform_specific/wayland/mod.rs @@ -16,7 +16,7 @@ use cctk::sctk::reexports::client::protocol::wl_surface::WlSurface; use cctk::sctk::seat::keyboard::Modifiers; use cursor_icon::CursorIcon; use iced_futures::futures::channel::mpsc; -use iced_graphics::{Compositor, compositor}; +use iced_graphics::compositor; use iced_runtime::core::{Vector, window}; use raw_window_handle::{HasDisplayHandle, HasWindowHandle, RawWindowHandle}; use sctk_event::SctkEvent; diff --git a/winit/src/platform_specific/wayland/sctk_event.rs b/winit/src/platform_specific/wayland/sctk_event.rs index 8c2b24df..a11ebe66 100755 --- a/winit/src/platform_specific/wayland/sctk_event.rs +++ b/winit/src/platform_specific/wayland/sctk_event.rs @@ -27,7 +27,7 @@ use iced_futures::{ }, futures::{SinkExt, channel::mpsc}, }; -use iced_graphics::{Compositor, compositor}; +use iced_graphics::compositor; use iced_runtime::{ core::{ Point, @@ -282,7 +282,6 @@ pub enum SubsurfaceEventVariant { Created { parent_id: window::Id, parent: WlSurface, - surface: WlSurface, qh: QueueHandle, common_surface: CommonSurface, surface_id: SurfaceId, @@ -1503,7 +1502,6 @@ impl SctkEvent { common, z, parent, - surface: _, qh, surface_id, display, diff --git a/winit/src/platform_specific/wayland/subsurface_widget.rs b/winit/src/platform_specific/wayland/subsurface_widget.rs index 7f15854b..c09e2424 100644 --- a/winit/src/platform_specific/wayland/subsurface_widget.rs +++ b/winit/src/platform_specific/wayland/subsurface_widget.rs @@ -7,7 +7,6 @@ use crate::core::{ widget::{self, Widget}, }; use std::{ - borrow::BorrowMut, cell::RefCell, collections::HashMap, fmt::Debug, @@ -624,7 +623,7 @@ impl Drop for SubsurfaceState { } #[derive(Clone, Debug)] -pub(crate) struct SubsurfaceInstance { +pub struct SubsurfaceInstance { pub(crate) wl_surface: WlSurface, pub(crate) wl_subsurface: WlSubsurface, pub(crate) wp_viewport: WpViewport, diff --git a/winit/src/proxy.rs b/winit/src/proxy.rs index e65de2aa..aabe15c3 100644 --- a/winit/src/proxy.rs +++ b/winit/src/proxy.rs @@ -33,7 +33,7 @@ impl Proxy { const MAX_SIZE: usize = 100; /// Creates a new [`Proxy`] from an `EventLoopProxy`. - pub fn new( + pub(crate) fn new( raw: winit::event_loop::EventLoopProxy, event_sender: mpsc::UnboundedSender>, ) -> (Self, impl Future) { diff --git a/winit/src/window.rs b/winit/src/window.rs index 89368802..ecb2107a 100644 --- a/winit/src/window.rs +++ b/winit/src/window.rs @@ -14,7 +14,7 @@ use crate::core::text; use crate::core::theme::{self, Base}; use crate::core::time::Instant; use crate::core::{ - Color, Element, InputMethod, Padding, Point, Rectangle, Size, Text, Vector, + Color, InputMethod, Padding, Point, Rectangle, Size, Text, Vector, }; use crate::graphics::Compositor; use crate::program::{self, Program}; @@ -26,10 +26,6 @@ use winit::monitor::MonitorHandle; use std::collections::BTreeMap; use std::sync::Arc; -pub(crate) type ViewFn = Arc< - Box Option> + Send + Sync + 'static>, ->; - pub struct WindowManager where P: Program, From d33d068c17e3a16d2444917820682f934faaa299 Mon Sep 17 00:00:00 2001 From: Votre Nom Date: Tue, 5 May 2026 18:38:57 +0200 Subject: [PATCH 17/72] =?UTF-8?q?yoda:=20iced=5Fwidget=20cleanup=20(7?= =?UTF-8?q?=E2=86=920=20warnings)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - overlay/menu.rs:578: real bug fix — List::draw was rendering with text::Wrapping::default() instead of the configured self.text_wrap. Wiring it through eliminates the 'field never read' warning AND honors the wrap setting that was being silently dropped. - slider.rs:735-744: replace `if let Ok(x) = …try_into() { … }` with irrefutable `let Ok(x) = …try_into();` (the conversion is provably Infallible at the call site). Same behavior, no compiler noise. - lazy.rs:8 / lazy/component.rs:13: drop unused `iced_renderer::core::widget::Operation` imports. Leyoda 2026 – GPLv3 --- widget/src/lazy.rs | 1 - widget/src/lazy/component.rs | 1 - widget/src/overlay/menu.rs | 2 +- widget/src/slider.rs | 20 ++++++++------------ 4 files changed, 9 insertions(+), 15 deletions(-) diff --git a/widget/src/lazy.rs b/widget/src/lazy.rs index 7a2611ee..b4db46a5 100644 --- a/widget/src/lazy.rs +++ b/widget/src/lazy.rs @@ -5,7 +5,6 @@ pub mod component; #[allow(deprecated)] pub use component::Component; -use iced_renderer::core::widget::Operation; mod cache; diff --git a/widget/src/lazy/component.rs b/widget/src/lazy/component.rs index 682fd458..b3c51f37 100644 --- a/widget/src/lazy/component.rs +++ b/widget/src/lazy/component.rs @@ -10,7 +10,6 @@ use crate::core::{ self, Clipboard, Element, Length, Rectangle, Shell, Size, Vector, Widget, }; -use iced_renderer::core::widget::Operation; use ouroboros::self_referencing; use std::cell::RefCell; use std::marker::PhantomData; diff --git a/widget/src/overlay/menu.rs b/widget/src/overlay/menu.rs index 94d2b6ad..e7c4dc23 100644 --- a/widget/src/overlay/menu.rs +++ b/widget/src/overlay/menu.rs @@ -575,7 +575,7 @@ where align_x: text::Alignment::Default, align_y: alignment::Vertical::Center, shaping: self.text_shaping, - wrapping: text::Wrapping::default(), + wrapping: self.text_wrap, ellipsize: text::Ellipsize::default(), }, Point::new(bounds.x + self.padding.left, bounds.center_y()), diff --git a/widget/src/slider.rs b/widget/src/slider.rs index e3fe484a..9516f55c 100644 --- a/widget/src/slider.rs +++ b/widget/src/slider.rs @@ -732,18 +732,14 @@ where node.set_labelled_by(label.clone()); } - if let Ok(min) = self.range.start().clone().try_into() { - node.set_min_numeric_value(min); - } - if let Ok(max) = self.range.end().clone().try_into() { - node.set_max_numeric_value(max); - } - if let Ok(value) = self.value.clone().try_into() { - node.set_numeric_value(value); - } - if let Ok(step) = self.step.clone().try_into() { - node.set_numeric_value_step(step); - } + let Ok(min) = self.range.start().clone().try_into(); + node.set_min_numeric_value(min); + let Ok(max) = self.range.end().clone().try_into(); + node.set_max_numeric_value(max); + let Ok(value) = self.value.clone().try_into(); + node.set_numeric_value(value); + let Ok(step) = self.step.clone().try_into(); + node.set_numeric_value_step(step); // TODO: This could be a setting on the slider node.set_live(iced_accessibility::accesskit::Live::Polite); From 6b069b2b4bc252d8fdc4d2a93ff533376c4f0dee Mon Sep 17 00:00:00 2001 From: Votre Nom Date: Tue, 5 May 2026 18:45:49 +0200 Subject: [PATCH 18/72] =?UTF-8?q?yoda:=20iced=5Fcore=20+=20iced=5Fwgpu=20c?= =?UTF-8?q?leanup=20(3=E2=86=920=20warnings)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit iced_core/settings.rs: drop dead `From for iced_winit::Settings` impl gated behind a `winit` feature that doesn't exist on iced_core (and shouldn't — that would invert the dep direction). The impl was unreachable code. iced_wgpu/window/compositor.rs: collapse the unused initial `adapter_options` declaration into the only branch that uses it (the fallback path that re-creates the instance with GL allowed). The original allocation was always re-assigned before being read. iced_wgpu/lib.rs: remove `Renderer::draw_overlay` — private debug method with no caller anywhere in the workspace. cargo fix then dropped the imports that became orphans (Color, Size, Vector, alignment). Leyoda 2026 – GPLv3 --- core/src/settings.rs | 10 -------- wgpu/src/lib.rs | 46 +---------------------------------- wgpu/src/window/compositor.rs | 8 +----- 3 files changed, 2 insertions(+), 62 deletions(-) diff --git a/core/src/settings.rs b/core/src/settings.rs index be744b36..2ee1021d 100644 --- a/core/src/settings.rs +++ b/core/src/settings.rs @@ -63,13 +63,3 @@ impl Default for Settings { } } -#[cfg(feature = "winit")] -impl From for iced_winit::Settings { - fn from(settings: Settings) -> iced_winit::Settings { - iced_winit::Settings { - id: settings.id, - fonts: settings.fonts, - is_daemon: settings.is_daemon, - } - } -} diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 830f9911..4b22ad0a 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -65,7 +65,7 @@ pub use geometry::Geometry; use crate::core::renderer; use crate::core::{ Background, Color, Font, Pixels, Point, Rectangle, Size, - Transformation, Vector, + Transformation, }; use crate::graphics::mesh; use crate::graphics::text::{Editor, Paragraph}; @@ -671,50 +671,6 @@ impl Renderer { }); } - fn draw_overlay( - &mut self, - overlay: &[impl AsRef], - viewport: &Viewport, - ) { - use crate::core::Renderer as _; - use crate::core::alignment; - use crate::core::text::Renderer as _; - - self.with_layer( - Rectangle::with_size(viewport.logical_size()), - |renderer| { - for (i, line) in overlay.iter().enumerate() { - let text = crate::core::Text { - content: line.as_ref().to_owned(), - bounds: viewport.logical_size(), - size: Pixels(20.0), - line_height: core::text::LineHeight::default(), - font: Font::MONOSPACE, - align_x: core::text::Alignment::Left, - align_y: alignment::Vertical::Top, - shaping: core::text::Shaping::Advanced, - wrapping: core::text::Wrapping::Word, - ellipsize: core::text::Ellipsize::None, - }; - - renderer.fill_text( - text.clone(), - Point::new(11.0, 11.0 + 25.0 * i as f32), - Color::from_rgba(0.9, 0.9, 0.9, 1.0), - Rectangle::with_size(Size::INFINITE), - ); - - renderer.fill_text( - text, - Point::new(11.0, 11.0 + 25.0 * i as f32) - + Vector::new(-1.0, -1.0), - Color::BLACK, - Rectangle::with_size(Size::INFINITE), - ); - } - }, - ); - } } impl core::Renderer for Renderer { diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index 56c01980..a7009d14 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -138,12 +138,6 @@ impl Compositor { .clone() .and_then(|window| instance.create_surface(window).ok()); - let mut adapter_options = wgpu::RequestAdapterOptions { - power_preference: wgpu::PowerPreference::from_env() - .unwrap_or(wgpu::PowerPreference::HighPerformance), - compatible_surface: compatible_surface.as_ref(), - force_fallback_adapter: false, - }; let mut adapter = None; #[cfg_attr(not(unix), allow(dead_code))] if std::env::var_os("WGPU_ADAPTER_NAME").is_none() { @@ -205,7 +199,7 @@ impl Compositor { .await; compatible_surface = compatible_window .and_then(|window| instance.create_surface(window).ok()); - adapter_options = wgpu::RequestAdapterOptions { + let adapter_options = wgpu::RequestAdapterOptions { power_preference: wgpu::PowerPreference::from_env() .unwrap_or(wgpu::PowerPreference::HighPerformance), compatible_surface: compatible_surface.as_ref(), From e000c71ff230036244b5ed4e82d1ba3b0c59bdad Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Wed, 6 May 2026 11:27:02 -0400 Subject: [PATCH 19/72] fix: send redraw request after events creation events must be handled before processing redraws --- .../wayland/event_loop/mod.rs | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/winit/src/platform_specific/wayland/event_loop/mod.rs b/winit/src/platform_specific/wayland/event_loop/mod.rs index 976595a7..61bf12ea 100644 --- a/winit/src/platform_specific/wayland/event_loop/mod.rs +++ b/winit/src/platform_specific/wayland/event_loop/mod.rs @@ -488,6 +488,23 @@ impl SctkEventLoop { let had_events = !state.state.sctk_events.is_empty(); let mut wake_up = had_events; + for e in state.state.sctk_events.drain(..) { + if let SctkEvent::Winit(id, e) = e { + _ = state + .state + .events_sender + .unbounded_send(Control::Winit(id, e)); + } else { + _ = + state + .state + .events_sender + .unbounded_send(Control::PlatformSpecific( + crate::platform_specific::Event::Wayland(e), + )); + } + } + for s in state .state @@ -532,22 +549,6 @@ impl SctkEventLoop { ); } - for e in state.state.sctk_events.drain(..) { - if let SctkEvent::Winit(id, e) = e { - _ = state - .state - .events_sender - .unbounded_send(Control::Winit(id, e)); - } else { - _ = - state - .state - .events_sender - .unbounded_send(Control::PlatformSpecific( - crate::platform_specific::Event::Wayland(e), - )); - } - } if wake_up { state.state.proxy.wake_up(); } From d7595fab95579f640d43d90e16c174709c4b5c01 Mon Sep 17 00:00:00 2001 From: Lcstyle Date: Wed, 18 Feb 2026 17:22:13 -0500 Subject: [PATCH 20/72] fix: bootstrap FrameStatus on session lock surface configure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The session lock configure handler was missing receive_frame() and request_redraw() calls that the layer surface configure handler has. Without these, after S3 resume or DPMS wake, the FrameStatus entry for lock surfaces could be missing, causing the rendering gate to never reach Ready state — resulting in permanently grey lock screens. Co-Authored-By: Claude Opus 4.6 --- .../platform_specific/wayland/handlers/session_lock.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/winit/src/platform_specific/wayland/handlers/session_lock.rs b/winit/src/platform_specific/wayland/handlers/session_lock.rs index d0eee5ef..6c617a20 100644 --- a/winit/src/platform_specific/wayland/handlers/session_lock.rs +++ b/winit/src/platform_specific/wayland/handlers/session_lock.rs @@ -1,6 +1,10 @@ use crate::{ event_loop::state::CommonSurface, - platform_specific::wayland::{handlers::SctkState, sctk_event::SctkEvent}, + platform_specific::wayland::{ + event_loop::state::receive_frame, + handlers::SctkState, + sctk_event::SctkEvent, + }, }; use cctk::sctk::{ delegate_session_lock, @@ -67,6 +71,10 @@ impl SessionLockHandler for SctkState { configure, first, }); + + let wl_surface = session_lock_surface.wl_surface().clone(); + receive_frame(&mut self.frame_status, &wl_surface); + self.request_redraw(&wl_surface); } } From f752bba18f4651eee63d2d187ebfdfb0e620f8ef Mon Sep 17 00:00:00 2001 From: KENZ Date: Sat, 25 Apr 2026 09:54:04 +0900 Subject: [PATCH 21/72] =?UTF-8?q?Revert=20"Fix=20the=20candidate=20window?= =?UTF-8?q?=20position=20of=20fcitx5=20which=20does't=20work=20well=20wi?= =?UTF-8?q?=E2=80=A6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit a9bcb0052944d9fbf33ce0f6a01a80a20cbcd61b. --- winit/src/window.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/winit/src/window.rs b/winit/src/window.rs index 87d35a5a..e56483f4 100644 --- a/winit/src/window.rs +++ b/winit/src/window.rs @@ -335,19 +335,9 @@ where } if self.ime_state != Some((cursor, purpose)) { - // Specify only the bottom-left position of the cursor on Linux - // because fcitx5 doesn't work well with cursor areas of - // the top-left position and height. - // The candidate window hides the composing text (a.k.a. preedit). - let (cursor_y, cursor_height) = - if cfg!(not(any(target_os = "windows", target_os = "macos"))) { - (cursor.y + cursor.height, 0.0) - } else { - (cursor.y, cursor.height) - }; self.raw.set_ime_cursor_area( - LogicalPosition::new(cursor.x, cursor_y).into(), - LogicalSize::new(cursor.width, cursor_height).into(), + LogicalPosition::new(cursor.x, cursor.y).into(), + LogicalSize::new(cursor.width, cursor.height).into(), ); self.raw.set_ime_purpose(conversion::ime_purpose(purpose)); From 1444d5c43e8b103ca8077555606443ab77e03ce5 Mon Sep 17 00:00:00 2001 From: KENZ Date: Sat, 2 May 2026 14:28:09 +0900 Subject: [PATCH 22/72] fix(ime): Don't panic if some IME sends DeleteSurrounding events --- winit/src/conversion.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index cc5676b5..97cc97a6 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -387,19 +387,19 @@ pub fn window_event( self::modifiers(new_modifiers.state()), ))) } - WindowEvent::Ime(event) => Some(Event::InputMethod(match event { - Ime::Enabled => input_method::Event::Opened, - Ime::Preedit(content, size) => input_method::Event::Preedit( + WindowEvent::Ime(event) => match event { + Ime::Enabled => Some(input_method::Event::Opened), + Ime::Preedit(content, size) => Some(input_method::Event::Preedit( content, size.map(|(start, end)| start..end), - ), - Ime::Commit(content) => input_method::Event::Commit(content), - Ime::Disabled => input_method::Event::Closed, - Ime::DeleteSurrounding { - before_bytes, - after_bytes, - } => todo!(), - })), + )), + Ime::Commit(content) => Some(input_method::Event::Commit(content)), + Ime::Disabled => Some(input_method::Event::Closed), + // Upstream iced depends on the winit version which doesn't support + // this kind of ime event. + Ime::DeleteSurrounding { .. } => None, + } + .map(Event::InputMethod), WindowEvent::Focused(focused) => Some(Event::Window(if focused { window::Event::Focused } else { From 347d91f7ead2912694f67416e60a72afdba00715 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Mon, 20 Apr 2026 12:16:44 -0400 Subject: [PATCH 23/72] improv(wgpu): adapter selection --- wgpu/src/window/compositor.rs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index d3f4bf8c..0c354dfd 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -76,18 +76,23 @@ impl Compositor { .or_else(|| get_x11_device_ids(window)) }); + #[cfg(all( + unix, + not(feature = "cctk"), + not(target_os = "macos"), + not(target_os = "redox") + ))] + let ids = compatible_window + .as_ref() + .and_then(|window| get_x11_device_ids(window)); + // HACK: // 1. If we specifically didn't select an nvidia gpu // 2. and the user didn't specifically request an nvidia gpu // 3. and the user didn't set an adapter name, // 4. and the user didn't request the high power pref // => don't load the nvidia icd, as it might power on the gpu in hybrid setups causing severe delays - #[cfg(all( - unix, - feature = "cctk", - not(target_os = "macos"), - not(target_os = "redox") - ))] + #[cfg(all(unix, not(target_os = "macos"), not(target_os = "redox")))] if !matches!(ids, Some((0x10de, _))) && std::env::var_os("__NV_PRIME_RENDER_OFFLOAD") .is_none_or(|var| var == "0") @@ -149,7 +154,6 @@ impl Compositor { if std::env::var_os("WGPU_ADAPTER_NAME").is_none() { #[cfg(all( unix, - feature = "cctk", not(target_os = "macos"), not(target_os = "redox") ))] @@ -187,6 +191,8 @@ impl Compositor { true } }); + } else { + adapter = instance.request_adapter(&adapter_options).await.ok(); } let adapter = match adapter { From 251254ad5179f05b849e420425b72d4c40091db1 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Fri, 15 May 2026 13:38:15 -0600 Subject: [PATCH 24/72] feat: add `selectable()` to Text --- Cargo.lock | 1 + core/Cargo.toml | 1 + core/src/widget/text.rs | 451 +++++++++++++++++++++++++++++++++++-- examples/todos/src/main.rs | 1 + tester/src/lib.rs | 2 + widget/src/checkbox.rs | 1 + widget/src/radio.rs | 1 + widget/src/text/rich.rs | 2 +- widget/src/toggler.rs | 1 + 9 files changed, 442 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 383d8cfa..38f19187 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3023,6 +3023,7 @@ dependencies = [ "serde", "smol_str", "thiserror 2.0.18", + "unicode-segmentation", "web-time", "window_clipboard", ] diff --git a/core/Cargo.toml b/core/Cargo.toml index e64a5c37..0a376b7c 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -31,6 +31,7 @@ num-traits.workspace = true rustc-hash.workspace = true smol_str.workspace = true thiserror.workspace = true +unicode-segmentation.workspace = true web-time.workspace = true serde.workspace = true diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs index 1e40bf9e..0c0ddc54 100644 --- a/core/src/widget/text.rs +++ b/core/src/widget/text.rs @@ -22,16 +22,18 @@ //! ``` use crate::alignment; use crate::layout; -use crate::mouse; +use crate::mouse::{self, click}; use crate::renderer; +use crate::text; use crate::text::paragraph::{self, Paragraph}; -use crate::text::{self, Fragment}; use crate::widget::tree::{self, Tree}; use crate::{ - Color, Element, Layout, Length, Pixels, Rectangle, Size, Theme, Widget, + Clipboard, Color, Element, Event, Layout, Length, Pixels, Point, Rectangle, + Shell, Size, Theme, Widget, keyboard, touch, }; -use std::borrow::Cow; +use unicode_segmentation::UnicodeSegmentation; + pub use text::{Alignment, Ellipsize, LineHeight, Shaping, Wrapping}; /// A bunch of text. @@ -65,6 +67,7 @@ where fragment: text::Fragment<'a>, format: Format, class: Theme::Class<'a>, + selectable: bool, } impl<'a, Theme, Renderer> Text<'a, Theme, Renderer> @@ -79,6 +82,7 @@ where fragment: fragment.into_fragment(), format: Format::default(), class: Theme::default(), + selectable: false, } } @@ -189,7 +193,17 @@ where { let color = color.map(Into::into); - self.style(move |_theme| Style { color }) + self.style(move |_theme| Style { + color, + ..Style::default() + }) + } + + /// Makes the [`Text`] selectable. When enabled, the user can click and + /// drag to select text, and copy it with Ctrl+C / Cmd+C. + pub fn selectable(mut self) -> Self { + self.selectable = true; + self } /// Sets the style class of the [`Text`]. @@ -202,7 +216,53 @@ where } /// The internal state of a [`Text`] widget. -pub type State

= paragraph::Plain

; +pub struct State { + /// The cached paragraph layout. + pub paragraph: paragraph::Plain

, + /// Lazily allocated when text is selectable and first interacted with. + selection: Option>, +} + +impl Default for State

{ + fn default() -> Self { + Self { + paragraph: paragraph::Plain::default(), + selection: None, + } + } +} + +impl std::fmt::Debug for State

{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("State") + .field("selection", &self.selection) + .finish_non_exhaustive() + } +} + +impl std::ops::Deref for State

{ + type Target = paragraph::Plain

; + + fn deref(&self) -> ¶graph::Plain

{ + &self.paragraph + } +} + +impl std::ops::DerefMut for State

{ + fn deref_mut(&mut self) -> &mut paragraph::Plain

{ + &mut self.paragraph + } +} + +#[derive(Debug, Clone, Default)] +struct SelectionState { + anchor: usize, + end: usize, + dragging: bool, + focused: bool, + modifiers: keyboard::Modifiers, + last_click: Option, +} impl Widget for Text<'_, Theme, Renderer> @@ -215,7 +275,7 @@ where } fn state(&self) -> tree::State { - tree::State::new(paragraph::Plain::::default()) + tree::State::new(State::::default()) } fn size(&self) -> Size { @@ -231,8 +291,10 @@ where renderer: &Renderer, limits: &layout::Limits, ) -> layout::Node { + let state = tree.state.downcast_mut::>(); + layout( - tree.state.downcast_mut::>(), + &mut state.paragraph, renderer, limits, &self.fragment, @@ -252,15 +314,285 @@ where ) { let state = tree.state.downcast_ref::>(); let style = theme.style(&self.class); + let bounds = layout.bounds(); + let paragraph = state.paragraph.raw(); + if let Some(sel) = &state.selection { + let left = sel.anchor.min(sel.end); + let right = sel.anchor.max(sel.end); + let content: &str = self.fragment.as_ref(); - draw( - renderer, - defaults, - layout.bounds(), - state.raw(), - style, - viewport, - ); + if left != right { + let lo_byte = grapheme_to_byte(content, left); + let hi_byte = grapheme_to_byte(content, right); + + let anchor = bounds.anchor( + paragraph.min_bounds(), + paragraph.align_x(), + paragraph.align_y(), + ); + + let rects = paragraph.highlight( + 0, + (lo_byte, text::Affinity::After), + (hi_byte, text::Affinity::Before), + ); + + for r in rects { + renderer.fill_quad( + renderer::Quad { + bounds: Rectangle { + x: anchor.x + r.x, + y: anchor.y + r.y, + width: r.width, + height: r.height, + }, + ..renderer::Quad::default() + }, + style.selected_fill, + ); + } + } + } + + draw(renderer, defaults, bounds, paragraph, style, viewport); + } + + fn update( + &mut self, + tree: &mut Tree, + event: &Event, + layout: Layout<'_>, + cursor: mouse::Cursor, + _renderer: &Renderer, + clipboard: &mut dyn Clipboard, + shell: &mut Shell<'_, Message>, + _viewport: &Rectangle, + ) { + if !self.selectable { + return; + } + + let state = tree.state.downcast_mut::>(); + let bounds = layout.bounds(); + let content: &str = self.fragment.as_ref(); + let grapheme_count = content.graphemes(true).count(); + let paragraph = state.paragraph.raw(); + + match event { + Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) + | Event::Touch(touch::Event::FingerPressed { .. }) => { + if let Some(pos) = cursor.position_over(bounds) { + let sel = state.selection.get_or_insert_with(|| { + Box::new(SelectionState::default()) + }); + + let anchor = bounds.anchor( + paragraph.min_bounds(), + paragraph.align_x(), + paragraph.align_y(), + ); + let relative = + Point::new(pos.x - anchor.x, pos.y - anchor.y); + + let grapheme_pos = + hit_to_grapheme(paragraph, relative, content); + + let new_click = click::Click::new( + pos, + mouse::Button::Left, + sel.last_click.take(), + ); + + match new_click.kind() { + click::Kind::Single => { + if sel.modifiers.shift() { + sel.end = grapheme_pos; + } else { + sel.anchor = grapheme_pos; + sel.end = grapheme_pos; + } + sel.dragging = true; + } + click::Kind::Double => { + sel.anchor = + previous_start_of_word(content, grapheme_pos); + sel.end = next_end_of_word(content, grapheme_pos); + sel.dragging = true; + } + click::Kind::Triple => { + sel.anchor = 0; + sel.end = grapheme_count; + sel.dragging = true; + } + } + + sel.last_click = Some(new_click); + sel.focused = true; + shell.capture_event(); + } else if let Some(sel) = &mut state.selection { + sel.focused = false; + sel.anchor = 0; + sel.end = 0; + sel.dragging = false; + } + } + + Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) + | Event::Touch(touch::Event::FingerLifted { .. }) => { + if let Some(sel) = &mut state.selection { + sel.dragging = false; + } + } + + Event::Mouse(mouse::Event::CursorMoved { position }) + | Event::Touch(touch::Event::FingerMoved { position, .. }) => { + if let Some(sel) = &mut state.selection { + if sel.dragging { + let anchor = bounds.anchor( + paragraph.min_bounds(), + paragraph.align_x(), + paragraph.align_y(), + ); + let relative = Point::new( + position.x - anchor.x, + position.y - anchor.y, + ); + + sel.end = hit_to_grapheme(paragraph, relative, content); + shell.capture_event(); + } + } + } + + Event::Keyboard(keyboard::Event::KeyPressed { + key, + modifiers, + physical_key, + text: _, + .. + }) => { + let focused = + state.selection.as_ref().is_some_and(|s| s.focused); + if !focused { + return; + } + let sel = state.selection.as_mut().unwrap(); + + if modifiers.command() { + match key.to_latin(*physical_key) { + Some('c') => { + let left = sel.anchor.min(sel.end); + let right = sel.anchor.max(sel.end); + if left != right { + let selected: String = content + .graphemes(true) + .skip(left) + .take(right - left) + .collect(); + clipboard.write( + crate::clipboard::Kind::Standard, + selected, + ); + } + shell.capture_event(); + return; + } + Some('a') => { + sel.anchor = 0; + sel.end = grapheme_count; + shell.capture_event(); + return; + } + _ => {} + } + } + + match key { + keyboard::Key::Named(keyboard::key::Named::ArrowLeft) => { + let by_word = is_jump_modifier(*modifiers); + if modifiers.shift() { + sel.end = if by_word { + previous_start_of_word(content, sel.end) + } else { + sel.end.saturating_sub(1) + }; + } else { + let left = sel.anchor.min(sel.end); + let pos = if by_word { + previous_start_of_word(content, left) + } else { + left.saturating_sub(1) + }; + sel.anchor = pos; + sel.end = pos; + } + shell.capture_event(); + } + keyboard::Key::Named(keyboard::key::Named::ArrowRight) => { + let by_word = is_jump_modifier(*modifiers); + if modifiers.shift() { + sel.end = if by_word { + next_end_of_word(content, sel.end) + } else { + (sel.end + 1).min(grapheme_count) + }; + } else { + let right = sel.anchor.max(sel.end); + let pos = if by_word { + next_end_of_word(content, right) + } else { + (right + 1).min(grapheme_count) + }; + sel.anchor = pos; + sel.end = pos; + } + shell.capture_event(); + } + keyboard::Key::Named(keyboard::key::Named::Home) => { + if modifiers.shift() { + sel.end = 0; + } else { + sel.anchor = 0; + sel.end = 0; + } + shell.capture_event(); + } + keyboard::Key::Named(keyboard::key::Named::End) => { + if modifiers.shift() { + sel.end = grapheme_count; + } else { + sel.anchor = grapheme_count; + sel.end = grapheme_count; + } + shell.capture_event(); + } + _ => {} + } + } + + Event::Keyboard(keyboard::Event::ModifiersChanged(modifiers)) => { + if let Some(sel) = &mut state.selection { + sel.modifiers = *modifiers; + } + } + + _ => {} + } + } + + fn mouse_interaction( + &self, + _tree: &Tree, + layout: Layout<'_>, + cursor: mouse::Cursor, + _viewport: &Rectangle, + _renderer: &Renderer, + ) -> mouse::Interaction { + if self.selectable && cursor.is_over(layout.bounds()) { + mouse::Interaction::Text + } else { + mouse::Interaction::None + } } fn operate( @@ -471,12 +803,23 @@ where } /// The appearance of some text. -#[derive(Debug, Clone, Copy, PartialEq, Default)] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct Style { /// The [`Color`] of the text. /// /// The default, `None`, means using the inherited color. pub color: Option, + /// The fill [`Color`] of the selection highlight. + pub selected_fill: Color, +} + +impl Default for Style { + fn default() -> Self { + Self { + color: None, + selected_fill: DEFAULT_SELECTION_COLOR, + } + } } /// The theme catalog of a [`Text`]. @@ -510,13 +853,14 @@ impl Catalog for Theme { /// The default text styling; color is inherited. pub fn default(_theme: &Theme) -> Style { - Style { color: None } + Style::default() } /// Text with the default base color. pub fn base(theme: &Theme) -> Style { Style { color: Some(theme.palette().text), + ..Style::default() } } @@ -524,6 +868,7 @@ pub fn base(theme: &Theme) -> Style { pub fn primary(theme: &Theme) -> Style { Style { color: Some(theme.palette().primary), + ..Style::default() } } @@ -531,6 +876,7 @@ pub fn primary(theme: &Theme) -> Style { pub fn secondary(theme: &Theme) -> Style { Style { color: Some(theme.extended_palette().secondary.base.color), + ..Style::default() } } @@ -538,6 +884,7 @@ pub fn secondary(theme: &Theme) -> Style { pub fn success(theme: &Theme) -> Style { Style { color: Some(theme.palette().success), + ..Style::default() } } @@ -545,6 +892,7 @@ pub fn success(theme: &Theme) -> Style { pub fn warning(theme: &Theme) -> Style { Style { color: Some(theme.palette().warning), + ..Style::default() } } @@ -552,5 +900,72 @@ pub fn warning(theme: &Theme) -> Style { pub fn danger(theme: &Theme) -> Style { Style { color: Some(theme.palette().danger), + ..Style::default() + } +} + +const DEFAULT_SELECTION_COLOR: Color = Color { + r: 0.0, + g: 0.47, + b: 0.84, + a: 0.3, +}; + +fn grapheme_to_byte(content: &str, grapheme_index: usize) -> usize { + content + .graphemes(true) + .take(grapheme_index) + .map(|g| g.len()) + .sum() +} + +fn hit_to_grapheme( + paragraph: &P, + point: Point, + content: &str, +) -> usize { + match paragraph.hit_test(point) { + Some(hit) => { + let byte_offset = hit.cursor().min(content.len()); + content[..byte_offset].graphemes(true).count() + } + None => content.graphemes(true).count(), + } +} + +fn previous_start_of_word(content: &str, grapheme_index: usize) -> usize { + let graphemes: Vec<&str> = content.graphemes(true).collect(); + let clamped = grapheme_index.min(graphemes.len()); + let before: String = graphemes[..clamped].concat(); + + UnicodeSegmentation::split_word_bound_indices(&*before) + .filter(|(_, word)| !word.trim_start().is_empty()) + .next_back() + .map_or(0, |(i, prev_word)| { + clamped + - prev_word.graphemes(true).count() + - before[i + prev_word.len()..].graphemes(true).count() + }) +} + +fn next_end_of_word(content: &str, grapheme_index: usize) -> usize { + let graphemes: Vec<&str> = content.graphemes(true).collect(); + let clamped = grapheme_index.min(graphemes.len()); + let after: String = graphemes[clamped..].concat(); + + UnicodeSegmentation::split_word_bound_indices(&*after) + .find(|(_, word)| !word.trim_start().is_empty()) + .map_or(graphemes.len(), |(i, next_word)| { + clamped + + next_word.graphemes(true).count() + + after[..i].graphemes(true).count() + }) +} + +fn is_jump_modifier(modifiers: keyboard::Modifiers) -> bool { + if cfg!(target_os = "macos") { + modifiers.alt() + } else { + modifiers.control() } } diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs index 2e3722b1..9fe39035 100644 --- a/examples/todos/src/main.rs +++ b/examples/todos/src/main.rs @@ -477,6 +477,7 @@ fn delete_icon() -> Text<'static> { fn subtle(theme: &Theme) -> text::Style { text::Style { color: Some(theme.extended_palette().background.strongest.color), + ..text::Style::default() } } diff --git a/tester/src/lib.rs b/tester/src/lib.rs index 334f17bc..f41fbb68 100644 --- a/tester/src/lib.rs +++ b/tester/src/lib.rs @@ -775,6 +775,7 @@ impl Tester

{ } _ => None, }, + ..text::Style::default() }) .into() }, @@ -945,6 +946,7 @@ where text(label).size(14).style(|theme: &core::Theme| { text::Style { color: Some(theme.extended_palette().background.weak.text), + ..text::Style::default() } }), space::horizontal(), diff --git a/widget/src/checkbox.rs b/widget/src/checkbox.rs index 873a4541..6ac48b0e 100644 --- a/widget/src/checkbox.rs +++ b/widget/src/checkbox.rs @@ -505,6 +505,7 @@ where state.raw(), crate::text::Style { color: style.text_color, + ..crate::text::Style::default() }, viewport, ); diff --git a/widget/src/radio.rs b/widget/src/radio.rs index 1aa97355..bdca259c 100644 --- a/widget/src/radio.rs +++ b/widget/src/radio.rs @@ -459,6 +459,7 @@ where state.raw(), crate::text::Style { color: style.text_color, + ..crate::text::Style::default() }, viewport, ); diff --git a/widget/src/text/rich.rs b/widget/src/text/rich.rs index cd368e83..80abc8d5 100644 --- a/widget/src/text/rich.rs +++ b/widget/src/text/rich.rs @@ -179,7 +179,7 @@ where { let color = color.map(Into::into); - self.style(move |_theme| Style { color }) + self.style(move |_theme| Style { color, ..Style::default() }) } /// Sets the default style class of the [`Rich`] text. diff --git a/widget/src/toggler.rs b/widget/src/toggler.rs index d398a79b..6709f1dc 100644 --- a/widget/src/toggler.rs +++ b/widget/src/toggler.rs @@ -483,6 +483,7 @@ where state.raw(), crate::text::Style { color: style.text_color, + ..crate::text::Style::default() }, viewport, ); From 346faf2e7951dd4ea6fe7fb3f677e34631145d88 Mon Sep 17 00:00:00 2001 From: Ericky Dos Santos Date: Tue, 6 Jan 2026 13:26:01 -0500 Subject: [PATCH 25/72] Make shader_f16 optional because it does not work in webgl --- wgpu/src/window/compositor.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index 0c354dfd..bbef994d 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -295,6 +295,13 @@ impl Compositor { ..limits }); + // Request SHADER_F16 only if the adapter supports it (e.g., not available in WebGL2) + let required_features = if adapter.features().contains(wgpu::Features::SHADER_F16) { + wgpu::Features::SHADER_F16 + } else { + wgpu::Features::empty() + }; + let mut errors = Vec::new(); for required_limits in limits { @@ -303,7 +310,7 @@ impl Compositor { label: Some( "iced_wgpu::window::compositor device descriptor", ), - required_features: wgpu::Features::SHADER_F16, + required_features, required_limits: required_limits.clone(), memory_hints: wgpu::MemoryHints::MemoryUsage, trace: wgpu::Trace::Off, From 9ae155b8e26480fd78ff289fceec0cdf2d476463 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Wed, 20 May 2026 00:25:37 -0600 Subject: [PATCH 26/72] fix: crash while resizing on x11 --- wgpu/src/window/compositor.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index bbef994d..4033aea4 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -368,6 +368,13 @@ pub fn present( ) -> Result<(), compositor::SurfaceError> { match surface.get_current_texture() { Ok(frame) => { + if frame.suboptimal + || frame.texture.width() != viewport.physical_width() + || frame.texture.height() != viewport.physical_height() + { + return Err(compositor::SurfaceError::Outdated); + } + let view = &frame .texture .create_view(&wgpu::TextureViewDescriptor::default()); From 2e1e4bd6e0a8cc46290d9354428bf7a0f3ca752d Mon Sep 17 00:00:00 2001 From: Hojjat Date: Tue, 19 May 2026 19:36:16 -0600 Subject: [PATCH 27/72] feat: add HasSelectableText trait to Text widget --- core/src/widget/text.rs | 220 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 208 insertions(+), 12 deletions(-) diff --git a/core/src/widget/text.rs b/core/src/widget/text.rs index 0c0ddc54..2ba0ada4 100644 --- a/core/src/widget/text.rs +++ b/core/src/widget/text.rs @@ -221,6 +221,9 @@ pub struct State { pub paragraph: paragraph::Plain

, /// Lazily allocated when text is selectable and first interacted with. selection: Option>, + focused: bool, + keyboard_focused: bool, + context_menu_position: Option, } impl Default for State

{ @@ -228,6 +231,9 @@ impl Default for State

{ Self { paragraph: paragraph::Plain::default(), selection: None, + focused: false, + keyboard_focused: false, + context_menu_position: None, } } } @@ -236,10 +242,43 @@ impl std::fmt::Debug for State

{ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("State") .field("selection", &self.selection) + .field("focused", &self.focused) .finish_non_exhaustive() } } +impl State

{ + /// Returns `true` if the widget currently has focus. + pub fn is_focused(&self) -> bool { + self.focused + } + + /// Returns `true` if focus was gained via keyboard navigation (Tab). + pub fn is_keyboard_focused(&self) -> bool { + self.keyboard_focused + } + + /// Clears focus, selection, and all interaction state. + pub fn clear_focus(&mut self) { + self.focused = false; + self.keyboard_focused = false; + self.context_menu_position = None; + if let Some(sel) = &mut self.selection { + sel.clear(); + } + } + + /// Returns the context menu position, if a context menu should be shown. + pub fn context_menu_position(&self) -> Option { + self.context_menu_position + } + + /// Sets or clears the context menu position. + pub fn set_context_menu_position(&mut self, pos: Option) { + self.context_menu_position = pos; + } +} + impl std::ops::Deref for State

{ type Target = paragraph::Plain

; @@ -259,11 +298,33 @@ struct SelectionState { anchor: usize, end: usize, dragging: bool, - focused: bool, modifiers: keyboard::Modifiers, last_click: Option, } +impl SelectionState { + fn clear(&mut self) { + self.anchor = 0; + self.end = 0; + self.dragging = false; + } +} + +impl crate::widget::operation::Focusable for State

{ + fn is_focused(&self) -> bool { + self.focused + } + + fn focus(&mut self) { + self.focused = true; + self.keyboard_focused = true; + } + + fn unfocus(&mut self) { + self.clear_focus(); + } +} + impl Widget for Text<'_, Theme, Renderer> where @@ -378,9 +439,29 @@ where let grapheme_count = content.graphemes(true).count(); let paragraph = state.paragraph.raw(); + // Any click outside this widget clears selection and focus. + if matches!( + event, + Event::Mouse(mouse::Event::ButtonPressed(_)) + | Event::Touch(touch::Event::FingerPressed { .. }) + ) { + if cursor.position_over(bounds).is_none() { + state.focused = false; + state.keyboard_focused = false; + if let Some(sel) = &mut state.selection { + sel.clear(); + } + } + } + match event { Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) | Event::Touch(touch::Event::FingerPressed { .. }) => { + if state.context_menu_position.take().is_some() { + shell.capture_event(); + return; + } + if let Some(pos) = cursor.position_over(bounds) { let sel = state.selection.get_or_insert_with(|| { Box::new(SelectionState::default()) @@ -427,13 +508,18 @@ where } sel.last_click = Some(new_click); - sel.focused = true; + state.focused = true; + state.keyboard_focused = false; + shell.capture_event(); + } + } + + Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Right)) => { + if let Some(pos) = cursor.position_over(bounds) { + state.context_menu_position = Some(pos); + state.focused = true; + state.keyboard_focused = false; shell.capture_event(); - } else if let Some(sel) = &mut state.selection { - sel.focused = false; - sel.anchor = 0; - sel.end = 0; - sel.dragging = false; } } @@ -471,12 +557,12 @@ where text: _, .. }) => { - let focused = - state.selection.as_ref().is_some_and(|s| s.focused); - if !focused { + if !state.focused { return; } - let sel = state.selection.as_mut().unwrap(); + let sel = state + .selection + .get_or_insert_with(|| Box::new(SelectionState::default())); if modifiers.command() { match key.to_latin(*physical_key) { @@ -597,12 +683,17 @@ where fn operate( &mut self, - _tree: &mut Tree, + tree: &mut Tree, layout: Layout<'_>, _renderer: &Renderer, operation: &mut dyn super::Operation, ) { operation.text(None, layout.bounds(), &self.fragment); + + if self.selectable { + let state = tree.state.downcast_mut::>(); + operation.focusable(None, layout.bounds(), state); + } } #[cfg(feature = "a11y")] @@ -904,6 +995,111 @@ pub fn danger(theme: &Theme) -> Style { } } +use crate::widget::tree::Tree as WidgetTree; + +/// Implement this on a **widget** to enable context menu support for +/// text selection (Copy, Select All, and optionally Cut / Paste) in libcosmic +pub trait HasSelectableText { + /// Returns the currently selected text, if any. + fn selected_text(&self, tree: &WidgetTree) -> Option; + + /// Selects all text. + fn select_all(&self, tree: &mut WidgetTree); + + /// Returns `true` if the widget is editable (enables Cut / Paste). + fn is_editable(&self) -> bool { + false + } + + /// Returns `true` if the widget is currently focused. + fn is_focused(&self, tree: &WidgetTree) -> bool; + + /// Returns the position where the context menu should appear + fn context_menu_position(&self, tree: &WidgetTree) -> Option; + + /// Sets or clears the context menu position. + fn set_context_menu_position( + &self, + tree: &mut WidgetTree, + pos: Option, + ); + + /// Copies the selection to the clipboard. + fn copy_to_clipboard( + &self, + tree: &WidgetTree, + clipboard: &mut dyn Clipboard, + ) { + if let Some(text) = self.selected_text(tree) { + clipboard.write(crate::clipboard::Kind::Standard, text); + } + } + + /// Deletes the selected text and returns the new full content. + /// Only called when [`is_editable`](Self::is_editable) is `true`. + fn delete_selection(&self, _tree: &mut WidgetTree) -> Option { + None + } + + /// Inserts `text` at the cursor (replacing any selection) and returns + /// the new full content. + /// Only called when [`is_editable`](Self::is_editable) is `true`. + fn paste_text( + &self, + _tree: &mut WidgetTree, + _text: &str, + ) -> Option { + None + } +} + +impl HasSelectableText + for Text<'_, Theme, Renderer> +{ + fn selected_text(&self, tree: &WidgetTree) -> Option { + let state = tree.state.downcast_ref::>(); + let sel = state.selection.as_ref()?; + let left = sel.anchor.min(sel.end); + let right = sel.anchor.max(sel.end); + if left == right { + return None; + } + let content = state.paragraph.content(); + let lo = grapheme_to_byte(content, left); + let hi = grapheme_to_byte(content, right); + content.get(lo..hi).map(|s| s.to_owned()) + } + + fn select_all(&self, tree: &mut WidgetTree) { + let state = tree.state.downcast_mut::>(); + let count = state.paragraph.content().graphemes(true).count(); + let sel = state + .selection + .get_or_insert_with(|| Box::new(SelectionState::default())); + sel.anchor = 0; + sel.end = count; + } + + fn is_focused(&self, tree: &WidgetTree) -> bool { + let state = tree.state.downcast_ref::>(); + state.is_focused() + } + + fn context_menu_position(&self, tree: &WidgetTree) -> Option { + let state = tree.state.downcast_ref::>(); + state.context_menu_position() + } + + fn set_context_menu_position( + &self, + tree: &mut WidgetTree, + pos: Option, + ) { + let state = tree.state.downcast_mut::>(); + state.set_context_menu_position(pos); + } +} + const DEFAULT_SELECTION_COLOR: Color = Color { r: 0.0, g: 0.47, From a7ca336eb4db0fe89d2bdeb90b57140e0ebca141 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Tue, 19 May 2026 19:36:22 -0600 Subject: [PATCH 28/72] feat: HasSelectableText impl to TextEditor --- core/src/text/editor.rs | 2 + graphics/src/text/editor.rs | 4 ++ widget/src/text_editor.rs | 126 +++++++++++++++++++++++++++++++++++- 3 files changed, 131 insertions(+), 1 deletion(-) diff --git a/core/src/text/editor.rs b/core/src/text/editor.rs index e0b87756..ff89af01 100644 --- a/core/src/text/editor.rs +++ b/core/src/text/editor.rs @@ -78,6 +78,8 @@ pub enum Action { SelectLine, /// Select the entire buffer. SelectAll, + /// Clear the selection + ClearSelection, /// Perform an [`Edit`]. Edit(Edit), /// Click the [`Editor`] at the given [`Point`]. diff --git a/graphics/src/text/editor.rs b/graphics/src/text/editor.rs index b284c76b..1586479e 100644 --- a/graphics/src/text/editor.rs +++ b/graphics/src/text/editor.rs @@ -336,6 +336,10 @@ impl editor::Editor for Editor { } } + Action::ClearSelection => { + editor.set_selection(cosmic_text::Selection::None); + } + // Editing events Action::Edit(edit) => { let topmost_line_before_edit = editor diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index b93c96f3..a8f243fa 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -544,6 +544,8 @@ pub struct State { highlighter: RefCell, highlighter_settings: Highlighter::Settings, highlighter_format_address: usize, + context_menu_position: Option, + pending_edit: Option, } #[derive(Debug, Clone)] @@ -579,6 +581,14 @@ impl State { pub fn is_focused(&self) -> bool { self.focus.is_some() } + + /// Clears focus, selection, and all interaction state. + pub fn clear_focus(&mut self) { + self.focus = None; + self.drag_click = None; + self.context_menu_position = None; + self.pending_edit = Some(Action::ClearSelection); + } } impl operation::Focusable @@ -593,7 +603,7 @@ impl operation::Focusable } fn unfocus(&mut self) { - self.focus = None; + self.clear_focus(); } } @@ -621,6 +631,8 @@ where )), highlighter_settings: self.highlighter_settings.clone(), highlighter_format_address: self.highlighter_format as usize, + context_menu_position: None, + pending_edit: None, }) } @@ -699,6 +711,58 @@ where shell: &mut Shell<'_, Message>, _viewport: &Rectangle, ) { + // Handle context menu and focus-loss on clicks outside. + { + let state = tree.state.downcast_mut::>(); + let text_bounds = layout.bounds(); + + if matches!( + event, + Event::Mouse(mouse::Event::ButtonPressed(_)) + | Event::Touch( + crate::core::touch::Event::FingerPressed { .. } + ) + ) && cursor.position_over(text_bounds).is_none() + { + state.clear_focus(); + } + + match event { + Event::Mouse(mouse::Event::ButtonPressed( + mouse::Button::Right, + )) => { + if let Some(pos) = cursor.position_over(text_bounds) { + if state.focus.is_none() { + state.focus = Some(Focus::now()); + } + state.context_menu_position = Some(pos); + shell.capture_event(); + return; + } + } + Event::Mouse(mouse::Event::ButtonPressed( + mouse::Button::Left, + )) => { + if state.context_menu_position.take().is_some() { + shell.capture_event(); + return; + } + } + _ => {} + } + } + + // Process pending edits from context menu + // publishes via on_edit so the app calls content.perform(). + { + let state = tree.state.downcast_mut::>(); + if let Some(action) = state.pending_edit.take() { + if let Some(on_edit) = self.on_edit.as_ref() { + shell.publish((on_edit)(action)); + } + } + } + let Some(on_edit) = self.on_edit.as_ref() else { return; }; @@ -1545,3 +1609,63 @@ pub(crate) fn convert_macos_shortcut( Some(keyboard::Key::Named(key)) } + +use crate::core::widget::text::HasSelectableText; + +impl HasSelectableText + for TextEditor<'_, Highlighter, Message, Theme, Renderer> +where + Highlighter: text::Highlighter, + Theme: Catalog, + Renderer: text::Renderer, +{ + fn selected_text(&self, _tree: &widget::Tree) -> Option { + self.content.selection() + } + + fn select_all(&self, tree: &mut widget::Tree) { + let state = tree.state.downcast_mut::>(); + state.pending_edit = Some(Action::SelectAll); + } + + fn is_editable(&self) -> bool { + self.on_edit.is_some() + } + + fn is_focused(&self, tree: &widget::Tree) -> bool { + tree.state.downcast_ref::>().is_focused() + } + + fn context_menu_position(&self, tree: &widget::Tree) -> Option { + tree.state + .downcast_ref::>() + .context_menu_position + } + + fn set_context_menu_position( + &self, + tree: &mut widget::Tree, + pos: Option, + ) { + tree.state + .downcast_mut::>() + .context_menu_position = pos; + } + + fn delete_selection(&self, tree: &mut widget::Tree) -> Option { + let state = tree.state.downcast_mut::>(); + state.pending_edit = Some(Action::Edit(Edit::Delete)); + Some(String::new()) + } + + fn paste_text( + &self, + tree: &mut widget::Tree, + text: &str, + ) -> Option { + let state = tree.state.downcast_mut::>(); + state.pending_edit = + Some(Action::Edit(Edit::Paste(Arc::new(text.to_owned())))); + Some(String::new()) + } +} From b007caba44b0be1d282edbe1cd6fcd440ef06eab Mon Sep 17 00:00:00 2001 From: Hojjat Date: Tue, 19 May 2026 19:36:26 -0600 Subject: [PATCH 29/72] feat: add direct SCTK action sender for wayland popups --- winit/src/platform_specific/wayland/mod.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/winit/src/platform_specific/wayland/mod.rs b/winit/src/platform_specific/wayland/mod.rs index 9b3a7ec0..0ba156d7 100644 --- a/winit/src/platform_specific/wayland/mod.rs +++ b/winit/src/platform_specific/wayland/mod.rs @@ -25,10 +25,23 @@ use std::{collections::HashMap, sync::Arc}; use subsurface_widget::{SubsurfaceInstance, SubsurfaceState}; use wayland_backend::client::ObjectId; use wayland_client::{Connection, Proxy}; +use std::sync::OnceLock; use winit::dpi::Size; use winit::event_loop::OwnedDisplayHandle; use winit::window::ImePurpose; +static SCTK_ACTION_SENDER: OnceLock> = OnceLock::new(); + +/// Sends a platform-specific wayland action directly to the SCTK event loop, +/// bypassing the async Task system. This is needed when widgets queue popup +/// actions outside of the normal message flow (e.g., text context menus that +/// don't publish app messages). +pub fn send_wayland_action_direct(action: iced_runtime::platform_specific::wayland::Action) { + if let Some(sender) = SCTK_ACTION_SENDER.get() { + _ = sender.send(Action::Action(action)); + } +} + pub(crate) enum Action { Action(iced_runtime::platform_specific::wayland::Action), SetCursor(CursorIcon), @@ -136,6 +149,9 @@ impl PlatformSpecific { self.wayland.display_handle.clone().unwrap(), ) .ok(); + if let Some(ref sender) = self.wayland.sender { + _ = SCTK_ACTION_SENDER.set(sender.clone()); + } self } From 98fb6a0fba98cfdb6c04f33ccf0be6abad7fcfff Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Wed, 20 May 2026 17:00:28 +0200 Subject: [PATCH 30/72] docs: update cosmic-protocols with docs cfg fix --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d60bcb8d..e9f43f7f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -120,7 +120,7 @@ winit = [ ] wayland = ["iced_renderer/wayland", "iced_winit/wayland"] cctk = ["iced_winit/cctk", "iced_widget/cctk", "iced_core/cctk", "wayland"] -# Enables the sctk shell. +# Enables the sctk shell. [dependencies] @@ -274,7 +274,7 @@ tiny-skia = { version = "0.11", default-features = false, features = [ "std", "simd", ] } -cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "160b086" } +cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "c253ec1" } softbuffer = { git = "https://github.com/pop-os/softbuffer", tag = "cosmic-4.0" } syntect = "5.2" tokio = "1.0" From 6105d8bdef8bcd39fbca1ef168d82c986dd18d20 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Fri, 22 May 2026 15:40:59 -0400 Subject: [PATCH 31/72] reexport geometry from iced_graphics --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 8d408969..46685d76 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -682,7 +682,7 @@ pub use error::Error; pub use event::Event; pub use executor::Executor; pub use font::Font; -pub use renderer::Renderer; +pub use renderer::{Renderer, graphics::geometry}; pub use task::Task; pub use window::Window; From f4870187088a14d398f2075c5ccda611387dcdcc Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Sat, 23 May 2026 20:55:59 +0200 Subject: [PATCH 32/72] chore: gate accessibility-only winit state --- winit/src/lib.rs | 4 +++- winit/src/window/state.rs | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 3c5a5d29..9bc2db96 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -188,8 +188,9 @@ where sender: mpsc::UnboundedSender>, receiver: mpsc::UnboundedReceiver, error: Option, + #[cfg(feature = "a11y")] control_sender: mpsc::UnboundedSender, - + #[cfg(feature = "a11y")] adapters: std::collections::HashMap, @@ -208,6 +209,7 @@ where id: settings.id, sender: event_sender, receiver: control_receiver, + #[cfg(feature = "a11y")] control_sender: control_sender.clone(), error: None, diff --git a/winit/src/window/state.rs b/winit/src/window/state.rs index 98fdf9ee..1e16fc51 100644 --- a/winit/src/window/state.rs +++ b/winit/src/window/state.rs @@ -97,6 +97,7 @@ where self.ready = ready; } + #[cfg(feature = "a11y")] pub(crate) fn set_a11y_ready(&mut self, ready: bool) { self.a11y_ready = ready; } From 81639935398a856f3164dc406fbac78922c258fc Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Mon, 25 May 2026 11:35:03 +0200 Subject: [PATCH 33/72] chore: refresh lockfile for local clipboard fork --- Cargo.lock | 60 +++++------------------------------------------------- 1 file changed, 5 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9fddcd2e..0a138409 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1071,7 +1071,7 @@ dependencies = [ [[package]] name = "clipboard_macos" version = "0.1.0" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" +source = "git+https://forge.aditua.com/leyoda/window_clipboard.git?branch=yoda-x11-optional#319db02e5219c557c8f03b0e33a8eb4075cabb85" dependencies = [ "objc", "objc-foundation", @@ -1081,22 +1081,13 @@ dependencies = [ [[package]] name = "clipboard_wayland" version = "0.2.2" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" +source = "git+https://forge.aditua.com/leyoda/window_clipboard.git?branch=yoda-x11-optional#319db02e5219c557c8f03b0e33a8eb4075cabb85" dependencies = [ "dnd", "mime 0.1.0", "smithay-clipboard", ] -[[package]] -name = "clipboard_x11" -version = "0.4.2" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" -dependencies = [ - "thiserror 1.0.69", - "x11rb", -] - [[package]] name = "clock" version = "0.1.0" @@ -1617,7 +1608,7 @@ dependencies = [ [[package]] name = "dnd" version = "0.1.0" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" +source = "git+https://forge.aditua.com/leyoda/window_clipboard.git?branch=yoda-x11-optional#319db02e5219c557c8f03b0e33a8eb4075cabb85" dependencies = [ "bitflags 2.11.0", "mime 0.1.0", @@ -1654,45 +1645,12 @@ name = "dpi" version = "0.1.2" source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" -[[package]] -name = "drm" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0f8a69e60d75ae7dab4ef26a59ca99f2a89d4c142089b537775ae0c198bdcde" -dependencies = [ - "bitflags 2.11.0", - "bytemuck", - "drm-ffi", - "drm-fourcc", - "rustix 0.38.44", -] - -[[package]] -name = "drm-ffi" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41334f8405792483e32ad05fbb9c5680ff4e84491883d2947a4757dc54cb2ac6" -dependencies = [ - "drm-sys", - "rustix 0.38.44", -] - [[package]] name = "drm-fourcc" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4" -[[package]] -name = "drm-sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d09ff881f92f118b11105ba5e34ff8f4adf27b30dae8f12e28c193af1c83176" -dependencies = [ - "libc", - "linux-raw-sys 0.6.5", -] - [[package]] name = "editor" version = "0.1.0" @@ -3829,12 +3787,6 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" -[[package]] -name = "linux-raw-sys" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7" - [[package]] name = "linux-raw-sys" version = "0.12.1" @@ -4060,7 +4012,7 @@ dependencies = [ [[package]] name = "mime" version = "0.1.0" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" +source = "git+https://forge.aditua.com/leyoda/window_clipboard.git?branch=yoda-x11-optional#319db02e5219c557c8f03b0e33a8eb4075cabb85" dependencies = [ "smithay-clipboard", ] @@ -6366,7 +6318,6 @@ dependencies = [ "cfg_aliases", "cocoa", "core-graphics", - "drm", "fastrand", "foreign-types 0.5.0", "js-sys", @@ -8048,12 +7999,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "window_clipboard" version = "0.4.1" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#3a7af79e54db6854d8aa9d9e2866a9288d0f95d5" +source = "git+https://forge.aditua.com/leyoda/window_clipboard.git?branch=yoda-x11-optional#319db02e5219c557c8f03b0e33a8eb4075cabb85" dependencies = [ "clipboard-win", "clipboard_macos", "clipboard_wayland", - "clipboard_x11", "dnd", "mime 0.1.0", "raw-window-handle", From 756e5691d770656e797511b1831b2a6b489d92e1 Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Mon, 25 May 2026 18:09:40 +0200 Subject: [PATCH 34/72] chore: use local cctk and clipboard crates --- Cargo.lock | 7 ------- Cargo.toml | 8 ++++---- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a138409..0f16532c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1071,7 +1071,6 @@ dependencies = [ [[package]] name = "clipboard_macos" version = "0.1.0" -source = "git+https://forge.aditua.com/leyoda/window_clipboard.git?branch=yoda-x11-optional#319db02e5219c557c8f03b0e33a8eb4075cabb85" dependencies = [ "objc", "objc-foundation", @@ -1081,7 +1080,6 @@ dependencies = [ [[package]] name = "clipboard_wayland" version = "0.2.2" -source = "git+https://forge.aditua.com/leyoda/window_clipboard.git?branch=yoda-x11-optional#319db02e5219c557c8f03b0e33a8eb4075cabb85" dependencies = [ "dnd", "mime 0.1.0", @@ -1280,7 +1278,6 @@ dependencies = [ [[package]] name = "cosmic-client-toolkit" version = "0.2.0" -source = "git+https://github.com/pop-os/cosmic-protocols?rev=160b086#160b086abe03cd34a8a375d7fbe47b24308d1f38" dependencies = [ "bitflags 2.11.0", "cosmic-protocols", @@ -1293,7 +1290,6 @@ dependencies = [ [[package]] name = "cosmic-protocols" version = "0.2.0" -source = "git+https://github.com/pop-os/cosmic-protocols?rev=160b086#160b086abe03cd34a8a375d7fbe47b24308d1f38" dependencies = [ "bitflags 2.11.0", "wayland-backend", @@ -1608,7 +1604,6 @@ dependencies = [ [[package]] name = "dnd" version = "0.1.0" -source = "git+https://forge.aditua.com/leyoda/window_clipboard.git?branch=yoda-x11-optional#319db02e5219c557c8f03b0e33a8eb4075cabb85" dependencies = [ "bitflags 2.11.0", "mime 0.1.0", @@ -4012,7 +4007,6 @@ dependencies = [ [[package]] name = "mime" version = "0.1.0" -source = "git+https://forge.aditua.com/leyoda/window_clipboard.git?branch=yoda-x11-optional#319db02e5219c557c8f03b0e33a8eb4075cabb85" dependencies = [ "smithay-clipboard", ] @@ -7999,7 +7993,6 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "window_clipboard" version = "0.4.1" -source = "git+https://forge.aditua.com/leyoda/window_clipboard.git?branch=yoda-x11-optional#319db02e5219c557c8f03b0e33a8eb4075cabb85" dependencies = [ "clipboard-win", "clipboard_macos", diff --git a/Cargo.toml b/Cargo.toml index 99841e8a..1cb6dd7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -275,7 +275,7 @@ tiny-skia = { version = "0.11", default-features = false, features = [ "std", "simd", ] } -cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "160b086" } +cctk = { path = "../../cosmic-protocols/client-toolkit", package = "cosmic-client-toolkit" } # Yoda: default-features=false drops softbuffer's x11 / x11-dlopen (pulled # tiny-xlib + as-raw-xcb-connection). The wayland + wayland-dlopen features # are re-activated via iced_tiny_skia's own `wayland` feature propagation. @@ -309,9 +309,9 @@ winapi = "0.3" # an opt-in feature. default-features=false + features=["wayland"] drops # clipboard_x11 + x11rb from the build. Branch yoda-x11-optional on # https://forge.aditua.com/leyoda/window_clipboard. -window_clipboard = { git = "https://forge.aditua.com/leyoda/window_clipboard.git", branch = "yoda-x11-optional", default-features = false, features = ["wayland"] } -dnd = { git = "https://forge.aditua.com/leyoda/window_clipboard.git", branch = "yoda-x11-optional" } -mime = { git = "https://forge.aditua.com/leyoda/window_clipboard.git", branch = "yoda-x11-optional" } +window_clipboard = { path = "../../window_clipboard", default-features = false, features = ["wayland"] } +dnd = { path = "../../window_clipboard/dnd" } +mime = { path = "../../window_clipboard/mime" } # Yoda: default-features = false drops winit's x11 default, which otherwise # pulls winit-x11, x11-dl, tiny-xlib, as-raw-xcb-connection. Our Wayland-only # fork doesn't need any of that — the wayland + wayland-dlopen features are From 12fd244e954c6e7e87bd4b9b8b5dd7aa2ab948d5 Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Mon, 25 May 2026 18:27:54 +0200 Subject: [PATCH 35/72] chore: use local glyphon and cosmic-text --- Cargo.lock | 5 ++--- Cargo.toml | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f16532c..14fbd880 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1302,8 +1302,7 @@ dependencies = [ [[package]] name = "cosmic-text" -version = "0.18.2" -source = "git+https://github.com/pop-os/cosmic-text.git#9a2ab09f06905e91f41d64ac6eee887726e7fd76" +version = "0.19.0" dependencies = [ "bitflags 2.11.0", "fontdb", @@ -1321,6 +1320,7 @@ dependencies = [ "unicode-linebreak", "unicode-script", "unicode-segmentation", + "unicode-width", ] [[package]] @@ -1427,7 +1427,6 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "cryoglyph" version = "0.1.0" -source = "git+https://github.com/pop-os/glyphon.git?tag=cosmic-0.14#c49de15bce4d8254ac136d1be9911960cc85ce12" dependencies = [ "cosmic-text", "etagere", diff --git a/Cargo.toml b/Cargo.toml index 1cb6dd7e..fd6b9ecb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -238,10 +238,10 @@ async-std = "1.0" bitflags = "2.5" bytemuck = { version = "1.0", features = ["derive"] } bytes = "1.6" -cosmic-text = { git = "https://github.com/pop-os/cosmic-text.git" } +cosmic-text = { path = "../../cosmic-text" } # cosmic-text = "0.10" dark-light = "1.0" -cryoglyph = { package = "cryoglyph", git = "https://github.com/pop-os/glyphon.git", tag = "cosmic-0.14" } +cryoglyph = { package = "cryoglyph", path = "../../glyphon" } resvg = "0.45" web-sys = "0.3.69" guillotiere = "0.6" From de1247123a631087d2f78831c99f5f1b66d5a582 Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Mon, 25 May 2026 19:36:22 +0200 Subject: [PATCH 36/72] chore: use local winit and softbuffer --- Cargo.lock | 14 -------------- Cargo.toml | 25 ++++++++++++++++++++++--- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 14fbd880..3aa9a01d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1637,7 +1637,6 @@ dependencies = [ [[package]] name = "dpi" version = "0.1.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" [[package]] name = "drm-fourcc" @@ -6246,7 +6245,6 @@ dependencies = [ [[package]] name = "smithay-clipboard" version = "0.8.0" -source = "git+https://github.com/pop-os/smithay-clipboard?tag=sctk-0.20#859b02c88f45c554049a67c6ddeec1692ce0e20b" dependencies = [ "libc", "raw-window-handle", @@ -6304,7 +6302,6 @@ dependencies = [ [[package]] name = "softbuffer" version = "0.4.1" -source = "git+https://github.com/pop-os/softbuffer?tag=cosmic-4.0#a3f77e251e7422803f693df6e3fc313c010c4dcb" dependencies = [ "as-raw-xcb-connection", "bytemuck", @@ -8563,7 +8560,6 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ "bitflags 2.11.0", "cfg_aliases", @@ -8589,7 +8585,6 @@ dependencies = [ [[package]] name = "winit-android" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ "android-activity", "bitflags 2.11.0", @@ -8604,7 +8599,6 @@ dependencies = [ [[package]] name = "winit-appkit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ "bitflags 2.11.0", "block2 0.6.2", @@ -8626,7 +8620,6 @@ dependencies = [ [[package]] name = "winit-common" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ "memmap2 0.9.10", "objc2 0.6.4", @@ -8641,7 +8634,6 @@ dependencies = [ [[package]] name = "winit-core" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ "bitflags 2.11.0", "cursor-icon", @@ -8655,7 +8647,6 @@ dependencies = [ [[package]] name = "winit-orbital" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ "bitflags 2.11.0", "dpi", @@ -8671,7 +8662,6 @@ dependencies = [ [[package]] name = "winit-uikit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ "bitflags 2.11.0", "block2 0.6.2", @@ -8691,7 +8681,6 @@ dependencies = [ [[package]] name = "winit-wayland" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ "ahash", "bitflags 2.11.0", @@ -8717,7 +8706,6 @@ dependencies = [ [[package]] name = "winit-web" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ "atomic-waker", "bitflags 2.11.0", @@ -8739,7 +8727,6 @@ dependencies = [ [[package]] name = "winit-win32" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ "bitflags 2.11.0", "cursor-icon", @@ -8755,7 +8742,6 @@ dependencies = [ [[package]] name = "winit-x11" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#a610ac9c7a72b39ff102ed4d946291618dc725b6" dependencies = [ "bitflags 2.11.0", "bytemuck", diff --git a/Cargo.toml b/Cargo.toml index fd6b9ecb..488eb21f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -279,7 +279,7 @@ cctk = { path = "../../cosmic-protocols/client-toolkit", package = "cosmic-clien # Yoda: default-features=false drops softbuffer's x11 / x11-dlopen (pulled # tiny-xlib + as-raw-xcb-connection). The wayland + wayland-dlopen features # are re-activated via iced_tiny_skia's own `wayland` feature propagation. -softbuffer = { git = "https://github.com/pop-os/softbuffer", tag = "cosmic-4.0", default-features = false } +softbuffer = { path = "../../softbuffer", default-features = false } syntect = "5.2" tokio = "1.0" tracing = "0.1" @@ -316,10 +316,29 @@ mime = { path = "../../window_clipboard/mime" } # pulls winit-x11, x11-dl, tiny-xlib, as-raw-xcb-connection. Our Wayland-only # fork doesn't need any of that — the wayland + wayland-dlopen features are # re-enabled via iced_winit's own feature propagation from libcosmic-yoda. -winit = { git = "https://github.com/pop-os/winit.git", tag = "cosmic-0.14", default-features = false } -winit-core = { git = "https://github.com/pop-os/winit.git", tag = "cosmic-0.14" } +winit = { path = "../../winit/winit", default-features = false } +winit-core = { path = "../../winit/winit-core" } cursor-icon = "1.1.0" +[patch.'https://github.com/pop-os/softbuffer'] +softbuffer = { path = "../../softbuffer" } + +[patch.'https://github.com/pop-os/smithay-clipboard'] +smithay-clipboard = { path = "../../smithay-clipboard" } + +[patch.'https://github.com/pop-os/winit.git'] +dpi = { path = "../../winit/dpi" } +winit = { path = "../../winit/winit" } +winit-android = { path = "../../winit/winit-android" } +winit-appkit = { path = "../../winit/winit-appkit" } +winit-common = { path = "../../winit/winit-common" } +winit-core = { path = "../../winit/winit-core" } +winit-orbital = { path = "../../winit/winit-orbital" } +winit-uikit = { path = "../../winit/winit-uikit" } +winit-wayland = { path = "../../winit/winit-wayland" } +winit-web = { path = "../../winit/winit-web" } +winit-win32 = { path = "../../winit/winit-win32" } +winit-x11 = { path = "../../winit/winit-x11" } [workspace.lints.rust] rust_2018_idioms = { level = "deny", priority = -1 } From a7d71d9aceddcdd6cad5628b6ca18aab89edfa97 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Wed, 27 May 2026 11:30:30 -0400 Subject: [PATCH 37/72] chore: modifiers event on keyboard enter and leave --- .../wayland/event_loop/state.rs | 8 +-- .../wayland/handlers/seat/keyboard.rs | 60 +++++++++++++++++-- .../wayland/handlers/seat/seat.rs | 5 +- 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index f99e48ba..e47caa94 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -30,7 +30,6 @@ use std::{ convert::Infallible, fmt::Debug, sync::{Arc, Mutex, atomic::AtomicU32}, - thread::panicking, time::Duration, }; use wayland_backend::client::ObjectId; @@ -71,7 +70,7 @@ use cctk::{ registry::RegistryState, seat::{ SeatState, - keyboard::KeyEvent, + keyboard::{KeyEvent, Modifiers}, pointer::{CursorIcon, PointerData, ThemedPointer}, touch::TouchData, }, @@ -97,7 +96,6 @@ use cctk::{ }; use iced_runtime::{ core::{self, Point, touch}, - keyboard::Modifiers, platform_specific::{ self, wayland::{ @@ -1469,7 +1467,7 @@ impl SctkState { // TODO how to handle this when there's no lock? if let Some((surface, _)) = self.get_lock_surface(id, &output) { let wl_surface = surface.wl_surface(); - + receive_frame(&mut self.frame_status, &wl_surface); } } @@ -1653,7 +1651,7 @@ impl SctkState { bg_effect_mgr.enqueue(id, rectangles.clone()); return Ok(()); } - + let s = if let Some(s) = self.popups.iter().find(|s| s.data.id == id) { s.popup.wl_surface() } else if let Some(s) = self.layer_surfaces.iter().find(|s| s.id == id) { diff --git a/winit/src/platform_specific/wayland/handlers/seat/keyboard.rs b/winit/src/platform_specific/wayland/handlers/seat/keyboard.rs index 5ff7fb4b..f83e1180 100644 --- a/winit/src/platform_specific/wayland/handlers/seat/keyboard.rs +++ b/winit/src/platform_specific/wayland/handlers/seat/keyboard.rs @@ -4,10 +4,46 @@ use crate::platform_specific::wayland::{ }; use cctk::sctk::{ delegate_keyboard, - seat::keyboard::{KeyboardHandler, Keysym}, + seat::keyboard::{KeyboardHandler, Keysym, Modifiers}, }; use cctk::sctk::{reexports::client::Proxy, seat::keyboard::RawModifiers}; +fn modifiers_from_keysyms( + keysyms: &[Keysym], + previous: Modifiers, +) -> Modifiers { + let mut modifiers = Modifiers { + caps_lock: previous.caps_lock, + num_lock: previous.num_lock, + ..Modifiers::default() + }; + + for keysym in keysyms { + match keysym.raw() { + xkeysym::key::Shift_L | xkeysym::key::Shift_R => { + modifiers.shift = true + } + xkeysym::key::Control_L | xkeysym::key::Control_R => { + modifiers.ctrl = true + } + xkeysym::key::Alt_L | xkeysym::key::Alt_R => modifiers.alt = true, + xkeysym::key::Super_L + | xkeysym::key::Super_R + | xkeysym::key::Hyper_L + | xkeysym::key::Hyper_R + | xkeysym::key::Meta_L + | xkeysym::key::Meta_R => modifiers.logo = true, + xkeysym::key::Caps_Lock | xkeysym::key::Shift_Lock => { + modifiers.caps_lock = true + } + xkeysym::key::Num_Lock => modifiers.num_lock = true, + _ => {} + } + } + + modifiers +} + impl KeyboardHandler for SctkState { fn enter( &mut self, @@ -17,9 +53,9 @@ impl KeyboardHandler for SctkState { surface: &cctk::sctk::reexports::client::protocol::wl_surface::WlSurface, _serial: u32, _raw: &[u32], - _keysyms: &[Keysym], + keysyms: &[Keysym], ) { - let (i, mut is_active, seat) = { + let (i, mut is_active, seat, modifiers) = { let (i, is_active, my_seat) = match self.seats.iter_mut().enumerate().find_map(|(i, s)| { if s.kbd.as_ref() == Some(keyboard) { @@ -41,9 +77,11 @@ impl KeyboardHandler for SctkState { surface }; _ = my_seat.kbd_focus.replace(surface.clone()); + let modifiers = modifiers_from_keysyms(keysyms, my_seat._modifiers); + my_seat._modifiers = modifiers; let seat = my_seat.seat.clone(); - (i, is_active, seat) + (i, is_active, seat, modifiers) }; if !is_active && self.seats[0].kbd_focus.is_none() { @@ -73,6 +111,12 @@ impl KeyboardHandler for SctkState { seat_id: seat.clone(), surface: surface.clone(), }); + self.sctk_events.push(SctkEvent::KeyboardEvent { + variant: KeyboardEventVariant::Modifiers(modifiers), + kbd_id: keyboard.clone(), + seat_id: seat.clone(), + surface: surface.clone(), + }); } } } @@ -126,6 +170,7 @@ impl KeyboardHandler for SctkState { if self.windows.iter().any(|w| w.window.id() == id) { continue; } + let modifiers = s._modifiers; self.sctk_events.push(SctkEvent::Winit( id, winit::event::WindowEvent::Focused(true), @@ -137,6 +182,12 @@ impl KeyboardHandler for SctkState { kbd_id: s.kbd.clone().unwrap(), seat_id: s.seat.clone(), surface: surface.clone(), + }); + self.sctk_events.push(SctkEvent::KeyboardEvent { + variant: KeyboardEventVariant::Modifiers(modifiers), + kbd_id: s.kbd.clone().unwrap(), + seat_id: s.seat.clone(), + surface: surface.clone(), }) } } @@ -248,6 +299,7 @@ impl KeyboardHandler for SctkState { }; let seat_id = my_seat.seat.clone(); let kbd_id = keyboard.clone(); + my_seat._modifiers = modifiers; if is_active { if let Some(surface) = my_seat.kbd_focus.clone() { diff --git a/winit/src/platform_specific/wayland/handlers/seat/seat.rs b/winit/src/platform_specific/wayland/handlers/seat/seat.rs index 2901ce8e..ee6b0e6e 100644 --- a/winit/src/platform_specific/wayland/handlers/seat/seat.rs +++ b/winit/src/platform_specific/wayland/handlers/seat/seat.rs @@ -4,10 +4,9 @@ use crate::platform_specific::wayland::{ }; use cctk::sctk::{ delegate_seat, - reexports::client::{protocol::wl_keyboard::WlKeyboard, Proxy}, - seat::{pointer::ThemeSpec, SeatHandler}, + reexports::client::{Proxy, protocol::wl_keyboard::WlKeyboard}, + seat::{SeatHandler, keyboard::Modifiers, pointer::ThemeSpec}, }; -use iced_runtime::keyboard::Modifiers; use std::sync::Arc; impl SeatHandler for SctkState { From 0094b347d408aabc78091f744cb4eac49de1a7e4 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Thu, 21 May 2026 17:38:04 -0600 Subject: [PATCH 38/72] fix: avoid deadlock in context menu rendering --- winit/src/platform_specific/wayland/event_loop/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winit/src/platform_specific/wayland/event_loop/mod.rs b/winit/src/platform_specific/wayland/event_loop/mod.rs index 61bf12ea..3949d270 100644 --- a/winit/src/platform_specific/wayland/event_loop/mod.rs +++ b/winit/src/platform_specific/wayland/event_loop/mod.rs @@ -538,7 +538,6 @@ impl SctkEventLoop { wake_up = true; _ = s.frame(&state.state.queue_handle, s.clone()); - _ = state.state.frame_status.remove(&id); _ = state.state.events_sender.unbounded_send( Control::Winit( winit::window::WindowId::from_raw( @@ -547,6 +546,7 @@ impl SctkEventLoop { winit::event::WindowEvent::RedrawRequested, ), ); + _ = state.state.frame_status.insert(id, state::FrameStatus::Received); } if wake_up { From dfcd989947a7493b73342732ace786c0af873261 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Wed, 27 May 2026 14:50:31 -0600 Subject: [PATCH 39/72] fix: present suboptimal frames --- wgpu/src/window/compositor.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index 4033aea4..f0595f2b 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -368,13 +368,14 @@ pub fn present( ) -> Result<(), compositor::SurfaceError> { match surface.get_current_texture() { Ok(frame) => { - if frame.suboptimal - || frame.texture.width() != viewport.physical_width() + if frame.texture.width() != viewport.physical_width() || frame.texture.height() != viewport.physical_height() { return Err(compositor::SurfaceError::Outdated); } + let suboptimal = frame.suboptimal; + let view = &frame .texture .create_view(&wgpu::TextureViewDescriptor::default()); @@ -390,6 +391,10 @@ pub fn present( on_pre_present(); frame.present(); + if suboptimal { + return Err(compositor::SurfaceError::Outdated); + } + Ok(()) } Err(error) => match error { From 9c748f1656bc15d159651eea0091c13c024ebc47 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Wed, 27 May 2026 17:25:49 -0400 Subject: [PATCH 40/72] Revert "fix: avoid deadlock in context menu rendering" This reverts commit 0094b347d408aabc78091f744cb4eac49de1a7e4. --- winit/src/platform_specific/wayland/event_loop/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winit/src/platform_specific/wayland/event_loop/mod.rs b/winit/src/platform_specific/wayland/event_loop/mod.rs index 3949d270..61bf12ea 100644 --- a/winit/src/platform_specific/wayland/event_loop/mod.rs +++ b/winit/src/platform_specific/wayland/event_loop/mod.rs @@ -538,6 +538,7 @@ impl SctkEventLoop { wake_up = true; _ = s.frame(&state.state.queue_handle, s.clone()); + _ = state.state.frame_status.remove(&id); _ = state.state.events_sender.unbounded_send( Control::Winit( winit::window::WindowId::from_raw( @@ -546,7 +547,6 @@ impl SctkEventLoop { winit::event::WindowEvent::RedrawRequested, ), ); - _ = state.state.frame_status.insert(id, state::FrameStatus::Received); } if wake_up { From 590e093086247dfc0b41580f752a4d59d5817a78 Mon Sep 17 00:00:00 2001 From: Gavin John Date: Fri, 29 May 2026 10:47:32 -0700 Subject: [PATCH 41/72] fix(text): don't reload cache every redraw I have >1000 fonts installed. COSMIC has always been somewhat laggy for me, but I had assumed it was just like that for everyone, or was the fault of my T480s. Eventually, when trying to diagnose some hitching, I ended up discovering that cosmic-launcher was consuming on average ~5% total CPU over time, which led me to discover that it was fetching all the fonts from disk and software rendering the fonts, every redraw, causing the high cpu usage *and* the stutters (as a result of hammering disk I/O). Oops. The fix is simple: just persist the cache across redraws. --- tiny_skia/src/text.rs | 11 ++++++++--- wgpu/src/text.rs | 5 ++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index add4dee8..dfd4d5f8 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -15,6 +15,7 @@ use std::collections::hash_map; pub struct Pipeline { glyph_cache: GlyphCache, cache: RefCell, + swash_cache: cosmic_text::SwashCache, } impl Pipeline { @@ -22,6 +23,7 @@ impl Pipeline { Pipeline { glyph_cache: GlyphCache::new(), cache: RefCell::new(Cache::new()), + swash_cache: cosmic_text::SwashCache::new(), } } @@ -54,6 +56,7 @@ impl Pipeline { draw( font_system.raw(), &mut self.glyph_cache, + &mut self.swash_cache, paragraph.buffer(), position, color, @@ -81,6 +84,7 @@ impl Pipeline { draw( font_system.raw(), &mut self.glyph_cache, + &mut self.swash_cache, editor.buffer(), position, color, @@ -142,6 +146,7 @@ impl Pipeline { draw( font_system, &mut self.glyph_cache, + &mut self.swash_cache, &entry.buffer, Point::new(x, y), color, @@ -165,6 +170,7 @@ impl Pipeline { draw( font_system.raw(), &mut self.glyph_cache, + &mut self.swash_cache, buffer, position, color, @@ -183,6 +189,7 @@ impl Pipeline { fn draw( font_system: &mut cosmic_text::FontSystem, glyph_cache: &mut GlyphCache, + swash_cache: &mut cosmic_text::SwashCache, buffer: &cosmic_text::Buffer, position: Point, color: Color, @@ -192,8 +199,6 @@ fn draw( ) { let position = position * transformation; - let mut swash = cosmic_text::SwashCache::new(); - for run in buffer.layout_runs() { for glyph in run.glyphs { let physical_glyph = glyph.physical( @@ -205,7 +210,7 @@ fn draw( physical_glyph.cache_key, glyph.color_opt.map(from_color).unwrap_or(color), font_system, - &mut swash, + swash_cache, ) { let pixmap = tiny_skia::PixmapRef::from_bytes( buffer, diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index b6d9e679..76b16c5c 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -308,6 +308,7 @@ pub struct State { prepare_layer: usize, cache: BufferCache, storage: Storage, + swash_cache: cryoglyph::SwashCache, } impl State { @@ -352,6 +353,7 @@ impl State { renderer, &mut atlas, &mut self.cache, + &mut self.swash_cache, text, layer_bounds * layer_transformation, layer_transformation * *transformation, @@ -448,6 +450,7 @@ fn prepare( renderer: &mut cryoglyph::TextRenderer, atlas: &mut cryoglyph::TextAtlas, buffer_cache: &mut BufferCache, + swash_cache: &mut cryoglyph::SwashCache, sections: &[Text], layer_bounds: Rectangle, layer_transformation: Transformation, @@ -643,6 +646,6 @@ fn prepare( atlas, viewport, text_areas, - &mut cryoglyph::SwashCache::new(), + swash_cache, ) } From ebb3b125bfc829617411f831afada122b6b4d02c Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Fri, 29 May 2026 16:43:44 -0400 Subject: [PATCH 42/72] Revert "fix(text): don't reload cache every redraw" This reverts commit 590e093086247dfc0b41580f752a4d59d5817a78. --- tiny_skia/src/text.rs | 11 +++-------- wgpu/src/text.rs | 5 +---- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index dfd4d5f8..add4dee8 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -15,7 +15,6 @@ use std::collections::hash_map; pub struct Pipeline { glyph_cache: GlyphCache, cache: RefCell, - swash_cache: cosmic_text::SwashCache, } impl Pipeline { @@ -23,7 +22,6 @@ impl Pipeline { Pipeline { glyph_cache: GlyphCache::new(), cache: RefCell::new(Cache::new()), - swash_cache: cosmic_text::SwashCache::new(), } } @@ -56,7 +54,6 @@ impl Pipeline { draw( font_system.raw(), &mut self.glyph_cache, - &mut self.swash_cache, paragraph.buffer(), position, color, @@ -84,7 +81,6 @@ impl Pipeline { draw( font_system.raw(), &mut self.glyph_cache, - &mut self.swash_cache, editor.buffer(), position, color, @@ -146,7 +142,6 @@ impl Pipeline { draw( font_system, &mut self.glyph_cache, - &mut self.swash_cache, &entry.buffer, Point::new(x, y), color, @@ -170,7 +165,6 @@ impl Pipeline { draw( font_system.raw(), &mut self.glyph_cache, - &mut self.swash_cache, buffer, position, color, @@ -189,7 +183,6 @@ impl Pipeline { fn draw( font_system: &mut cosmic_text::FontSystem, glyph_cache: &mut GlyphCache, - swash_cache: &mut cosmic_text::SwashCache, buffer: &cosmic_text::Buffer, position: Point, color: Color, @@ -199,6 +192,8 @@ fn draw( ) { let position = position * transformation; + let mut swash = cosmic_text::SwashCache::new(); + for run in buffer.layout_runs() { for glyph in run.glyphs { let physical_glyph = glyph.physical( @@ -210,7 +205,7 @@ fn draw( physical_glyph.cache_key, glyph.color_opt.map(from_color).unwrap_or(color), font_system, - swash_cache, + &mut swash, ) { let pixmap = tiny_skia::PixmapRef::from_bytes( buffer, diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index 76b16c5c..b6d9e679 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -308,7 +308,6 @@ pub struct State { prepare_layer: usize, cache: BufferCache, storage: Storage, - swash_cache: cryoglyph::SwashCache, } impl State { @@ -353,7 +352,6 @@ impl State { renderer, &mut atlas, &mut self.cache, - &mut self.swash_cache, text, layer_bounds * layer_transformation, layer_transformation * *transformation, @@ -450,7 +448,6 @@ fn prepare( renderer: &mut cryoglyph::TextRenderer, atlas: &mut cryoglyph::TextAtlas, buffer_cache: &mut BufferCache, - swash_cache: &mut cryoglyph::SwashCache, sections: &[Text], layer_bounds: Rectangle, layer_transformation: Transformation, @@ -646,6 +643,6 @@ fn prepare( atlas, viewport, text_areas, - swash_cache, + &mut cryoglyph::SwashCache::new(), ) } From 5013f63956d9797571cfcebba6778adf9c8c3d87 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Fri, 29 May 2026 17:16:30 -0600 Subject: [PATCH 43/72] improv: reuse loaded fonts by cosmic-text for svg renderer --- graphics/src/text.rs | 8 ++++++++ tiny_skia/src/vector.rs | 15 ++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/graphics/src/text.rs b/graphics/src/text.rs index 230a362d..910cbbde 100644 --- a/graphics/src/text.rs +++ b/graphics/src/text.rs @@ -161,6 +161,14 @@ impl FontSystem { &mut self.raw } + /// Returns a reference to the underlying [`fontdb::Database`]. + /// + /// Unlike going through [`raw`](Self::raw) and `db_mut`, this does not + /// clear `cosmic-text`'s internal font-match cache. + pub fn db(&self) -> &cosmic_text::fontdb::Database { + self.raw.db() + } + /// Loads a font from its bytes. pub fn load_font(&mut self, bytes: Cow<'static, [u8]>) { if let Cow::Borrowed(bytes) = bytes { diff --git a/tiny_skia/src/vector.rs b/tiny_skia/src/vector.rs index 59cd1993..2c3b219c 100644 --- a/tiny_skia/src/vector.rs +++ b/tiny_skia/src/vector.rs @@ -1,5 +1,6 @@ use crate::core::svg::{Data, Handle}; use crate::core::{Color, Rectangle, Size}; +use crate::graphics::text; use resvg::usvg; use rustc_hash::{FxHashMap, FxHashSet}; @@ -74,6 +75,7 @@ struct Cache { rasters: FxHashMap, raster_hits: FxHashSet, fontdb: Option>, + fontdb_version: Option, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -87,12 +89,15 @@ impl Cache { fn load(&mut self, handle: &Handle) -> Option<&usvg::Tree> { let id = handle.id(); - // TODO: Reuse `cosmic-text` font database - if self.fontdb.is_none() { - let mut fontdb = usvg::fontdb::Database::new(); - fontdb.load_system_fonts(); + // Reuse the font database already loaded by the `cosmic-text` font + // system. We clone it once and refresh only when a font is + // loaded (i.e. when the font system's version changes). + let font_system = text::font_system().read().expect("Read font system"); + let version = font_system.version(); - self.fontdb = Some(Arc::new(fontdb)); + if self.fontdb_version != Some(version) { + self.fontdb = Some(Arc::new(font_system.db().clone())); + self.fontdb_version = Some(version); } let options = usvg::Options { From dcf4cf01943b5a1baf7b7360ab7d604369a5c470 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Fri, 5 Jun 2026 19:20:37 -0400 Subject: [PATCH 44/72] improv: ignore duplicate surfaces and log a warning --- .../wayland/event_loop/state.rs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index e47caa94..6e39fdc2 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -508,6 +508,10 @@ pub struct SctkState { /// An error that occurred while running an application. #[derive(Debug, thiserror::Error)] pub enum PopupCreationError { + /// The requested ID already exists. + #[error("The requested ID already exists")] + AlreadyExists, + /// Positioner creation failed #[error("Positioner creation failed")] PositionerCreationFailed(GlobalError), @@ -528,6 +532,10 @@ pub enum PopupCreationError { /// An error that occurred while running an application. #[derive(Debug, thiserror::Error)] pub enum LayerSurfaceCreationError { + /// The requested ID already exists. + #[error("The requested ID already exists")] + AlreadyExists, + /// Layer shell is not supported by the compositor #[error("Layer shell is not supported by the compositor")] LayerShellNotSupported, @@ -544,6 +552,10 @@ pub enum LayerSurfaceCreationError { /// An error that occurred while running an application. #[derive(Debug, thiserror::Error)] pub enum SubsurfaceCreationError { + /// The requested ID already exists. + #[error("The requested ID already exists")] + AlreadyExists, + /// Subsurface creation failed #[error("Subsurface creation failed")] CreationFailed(GlobalError), @@ -682,6 +694,18 @@ impl SctkState { ), PopupCreationError, > { + if self.layer_surfaces.iter().any(|s| s.id == settings.id) + || self.windows.iter().any(|w| w.id == settings.id) + || self.popups.iter().any(|p| p.data.id == settings.id) + || self.subsurfaces.iter().any(|s| s.id == settings.id) + { + log::warn!( + "Popup surface with id {:?} already exists", + settings.id + ); + return Err(PopupCreationError::AlreadyExists); + } + let (parent, toplevel) = if let Some(parent) = self.layer_surfaces.iter().find(|l| l.id == settings.parent) { @@ -922,6 +946,15 @@ impl SctkState { IcedOutput::Output(output) => Some(output), }; + if self.layer_surfaces.iter().any(|s| s.id == id) + || self.windows.iter().any(|w| w.id == id) + || self.popups.iter().any(|p| p.data.id == id) + || self.subsurfaces.iter().any(|s| s.id == id) + { + log::warn!("Layer surface with id {id:?} already exists"); + return Err(LayerSurfaceCreationError::AlreadyExists); + } + let layer_shell = self .layer_shell .as_ref() @@ -1015,6 +1048,14 @@ impl SctkState { id: core::window::Id, output: &WlOutput, ) -> Option<(CommonSurface, Arc>)> { + if self.layer_surfaces.iter().any(|s| s.id == id) + || self.windows.iter().any(|w| w.id == id) + || self.popups.iter().any(|p| p.data.id == id) + || self.subsurfaces.iter().any(|s| s.id == id) + { + log::warn!("Lock surface with id {id:?} already exists"); + return None; + } if let Some(lock) = self.session_lock.as_ref() { let wl_surface = self.compositor_state.create_surface(&self.queue_handle); @@ -1755,6 +1796,14 @@ impl SctkState { let Some(subsurface_state) = self.subsurface_state.as_ref() else { return Err(SubsurfaceCreationError::Unsupported); }; + if self.layer_surfaces.iter().any(|s| s.id == settings.id) + || self.windows.iter().any(|w| w.id == settings.id) + || self.popups.iter().any(|p| p.data.id == settings.id) + || self.subsurfaces.iter().any(|s| s.id == settings.id) + { + log::warn!("Subsurface with id {:?} already exists", settings.id); + return Err(SubsurfaceCreationError::AlreadyExists); + } let size = settings.size.unwrap_or(Size::new(1., 1.)); let half_w = size.width / 2.; From f725961c8714b3e7f9257c70f44d9a5fb1589a07 Mon Sep 17 00:00:00 2001 From: Ilia Malanin Date: Tue, 9 Jun 2026 13:56:32 +0200 Subject: [PATCH 45/72] fix: reuse wgpu compositor across windows --- winit/src/lib.rs | 53 +++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 735d73aa..95df205b 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -864,28 +864,30 @@ async fn run_instance

( platform_specific_handler.send_wayland( platform_specific::Action::TrackWindow(window.clone(), id), ); - match create_compositor::

( - window.clone(), - CreateCompositor { - proxy: &proxy, - runtime: &mut runtime, - display_handle: &display_handle, - graphics_settings: &graphics_settings, - default_fonts: &default_fonts, - }, - ) - .await - { - Ok(comp) => { - compositor = Some(comp); - } - Err(error) => { - control_sender - .start_send(Control::Crash( - Error::GraphicsCreationFailed(error), - )) - .expect("Send control message"); - continue; + if compositor.is_none() { + match create_compositor::

( + window.clone(), + CreateCompositor { + proxy: &proxy, + runtime: &mut runtime, + display_handle: &display_handle, + graphics_settings: &graphics_settings, + default_fonts: &default_fonts, + }, + ) + .await + { + Ok(comp) => { + compositor = Some(comp); + } + Err(error) => { + control_sender + .start_send(Control::Crash( + Error::GraphicsCreationFailed(error), + )) + .expect("Send control message"); + continue; + } } } @@ -1014,6 +1016,7 @@ async fn run_instance

( &mut is_window_opening, &mut system_theme, &mut platform_specific_handler, + is_daemon, ); if exited { runtime.track(None.into_iter()); @@ -1171,6 +1174,7 @@ async fn run_instance

( &mut is_window_opening, &mut system_theme, &mut platform_specific_handler, + is_daemon, ); } @@ -1369,6 +1373,7 @@ async fn run_instance

( &mut is_window_opening, &mut system_theme, &mut platform_specific_handler, + is_daemon, ); } else { window.state.update(&program, window.raw.as_ref(), &event); @@ -1562,6 +1567,7 @@ async fn run_instance

( &mut is_window_opening, &mut system_theme, &mut platform_specific_handler, + is_daemon, ); if exited { runtime.track(None.into_iter()); @@ -2106,6 +2112,7 @@ fn run_action<'a, P, C>( is_window_opening: &mut bool, system_theme: &mut theme::Mode, platform_specific: &mut crate::platform_specific::PlatformSpecific, + is_daemon: bool, ) -> bool where P: Program, @@ -2190,7 +2197,7 @@ where )); } - if window_manager.is_empty() { + if window_manager.is_empty() && !is_daemon { *compositor = None; } } From c3c8fcf52cbe46c864459e74357dfe7985072a70 Mon Sep 17 00:00:00 2001 From: Ilia Malanin Date: Tue, 9 Jun 2026 14:06:09 +0200 Subject: [PATCH 46/72] refactor: wrap repeated run_action call in a macro --- winit/src/lib.rs | 94 ++++++++++++++---------------------------------- 1 file changed, 26 insertions(+), 68 deletions(-) diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 95df205b..410949ac 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -838,6 +838,28 @@ async fn run_instance

( log::info!("System theme: {system_theme:?}"); + macro_rules! run_action { + ($action:expr) => { + run_action( + $action, + &program, + &mut runtime, + &mut compositor, + &mut events, + &mut messages, + &mut clipboard, + &mut control_sender, + &mut user_interfaces, + &mut window_manager, + &mut ui_caches, + &mut is_window_opening, + &mut system_theme, + &mut platform_specific_handler, + is_daemon, + ) + }; + } + 'next_event: loop { // Empty the queue if possible let event = if let Ok(event) = event_receiver.try_recv() { @@ -1001,23 +1023,7 @@ async fn run_instance

( } } Event::UserEvent(action) => { - let exited = run_action( - action, - &program, - &mut runtime, - &mut compositor, - &mut events, - &mut messages, - &mut clipboard, - &mut control_sender, - &mut user_interfaces, - &mut window_manager, - &mut ui_caches, - &mut is_window_opening, - &mut system_theme, - &mut platform_specific_handler, - is_daemon, - ); + let exited = run_action!(action); if exited { runtime.track(None.into_iter()); } @@ -1159,23 +1165,7 @@ async fn run_instance

( continue; } - _ = run_action( - action, - &program, - &mut runtime, - &mut compositor, - &mut events, - &mut messages, - &mut clipboard, - &mut control_sender, - &mut user_interfaces, - &mut window_manager, - &mut ui_caches, - &mut is_window_opening, - &mut system_theme, - &mut platform_specific_handler, - is_daemon, - ); + _ = run_action!(action); } for (window_id, window) in window_manager.iter_mut() { @@ -1358,23 +1348,7 @@ async fn run_instance

( if matches!(event, winit::event::WindowEvent::CloseRequested) && window.exit_on_close_request { - _ = run_action( - Action::Window(runtime::window::Action::Close(id)), - &program, - &mut runtime, - &mut compositor, - &mut events, - &mut messages, - &mut clipboard, - &mut control_sender, - &mut user_interfaces, - &mut window_manager, - &mut ui_caches, - &mut is_window_opening, - &mut system_theme, - &mut platform_specific_handler, - is_daemon, - ); + _ = run_action!(Action::Window(runtime::window::Action::Close(id))); } else { window.state.update(&program, window.raw.as_ref(), &event); @@ -1552,23 +1526,7 @@ async fn run_instance

( )); for action in actions { - let exited = run_action( - action, - &program, - &mut runtime, - &mut compositor, - &mut events, - &mut messages, - &mut clipboard, - &mut control_sender, - &mut user_interfaces, - &mut window_manager, - &mut ui_caches, - &mut is_window_opening, - &mut system_theme, - &mut platform_specific_handler, - is_daemon, - ); + let exited = run_action!(action); if exited { runtime.track(None.into_iter()); } From 62b90179a298b06ed3e88362e08ef47f8557da27 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Wed, 10 Jun 2026 11:47:42 -0600 Subject: [PATCH 47/72] Fix List widget not updating children because iterator not consumed --- widget/src/list.rs | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/widget/src/list.rs b/widget/src/list.rs index de9fe9b8..d7cadd50 100644 --- a/widget/src/list.rs +++ b/widget/src/list.rs @@ -363,24 +363,25 @@ where let state = tree.state.downcast_mut::(); let offset = layout.position() - Point::ORIGIN; - self.visible_elements + for (element, (index, layout, tree)) in self + .visible_elements .iter_mut() .zip(&mut state.visible_layouts) - .map(|(element, (index, layout, tree))| { - element.as_widget_mut().update( - tree, - event, - Layout::with_offset( - offset + Vector::new(0.0, self.spacing * *index as f32), - layout, - ), - cursor, - renderer, - clipboard, - shell, - viewport, - ) - }); + { + element.as_widget_mut().update( + tree, + event, + Layout::with_offset( + offset + Vector::new(0.0, self.spacing * *index as f32), + layout, + ), + cursor, + renderer, + clipboard, + shell, + viewport, + ); + } if let Event::Window(window::Event::RedrawRequested(_)) = event { match &mut state.task { From 7afd9ee0f83cfd1a4e9f9b56cf0f365e5ae60347 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Fri, 19 Jun 2026 18:31:15 -0600 Subject: [PATCH 48/72] fix: add alt clipboard bindings for text_editor --- widget/src/text_editor.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index a8f243fa..34a8825f 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -1287,6 +1287,23 @@ impl Binding { return Some(binding); } + let alt_clipboard = match key.as_ref() { + keyboard::Key::Named(key::Named::Insert) if modifiers.shift() => { + Some(Self::Paste) + } + keyboard::Key::Named(key::Named::Insert) if modifiers.command() => { + Some(Self::Copy) + } + keyboard::Key::Named(key::Named::Delete) if modifiers.shift() => { + Some(Self::Cut) + } + _ => None, + }; + + if let Some(binding) = alt_clipboard { + return Some(binding); + } + #[cfg(target_os = "macos")] let modified_key = convert_macos_shortcut(&key, modifiers).unwrap_or(modified_key); From 9f410558611b6e7e1027a7b227a7fab0b9019b93 Mon Sep 17 00:00:00 2001 From: Hojjat Date: Mon, 29 Jun 2026 14:41:20 -0600 Subject: [PATCH 49/72] Revert "feat: add direct SCTK action sender for wayland popups" This reverts commit b007caba44b0be1d282edbe1cd6fcd440ef06eab. --- winit/src/platform_specific/wayland/mod.rs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/winit/src/platform_specific/wayland/mod.rs b/winit/src/platform_specific/wayland/mod.rs index 0ba156d7..9b3a7ec0 100644 --- a/winit/src/platform_specific/wayland/mod.rs +++ b/winit/src/platform_specific/wayland/mod.rs @@ -25,23 +25,10 @@ use std::{collections::HashMap, sync::Arc}; use subsurface_widget::{SubsurfaceInstance, SubsurfaceState}; use wayland_backend::client::ObjectId; use wayland_client::{Connection, Proxy}; -use std::sync::OnceLock; use winit::dpi::Size; use winit::event_loop::OwnedDisplayHandle; use winit::window::ImePurpose; -static SCTK_ACTION_SENDER: OnceLock> = OnceLock::new(); - -/// Sends a platform-specific wayland action directly to the SCTK event loop, -/// bypassing the async Task system. This is needed when widgets queue popup -/// actions outside of the normal message flow (e.g., text context menus that -/// don't publish app messages). -pub fn send_wayland_action_direct(action: iced_runtime::platform_specific::wayland::Action) { - if let Some(sender) = SCTK_ACTION_SENDER.get() { - _ = sender.send(Action::Action(action)); - } -} - pub(crate) enum Action { Action(iced_runtime::platform_specific::wayland::Action), SetCursor(CursorIcon), @@ -149,9 +136,6 @@ impl PlatformSpecific { self.wayland.display_handle.clone().unwrap(), ) .ok(); - if let Some(ref sender) = self.wayland.sender { - _ = SCTK_ACTION_SENDER.set(sender.clone()); - } self } From 1bcba7e30cb082df1629f8ecdb02123f1403439b Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Thu, 16 Apr 2026 23:01:58 -0400 Subject: [PATCH 50/72] wip: corner radius v2 --- Cargo.lock | 4 +- Cargo.toml | 2 +- src/lib.rs | 4 +- .../wayland/event_loop/mod.rs | 13 +- .../wayland/event_loop/state.rs | 123 ++++++++++++------ .../wayland/handlers/shell/corner_radius.rs | 55 +++++--- winit/src/platform_specific/wayland/mod.rs | 1 - 7 files changed, 137 insertions(+), 65 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 38f19187..11a85d77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1294,7 +1294,7 @@ dependencies = [ [[package]] name = "cosmic-client-toolkit" version = "0.2.0" -source = "git+https://github.com/pop-os/cosmic-protocols?rev=160b086#160b086abe03cd34a8a375d7fbe47b24308d1f38" +source = "git+https://github.com/pop-os/cosmic-protocols?rev=a7d2d7a#a7d2d7a6188425f699eaddf7a025617ce56068ae" dependencies = [ "bitflags 2.11.0", "cosmic-protocols", @@ -1307,7 +1307,7 @@ dependencies = [ [[package]] name = "cosmic-protocols" version = "0.2.0" -source = "git+https://github.com/pop-os/cosmic-protocols?rev=160b086#160b086abe03cd34a8a375d7fbe47b24308d1f38" +source = "git+https://github.com/pop-os/cosmic-protocols?rev=a7d2d7a#a7d2d7a6188425f699eaddf7a025617ce56068ae" dependencies = [ "bitflags 2.11.0", "wayland-backend", diff --git a/Cargo.toml b/Cargo.toml index e9f43f7f..b5e1b8d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -274,7 +274,7 @@ tiny-skia = { version = "0.11", default-features = false, features = [ "std", "simd", ] } -cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "c253ec1" } +cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "a7d2d7a" } softbuffer = { git = "https://github.com/pop-os/softbuffer", tag = "cosmic-4.0" } syntect = "5.2" tokio = "1.0" diff --git a/src/lib.rs b/src/lib.rs index 46685d76..6e57128b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -682,7 +682,9 @@ pub use error::Error; pub use event::Event; pub use executor::Executor; pub use font::Font; -pub use renderer::{Renderer, graphics::geometry}; +pub use renderer::Renderer; +#[cfg(feature = "canvas")] +pub use renderer::graphics::geometry; pub use task::Task; pub use window::Window; diff --git a/winit/src/platform_specific/wayland/event_loop/mod.rs b/winit/src/platform_specific/wayland/event_loop/mod.rs index 61bf12ea..fea1c28c 100644 --- a/winit/src/platform_specific/wayland/event_loop/mod.rs +++ b/winit/src/platform_specific/wayland/event_loop/mod.rs @@ -33,7 +33,7 @@ use cctk::{ reexports::{ calloop::{self, EventLoop}, client::{ - ConnectError, Connection, Proxy, globals::registry_queue_init, + Connection, Proxy, globals::registry_queue_init, }, }, registry::RegistryState, @@ -46,8 +46,6 @@ use cctk::{ }; use raw_window_handle::HasDisplayHandle; use state::{FrameStatus, SctkWindow, send_event}; -#[cfg(feature = "a11y")] -use std::sync::{Arc, Mutex}; use std::{ collections::{HashMap, HashSet}, fmt::Debug, @@ -71,8 +69,8 @@ pub struct SctkEventLoop { pub(crate) state: SctkState, } +#[derive(Debug)] pub enum Error { - Connect(ConnectError), Calloop(calloop::Error), Global(GlobalError), NoDisplayHandle, @@ -129,7 +127,7 @@ impl SctkEventLoop { crate::platform_specific::Action::ResizeWindow(id) => { if let Some((_, v)) = state.windows.iter() .find(|w| w.id == id) - .map(|w| w.corner_radius.as_ref()) + .map(|w| state.corner_radii.get(&id)) .unwrap_or_default() { _ = state.handle_action(iced_runtime::platform_specific::wayland::Action::RoundedCorners(id, *v)); } @@ -138,7 +136,7 @@ impl SctkEventLoop { window, id, ) => { - state.windows.push(SctkWindow { window, id, corner_radius: Default::default() }); + state.windows.push(SctkWindow { window, id }); if let Some(v) = state.pending_corner_radius.remove(&id) { _ = state.handle_action(iced_runtime::platform_specific::wayland::Action::RoundedCorners(id, Some(v))); } @@ -350,7 +348,7 @@ impl SctkEventLoop { ), corner_radius_manager: registry_state.bind_one::( &qh, - 1..=1, + 1..=2, (), ).ok(), toplevel_manager: ToplevelManagerState::try_new( @@ -377,6 +375,7 @@ impl SctkEventLoop { seats: Vec::new(), windows: Vec::new(), blur_surfaces: HashMap::new(), + corner_radii: HashMap::new(), layer_surfaces: Vec::new(), popups: Vec::new(), lock_surfaces: Vec::new(), diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index 6e39fdc2..11f987f9 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -1,10 +1,7 @@ use crate::{ Control, handlers::{ - activation::IcedRequestData, - ext_background_effect, - overlap::{OverlapNotificationV1, OverlapNotifyV1}, - text_input::{Preedit, TextInputManager}, + activation::IcedRequestData, ext_background_effect, overlap::{OverlapNotificationV1, OverlapNotifyV1}, shell::corner_radius::CornerRadiusWrapper, text_input::{Preedit, TextInputManager} }, platform_specific::{ Event, @@ -65,7 +62,7 @@ use cctk::{ wl_surface::{self, WlSurface}, wl_touch::WlTouch, }, - }, + }, protocols_wlr::layer_shell::v1::client::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1, }, registry::RegistryState, seat::{ @@ -341,22 +338,13 @@ pub struct SctkPopupData { pub(crate) grab: bool, } -#[derive(Debug)] -pub struct MyCosmicCornerRadiusToplevelV1(CosmicCornerRadiusToplevelV1); - -impl Drop for MyCosmicCornerRadiusToplevelV1 { - fn drop(&mut self) { - self.0.destroy(); - } -} #[derive(Debug, Clone)] -pub struct SctkCornerRadius(Arc); +pub struct SctkCornerRadius(Arc); pub struct SctkWindow { pub(crate) window: Arc, pub(crate) id: core::window::Id, - pub(crate) corner_radius: Option<(SctkCornerRadius, Option)>, } impl SctkWindow { @@ -444,6 +432,7 @@ pub struct SctkState { pub(crate) subsurfaces: Vec, pub(crate) lock_surfaces: Vec, pub(crate) blur_surfaces: HashMap>, + pub(crate) corner_radii: HashMap)>, pub(crate) touch_points: HashMap, /// Window updates, which are coming from SCTK or the compositor, which require @@ -1137,6 +1126,7 @@ impl SctkState { s.destroy(); } } + _ = self.corner_radii.remove(&id); let (removed, remaining): (Vec<_>, Vec<_>) = self .subsurfaces @@ -1396,6 +1386,8 @@ impl SctkState { s.destroy(); } } + _ = self.corner_radii.remove(&id); + let (removed, remaining): (Vec<_>, Vec<_>) = self .subsurfaces @@ -1524,6 +1516,8 @@ impl SctkState { s.destroy(); } } + _ = self.corner_radii.remove(&id); + let (removed, remaining): (Vec<_>, Vec<_>) = self .subsurfaces .drain(..) @@ -1609,6 +1603,8 @@ impl SctkState { s.destroy(); } } + _ = self.corner_radii.remove(&id); + if let Some((wl_surface, f)) = self.seats.iter_mut().find(|f| { f.kbd_focus.as_ref().is_some_and(|f| *f == destroyed) }).and_then(|f| Some((parent, &mut f.kbd_focus))) { @@ -1636,8 +1632,25 @@ impl SctkState { } Action::RoundedCorners(id, v) => { if let Some(manager) = self.corner_radius_manager.as_ref() { - if let Some(w) = self.windows.iter_mut().find(|w| w.id == id) { - let geo_size: LogicalSize = w.window.surface_size().cast::().to_logical(w.window.scale_factor()); + enum Surface { + Xdg(XdgSurface, Option), + Wlr(ZwlrLayerSurfaceV1), + } + let s = if let Some(w) = self.windows.iter_mut().find(|w| w.id == id) { + Some((Surface::Xdg(w.xdg_surface(&self.connection), Some(w.xdg_toplevel(&self.connection))), w.window.surface_size().cast::().to_logical(w.window.scale_factor()))) + } else if let Some(p) = self.popups.iter_mut().find(|w| w.data.id == id) { + let guard = p.common.lock().unwrap(); + Some((Surface::Xdg(p.popup.xdg_surface().clone(), None), guard.size.cast::())) + } else if let Some(l) = self.layer_surfaces.iter_mut().find(|l| l.id == id) { + let guard = l.common.lock().unwrap(); + match l.surface.kind() { + SurfaceKind::Wlr(l) => Some((Surface::Wlr(l.clone()), guard.size.cast::())), + _ => None + } + } else { + None + }; + if let Some((s, geo_size)) = s { let half_min_dim = (geo_size.width as u32).min(geo_size.height as u32) / 2; if let Some(radii) = v { @@ -1647,37 +1660,73 @@ impl SctkState { bottom_right: radii.bottom_right.min(half_min_dim), bottom_left: radii.bottom_left.min(half_min_dim), }; - if let Some((protocol_object, corner_radii)) = w.corner_radius.as_mut() { + if let Some((protocol_object, corner_radii)) = self.corner_radii.get_mut(&id) { if *corner_radii != Some(adjusted_radii) { - protocol_object.0.0.set_radius( + match protocol_object.0.as_ref() { + CornerRadiusWrapper::Xdg(protocol_object) => protocol_object.set_radius( + adjusted_radii.top_left, + adjusted_radii.top_right, + adjusted_radii.bottom_right, + adjusted_radii.bottom_left, + ), + CornerRadiusWrapper::Wlr(protocol_object) => protocol_object.set_radius( + adjusted_radii.top_left, + adjusted_radii.top_right, + adjusted_radii.bottom_right, + adjusted_radii.bottom_left, + ) + }; + *corner_radii = Some(adjusted_radii.clone()); + } + } else { + + let protocol_object = match s { + Surface::Xdg(s, w) => { + if manager.version() == 1 { + if let Some(w) = w { + CornerRadiusWrapper::Xdg(manager.get_corner_radius(&w, &self.queue_handle, ())) + } else { + log::error!("Corner radius is not supported for popups on xdg shell v1"); + return Ok(()); + } + } else { + CornerRadiusWrapper::Xdg(manager.get_corner_radius_surface(&s, &self.queue_handle, ()))} + } + Surface::Wlr(l) => { + if manager.version() == 1 { + return Ok(()); + } + CornerRadiusWrapper::Wlr(manager.get_corner_radius_layer(&l, &self.queue_handle, ()))} + }; + match &protocol_object { + CornerRadiusWrapper::Xdg(protocol_object) => protocol_object.set_radius( adjusted_radii.top_left, adjusted_radii.top_right, adjusted_radii.bottom_right, adjusted_radii.bottom_left, - ); - *corner_radii = Some(adjusted_radii.clone()); - } - } else { - let toplevel = w.xdg_toplevel(&self.connection); - - let protocol_object = manager.get_corner_radius(&toplevel, &self.queue_handle, ()); - - protocol_object.set_radius( - adjusted_radii.top_left, - adjusted_radii.top_right, - adjusted_radii.bottom_right, - adjusted_radii.bottom_left, - ); - w.corner_radius = Some((SctkCornerRadius(Arc::new(MyCosmicCornerRadiusToplevelV1( protocol_object))), Some(adjusted_radii.clone()))); + ), + CornerRadiusWrapper::Wlr(protocol_object) => protocol_object.set_radius( + adjusted_radii.top_left, + adjusted_radii.top_right, + adjusted_radii.bottom_right, + adjusted_radii.bottom_left, + ) + }; + _ = self.corner_radii.insert(id, (SctkCornerRadius(Arc::new(protocol_object)), Some(adjusted_radii.clone()))); } } else { - if let Some(old) = w.corner_radius.as_mut() { - old.0.0.as_ref().0.unset_radius(); + if let Some(old) = self.corner_radii.get_mut(&id) { + match old.0.0.as_ref() { + CornerRadiusWrapper::Xdg(protocol_object) => protocol_object.unset_radius(), + CornerRadiusWrapper::Wlr(protocol_object) => { + protocol_object.unset_radius() + } + }; old.1 = None; } } } else { - if let Some(v) = v{ + if let Some(v) = v { _ = self.pending_corner_radius.insert(id, v); } else { _ = self.pending_corner_radius.remove(&id); diff --git a/winit/src/platform_specific/wayland/handlers/shell/corner_radius.rs b/winit/src/platform_specific/wayland/handlers/shell/corner_radius.rs index bd7d2409..c4bdda88 100644 --- a/winit/src/platform_specific/wayland/handlers/shell/corner_radius.rs +++ b/winit/src/platform_specific/wayland/handlers/shell/corner_radius.rs @@ -1,17 +1,29 @@ -use cctk::{sctk, cosmic_protocols::{ - corner_radius::v1::client::{ +use cctk::{ + cosmic_protocols::corner_radius::v1::client::{ + cosmic_corner_radius_layer_v1::CosmicCornerRadiusLayerV1, cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1, }, - overlap_notify::v1::client::zcosmic_overlap_notification_v1::ZcosmicOverlapNotificationV1, -}}; -use sctk::reexports::{ - client::{Connection, Dispatch, Proxy}, - + sctk, }; +use sctk::reexports::client::{Connection, Dispatch, Proxy}; use crate::event_loop::state::SctkState; -use crate::platform_specific::wayland::SctkEvent; + +#[derive(Debug)] +pub enum CornerRadiusWrapper { + Xdg(CosmicCornerRadiusToplevelV1), + Wlr(CosmicCornerRadiusLayerV1), +} + +impl Drop for CornerRadiusWrapper { + fn drop(&mut self) { + match self { + Self::Xdg(c) => c.destroy(), + Self::Wlr(c) => c.destroy(), + }; + } +} impl Dispatch for SctkState { fn event( @@ -21,15 +33,11 @@ impl Dispatch for SctkState { _data: &(), _conn: &Connection, _qhandle: &sctk::reexports::client::QueueHandle, - ) {} + ) { + } } -impl - Dispatch< - CosmicCornerRadiusToplevelV1, - (), - > for SctkState -{ +impl Dispatch for SctkState { fn event( state: &mut Self, _proxy: &CosmicCornerRadiusToplevelV1, @@ -39,7 +47,22 @@ impl _qhandle: &sctk::reexports::client::QueueHandle, ) { match event { - _ => unimplemented!() + _ => unimplemented!(), + } + } +} + +impl Dispatch for SctkState { + fn event( + state: &mut Self, + _proxy: &CosmicCornerRadiusLayerV1, + event: ::Event, + _data: &(), + _conn: &Connection, + _qhandle: &sctk::reexports::client::QueueHandle, + ) { + match event { + _ => unimplemented!(), } } } diff --git a/winit/src/platform_specific/wayland/mod.rs b/winit/src/platform_specific/wayland/mod.rs index 9b3a7ec0..bbbce8f1 100644 --- a/winit/src/platform_specific/wayland/mod.rs +++ b/winit/src/platform_specific/wayland/mod.rs @@ -128,7 +128,6 @@ impl PlatformSpecific { }; self.wayland.display_handle = Some(display); self.wayland.proxy = Some(raw); - // TODO remove this self.wayland.sender = crate::platform_specific::event_loop::SctkEventLoop::new( self.wayland.winit_event_sender.clone().unwrap(), From a63d57261f07b86f3237ce4be053efa94cb33dbe Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Fri, 17 Apr 2026 13:41:09 -0400 Subject: [PATCH 51/72] blur enabled event --- core/src/event/wayland/mod.rs | 2 ++ .../wayland/handlers/ext_background_effect.rs | 14 ++++++++--- .../platform_specific/wayland/sctk_event.rs | 25 ++++++------------- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/core/src/event/wayland/mod.rs b/core/src/event/wayland/mod.rs index 03e74407..5050ce66 100644 --- a/core/src/event/wayland/mod.rs +++ b/core/src/event/wayland/mod.rs @@ -46,4 +46,6 @@ pub enum Event { Subsurface(SubsurfaceEvent), /// Keyboard inhibit shortcuts ShortcutsInhibited(bool), + /// Blur Support Enabled + BlurEnabled, } diff --git a/winit/src/platform_specific/wayland/handlers/ext_background_effect.rs b/winit/src/platform_specific/wayland/handlers/ext_background_effect.rs index 03a80da9..2d0df67a 100644 --- a/winit/src/platform_specific/wayland/handlers/ext_background_effect.rs +++ b/winit/src/platform_specific/wayland/handlers/ext_background_effect.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use cctk::sctk; +use iced_futures::futures::SinkExt; use iced_runtime::core::Rectangle; use iced_runtime::platform_specific::wayland::Action; use sctk::globals::GlobalData; @@ -11,7 +12,7 @@ use wayland_protocols::ext::background_effect::v1::client::ext_background_effect use wayland_protocols::ext::background_effect::v1::client::ext_background_effect_surface_v1::ExtBackgroundEffectSurfaceV1; use crate::event_loop::state::SctkState; -use crate::window; +use crate::{platform_specific, window}; #[derive(Debug, Clone)] pub struct ExtBackgroundEffectManager { @@ -70,8 +71,15 @@ impl Dispatch state.ext_background_effect_manager.as_mut() { bg_effect_mgr.capabilities = capability; - queued_actions = - bg_effect_mgr.queued_blur_actions.drain().collect(); + if capability.contains(Capability::Blur) { + queued_actions = bg_effect_mgr + .queued_blur_actions + .drain() + .collect(); + state + .sctk_events + .push(crate::sctk_event::SctkEvent::Blur); + } } for (id, rects) in queued_actions { _ = state.handle_action(Action::BlurSurface(id, rects)); diff --git a/winit/src/platform_specific/wayland/sctk_event.rs b/winit/src/platform_specific/wayland/sctk_event.rs index 8845b0c9..2ac54bed 100755 --- a/winit/src/platform_specific/wayland/sctk_event.rs +++ b/winit/src/platform_specific/wayland/sctk_event.rs @@ -68,10 +68,8 @@ use cctk::{ xdg::{popup::PopupConfigure, window::WindowConfigure}, }, }, - wayland_client::protocol::wl_subsurface::WlSubsurface, }; use std::{ - any::Any, collections::HashMap, num::NonZeroU32, sync::{Arc, Mutex}, @@ -98,9 +96,7 @@ use super::{ #[derive(Debug, Clone)] pub enum SctkEvent { - // - // Input events - // + Blur, SeatEvent { variant: SeatEventVariant, id: WlSeat, @@ -122,11 +118,6 @@ pub enum SctkEvent { seat_id: WlSeat, surface: WlSurface, }, - // TODO data device & touch - - // - // Surface Events - // WindowEvent { variant: WindowEventVariant, id: WlSurface, @@ -167,10 +158,6 @@ pub enum SctkEvent { }, SubsurfaceEvent(SubsurfaceEventVariant), - - // - // output events - // NewOutput { id: WlOutput, info: Option, @@ -180,9 +167,7 @@ pub enum SctkEvent { info: OutputInfo, }, RemovedOutput(WlOutput), - // - // compositor events - // + ScaleFactorChanged { factor: f64, id: WlOutput, @@ -1738,6 +1723,12 @@ impl SctkEvent { ), ), )), + SctkEvent::Blur => events.push(( + None, + iced_runtime::core::Event::PlatformSpecific( + PlatformSpecific::Wayland(wayland::Event::BlurEnabled), + ), + )), } } } From e0c7d353aa3915a7543c253679f5038703f20436 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Fri, 17 Apr 2026 13:41:21 -0400 Subject: [PATCH 52/72] better handle pending corners --- .../wayland/event_loop/state.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index 11f987f9..ff6e892a 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -1099,6 +1099,12 @@ impl SctkState { id: wl_surface.clone(), } ); + if let Some(corners) = self.pending_corner_radius.remove(&id) { + self.handle_action(Action::RoundedCorners( + id, + Some(corners), + ))?; + } } } platform_specific::wayland::layer_surface::Action::Size { @@ -1318,6 +1324,12 @@ impl SctkState { SctkEvent::PopupEvent { variant: crate::platform_specific::wayland::sctk_event::PopupEventVariant::Created(queue_handle.clone(), surface, id, common, state.connection.display()), toplevel_id, parent_id, id: wl_surface }); + if let Some(corners) = state.pending_corner_radius.remove(&id) { + state.handle_action(Action::RoundedCorners ( + id, + Some(corners), + )); + } } Err(err) => { log::error!("Failed to create popup. {err:?}"); @@ -1327,7 +1339,6 @@ impl SctkState { } }); } - // log::error!("Invalid popup Id {:?}", popup.id); } else { self.pending_popup = None; match self.get_popup(settings) { @@ -1337,6 +1348,12 @@ impl SctkState { SctkEvent::PopupEvent { variant: crate::platform_specific::wayland::sctk_event::PopupEventVariant::Created(self.queue_handle.clone(), surface, id, common, self.connection.display()), toplevel_id, parent_id, id: wl_surface }); + if let Some(corners) = self.pending_corner_radius.remove(&id) { + self.handle_action(Action::RoundedCorners ( + id, + Some(corners), + )); + } } Err(err) => { log::error!("Failed to create popup. {err:?}"); From f6fa506f6cc60774fd8606125d005ba9f5074565 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Mon, 20 Apr 2026 15:33:26 -0400 Subject: [PATCH 53/72] chore(layer shell): add padding action --- .../wayland/layer_surface.rs | 43 ++++++++++++++----- .../wayland/commands/layer_surface.rs | 15 ++++++- .../wayland/event_loop/state.rs | 8 ++++ 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/runtime/src/platform_specific/wayland/layer_surface.rs b/runtime/src/platform_specific/wayland/layer_surface.rs index 4745ef67..6e5f3e9e 100644 --- a/runtime/src/platform_specific/wayland/layer_surface.rs +++ b/runtime/src/platform_specific/wayland/layer_surface.rs @@ -6,8 +6,8 @@ use cctk::sctk::{ }; use iced_core::layout::Limits; -use iced_core::window::Id; use iced_core::Rectangle; +use iced_core::window::Id; /// output for layer surface #[derive(Debug, Clone)] @@ -150,6 +150,13 @@ pub enum Action { /// layer of the layer surface layer: Layer, }, + /// padding of the surface geometry + Padding { + /// id of the layer surface + id: Id, + /// padding of the surface geometry + padding: IcedMargin, + }, } impl fmt::Debug for Action { @@ -162,35 +169,51 @@ impl fmt::Debug for Action { ), Action::Size { id, width, height } => write!( f, - "Action::LayerSurfaceAction::Size {{ id: {:#?}, width: {:?}, height: {:?} }}", id, width, height + "Action::LayerSurfaceAction::Size {{ id: {:#?}, width: {:?}, height: {:?} }}", + id, width, height ), Action::Destroy(id) => write!( f, - "Action::LayerSurfaceAction::Destroy {{ id: {:#?} }}", id + "Action::LayerSurfaceAction::Destroy {{ id: {:#?} }}", + id ), Action::Anchor { id, anchor } => write!( f, - "Action::LayerSurfaceAction::Anchor {{ id: {:#?}, anchor: {:?} }}", id, anchor + "Action::LayerSurfaceAction::Anchor {{ id: {:#?}, anchor: {:?} }}", + id, anchor ), Action::ExclusiveZone { id, exclusive_zone } => write!( f, - "Action::LayerSurfaceAction::ExclusiveZone {{ id: {:#?}, exclusive_zone: {exclusive_zone} }}", id + "Action::LayerSurfaceAction::ExclusiveZone {{ id: {:#?}, exclusive_zone: {exclusive_zone} }}", + id ), Action::Margin { id, margin } => write!( f, - "Action::LayerSurfaceAction::Margin {{ id: {:#?}, margin: {:?} }}", id, margin + "Action::LayerSurfaceAction::Margin {{ id: {:#?}, margin: {:?} }}", + id, margin ), - Action::KeyboardInteractivity { id, keyboard_interactivity } => write!( + Action::KeyboardInteractivity { + id, + keyboard_interactivity, + } => write!( f, - "Action::LayerSurfaceAction::KeyboardInteractivity {{ id: {:#?}, keyboard_interactivity: {:?} }}", id, keyboard_interactivity + "Action::LayerSurfaceAction::KeyboardInteractivity {{ id: {:#?}, keyboard_interactivity: {:?} }}", + id, keyboard_interactivity ), Action::InputZone { id, zone } => write!( f, - "Action::LayerSurfaceAction::InputZone {{ id: {:#?}, zone: {:?} }}", id, zone + "Action::LayerSurfaceAction::InputZone {{ id: {:#?}, zone: {:?} }}", + id, zone ), Action::Layer { id, layer } => write!( f, - "Action::LayerSurfaceAction::Layer {{ id: {:#?}, layer: {:?} }}", id, layer + "Action::LayerSurfaceAction::Layer {{ id: {:#?}, layer: {:?} }}", + id, layer + ), + Action::Padding { id, padding } => write!( + f, + "Action::LayerSurfaceAction::Padding {{ id: {:#?}, padding: {:?} }}", + id, padding ), } } diff --git a/winit/src/platform_specific/wayland/commands/layer_surface.rs b/winit/src/platform_specific/wayland/commands/layer_surface.rs index 839db95c..cdb4e93d 100644 --- a/winit/src/platform_specific/wayland/commands/layer_surface.rs +++ b/winit/src/platform_specific/wayland/commands/layer_surface.rs @@ -2,7 +2,7 @@ use crate::core::window::Id as SurfaceId; use iced_runtime::{ - self, + self, Action, Task, platform_specific::{ self, wayland::{ @@ -10,7 +10,7 @@ use iced_runtime::{ layer_surface::{IcedMargin, SctkLayerSurfaceSettings}, }, }, - task, Action, Task, + task, }; pub use cctk::sctk::shell::wlr_layer::{Anchor, KeyboardInteractivity, Layer}; @@ -114,3 +114,14 @@ pub fn set_layer(id: SurfaceId, layer: Layer) -> Task { )), )) } + +pub fn set_padding( + id: SurfaceId, + padding: IcedMargin, +) -> Task { + task::effect(Action::PlatformSpecific( + platform_specific::Action::Wayland(wayland::Action::LayerSurface( + wayland::layer_surface::Action::Padding { id, padding }, + )), + )) +} diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index ff6e892a..d0159a35 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -1229,6 +1229,14 @@ impl SctkState { } }, + platform_specific::wayland::layer_surface::Action::Padding { id, padding } => { + // corner radius padding + if let Some((protocol_object, _)) = self.corner_radii.get_mut(&id) { + if let CornerRadiusWrapper::Wlr(protocol_object) = protocol_object.0.as_ref() { + protocol_object.set_padding(padding.top, padding.right, padding.bottom, padding.left); + } + } + }, }, Action::Popup(action) => match action { platform_specific::wayland::popup::Action::Popup { popup: settings } => { From 6521f7fa20a891d61f1c8782f78e5435968f1f48 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Sun, 10 May 2026 22:36:29 -0400 Subject: [PATCH 54/72] fix: improved layer surface popup cleanup --- winit/src/platform_specific/wayland/event_loop/state.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index d0159a35..dc793561 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -1124,6 +1124,12 @@ impl SctkState { } }, platform_specific::wayland::layer_surface::Action::Destroy(id) => { + if let Some(p) = self + .popups + .iter().find_map(|p| + self.layer_surfaces.iter().find_map(|l| if l.id == id && l.surface.wl_surface() == p.data.parent.wl_surface() {Some(p.data.id)} else {None})) { + _ = self.handle_action(Action::Popup(platform_specific::wayland::popup::Action::Destroy { id: p })); + } if let Some(i) = self.layer_surfaces.iter().position(|l| l.id == id) { let l = self.layer_surfaces.remove(i); @@ -1155,6 +1161,8 @@ impl SctkState { if let Some(destroyed) = self.id_map.remove(&l.surface.wl_surface().id()) { _ = self.destroyed.insert(destroyed); } + + send_event(&self.events_sender, &self.proxy, SctkEvent::LayerSurfaceEvent { variant: LayerSurfaceEventVariant::Done, id: l.surface.wl_surface().clone(), From b8b0804140e8ade4fb2058eff173b4cd450a7b83 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Tue, 19 May 2026 14:47:13 -0400 Subject: [PATCH 55/72] fix(overlap): fix check for disabling --- winit/src/platform_specific/wayland/event_loop/state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index dc793561..998a599a 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -1590,7 +1590,7 @@ impl SctkState { }; let notification = overlap_notify_state.notify.notify_on_overlap(wlr, &self.queue_handle, OverlapNotificationV1 { surface: layer_surface.surface.wl_surface().clone() }); _ = self.overlap_notifications.insert(my_id, notification); - } else { + } else if !enabled { _ = self.overlap_notifications.remove(&my_id); } } else { From 6be49cb530e76c78ac767e89cd9f869533409476 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Thu, 21 May 2026 14:10:28 -0400 Subject: [PATCH 56/72] blur command helper --- .../platform_specific/wayland/commands/blur.rs | 17 +++++++++++++++++ .../platform_specific/wayland/commands/mod.rs | 1 + 2 files changed, 18 insertions(+) create mode 100644 winit/src/platform_specific/wayland/commands/blur.rs diff --git a/winit/src/platform_specific/wayland/commands/blur.rs b/winit/src/platform_specific/wayland/commands/blur.rs new file mode 100644 index 00000000..e9a73646 --- /dev/null +++ b/winit/src/platform_specific/wayland/commands/blur.rs @@ -0,0 +1,17 @@ +use iced_futures::core::window; +use iced_runtime::{ + self, Action, Task, + platform_specific::{self, wayland}, + task, +}; + +pub fn blur( + id: window::Id, + blur: Option>, +) -> Task<()> { + task::oneshot(|_| { + Action::PlatformSpecific(platform_specific::Action::Wayland( + wayland::Action::BlurSurface(id, blur), + )) + }) +} diff --git a/winit/src/platform_specific/wayland/commands/mod.rs b/winit/src/platform_specific/wayland/commands/mod.rs index 191dc3a5..cd6832c7 100644 --- a/winit/src/platform_specific/wayland/commands/mod.rs +++ b/winit/src/platform_specific/wayland/commands/mod.rs @@ -1,6 +1,7 @@ //! Interact with the wayland objects of your application. pub mod activation; +pub mod blur; pub mod corner_radius; pub mod keyboard_shortcuts_inhibit; pub mod layer_surface; From 5cc9f8d621df536facf605adcee3a25c25666e9f Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Thu, 21 May 2026 14:11:20 -0400 Subject: [PATCH 57/72] fix: single blur surface per wl surface --- .../wayland/event_loop/state.rs | 72 ++++++------------- 1 file changed, 23 insertions(+), 49 deletions(-) diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index 998a599a..0fb1a132 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -431,7 +431,7 @@ pub struct SctkState { pub(crate) popups: Vec, pub(crate) subsurfaces: Vec, pub(crate) lock_surfaces: Vec, - pub(crate) blur_surfaces: HashMap>, + pub(crate) blur_surfaces: HashMap, pub(crate) corner_radii: HashMap)>, pub(crate) touch_points: HashMap, @@ -1134,9 +1134,7 @@ impl SctkState { let l = self.layer_surfaces.remove(i); if let Some(blurred) = self.blur_surfaces.remove(&l.id) { - for s in blurred { - s.destroy(); - } + blurred.destroy(); } _ = self.corner_radii.remove(&id); @@ -1415,9 +1413,7 @@ impl SctkState { } if let Some(blurred) = self.blur_surfaces.remove(&id) { - for s in blurred { - s.destroy(); - } + blurred.destroy(); } _ = self.corner_radii.remove(&id); @@ -1545,9 +1541,7 @@ impl SctkState { { let surface = self.lock_surfaces.remove(i); if let Some(blurred) = self.blur_surfaces.remove(&surface.id) { - for s in blurred { - s.destroy(); - } + blurred.destroy(); } _ = self.corner_radii.remove(&id); @@ -1632,9 +1626,7 @@ impl SctkState { } for (destroyed, parent, id) in destroyed { if let Some(blurred) = self.blur_surfaces.remove(&id) { - for s in blurred { - s.destroy(); - } + blurred.destroy(); } _ = self.corner_radii.remove(&id); @@ -1790,45 +1782,27 @@ impl SctkState { let existing_blur = self.blur_surfaces.entry(id); match (existing_blur, rectangles) { (Entry::Occupied(occupied_entry), None) => { - let blur_surfaces = occupied_entry.remove(); - for region in blur_surfaces { - region.destroy(); - } + let blur_surface = occupied_entry.remove(); + blur_surface.destroy(); }, (Entry::Occupied(mut occupied_entry), Some(rectangles)) => { - let blur_surfaces = occupied_entry.get_mut(); - let regions = rectangles.into_iter().map(|rect| { - let region = self + let blur_surface = occupied_entry.get_mut(); + let region = self .compositor_state .wl_compositor() .create_region(&self.queue_handle, ()); + for rect in rectangles.into_iter() { region.add( rect.x.round() as i32, rect.y.round() as i32, rect.width.round() as i32, rect.height.round() as i32, ); - region - }).collect::>(); - if regions.len() > blur_surfaces.len() { - // add extra blur surfaces if needed - for _ in blur_surfaces.len()..regions.len() { - let Some(extra_region) = self.ext_background_effect_manager.as_mut().map(|mgr| mgr.blur(s, &self.queue_handle)) else { - log::error!("Failed to create blur effect for surface"); - return Ok(()); - }; - blur_surfaces.push(extra_region); - } - } else if regions.len() < blur_surfaces.len() { - for surface in blur_surfaces.iter().skip(regions.len()) { - surface.destroy(); - } } - + // update existing blur surfaces - for (blur_surface, region) in blur_surfaces.iter().zip(regions.into_iter()) { - blur_surface.set_blur_region(Some(®ion)); - } + blur_surface.set_blur_region(Some(®ion)); + }, (Entry::Vacant(..), None) => { // nothing to remove @@ -1838,23 +1812,23 @@ impl SctkState { log::error!("Blur effect is not supported."); return Ok(()); } - let blur_surfaces = rectangles.into_iter().map(|rect| { let region = self .compositor_state .wl_compositor() .create_region(&self.queue_handle, ()); - region.add( - rect.x.round() as i32, - rect.y.round() as i32, - rect.width.round() as i32, - rect.height.round() as i32, - ); + for rect in rectangles { + region.add( + rect.x.round() as i32, + rect.y.round() as i32, + rect.width.round() as i32, + rect.height.round() as i32, + ); + } + let blur_manager = self.ext_background_effect_manager.as_mut().unwrap(); let blur_surface = blur_manager.blur(s, &self.queue_handle); blur_surface.set_blur_region(Some(®ion)); - blur_surface - }).collect::>(); - _ = vacant_entry.insert(blur_surfaces); + _ = vacant_entry.insert(blur_surface); }, } }, From 46781102fe38b1bc26e6486085ea5446230293f3 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Thu, 28 May 2026 19:21:54 -0400 Subject: [PATCH 58/72] fix: set blur and corners on creation --- .../wayland/event_loop/mod.rs | 1 + .../wayland/event_loop/state.rs | 180 ++++++++++-------- 2 files changed, 100 insertions(+), 81 deletions(-) diff --git a/winit/src/platform_specific/wayland/event_loop/mod.rs b/winit/src/platform_specific/wayland/event_loop/mod.rs index fea1c28c..b4589840 100644 --- a/winit/src/platform_specific/wayland/event_loop/mod.rs +++ b/winit/src/platform_specific/wayland/event_loop/mod.rs @@ -401,6 +401,7 @@ impl SctkEventLoop { preedit: None, pending_delete: None, pending_commit: None, + pending_blur: HashMap::new(), }, _features: Default::default(), }; diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index 0fb1a132..d66f99c5 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -39,15 +39,12 @@ use cctk::{ cosmic_protocols::{ corner_radius::v1::client::{ cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, - cosmic_corner_radius_toplevel_v1::CosmicCornerRadiusToplevelV1, }, overlap_notify::v1::client::zcosmic_overlap_notification_v1::ZcosmicOverlapNotificationV1, - }, - sctk::{ + }, sctk::{ activation::{ActivationState, RequestData}, compositor::CompositorState, error::GlobalError, - globals::GlobalData, output::OutputState, reexports::{ calloop::{LoopHandle, timer::TimeoutAction}, @@ -87,9 +84,7 @@ use cctk::{ }, }, shm::{Shm, multi::MultiPool}, - }, - toplevel_info::ToplevelInfoState, - toplevel_management::ToplevelManagerState, + }, toplevel_info::ToplevelInfoState, toplevel_management::ToplevelManagerState }; use iced_runtime::{ core::{self, Point, touch}, @@ -104,7 +99,7 @@ use iced_runtime::{ }, }; use wayland_protocols::{ - ext::background_effect::v1::client::ext_background_effect_surface_v1::ExtBackgroundEffectSurfaceV1, + ext::background_effect::v1::client::{ext_background_effect_manager_v1, ext_background_effect_surface_v1::ExtBackgroundEffectSurfaceV1}, wp::{ fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1, keyboard_shortcuts_inhibit::zv1::client::{ @@ -486,6 +481,7 @@ pub struct SctkState { pub(crate) corner_radius_manager: Option, pub(crate) pending_corner_radius: HashMap, + pub(crate) pending_blur: HashMap>, pub(crate) text_input_manager: Option, pub(crate) text_input: Option>, @@ -836,6 +832,7 @@ impl SctkState { ) } }; + let toplevel = toplevel.clone(); popup.xdg_surface().set_window_geometry( 0, @@ -868,6 +865,18 @@ impl SctkState { } _ = wl_surface.frame(&self.queue_handle, wl_surface.clone()); + if let Some(corners) = self.pending_corner_radius.remove(&settings.id) { + self.handle_action(Action::RoundedCorners ( + settings.id, + Some(corners), + )); + } + if let Some(blur) = self.pending_blur.remove(&settings.id) { + self.apply_blur(settings.id, Some(blur), &wl_surface); + } + + + wl_surface.commit(); let wp_viewport = self.viewporter_state.as_ref().map(|state| { @@ -996,6 +1005,15 @@ impl SctkState { layer_surface.set_input_region(Some(®ion)); region.destroy(); } + if let Some(blur) = self.pending_blur.remove(&id) { + self.apply_blur(id, Some(blur), &wl_surface); + } + if let Some(corners) = self.pending_corner_radius.remove(&id) { + _ = self.handle_action(Action::RoundedCorners( + id, + Some(corners), + )); + } layer_surface.commit(); let wp_viewport = self.viewporter_state.as_ref().map(|state| { @@ -1099,12 +1117,6 @@ impl SctkState { id: wl_surface.clone(), } ); - if let Some(corners) = self.pending_corner_radius.remove(&id) { - self.handle_action(Action::RoundedCorners( - id, - Some(corners), - ))?; - } } } platform_specific::wayland::layer_surface::Action::Size { @@ -1338,12 +1350,6 @@ impl SctkState { SctkEvent::PopupEvent { variant: crate::platform_specific::wayland::sctk_event::PopupEventVariant::Created(queue_handle.clone(), surface, id, common, state.connection.display()), toplevel_id, parent_id, id: wl_surface }); - if let Some(corners) = state.pending_corner_radius.remove(&id) { - state.handle_action(Action::RoundedCorners ( - id, - Some(corners), - )); - } } Err(err) => { log::error!("Failed to create popup. {err:?}"); @@ -1362,12 +1368,6 @@ impl SctkState { SctkEvent::PopupEvent { variant: crate::platform_specific::wayland::sctk_event::PopupEventVariant::Created(self.queue_handle.clone(), surface, id, common, self.connection.display()), toplevel_id, parent_id, id: wl_surface }); - if let Some(corners) = self.pending_corner_radius.remove(&id) { - self.handle_action(Action::RoundedCorners ( - id, - Some(corners), - )); - } } Err(err) => { log::error!("Failed to create popup. {err:?}"); @@ -1776,66 +1776,74 @@ impl SctkState { } else if let Some(subsurface) = self.subsurfaces.iter().find(|s| s.id == id) { &subsurface.instance.wl_surface } else { - log::error!("Failed to find surface for blur action"); + log::info!("Failed to find surface for blur action"); + if let Some(rectangles) = rectangles { + _ = self.pending_blur.insert(id, rectangles.clone()); + } return Ok(()); - }; - let existing_blur = self.blur_surfaces.entry(id); - match (existing_blur, rectangles) { - (Entry::Occupied(occupied_entry), None) => { - let blur_surface = occupied_entry.remove(); - blur_surface.destroy(); - }, - (Entry::Occupied(mut occupied_entry), Some(rectangles)) => { - let blur_surface = occupied_entry.get_mut(); - let region = self - .compositor_state - .wl_compositor() - .create_region(&self.queue_handle, ()); - for rect in rectangles.into_iter() { - region.add( - rect.x.round() as i32, - rect.y.round() as i32, - rect.width.round() as i32, - rect.height.round() as i32, - ); - } - - // update existing blur surfaces - blur_surface.set_blur_region(Some(®ion)); - - }, - (Entry::Vacant(..), None) => { - // nothing to remove - }, - (Entry::Vacant(vacant_entry), Some(rectangles)) => { - if self.ext_background_effect_manager.is_none() { - log::error!("Blur effect is not supported."); - return Ok(()); - } - let region = self - .compositor_state - .wl_compositor() - .create_region(&self.queue_handle, ()); - for rect in rectangles { - region.add( - rect.x.round() as i32, - rect.y.round() as i32, - rect.width.round() as i32, - rect.height.round() as i32, - ); - } - - let blur_manager = self.ext_background_effect_manager.as_mut().unwrap(); - let blur_surface = blur_manager.blur(s, &self.queue_handle); - blur_surface.set_blur_region(Some(®ion)); - _ = vacant_entry.insert(blur_surface); - }, - } + }.clone(); + self.apply_blur(id, rectangles, &s) }, }; Ok(()) } + fn apply_blur(&mut self, id: core::window::Id, rectangles: Option>, s: &WlSurface) { + let existing_blur = self.blur_surfaces.entry(id); + match (existing_blur, rectangles) { + (Entry::Occupied(occupied_entry), None) => { + let blur_surface = occupied_entry.remove(); + blur_surface.destroy(); + }, + (Entry::Occupied(mut occupied_entry), Some(rectangles)) => { + let blur_surface = occupied_entry.get_mut(); + let region = self + .compositor_state + .wl_compositor() + .create_region(&self.queue_handle, ()); + for rect in rectangles.into_iter() { + region.add( + rect.x.round() as i32, + rect.y.round() as i32, + rect.width.round() as i32, + rect.height.round() as i32, + ); + } + + // update existing blur surfaces + blur_surface.set_blur_region(Some(®ion)); + + }, + (Entry::Vacant(..), None) => { + // nothing to remove + }, + (Entry::Vacant(vacant_entry), Some(rectangles)) => { + if self.ext_background_effect_manager.is_none() { + log::error!("Blur effect is not supported."); + return; + } + let region = self + .compositor_state + .wl_compositor() + .create_region(&self.queue_handle, ()); + for rect in rectangles { + region.add( + rect.x.round() as i32, + rect.y.round() as i32, + rect.width.round() as i32, + rect.height.round() as i32, + ); + } + + let blur_manager = self.ext_background_effect_manager.as_mut().unwrap(); + let blur_surface = blur_manager.blur(s, &self.queue_handle); + blur_surface.set_blur_region(Some(®ion)); + _ = vacant_entry.insert(blur_surface); + }, + } + + } + pub fn get_subsurface( &mut self, settings: SctkSubsurfaceSettings, @@ -1849,7 +1857,7 @@ impl SctkState { ), SubsurfaceCreationError, > { - let Some(subsurface_state) = self.subsurface_state.as_ref() else { + let Some(subsurface_state) = self.subsurface_state.clone() else { return Err(SubsurfaceCreationError::Unsupported); }; if self.layer_surfaces.iter().any(|s| s.id == settings.id) @@ -1965,6 +1973,16 @@ impl SctkState { region.destroy(); } + if let Some(blur) = self.pending_blur.remove(&settings.id) { + _ = self.apply_blur(settings.id, Some(blur), &wl_surface); + } + if let Some(corners) = self.pending_corner_radius.remove(&settings.id) { + self.handle_action(Action::RoundedCorners ( + settings.id, + Some(corners), + )); + } + wl_surface.commit(); let wp_viewport = subsurface_state.wp_viewporter.get_viewport( From 8e94441efad36dca2cef70fa3bc431dd5160871a Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Thu, 4 Jun 2026 19:59:01 -0400 Subject: [PATCH 59/72] fix: apply initial corner radius after adding surfaces to the state otherwise the corners won't be set. --- .../wayland/event_loop/state.rs | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index d66f99c5..4fdfd09d 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -865,19 +865,12 @@ impl SctkState { } _ = wl_surface.frame(&self.queue_handle, wl_surface.clone()); - if let Some(corners) = self.pending_corner_radius.remove(&settings.id) { - self.handle_action(Action::RoundedCorners ( - settings.id, - Some(corners), - )); - } + if let Some(blur) = self.pending_blur.remove(&settings.id) { self.apply_blur(settings.id, Some(blur), &wl_surface); } - - wl_surface.commit(); let wp_viewport = self.viewporter_state.as_ref().map(|state| { let viewport = @@ -909,7 +902,14 @@ impl SctkState { common: common.clone(), close_with_children: settings.close_with_children, }); - + + if let Some(corners) = self.pending_corner_radius.remove(&settings.id) { + self.handle_action(Action::RoundedCorners ( + settings.id, + Some(corners), + )); + } + wl_surface.commit(); Ok(( settings.id, parent.wl_surface().clone(), @@ -1008,13 +1008,7 @@ impl SctkState { if let Some(blur) = self.pending_blur.remove(&id) { self.apply_blur(id, Some(blur), &wl_surface); } - if let Some(corners) = self.pending_corner_radius.remove(&id) { - _ = self.handle_action(Action::RoundedCorners( - id, - Some(corners), - )); - } - layer_surface.commit(); + let wp_viewport = self.viewporter_state.as_ref().map(|state| { state.get_viewport(layer_surface.wl_surface(), &self.queue_handle) @@ -1048,6 +1042,13 @@ impl SctkState { wp_fractional_scale, common: common.clone(), }); + if let Some(corners) = self.pending_corner_radius.remove(&id) { + _ = self.handle_action(Action::RoundedCorners( + id, + Some(corners), + )); + } + layer_surface.commit(); Ok((id, CommonSurface::Layer(layer_surface), common)) } pub fn get_lock_surface( @@ -1976,14 +1977,7 @@ impl SctkState { if let Some(blur) = self.pending_blur.remove(&settings.id) { _ = self.apply_blur(settings.id, Some(blur), &wl_surface); } - if let Some(corners) = self.pending_corner_radius.remove(&settings.id) { - self.handle_action(Action::RoundedCorners ( - settings.id, - Some(corners), - )); - } - - wl_surface.commit(); + let wp_viewport = subsurface_state.wp_viewporter.get_viewport( &wl_surface, @@ -2059,7 +2053,14 @@ impl SctkState { // XXX subsurfaces need to be sorted by z in descending order self.subsurfaces .sort_by(|a, b| b.instance.z.cmp(&a.instance.z)); + if let Some(corners) = self.pending_corner_radius.remove(&id) { + self.handle_action(Action::RoundedCorners ( + id, + Some(corners), + )); + } + wl_surface.commit(); Ok(( id, parent.wl_surface().clone(), From da9d15b2e8a0c15934035a898b1c64dab7af4059 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Thu, 25 Jun 2026 13:44:29 -0400 Subject: [PATCH 60/72] chore: update cosmic-protocols --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index b5e1b8d7..555f7901 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -274,7 +274,7 @@ tiny-skia = { version = "0.11", default-features = false, features = [ "std", "simd", ] } -cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "a7d2d7a" } +cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "32283d7" } softbuffer = { git = "https://github.com/pop-os/softbuffer", tag = "cosmic-4.0" } syntect = "5.2" tokio = "1.0" From 633ed144110b5be8bf87c14326ea46a09260bab9 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Thu, 25 Jun 2026 15:25:36 -0400 Subject: [PATCH 61/72] feat: popup reposition --- .../src/platform_specific/wayland/popup.rs | 28 +++++++----- .../wayland/commands/popup.rs | 21 +++++++-- .../wayland/event_loop/state.rs | 43 +++++++++++++++++++ 3 files changed, 79 insertions(+), 13 deletions(-) diff --git a/runtime/src/platform_specific/wayland/popup.rs b/runtime/src/platform_specific/wayland/popup.rs index e0475eb8..27279ab6 100644 --- a/runtime/src/platform_specific/wayland/popup.rs +++ b/runtime/src/platform_specific/wayland/popup.rs @@ -124,26 +124,34 @@ pub enum Action { /// height height: u32, }, + /// set the size of the popup + Reposition { + /// id of the popup + id: Id, + /// positioner of the popup + positioner: SctkPositioner, + }, } impl fmt::Debug for Action { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Action::Popup { popup, .. } => write!( - f, - "Action::PopupAction::Popup {{ popup: {:?} }}", - popup - ), - Action::Destroy { id } => write!( - f, - "Action::PopupAction::Destroy {{ id: {:?} }}", - id - ), + Action::Popup { popup, .. } => { + write!(f, "Action::PopupAction::Popup {{ popup: {:?} }}", popup) + } + Action::Destroy { id } => { + write!(f, "Action::PopupAction::Destroy {{ id: {:?} }}", id) + } Action::Size { id, width, height } => write!( f, "Action::PopupAction::Size {{ id: {:?}, width: {:?}, height: {:?} }}", id, width, height ), + Action::Reposition { id, positioner } => write!( + f, + "Action::Reposition {{ id: {:?}, positioner: {:?} }}", + id, positioner + ), } } } diff --git a/winit/src/platform_specific/wayland/commands/popup.rs b/winit/src/platform_specific/wayland/commands/popup.rs index f70d97f4..c702f4f1 100644 --- a/winit/src/platform_specific/wayland/commands/popup.rs +++ b/winit/src/platform_specific/wayland/commands/popup.rs @@ -1,12 +1,15 @@ //! Interact with the popups of your application. use crate::core::window::Id as SurfaceId; use iced_runtime::{ - self, + self, Action, Task, platform_specific::{ self, - wayland::{self, popup::SctkPopupSettings}, + wayland::{ + self, + popup::{SctkPopupSettings, SctkPositioner}, + }, }, - task, Action, Task, + task, }; /// @@ -32,6 +35,18 @@ pub fn set_size( )) } +/// +pub fn reposition( + id: SurfaceId, + positioner: SctkPositioner, +) -> Task { + task::effect(Action::PlatformSpecific( + platform_specific::Action::Wayland(wayland::Action::Popup( + wayland::popup::Action::Reposition { id, positioner }, + )), + )) +} + /// pub fn destroy_popup(id: SurfaceId) -> Task { task::effect(Action::PlatformSpecific( diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index 4fdfd09d..8126e864 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -1454,6 +1454,49 @@ impl SctkState { SctkEvent::PopupEvent { variant: crate::sctk_event::PopupEventVariant::Size(width, height), toplevel_id: sctk_popup.data.parent.wl_surface().clone(), parent_id: sctk_popup.data.parent.wl_surface().clone(), id: surface }); } }, + platform_specific::wayland::popup::Action::Reposition { id, positioner } => { + if let Some(sctk_popup) = self + .popups + .iter_mut() + .find(|s| s.data.id == id) + { + sctk_popup.data.positioner.set_anchor(positioner.anchor); + sctk_popup.data.positioner.set_anchor_rect( + positioner.anchor_rect.x, + positioner.anchor_rect.y, + positioner.anchor_rect.width, + positioner.anchor_rect.height, + ); + if let Ok(constraint_adjustment) = + positioner.constraint_adjustment.try_into() + { + sctk_popup.data.positioner.set_constraint_adjustment(constraint_adjustment); + } + sctk_popup.data.positioner.set_gravity(positioner.gravity); + sctk_popup.data.positioner.set_offset( + positioner.offset.0, + positioner.offset.1, + ); + if positioner.reactive { + sctk_popup.data.positioner.set_reactive(); + } + let guard =sctk_popup.common.lock().unwrap(); + let w = guard.size.width; + let h = guard.size.height; + drop(guard); + let size = positioner.size.unwrap_or((w, h)); + sctk_popup.popup + .xdg_surface() + .set_window_geometry(0, 0, w as i32, h as i32); + sctk_popup.update_viewport(w, h); + // update positioner + sctk_popup.data.positioner.set_size(w as i32, h as i32); + sctk_popup.popup.reposition(&sctk_popup.data.positioner, TOKEN_CTR.fetch_add(1, std::sync::atomic::Ordering::Relaxed)); let surface = sctk_popup.popup.wl_surface().clone(); + dbg!("repositioning..."); + _ = send_event(&self.events_sender, &self.proxy, + SctkEvent::PopupEvent { variant: crate::sctk_event::PopupEventVariant::Size(size.0, size.1), toplevel_id: sctk_popup.data.parent.wl_surface().clone(), parent_id: sctk_popup.data.parent.wl_surface().clone(), id: surface }); + } + }, }, Action::Activation(activation_event) => match activation_event { platform_specific::wayland::activation::Action::RequestToken { app_id, window, channel } => { From c781ff6199715f5650411c7ac625d4e1929bfdfb Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Thu, 25 Jun 2026 15:27:31 -0400 Subject: [PATCH 62/72] chore: cargo fmt --- examples/counter/src/main.rs | 4 +- examples/sctk_drag/src/dnd_destination.rs | 10 +- examples/sctk_drag/src/dnd_source.rs | 40 +++---- examples/sctk_subsurface/src/main.rs | 2 +- runtime/src/dnd.rs | 2 +- .../platform_specific/wayland/activation.rs | 2 +- wgpu/src/window/compositor.rs | 11 +- widget/src/keyed/column.rs | 27 +++-- widget/src/text/rich.rs | 5 +- winit/src/lib.rs | 108 ++++++++--------- .../wayland/commands/activation.rs | 4 +- .../wayland/commands/corner_radius.rs | 4 +- .../commands/keyboard_shortcuts_inhibit.rs | 4 +- .../wayland/commands/overlap_notify.rs | 3 +- .../wayland/commands/session_lock.rs | 4 +- .../wayland/commands/subsurface.rs | 4 +- .../wayland/event_loop/proxy.rs | 2 +- .../wayland/event_loop/state.rs | 110 +++++++++--------- .../wayland/handlers/seat/touch.rs | 4 +- .../wayland/handlers/session_lock.rs | 3 +- .../wayland/handlers/shell/layer.rs | 4 +- .../wayland/handlers/shell/mod.rs | 2 +- .../wayland/handlers/wp_viewporter.rs | 4 +- winit/src/platform_specific/wayland/mod.rs | 1 + 24 files changed, 192 insertions(+), 172 deletions(-) diff --git a/examples/counter/src/main.rs b/examples/counter/src/main.rs index 5027afd7..cfae782a 100644 --- a/examples/counter/src/main.rs +++ b/examples/counter/src/main.rs @@ -1,5 +1,5 @@ +use iced::widget::{button, column, text, Column}; use iced::Center; -use iced::widget::{Column, button, column, text}; pub fn main() -> iced::Result { iced::run(Counter::update, Counter::view) @@ -42,7 +42,7 @@ impl Counter { #[cfg(test)] mod tests { use super::*; - use iced_test::{Error, simulator}; + use iced_test::{simulator, Error}; #[test] fn it_counts() -> Result<(), Error> { diff --git a/examples/sctk_drag/src/dnd_destination.rs b/examples/sctk_drag/src/dnd_destination.rs index 1081d8bb..d1b3374b 100644 --- a/examples/sctk_drag/src/dnd_destination.rs +++ b/examples/sctk_drag/src/dnd_destination.rs @@ -3,20 +3,20 @@ use std::{ sync::atomic::{AtomicU64, Ordering}, }; -use iced::{Element, id::Id}; use iced::{ - Event, Length, Rectangle, clipboard::{ dnd::{self, DndAction, DndDestinationRectangle, DndEvent, OfferEvent}, mime::AllowedMimeTypes, }, event, id::Internal, - mouse, overlay, + mouse, overlay, Event, Length, Rectangle, }; +use iced::{id::Id, Element}; use iced_core::{ - self, Clipboard, Layout, Shell, Widget, layout, - widget::{Tree, tree}, + self, layout, + widget::{tree, Tree}, + Clipboard, Layout, Shell, Widget, }; pub fn dnd_destination<'a, Message: 'static>( diff --git a/examples/sctk_drag/src/dnd_source.rs b/examples/sctk_drag/src/dnd_source.rs index 1d8b85c4..e93b925e 100644 --- a/examples/sctk_drag/src/dnd_source.rs +++ b/examples/sctk_drag/src/dnd_source.rs @@ -1,16 +1,16 @@ use std::any::Any; -use iced::Element; use iced::id::Id; use iced::widget::container; +use iced::Element; use iced::{ - Event, Length, Point, Rectangle, clipboard::dnd::{DndAction, DndEvent, SourceEvent}, - event, mouse, overlay, + event, mouse, overlay, Event, Length, Point, Rectangle, }; use iced_core::{ - Clipboard, Shell, layout, renderer, - widget::{Tree, tree}, + layout, renderer, + widget::{tree, Tree}, + Clipboard, Shell, }; use iced_core::{Layout, Widget}; @@ -37,11 +37,11 @@ pub struct DndSource<'a, Message, AppMessage, D> { } impl< - 'a, - Message: 'static, - AppMessage: 'static, - D: iced::clipboard::mime::AsMimeTypes + std::marker::Send + 'static, -> DndSource<'a, Message, AppMessage, D> + 'a, + Message: 'static, + AppMessage: 'static, + D: iced::clipboard::mime::AsMimeTypes + std::marker::Send + 'static, + > DndSource<'a, Message, AppMessage, D> { pub fn new(child: impl Into>) -> Self { Self { @@ -119,11 +119,11 @@ impl< } impl< - 'a, - Message: 'static, - AppMessage: 'static, - D: iced::clipboard::mime::AsMimeTypes + std::marker::Send + 'static, -> Widget + 'a, + Message: 'static, + AppMessage: 'static, + D: iced::clipboard::mime::AsMimeTypes + std::marker::Send + 'static, + > Widget for DndSource<'a, Message, AppMessage, D> { fn children(&self) -> Vec { @@ -357,11 +357,11 @@ impl< } impl< - 'a, - Message: 'static, - AppMessage: 'static, - D: iced::clipboard::mime::AsMimeTypes + std::marker::Send + 'static, -> From> for Element<'a, Message> + 'a, + Message: 'static, + AppMessage: 'static, + D: iced::clipboard::mime::AsMimeTypes + std::marker::Send + 'static, + > From> for Element<'a, Message> { fn from(e: DndSource<'a, Message, AppMessage, D>) -> Element<'a, Message> { Element::new(e) diff --git a/examples/sctk_subsurface/src/main.rs b/examples/sctk_subsurface/src/main.rs index c00f7225..a204572c 100644 --- a/examples/sctk_subsurface/src/main.rs +++ b/examples/sctk_subsurface/src/main.rs @@ -7,7 +7,6 @@ use cctk::sctk::reexports::{ use iced::platform_specific::shell::commands::subsurface::get_subsurface; use iced::{ - Element, Length, Subscription, Task, event::wayland::Event as WaylandEvent, platform_specific::{ runtime::wayland::subsurface::SctkSubsurfaceSettings, @@ -15,6 +14,7 @@ use iced::{ }, widget::{button, column, text, text_input}, window::{self, Id, Settings}, + Element, Length, Subscription, Task, }; use std::sync::{Arc, Mutex}; diff --git a/runtime/src/dnd.rs b/runtime/src/dnd.rs index e6f2b267..2a0db116 100644 --- a/runtime/src/dnd.rs +++ b/runtime/src/dnd.rs @@ -6,7 +6,7 @@ use dnd::{DndDestinationRectangle, DndSurface}; use iced_core::clipboard::DndSource; use window_clipboard::mime::{AllowedMimeTypes, AsMimeTypes}; -use crate::{oneshot, task, Action, Task}; +use crate::{Action, Task, oneshot, task}; /// An action to be performed on the system. pub enum DndAction { diff --git a/runtime/src/platform_specific/wayland/activation.rs b/runtime/src/platform_specific/wayland/activation.rs index 64d4dc4d..3f48f01c 100644 --- a/runtime/src/platform_specific/wayland/activation.rs +++ b/runtime/src/platform_specific/wayland/activation.rs @@ -36,7 +36,7 @@ impl fmt::Debug for Action { f, "Action::ActivationAction::Activate {{ window: {:?}, token: {:?} }}", window, token, - ) + ), } } } diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index f0595f2b..58c7d713 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -296,11 +296,12 @@ impl Compositor { }); // Request SHADER_F16 only if the adapter supports it (e.g., not available in WebGL2) - let required_features = if adapter.features().contains(wgpu::Features::SHADER_F16) { - wgpu::Features::SHADER_F16 - } else { - wgpu::Features::empty() - }; + let required_features = + if adapter.features().contains(wgpu::Features::SHADER_F16) { + wgpu::Features::SHADER_F16 + } else { + wgpu::Features::empty() + }; let mut errors = Vec::new(); diff --git a/widget/src/keyed/column.rs b/widget/src/keyed/column.rs index baaee5c9..ef7d9d9a 100644 --- a/widget/src/keyed/column.rs +++ b/widget/src/keyed/column.rs @@ -293,9 +293,12 @@ where .zip(&mut tree.children) .zip(layout.children()) .for_each(|((child, state), c_layout)| { - child - .as_widget_mut() - .operate(state, c_layout.with_virtual_offset(layout.virtual_offset()), renderer, operation); + child.as_widget_mut().operate( + state, + c_layout.with_virtual_offset(layout.virtual_offset()), + renderer, + operation, + ); }); }); } @@ -318,7 +321,13 @@ where .zip(layout.children()) { child.as_widget_mut().update( - tree, event, c_layout.with_virtual_offset(layout.virtual_offset()), cursor, renderer, clipboard, shell, + tree, + event, + c_layout.with_virtual_offset(layout.virtual_offset()), + cursor, + renderer, + clipboard, + shell, viewport, ); } @@ -337,9 +346,13 @@ where .zip(&tree.children) .zip(layout.children()) .map(|((child, tree), c_layout)| { - child - .as_widget() - .mouse_interaction(tree, c_layout.with_virtual_offset(layout.virtual_offset()), cursor, viewport, renderer) + child.as_widget().mouse_interaction( + tree, + c_layout.with_virtual_offset(layout.virtual_offset()), + cursor, + viewport, + renderer, + ) }) .max() .unwrap_or_default() diff --git a/widget/src/text/rich.rs b/widget/src/text/rich.rs index 80abc8d5..ef44e2bf 100644 --- a/widget/src/text/rich.rs +++ b/widget/src/text/rich.rs @@ -179,7 +179,10 @@ where { let color = color.map(Into::into); - self.style(move |_theme| Style { color, ..Style::default() }) + self.style(move |_theme| Style { + color, + ..Style::default() + }) } /// Sets the default style class of the [`Rich`] text. diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 410949ac..517eddbc 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -40,12 +40,6 @@ pub mod clipboard; pub mod conversion; pub mod platform_specific; -#[cfg(feature = "program")] -pub mod program; - -#[cfg(feature = "system")] -pub mod system; - mod error; mod proxy; mod window; @@ -193,10 +187,13 @@ where error: Option, system_theme: Option>, control_sender: mpsc::UnboundedSender, - + #[cfg(feature = "a11y")] - adapters: std::collections::HashMap, - + adapters: std::collections::HashMap< + window::Id, + (u64, iced_accessibility::accesskit_winit::Adapter), + >, + #[cfg(target_arch = "wasm32")] is_booted: std::rc::Rc>, #[cfg(target_arch = "wasm32")] @@ -501,9 +498,15 @@ where } }; } - let window: Arc = Arc::from(window); + let window: Arc< + dyn winit::window::Window + 'static, + > = Arc::from(window); #[cfg(feature = "a11y")] - self.init_adapter(event_loop, id, window.clone()); + self.init_adapter( + event_loop, + id, + window.clone(), + ); self.process_event( event_loop, @@ -572,11 +575,13 @@ where .expect("Send event"); } Control::Winit(id, e) => { - #[cfg(all(feature = "cctk", target_os = "linux"))] + #[cfg(all( + feature = "cctk", + target_os = "linux" + ))] { if matches!(e, WindowEvent::RedrawRequested) - { - + { for id in crate::subsurface_widget::subsurface_ids(id) { _ = self.sender .unbounded_send(Event::Winit( @@ -597,7 +602,7 @@ where } } } - + self.sender .start_send(Event::Winit(id, e)) .expect("Send event"); @@ -610,7 +615,7 @@ where #[cfg(feature = "a11y")] Control::InitAdapter(id, window) => { self.init_adapter(event_loop, id, window); - + self.process_event( event_loop, Some(Event::A11yAdapter(id)), @@ -618,8 +623,8 @@ where } #[cfg(feature = "a11y")] Control::Cleanup(id) => { - _ = self.adapters.remove(&id); - }, + _ = self.adapters.remove(&id); + } }, _ => { break; @@ -633,34 +638,35 @@ where } } - #[cfg(feature = "a11y")] - fn init_adapter(&mut self, event_loop: &(dyn winit::event_loop::ActiveEventLoop + 'static), id: core::window::Id, window: Arc) { + #[cfg(feature = "a11y")] + fn init_adapter( + &mut self, + event_loop: &(dyn winit::event_loop::ActiveEventLoop + 'static), + id: core::window::Id, + window: Arc, + ) { use crate::a11y::*; use iced_accessibility::accesskit::{ - ActivationHandler, Node, NodeId, Role, - Tree, TreeUpdate, + ActivationHandler, Node, NodeId, Role, Tree, TreeUpdate, }; use iced_accessibility::accesskit_winit::Adapter; - - let node_id = - iced_runtime::core::id::window_node_id(); - - let activation_handler = - WinitActivationHandler { - proxy: self.control_sender.clone(), - title: String::new(), - }; - + + let node_id = iced_runtime::core::id::window_node_id(); + + let activation_handler = WinitActivationHandler { + proxy: self.control_sender.clone(), + title: String::new(), + }; + let action_handler = WinitActionHandler { id, proxy: self.control_sender.clone(), }; - - let deactivation_handler = - WinitDeactivationHandler { - proxy: self.control_sender.clone(), - }; - + + let deactivation_handler = WinitDeactivationHandler { + proxy: self.control_sender.clone(), + }; + _ = self.adapters.insert( id, ( @@ -674,8 +680,6 @@ where ), ), ); - - } } @@ -879,9 +883,8 @@ async fn run_instance

( exit_on_close_request, make_visible, on_open, - resize_border + resize_border, } => { - #[cfg(all(feature = "cctk", target_os = "linux"))] platform_specific_handler.send_wayland( platform_specific::Action::TrackWindow(window.clone(), id), @@ -937,7 +940,7 @@ async fn run_instance

( compositor, exit_on_close_request, system_theme, - resize_border + resize_border, ); window.raw.set_theme(conversion::window_theme( @@ -1034,7 +1037,7 @@ async fn run_instance

( continue; }; - let Some((id, mut window)) = + let Some((id, mut window)) = window_manager.get_mut_alias(window_id) else { continue; @@ -1049,12 +1052,12 @@ async fn run_instance

( )) .expect("Send redraw event"); continue; - } + } // XX must force update to corner radius before the surface is committed. #[cfg(all(feature = "cctk", target_os = "linux"))] if (window.surface_version != window.state.surface_version() - || window.logical_size() != window.state.logical_size() - ) && !crate::subsurface_widget::is_subsurface(window_id) + || window.logical_size() != window.state.logical_size()) + && !crate::subsurface_widget::is_subsurface(window_id) { platform_specific_handler.send_wayland( platform_specific::Action::ResizeWindow(id), @@ -1320,9 +1323,7 @@ async fn run_instance

( continue; }; // Initiates a drag resize window state when found. - if let Some(func) = - window.drag_resize_window_func.as_mut() - { + if let Some(func) = window.drag_resize_window_func.as_mut() { if func(window.raw.as_ref(), &event) { continue; } @@ -1348,7 +1349,9 @@ async fn run_instance

( if matches!(event, winit::event::WindowEvent::CloseRequested) && window.exit_on_close_request { - _ = run_action!(Action::Window(runtime::window::Action::Close(id))); + _ = run_action!(Action::Window( + runtime::window::Action::Close(id) + )); } else { window.state.update(&program, window.raw.as_ref(), &event); @@ -1736,7 +1739,6 @@ async fn run_instance

( }; // search windows for widget with operation - if result.is_none() { log::warn!( "start_dnd: widget {:?} not found; drag will fail", @@ -2113,7 +2115,7 @@ where on_open: channel, }) .expect("Send control action"); - + *is_window_opening = true; } window::Action::Close(id) => { diff --git a/winit/src/platform_specific/wayland/commands/activation.rs b/winit/src/platform_specific/wayland/commands/activation.rs index fa051031..442ee08c 100644 --- a/winit/src/platform_specific/wayland/commands/activation.rs +++ b/winit/src/platform_specific/wayland/commands/activation.rs @@ -1,8 +1,8 @@ use crate::core::window::Id as SurfaceId; use iced_runtime::{ - self, + self, Action, Task, platform_specific::{self, wayland}, - task, Action, Task, + task, }; pub fn request_token( diff --git a/winit/src/platform_specific/wayland/commands/corner_radius.rs b/winit/src/platform_specific/wayland/commands/corner_radius.rs index c5ba6016..4cc122dd 100644 --- a/winit/src/platform_specific/wayland/commands/corner_radius.rs +++ b/winit/src/platform_specific/wayland/commands/corner_radius.rs @@ -1,11 +1,11 @@ use iced_futures::core::window; use iced_runtime::{ - self, + self, Action, Task, platform_specific::{ self, wayland::{self, CornerRadius}, }, - task, Action, Task, + task, }; pub fn corner_radius( diff --git a/winit/src/platform_specific/wayland/commands/keyboard_shortcuts_inhibit.rs b/winit/src/platform_specific/wayland/commands/keyboard_shortcuts_inhibit.rs index 783b62c6..afc2e27b 100644 --- a/winit/src/platform_specific/wayland/commands/keyboard_shortcuts_inhibit.rs +++ b/winit/src/platform_specific/wayland/commands/keyboard_shortcuts_inhibit.rs @@ -1,7 +1,7 @@ use iced_runtime::{ - self, + self, Action, Task, platform_specific::{self, wayland}, - task, Action, Task, + task, }; pub fn inhibit_shortcuts(inhibit: bool) -> Task<()> { diff --git a/winit/src/platform_specific/wayland/commands/overlap_notify.rs b/winit/src/platform_specific/wayland/commands/overlap_notify.rs index 860838c3..417cfb24 100644 --- a/winit/src/platform_specific/wayland/commands/overlap_notify.rs +++ b/winit/src/platform_specific/wayland/commands/overlap_notify.rs @@ -1,7 +1,8 @@ use iced_futures::core::window::Id; use iced_runtime::{ + Action, Task, platform_specific::{self, wayland}, - task, Action, Task, + task, }; /// Request subscription for overlap notification events on the surface diff --git a/winit/src/platform_specific/wayland/commands/session_lock.rs b/winit/src/platform_specific/wayland/commands/session_lock.rs index 7f8748f7..a530c12e 100644 --- a/winit/src/platform_specific/wayland/commands/session_lock.rs +++ b/winit/src/platform_specific/wayland/commands/session_lock.rs @@ -1,9 +1,9 @@ use crate::core::window::Id as SurfaceId; use cctk::sctk::reexports::client::protocol::wl_output::WlOutput; use iced_runtime::{ - self, + self, Action, Task, platform_specific::{self, wayland}, - task, Action, Task, + task, }; pub fn lock() -> Task { diff --git a/winit/src/platform_specific/wayland/commands/subsurface.rs b/winit/src/platform_specific/wayland/commands/subsurface.rs index a76e3b4e..20c3cdb7 100644 --- a/winit/src/platform_specific/wayland/commands/subsurface.rs +++ b/winit/src/platform_specific/wayland/commands/subsurface.rs @@ -1,12 +1,12 @@ use crate::core::window::Id as SurfaceId; pub use cctk::sctk::shell::wlr_layer::{Anchor, KeyboardInteractivity, Layer}; use iced_runtime::{ - self, + self, Action, Task, platform_specific::{ self, wayland::{self, subsurface::SctkSubsurfaceSettings}, }, - task, Action, Task, + task, }; pub fn get_subsurface( diff --git a/winit/src/platform_specific/wayland/event_loop/proxy.rs b/winit/src/platform_specific/wayland/event_loop/proxy.rs index bdbc44a4..58229dc1 100644 --- a/winit/src/platform_specific/wayland/event_loop/proxy.rs +++ b/winit/src/platform_specific/wayland/event_loop/proxy.rs @@ -1,8 +1,8 @@ use cctk::sctk::reexports::calloop; use iced_futures::futures::{ + Sink, channel::mpsc, task::{Context, Poll}, - Sink, }; use std::pin::Pin; diff --git a/winit/src/platform_specific/wayland/event_loop/state.rs b/winit/src/platform_specific/wayland/event_loop/state.rs index 8126e864..b817e4d5 100644 --- a/winit/src/platform_specific/wayland/event_loop/state.rs +++ b/winit/src/platform_specific/wayland/event_loop/state.rs @@ -1,7 +1,11 @@ use crate::{ Control, handlers::{ - activation::IcedRequestData, ext_background_effect, overlap::{OverlapNotificationV1, OverlapNotifyV1}, shell::corner_radius::CornerRadiusWrapper, text_input::{Preedit, TextInputManager} + activation::IcedRequestData, + ext_background_effect, + overlap::{OverlapNotificationV1, OverlapNotifyV1}, + shell::corner_radius::CornerRadiusWrapper, + text_input::{Preedit, TextInputManager}, }, platform_specific::{ Event, @@ -37,11 +41,10 @@ use winit::{ use cctk::{ cosmic_protocols::{ - corner_radius::v1::client::{ - cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, - }, + corner_radius::v1::client::cosmic_corner_radius_manager_v1::CosmicCornerRadiusManagerV1, overlap_notify::v1::client::zcosmic_overlap_notification_v1::ZcosmicOverlapNotificationV1, - }, sctk::{ + }, + sctk::{ activation::{ActivationState, RequestData}, compositor::CompositorState, error::GlobalError, @@ -59,7 +62,8 @@ use cctk::{ wl_surface::{self, WlSurface}, wl_touch::WlTouch, }, - }, protocols_wlr::layer_shell::v1::client::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1, + }, + protocols_wlr::layer_shell::v1::client::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1, }, registry::RegistryState, seat::{ @@ -84,7 +88,9 @@ use cctk::{ }, }, shm::{Shm, multi::MultiPool}, - }, toplevel_info::ToplevelInfoState, toplevel_management::ToplevelManagerState + }, + toplevel_info::ToplevelInfoState, + toplevel_management::ToplevelManagerState, }; use iced_runtime::{ core::{self, Point, touch}, @@ -99,7 +105,10 @@ use iced_runtime::{ }, }; use wayland_protocols::{ - ext::background_effect::v1::client::{ext_background_effect_manager_v1, ext_background_effect_surface_v1::ExtBackgroundEffectSurfaceV1}, + ext::background_effect::v1::client::{ + ext_background_effect_manager_v1, + ext_background_effect_surface_v1::ExtBackgroundEffectSurfaceV1, + }, wp::{ fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1, keyboard_shortcuts_inhibit::zv1::client::{ @@ -333,7 +342,6 @@ pub struct SctkPopupData { pub(crate) grab: bool, } - #[derive(Debug, Clone)] pub struct SctkCornerRadius(Arc); @@ -865,13 +873,11 @@ impl SctkState { } _ = wl_surface.frame(&self.queue_handle, wl_surface.clone()); - + if let Some(blur) = self.pending_blur.remove(&settings.id) { self.apply_blur(settings.id, Some(blur), &wl_surface); } - - let wp_viewport = self.viewporter_state.as_ref().map(|state| { let viewport = state.get_viewport(popup.wl_surface(), &self.queue_handle); @@ -902,9 +908,9 @@ impl SctkState { common: common.clone(), close_with_children: settings.close_with_children, }); - + if let Some(corners) = self.pending_corner_radius.remove(&settings.id) { - self.handle_action(Action::RoundedCorners ( + self.handle_action(Action::RoundedCorners( settings.id, Some(corners), )); @@ -1008,7 +1014,6 @@ impl SctkState { if let Some(blur) = self.pending_blur.remove(&id) { self.apply_blur(id, Some(blur), &wl_surface); } - let wp_viewport = self.viewporter_state.as_ref().map(|state| { state.get_viewport(layer_surface.wl_surface(), &self.queue_handle) @@ -1043,10 +1048,7 @@ impl SctkState { common: common.clone(), }); if let Some(corners) = self.pending_corner_radius.remove(&id) { - _ = self.handle_action(Action::RoundedCorners( - id, - Some(corners), - )); + _ = self.handle_action(Action::RoundedCorners(id, Some(corners))); } layer_surface.commit(); Ok((id, CommonSurface::Layer(layer_surface), common)) @@ -1139,7 +1141,7 @@ impl SctkState { platform_specific::wayland::layer_surface::Action::Destroy(id) => { if let Some(p) = self .popups - .iter().find_map(|p| + .iter().find_map(|p| self.layer_surfaces.iter().find_map(|l| if l.id == id && l.surface.wl_surface() == p.data.parent.wl_surface() {Some(p.data.id)} else {None})) { _ = self.handle_action(Action::Popup(platform_specific::wayland::popup::Action::Destroy { id: p })); } @@ -1173,7 +1175,6 @@ impl SctkState { _ = self.destroyed.insert(destroyed); } - send_event(&self.events_sender, &self.proxy, SctkEvent::LayerSurfaceEvent { variant: LayerSurfaceEventVariant::Done, id: l.surface.wl_surface().clone(), @@ -1492,7 +1493,6 @@ impl SctkState { // update positioner sctk_popup.data.positioner.set_size(w as i32, h as i32); sctk_popup.popup.reposition(&sctk_popup.data.positioner, TOKEN_CTR.fetch_add(1, std::sync::atomic::Ordering::Relaxed)); let surface = sctk_popup.popup.wl_surface().clone(); - dbg!("repositioning..."); _ = send_event(&self.events_sender, &self.proxy, SctkEvent::PopupEvent { variant: crate::sctk_event::PopupEventVariant::Size(size.0, size.1), toplevel_id: sctk_popup.data.parent.wl_surface().clone(), parent_id: sctk_popup.data.parent.wl_surface().clone(), id: surface }); } @@ -1832,19 +1832,24 @@ impl SctkState { Ok(()) } - fn apply_blur(&mut self, id: core::window::Id, rectangles: Option>, s: &WlSurface) { + fn apply_blur( + &mut self, + id: core::window::Id, + rectangles: Option>, + s: &WlSurface, + ) { let existing_blur = self.blur_surfaces.entry(id); match (existing_blur, rectangles) { (Entry::Occupied(occupied_entry), None) => { let blur_surface = occupied_entry.remove(); blur_surface.destroy(); - }, + } (Entry::Occupied(mut occupied_entry), Some(rectangles)) => { let blur_surface = occupied_entry.get_mut(); let region = self - .compositor_state - .wl_compositor() - .create_region(&self.queue_handle, ()); + .compositor_state + .wl_compositor() + .create_region(&self.queue_handle, ()); for rect in rectangles.into_iter() { region.add( rect.x.round() as i32, @@ -1853,41 +1858,40 @@ impl SctkState { rect.height.round() as i32, ); } - + // update existing blur surfaces blur_surface.set_blur_region(Some(®ion)); - - }, + } (Entry::Vacant(..), None) => { // nothing to remove - }, + } (Entry::Vacant(vacant_entry), Some(rectangles)) => { if self.ext_background_effect_manager.is_none() { log::error!("Blur effect is not supported."); return; } - let region = self - .compositor_state - .wl_compositor() - .create_region(&self.queue_handle, ()); - for rect in rectangles { - region.add( - rect.x.round() as i32, - rect.y.round() as i32, - rect.width.round() as i32, - rect.height.round() as i32, - ); - } - - let blur_manager = self.ext_background_effect_manager.as_mut().unwrap(); - let blur_surface = blur_manager.blur(s, &self.queue_handle); - blur_surface.set_blur_region(Some(®ion)); + let region = self + .compositor_state + .wl_compositor() + .create_region(&self.queue_handle, ()); + for rect in rectangles { + region.add( + rect.x.round() as i32, + rect.y.round() as i32, + rect.width.round() as i32, + rect.height.round() as i32, + ); + } + + let blur_manager = + self.ext_background_effect_manager.as_mut().unwrap(); + let blur_surface = blur_manager.blur(s, &self.queue_handle); + blur_surface.set_blur_region(Some(®ion)); _ = vacant_entry.insert(blur_surface); - }, + } } - } - + pub fn get_subsurface( &mut self, settings: SctkSubsurfaceSettings, @@ -2020,7 +2024,6 @@ impl SctkState { if let Some(blur) = self.pending_blur.remove(&settings.id) { _ = self.apply_blur(settings.id, Some(blur), &wl_surface); } - let wp_viewport = subsurface_state.wp_viewporter.get_viewport( &wl_surface, @@ -2097,10 +2100,7 @@ impl SctkState { self.subsurfaces .sort_by(|a, b| b.instance.z.cmp(&a.instance.z)); if let Some(corners) = self.pending_corner_radius.remove(&id) { - self.handle_action(Action::RoundedCorners ( - id, - Some(corners), - )); + self.handle_action(Action::RoundedCorners(id, Some(corners))); } wl_surface.commit(); diff --git a/winit/src/platform_specific/wayland/handlers/seat/touch.rs b/winit/src/platform_specific/wayland/handlers/seat/touch.rs index f726fd93..a0b1cce0 100644 --- a/winit/src/platform_specific/wayland/handlers/seat/touch.rs +++ b/winit/src/platform_specific/wayland/handlers/seat/touch.rs @@ -9,12 +9,12 @@ use crate::{ use cctk::sctk::{ delegate_touch, reexports::client::{ - protocol::{wl_surface::WlSurface, wl_touch::WlTouch}, Connection, Proxy, QueueHandle, + protocol::{wl_surface::WlSurface, wl_touch::WlTouch}, }, seat::touch::TouchHandler, }; -use iced_runtime::core::{touch, Point}; +use iced_runtime::core::{Point, touch}; impl TouchHandler for SctkState { fn down( diff --git a/winit/src/platform_specific/wayland/handlers/session_lock.rs b/winit/src/platform_specific/wayland/handlers/session_lock.rs index 6c617a20..98eb5586 100644 --- a/winit/src/platform_specific/wayland/handlers/session_lock.rs +++ b/winit/src/platform_specific/wayland/handlers/session_lock.rs @@ -1,8 +1,7 @@ use crate::{ event_loop::state::CommonSurface, platform_specific::wayland::{ - event_loop::state::receive_frame, - handlers::SctkState, + event_loop::state::receive_frame, handlers::SctkState, sctk_event::SctkEvent, }, }; diff --git a/winit/src/platform_specific/wayland/handlers/shell/layer.rs b/winit/src/platform_specific/wayland/handlers/shell/layer.rs index 65e5724b..22fd6560 100644 --- a/winit/src/platform_specific/wayland/handlers/shell/layer.rs +++ b/winit/src/platform_specific/wayland/handlers/shell/layer.rs @@ -1,13 +1,13 @@ use crate::platform_specific::wayland::{ - event_loop::state::{receive_frame, SctkState}, + event_loop::state::{SctkState, receive_frame}, sctk_event::{LayerSurfaceEventVariant, SctkEvent}, }; use cctk::sctk::{ delegate_layer, reexports::client::Proxy, shell::{ - wlr_layer::{Anchor, KeyboardInteractivity, LayerShellHandler}, WaylandSurface, + wlr_layer::{Anchor, KeyboardInteractivity, LayerShellHandler}, }, }; use std::fmt::Debug; diff --git a/winit/src/platform_specific/wayland/handlers/shell/mod.rs b/winit/src/platform_specific/wayland/handlers/shell/mod.rs index af8b5961..c4117eb7 100644 --- a/winit/src/platform_specific/wayland/handlers/shell/mod.rs +++ b/winit/src/platform_specific/wayland/handlers/shell/mod.rs @@ -1,4 +1,4 @@ +pub mod corner_radius; pub mod layer; pub mod xdg_popup; pub mod xdg_window; -pub mod corner_radius; diff --git a/winit/src/platform_specific/wayland/handlers/wp_viewporter.rs b/winit/src/platform_specific/wayland/handlers/wp_viewporter.rs index 5cfe28d7..7bbd66d1 100644 --- a/winit/src/platform_specific/wayland/handlers/wp_viewporter.rs +++ b/winit/src/platform_specific/wayland/handlers/wp_viewporter.rs @@ -1,10 +1,10 @@ //! Handling of the wp-viewporter. +use cctk::sctk::reexports::client::Dispatch; use cctk::sctk::reexports::client::globals::{BindError, GlobalList}; use cctk::sctk::reexports::client::protocol::wl_surface::WlSurface; -use cctk::sctk::reexports::client::Dispatch; use cctk::sctk::reexports::client::{ - delegate_dispatch, Connection, Proxy, QueueHandle, + Connection, Proxy, QueueHandle, delegate_dispatch, }; use cctk::sctk::reexports::protocols::wp::viewporter::client::wp_viewport::WpViewport; use cctk::sctk::reexports::protocols::wp::viewporter::client::wp_viewporter::WpViewporter; diff --git a/winit/src/platform_specific/wayland/mod.rs b/winit/src/platform_specific/wayland/mod.rs index bbbce8f1..e98316ce 100644 --- a/winit/src/platform_specific/wayland/mod.rs +++ b/winit/src/platform_specific/wayland/mod.rs @@ -21,6 +21,7 @@ use iced_runtime::core::{Vector, window}; use raw_window_handle::{DisplayHandle, HasDisplayHandle, HasWindowHandle}; use raw_window_handle::{HasRawDisplayHandle, RawWindowHandle}; use sctk_event::SctkEvent; +use std::sync::OnceLock; use std::{collections::HashMap, sync::Arc}; use subsurface_widget::{SubsurfaceInstance, SubsurfaceState}; use wayland_backend::client::ObjectId; From a50a29b3905168b6c93cc48ae9bfa2205c59149a Mon Sep 17 00:00:00 2001 From: leyoda Date: Fri, 24 Apr 2026 06:00:03 +0200 Subject: [PATCH 63/72] yoda: drop x11 default on winit workspace dep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Was pulling winit's full x11 backend (winit-x11 + x11-dl) unconditionally despite iced_winit's own x11 feature being disabled. Fixed by adding default-features=false on the workspace-level winit dep — iced_winit/wayland + wayland-dlopen propagate to winit/wayland + wayland-dlopen as needed. --- Cargo.toml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 555f7901..bf7bcfdf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -304,7 +304,11 @@ winapi = "0.3" window_clipboard = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" } dnd = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" } mime = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" } -winit = { git = "https://github.com/pop-os/winit.git", tag = "cosmic-0.14" } +# Yoda: default-features = false drops winit's x11 default, which otherwise +# pulls winit-x11, x11-dl, tiny-xlib, as-raw-xcb-connection. Our Wayland-only +# fork doesn't need any of that — the wayland + wayland-dlopen features are +# re-enabled via iced_winit's own feature propagation from libcosmic-yoda. +winit = { git = "https://github.com/pop-os/winit.git", tag = "cosmic-0.14", default-features = false } winit-core = { git = "https://github.com/pop-os/winit.git", tag = "cosmic-0.14" } cursor-icon = "1.1.0" From 702b6359a54a4eb4ff5cd31a1edc818a31233f19 Mon Sep 17 00:00:00 2001 From: leyoda Date: Fri, 24 Apr 2026 06:24:15 +0200 Subject: [PATCH 64/72] yoda: gate iced_wgpu x11 backend behind an opt-in feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit iced_wgpu's unix block unconditionally depended on as-raw-xcb-connection, tiny-xlib and x11rb for a DRI3 device-id fallback in window/compositor.rs that only fires when wayland can't determine the GPU. On a Wayland-only build this code path never runs, so the deps are pure bloat. Changes: - Cargo.toml: move the 3 x11 crates to optional + new feature `x11` (not in default — wayland-only is the yoda target; users who need X11 opt in). - window.rs: cfg-gate `mod x11;` on feature = "x11" - window/compositor.rs: cfg-gate `use super::x11::get_x11_device_ids` + the or_else fallback on feature = "x11" (wrapped in a let-binding so the non-x11 branch compiles cleanly). Result: iced_wgpu no longer pulls any x11 crate when built without the feature. --- wgpu/Cargo.toml | 11 ++++++++--- wgpu/src/window.rs | 2 +- wgpu/src/window/compositor.rs | 8 +++++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 48fca1b8..ffbcd293 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -25,6 +25,11 @@ svg = ["iced_graphics/svg", "resvg/text"] web-colors = ["iced_graphics/web-colors"] webgl = ["wgpu/webgl"] strict-assertions = [] +# Yoda: opt-in X11 backend. Pulls tiny-xlib/as-raw-xcb-connection/x11rb +# (which otherwise were unconditional direct deps on unix). Wayland-only +# builds just leave this off — window/x11.rs and the DRI3 device-id +# fallback in window/compositor.rs are cfg-gated on it. +x11 = ["dep:as-raw-xcb-connection", "dep:tiny-xlib", "dep:x11rb"] [dependencies] iced_debug.workspace = true @@ -57,9 +62,9 @@ wayland-protocols.workspace = true wayland-backend = { version = "0.3.3", features = ["client_system"] } wayland-client = { version = "0.31.2" } wayland-sys = { version = "0.31.1", features = ["dlopen"] } -as-raw-xcb-connection = "1.0.1" -tiny-xlib = "0.2.3" -x11rb = { version = "0.13.1", features = [ +as-raw-xcb-connection = { version = "1.0.1", optional = true } +tiny-xlib = { version = "0.2.3", optional = true } +x11rb = { version = "0.13.1", optional = true, features = [ "allow-unsafe-code", "dl-libxcb", "dri3", diff --git a/wgpu/src/window.rs b/wgpu/src/window.rs index b9ec54bd..f71b7d3f 100644 --- a/wgpu/src/window.rs +++ b/wgpu/src/window.rs @@ -7,7 +7,7 @@ pub mod compositor; not(target_os = "redox") ))] mod wayland; -#[cfg(all(unix, not(target_os = "macos"), not(target_os = "redox")))] +#[cfg(all(unix, feature = "x11", not(target_os = "macos"), not(target_os = "redox")))] mod x11; pub use compositor::Compositor; diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index 58c7d713..d6186ab5 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -16,7 +16,7 @@ use crate::{Engine, Renderer}; not(target_os = "redox") ))] use super::wayland::get_wayland_device_ids; -#[cfg(all(unix, not(target_os = "macos"), not(target_os = "redox")))] +#[cfg(all(unix, feature = "x11", not(target_os = "macos"), not(target_os = "redox")))] use super::x11::get_x11_device_ids; use std::future::Future; @@ -72,8 +72,10 @@ impl Compositor { not(target_os = "redox") ))] let ids = compatible_window.as_ref().and_then(|window| { - get_wayland_device_ids(window) - .or_else(|| get_x11_device_ids(window)) + let w = get_wayland_device_ids(window); + #[cfg(feature = "x11")] + let w = w.or_else(|| get_x11_device_ids(window)); + w }); #[cfg(all( From f1f42f2bff0e1198c2f0b07d238f6b552df33717 Mon Sep 17 00:00:00 2001 From: leyoda Date: Fri, 24 Apr 2026 06:53:36 +0200 Subject: [PATCH 65/72] yoda: softbuffer + window_clipboard default-features=false Two one-line workspace-dep fixes that drop the last remaining X11 crates for Wayland-only builds: - softbuffer: its default = [kms, x11, x11-dlopen, wayland, wayland-dlopen] pulled tiny-xlib + as-raw-xcb-connection unconditionally even though iced_tiny_skia only needed softbuffer/wayland. Disabling the default lets iced_tiny_skia's own feature propagation ask for just wayland + wayland-dlopen. - window_clipboard: upstream pulled clipboard_x11 + clipboard_wayland unconditionally on unix. Our local fork (branch yoda-x11-optional) gates clipboard_x11 behind an opt-in feature, so default-features=false + features=["wayland"] drops ~500 x11 symbols (clipboard_x11, x11rb, x11rb-protocol). Combined with previous yoda-v4 cuts, cosmic-yoterm goes from 1526 -> 43 x11 symbols (-97%), and 55.4 MB -> 53.3 MB (-2.1 MB). --- Cargo.toml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bf7bcfdf..f3d7b8f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -275,7 +275,10 @@ tiny-skia = { version = "0.11", default-features = false, features = [ "simd", ] } cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "32283d7" } -softbuffer = { git = "https://github.com/pop-os/softbuffer", tag = "cosmic-4.0" } +# Yoda: default-features=false drops softbuffer's x11 / x11-dlopen (pulled +# tiny-xlib + as-raw-xcb-connection). The wayland + wayland-dlopen features +# are re-activated via iced_tiny_skia's own `wayland` feature propagation. +softbuffer = { git = "https://github.com/pop-os/softbuffer", tag = "cosmic-4.0", default-features = false } syntect = "5.2" tokio = "1.0" tracing = "0.1" @@ -301,7 +304,11 @@ wayland-client = { version = "0.31.5" } winapi = "0.3" # window_clipboard = "0.4.1" -window_clipboard = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" } +# Yoda: window_clipboard via git path = our local fork that has x11 gated +# behind an opt-in feature. default-features=false + features=["wayland"] +# drops clipboard_x11 + x11rb from the build. +# Kept at /home/lionel/Devels/window_clipboard branch yoda-x11-optional. +window_clipboard = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20", default-features = false, features = ["wayland"] } dnd = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" } mime = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" } # Yoda: default-features = false drops winit's x11 default, which otherwise From ce5ea665e2d45042456232ee0cc989eef9a7c5e4 Mon Sep 17 00:00:00 2001 From: Votre Nom Date: Tue, 5 May 2026 08:27:03 +0200 Subject: [PATCH 66/72] Fix high-signal widget and Wayland warnings Avoid recursive operation traversal, execute visible list updates instead of leaving a lazy iterator unused, remove unreachable cfg-gated surface creation code, and handle subsurface buffer attachment failures. --- widget/src/container.rs | 2 +- winit/src/platform_specific/mod.rs | 7 +++++-- winit/src/platform_specific/wayland/subsurface_widget.rs | 5 ++++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/widget/src/container.rs b/widget/src/container.rs index c9a300c9..e4aeabf2 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -601,7 +601,7 @@ pub fn visible_bounds(id: Id) -> Task> { operate: &mut dyn FnMut(&mut dyn Operation>), ) { self.depth += 1; - self.traverse(operate); + operate(self); self.depth -= 1; } diff --git a/winit/src/platform_specific/mod.rs b/winit/src/platform_specific/mod.rs index 9b74ee9c..5e84d16a 100644 --- a/winit/src/platform_specific/mod.rs +++ b/winit/src/platform_specific/mod.rs @@ -153,9 +153,12 @@ impl PlatformSpecific { ) -> Option> { #[cfg(all(feature = "cctk", target_os = "linux"))] { - return self.wayland.create_surface(); + self.wayland.create_surface() + } + #[cfg(not(all(feature = "cctk", target_os = "linux")))] + { + None } - None } pub(crate) fn update_surface_shm( diff --git a/winit/src/platform_specific/wayland/subsurface_widget.rs b/winit/src/platform_specific/wayland/subsurface_widget.rs index dbecc52d..c3173fa9 100644 --- a/winit/src/platform_specific/wayland/subsurface_widget.rs +++ b/winit/src/platform_specific/wayland/subsurface_widget.rs @@ -409,7 +409,10 @@ impl SubsurfaceState { .unwrap(); canvas[0..width as usize * height as usize * 4].copy_from_slice(data); surface.damage_buffer(0, 0, width as i32, height as i32); - buffer.attach_to(&surface); + if let Err(err) = buffer.attach_to(&surface) { + log::warn!("failed to attach shm buffer to subsurface: {err}"); + return; + } surface.offset(offset.x as i32, offset.y as i32); wp_viewport.set_destination( (width as f64 / scale) as i32, From b90b1413a69acb3bdbed49d62c7a6e14d43170d3 Mon Sep 17 00:00:00 2001 From: Votre Nom Date: Tue, 5 May 2026 12:52:06 +0200 Subject: [PATCH 67/72] yoda: point window_clipboard at public Forgejo fork MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace pop-os/window_clipboard sctk-0.20 (no wayland feature) with forge.aditua.com/leyoda/window_clipboard branch yoda-x11-optional. This removes the need for cosmic-files' [patch] redirect to a local path and makes libcosmic build standalone again. Leyoda 2026 – GPLv3 --- Cargo.toml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f3d7b8f9..1a0b86f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -304,13 +304,13 @@ wayland-client = { version = "0.31.5" } winapi = "0.3" # window_clipboard = "0.4.1" -# Yoda: window_clipboard via git path = our local fork that has x11 gated -# behind an opt-in feature. default-features=false + features=["wayland"] -# drops clipboard_x11 + x11rb from the build. -# Kept at /home/lionel/Devels/window_clipboard branch yoda-x11-optional. -window_clipboard = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20", default-features = false, features = ["wayland"] } -dnd = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" } -mime = { git = "https://github.com/pop-os/window_clipboard.git", tag = "sctk-0.20" } +# Yoda: window_clipboard pinned to our public fork that has x11 gated behind +# an opt-in feature. default-features=false + features=["wayland"] drops +# clipboard_x11 + x11rb from the build. Branch yoda-x11-optional on +# https://forge.aditua.com/leyoda/window_clipboard. +window_clipboard = { git = "https://forge.aditua.com/leyoda/window_clipboard.git", branch = "yoda-x11-optional", default-features = false, features = ["wayland"] } +dnd = { git = "https://forge.aditua.com/leyoda/window_clipboard.git", branch = "yoda-x11-optional" } +mime = { git = "https://forge.aditua.com/leyoda/window_clipboard.git", branch = "yoda-x11-optional" } # Yoda: default-features = false drops winit's x11 default, which otherwise # pulls winit-x11, x11-dl, tiny-xlib, as-raw-xcb-connection. Our Wayland-only # fork doesn't need any of that — the wayland + wayland-dlopen features are From 4e2e58e03d5f01ce8a328a9128ac23fefd61ca39 Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Sat, 23 May 2026 20:55:59 +0200 Subject: [PATCH 68/72] chore: gate accessibility-only winit state --- winit/src/lib.rs | 2 ++ winit/src/window/state.rs | 1 + 2 files changed, 3 insertions(+) diff --git a/winit/src/lib.rs b/winit/src/lib.rs index 517eddbc..918f6c2a 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -186,6 +186,7 @@ where receiver: mpsc::UnboundedReceiver, error: Option, system_theme: Option>, + #[cfg(feature = "a11y")] control_sender: mpsc::UnboundedSender, #[cfg(feature = "a11y")] @@ -212,6 +213,7 @@ where id: settings.id, sender: event_sender, receiver: control_receiver, + #[cfg(feature = "a11y")] control_sender: control_sender.clone(), error: None, system_theme: Some(system_theme_sender), diff --git a/winit/src/window/state.rs b/winit/src/window/state.rs index 98fdf9ee..1e16fc51 100644 --- a/winit/src/window/state.rs +++ b/winit/src/window/state.rs @@ -97,6 +97,7 @@ where self.ready = ready; } + #[cfg(feature = "a11y")] pub(crate) fn set_a11y_ready(&mut self, ready: bool) { self.a11y_ready = ready; } From 3982e04aa2d876adfcdb5fbf3a7beecd18d5d63f Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Mon, 25 May 2026 18:09:40 +0200 Subject: [PATCH 69/72] chore: use local cctk and clipboard crates --- Cargo.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1a0b86f1..6496fc07 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -274,7 +274,7 @@ tiny-skia = { version = "0.11", default-features = false, features = [ "std", "simd", ] } -cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "32283d7" } +cctk = { path = "../../cosmic-protocols/client-toolkit", package = "cosmic-client-toolkit" } # Yoda: default-features=false drops softbuffer's x11 / x11-dlopen (pulled # tiny-xlib + as-raw-xcb-connection). The wayland + wayland-dlopen features # are re-activated via iced_tiny_skia's own `wayland` feature propagation. @@ -308,9 +308,9 @@ winapi = "0.3" # an opt-in feature. default-features=false + features=["wayland"] drops # clipboard_x11 + x11rb from the build. Branch yoda-x11-optional on # https://forge.aditua.com/leyoda/window_clipboard. -window_clipboard = { git = "https://forge.aditua.com/leyoda/window_clipboard.git", branch = "yoda-x11-optional", default-features = false, features = ["wayland"] } -dnd = { git = "https://forge.aditua.com/leyoda/window_clipboard.git", branch = "yoda-x11-optional" } -mime = { git = "https://forge.aditua.com/leyoda/window_clipboard.git", branch = "yoda-x11-optional" } +window_clipboard = { path = "../../window_clipboard", default-features = false, features = ["wayland"] } +dnd = { path = "../../window_clipboard/dnd" } +mime = { path = "../../window_clipboard/mime" } # Yoda: default-features = false drops winit's x11 default, which otherwise # pulls winit-x11, x11-dl, tiny-xlib, as-raw-xcb-connection. Our Wayland-only # fork doesn't need any of that — the wayland + wayland-dlopen features are From cf7828fb705bc1901dd9684d682c000b6ff66bc1 Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Mon, 25 May 2026 18:27:54 +0200 Subject: [PATCH 70/72] chore: use local glyphon and cosmic-text --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6496fc07..22151d21 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -238,8 +238,8 @@ async-std = "1.0" bitflags = "2.5" bytemuck = { version = "1.0", features = ["derive"] } bytes = "1.6" -cosmic-text = "0.19" -cryoglyph = { git = "https://github.com/iced-rs/cryoglyph.git", rev = "e429a025df36ab8145708acb309080ae3deec17a" } +cosmic-text = { path = "../../cosmic-text" } +cryoglyph = { package = "cryoglyph", path = "../../glyphon" } dark-light = "1.0" resvg = "0.45" web-sys = "0.3.69" From 362b4abb1558374686080db674b8f7c5868ae6ac Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Mon, 25 May 2026 19:36:22 +0200 Subject: [PATCH 71/72] chore: use local winit and softbuffer --- Cargo.lock | 14 -------------- Cargo.toml | 25 ++++++++++++++++++++++--- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 11a85d77..1f6f716f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1658,7 +1658,6 @@ dependencies = [ [[package]] name = "dpi" version = "0.1.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" [[package]] name = "drm" @@ -6275,7 +6274,6 @@ dependencies = [ [[package]] name = "smithay-clipboard" version = "0.8.0" -source = "git+https://github.com/pop-os/smithay-clipboard?tag=sctk-0.20#859b02c88f45c554049a67c6ddeec1692ce0e20b" dependencies = [ "libc", "raw-window-handle", @@ -6333,7 +6331,6 @@ dependencies = [ [[package]] name = "softbuffer" version = "0.4.1" -source = "git+https://github.com/pop-os/softbuffer?tag=cosmic-4.0#a3f77e251e7422803f693df6e3fc313c010c4dcb" dependencies = [ "as-raw-xcb-connection", "bytemuck", @@ -8517,7 +8514,6 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "bitflags 2.11.0", "cfg_aliases", @@ -8543,7 +8539,6 @@ dependencies = [ [[package]] name = "winit-android" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "android-activity", "bitflags 2.11.0", @@ -8558,7 +8553,6 @@ dependencies = [ [[package]] name = "winit-appkit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "bitflags 2.11.0", "block2 0.6.2", @@ -8580,7 +8574,6 @@ dependencies = [ [[package]] name = "winit-common" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "memmap2 0.9.10", "objc2 0.6.4", @@ -8595,7 +8588,6 @@ dependencies = [ [[package]] name = "winit-core" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "bitflags 2.11.0", "cursor-icon", @@ -8609,7 +8601,6 @@ dependencies = [ [[package]] name = "winit-orbital" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "bitflags 2.11.0", "dpi", @@ -8625,7 +8616,6 @@ dependencies = [ [[package]] name = "winit-uikit" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "bitflags 2.11.0", "block2 0.6.2", @@ -8645,7 +8635,6 @@ dependencies = [ [[package]] name = "winit-wayland" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "ahash", "bitflags 2.11.0", @@ -8671,7 +8660,6 @@ dependencies = [ [[package]] name = "winit-web" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "atomic-waker", "bitflags 2.11.0", @@ -8693,7 +8681,6 @@ dependencies = [ [[package]] name = "winit-win32" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "bitflags 2.11.0", "cursor-icon", @@ -8709,7 +8696,6 @@ dependencies = [ [[package]] name = "winit-x11" version = "0.31.0-beta.2" -source = "git+https://github.com/pop-os/winit.git?tag=cosmic-0.14#261cda54017f98a12dc55569c864430fe6770366" dependencies = [ "bitflags 2.11.0", "bytemuck", diff --git a/Cargo.toml b/Cargo.toml index 22151d21..c49fcf92 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -278,7 +278,7 @@ cctk = { path = "../../cosmic-protocols/client-toolkit", package = "cosmic-clien # Yoda: default-features=false drops softbuffer's x11 / x11-dlopen (pulled # tiny-xlib + as-raw-xcb-connection). The wayland + wayland-dlopen features # are re-activated via iced_tiny_skia's own `wayland` feature propagation. -softbuffer = { git = "https://github.com/pop-os/softbuffer", tag = "cosmic-4.0", default-features = false } +softbuffer = { path = "../../softbuffer", default-features = false } syntect = "5.2" tokio = "1.0" tracing = "0.1" @@ -315,10 +315,29 @@ mime = { path = "../../window_clipboard/mime" } # pulls winit-x11, x11-dl, tiny-xlib, as-raw-xcb-connection. Our Wayland-only # fork doesn't need any of that — the wayland + wayland-dlopen features are # re-enabled via iced_winit's own feature propagation from libcosmic-yoda. -winit = { git = "https://github.com/pop-os/winit.git", tag = "cosmic-0.14", default-features = false } -winit-core = { git = "https://github.com/pop-os/winit.git", tag = "cosmic-0.14" } +winit = { path = "../../winit/winit", default-features = false } +winit-core = { path = "../../winit/winit-core" } cursor-icon = "1.1.0" +[patch.'https://github.com/pop-os/softbuffer'] +softbuffer = { path = "../../softbuffer" } + +[patch.'https://github.com/pop-os/smithay-clipboard'] +smithay-clipboard = { path = "../../smithay-clipboard" } + +[patch.'https://github.com/pop-os/winit.git'] +dpi = { path = "../../winit/dpi" } +winit = { path = "../../winit/winit" } +winit-android = { path = "../../winit/winit-android" } +winit-appkit = { path = "../../winit/winit-appkit" } +winit-common = { path = "../../winit/winit-common" } +winit-core = { path = "../../winit/winit-core" } +winit-orbital = { path = "../../winit/winit-orbital" } +winit-uikit = { path = "../../winit/winit-uikit" } +winit-wayland = { path = "../../winit/winit-wayland" } +winit-web = { path = "../../winit/winit-web" } +winit-win32 = { path = "../../winit/winit-win32" } +winit-x11 = { path = "../../winit/winit-x11" } [workspace.lints.rust] rust_2018_idioms = { level = "deny", priority = -1 } From 1a57634add6e820c299f1c59664cd98098a9c348 Mon Sep 17 00:00:00 2001 From: Lionel DARNIS Date: Thu, 2 Jul 2026 19:01:15 +0200 Subject: [PATCH 72/72] yoda: cargo fix sweep post-rebase (unused imports/vars) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Leyoda 2026 – GPLv3 --- Cargo.lock | 89 +++++++------------------- core/src/element.rs | 2 +- core/src/overlay/group.rs | 2 +- core/src/widget/operation/search_id.rs | 2 +- graphics/src/image.rs | 2 - runtime/src/dnd.rs | 4 +- runtime/src/lib.rs | 1 - widget/src/container.rs | 2 +- widget/src/keyed/column.rs | 1 - widget/src/list.rs | 2 +- widget/src/mouse_area.rs | 1 - widget/src/pane_grid/content.rs | 2 +- widget/src/scrollable.rs | 3 +- widget/src/stack.rs | 1 - widget/src/themer.rs | 1 - widget/src/toggler.rs | 5 +- 16 files changed, 32 insertions(+), 88 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1f6f716f..b5d874b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1076,7 +1076,6 @@ dependencies = [ [[package]] name = "clipboard_macos" version = "0.1.0" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "objc", "objc-foundation", @@ -1086,22 +1085,12 @@ dependencies = [ [[package]] name = "clipboard_wayland" version = "0.2.2" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "dnd", "mime 0.1.0", "smithay-clipboard", ] -[[package]] -name = "clipboard_x11" -version = "0.4.2" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" -dependencies = [ - "thiserror 1.0.69", - "x11rb", -] - [[package]] name = "clock" version = "0.1.0" @@ -1294,7 +1283,6 @@ dependencies = [ [[package]] name = "cosmic-client-toolkit" version = "0.2.0" -source = "git+https://github.com/pop-os/cosmic-protocols?rev=a7d2d7a#a7d2d7a6188425f699eaddf7a025617ce56068ae" dependencies = [ "bitflags 2.11.0", "cosmic-protocols", @@ -1307,7 +1295,6 @@ dependencies = [ [[package]] name = "cosmic-protocols" version = "0.2.0" -source = "git+https://github.com/pop-os/cosmic-protocols?rev=a7d2d7a#a7d2d7a6188425f699eaddf7a025617ce56068ae" dependencies = [ "bitflags 2.11.0", "wayland-backend", @@ -1321,8 +1308,6 @@ dependencies = [ [[package]] name = "cosmic-text" version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be17b688510d934ce13f48a2beba700e11583e281e0fda99c22bb256a14eda73" dependencies = [ "bitflags 2.11.0", "fontdb", @@ -1340,6 +1325,7 @@ dependencies = [ "unicode-linebreak", "unicode-script", "unicode-segmentation", + "unicode-width", ] [[package]] @@ -1446,7 +1432,6 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "cryoglyph" version = "0.1.0" -source = "git+https://github.com/iced-rs/cryoglyph.git?rev=e429a025df36ab8145708acb309080ae3deec17a#e429a025df36ab8145708acb309080ae3deec17a" dependencies = [ "cosmic-text", "etagere", @@ -1623,7 +1608,6 @@ dependencies = [ [[package]] name = "dnd" version = "0.1.0" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "bitflags 2.11.0", "mime 0.1.0", @@ -1659,45 +1643,12 @@ dependencies = [ name = "dpi" version = "0.1.2" -[[package]] -name = "drm" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0f8a69e60d75ae7dab4ef26a59ca99f2a89d4c142089b537775ae0c198bdcde" -dependencies = [ - "bitflags 2.11.0", - "bytemuck", - "drm-ffi", - "drm-fourcc", - "rustix 0.38.44", -] - -[[package]] -name = "drm-ffi" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41334f8405792483e32ad05fbb9c5680ff4e84491883d2947a4757dc54cb2ac6" -dependencies = [ - "drm-sys", - "rustix 0.38.44", -] - [[package]] name = "drm-fourcc" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4" -[[package]] -name = "drm-sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d09ff881f92f118b11105ba5e34ff8f4adf27b30dae8f12e28c193af1c83176" -dependencies = [ - "libc", - "linux-raw-sys 0.6.5", -] - [[package]] name = "editor" version = "0.1.0" @@ -2420,7 +2371,7 @@ dependencies = [ "log", "presser", "thiserror 2.0.18", - "windows 0.57.0", + "windows 0.62.2", ] [[package]] @@ -3785,14 +3736,14 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.16" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +checksum = "c943259e342f1e06ff2da7a83eabdfe7f92ce10262688dbf1895ff0b3e6e4652" dependencies = [ "bitflags 2.11.0", "libc", "plain", - "redox_syscall 0.7.4", + "redox_syscall 0.9.0", ] [[package]] @@ -3822,12 +3773,6 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" -[[package]] -name = "linux-raw-sys" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7" - [[package]] name = "linux-raw-sys" version = "0.12.1" @@ -4053,7 +3998,6 @@ dependencies = [ [[package]] name = "mime" version = "0.1.0" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "smithay-clipboard", ] @@ -5479,6 +5423,16 @@ dependencies = [ "font-types", ] +[[package]] +name = "redox_event" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5018d583d6d2f5499352aea8d177e9067d1eb03ab17c78169d5ba7a30001b15" +dependencies = [ + "bitflags 2.11.0", + "libredox", +] + [[package]] name = "redox_syscall" version = "0.5.18" @@ -5490,9 +5444,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.7.4" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" +checksum = "c5102a6aaa05aa011a238e178e6bca86d2cb56fc9f586d37cb80f5bca6e07759" dependencies = [ "bitflags 2.11.0", ] @@ -6337,7 +6291,6 @@ dependencies = [ "cfg_aliases", "cocoa", "core-graphics", - "drm", "fastrand", "foreign-types 0.5.0", "js-sys", @@ -8005,12 +7958,10 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "window_clipboard" version = "0.4.1" -source = "git+https://github.com/pop-os/window_clipboard.git?tag=sctk-0.20#f68595ee0e62fbd6589f4709b5aaa5c3c7ea5f6c" dependencies = [ "clipboard-win", "clipboard_macos", "clipboard_wayland", - "clipboard_x11", "dnd", "mime 0.1.0", "raw-window-handle", @@ -8607,7 +8558,7 @@ dependencies = [ "libredox", "orbclient", "raw-window-handle", - "redox_syscall 0.7.4", + "redox_event", "smol_str", "tracing", "winit-core", @@ -9240,3 +9191,7 @@ dependencies = [ "syn", "winnow 0.7.15", ] + +[[patch.unused]] +name = "cosmic-freedesktop-icons" +version = "0.4.0" diff --git a/core/src/element.rs b/core/src/element.rs index f97ed6bc..dbe449c5 100644 --- a/core/src/element.rs +++ b/core/src/element.rs @@ -1,4 +1,4 @@ -use crate::event::{self, Event}; +use crate::event::Event; use crate::id::Id; use crate::layout; use crate::mouse; diff --git a/core/src/overlay/group.rs b/core/src/overlay/group.rs index ec0906e7..1a4ce672 100644 --- a/core/src/overlay/group.rs +++ b/core/src/overlay/group.rs @@ -3,7 +3,7 @@ use crate::mouse; use crate::overlay; use crate::renderer; use crate::widget; -use crate::{Clipboard, Event, Layout, Overlay, Point, Rectangle, Shell, Size}; +use crate::{Clipboard, Event, Layout, Overlay, Shell, Size}; /// An [`Overlay`] container that displays multiple overlay [`overlay::Element`] /// children. diff --git a/core/src/widget/operation/search_id.rs b/core/src/widget/operation/search_id.rs index 1286abaf..e03fac8a 100644 --- a/core/src/widget/operation/search_id.rs +++ b/core/src/widget/operation/search_id.rs @@ -4,7 +4,7 @@ use super::Operation; use crate::{ Rectangle, id::Id, - widget::operation::{Outcome, focusable::Count}, + widget::operation::Outcome, }; /// Produces an [`Operation`] that searches for the Id diff --git a/graphics/src/image.rs b/graphics/src/image.rs index e5fe9281..d9b23216 100644 --- a/graphics/src/image.rs +++ b/graphics/src/image.rs @@ -2,8 +2,6 @@ #[cfg(feature = "image")] use crate::core::Bytes; -use crate::core::Color; -use crate::core::Radians; use crate::core::Rectangle; use crate::core::image; use crate::core::svg; diff --git a/runtime/src/dnd.rs b/runtime/src/dnd.rs index 2a0db116..2e526eb6 100644 --- a/runtime/src/dnd.rs +++ b/runtime/src/dnd.rs @@ -1,10 +1,8 @@ //! Access the clipboard. -use std::any::Any; use dnd::{DndDestinationRectangle, DndSurface}; -use iced_core::clipboard::DndSource; -use window_clipboard::mime::{AllowedMimeTypes, AsMimeTypes}; +use window_clipboard::mime::AllowedMimeTypes; use crate::{Action, Task, oneshot, task}; diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 22da3d66..68034bfc 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -28,7 +28,6 @@ pub use task::Task; pub use user_interface::UserInterface; pub use window::Window; -use crate::core::Color; use crate::futures::futures::channel::oneshot; use std::borrow::Cow; diff --git a/widget/src/container.rs b/widget/src/container.rs index e4aeabf2..a264007a 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -35,7 +35,7 @@ use crate::core::{ color, }; -use iced_runtime::{Action, Task, task}; +use iced_runtime::{Task, task}; /// A widget that aligns its contents inside of its boundaries. /// diff --git a/widget/src/keyed/column.rs b/widget/src/keyed/column.rs index ef7d9d9a..bb98d606 100644 --- a/widget/src/keyed/column.rs +++ b/widget/src/keyed/column.rs @@ -1,7 +1,6 @@ //! Keyed columns distribute content vertically while keeping continuity. //! Distribute content vertically. -use crate::core::event; use crate::core::layout; use crate::core::mouse; use crate::core::overlay; diff --git a/widget/src/list.rs b/widget/src/list.rs index d7cadd50..9f33244e 100644 --- a/widget/src/list.rs +++ b/widget/src/list.rs @@ -1,5 +1,5 @@ #![allow(missing_docs)] -use crate::core::event::{self, Event}; +use crate::core::event::Event; use crate::core::layout; use crate::core::mouse; use crate::core::overlay; diff --git a/widget/src/mouse_area.rs b/widget/src/mouse_area.rs index 3d355c52..4d808348 100644 --- a/widget/src/mouse_area.rs +++ b/widget/src/mouse_area.rs @@ -2,7 +2,6 @@ use iced_renderer::core::mouse::Click; -use crate::core::event; use crate::core::layout; use crate::core::mouse; use crate::core::overlay; diff --git a/widget/src/pane_grid/content.rs b/widget/src/pane_grid/content.rs index a76010e7..4c41e3a6 100644 --- a/widget/src/pane_grid/content.rs +++ b/widget/src/pane_grid/content.rs @@ -6,7 +6,7 @@ use crate::core::renderer; use crate::core::widget::{self, Tree}; use crate::core::{ self, Clipboard, Element, Event, Layout, Point, Rectangle, Shell, Size, - Vector, event, + Vector, }; use crate::pane_grid::{Draggable, TitleBar}; diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index e005a7b8..c906b66e 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -27,7 +27,6 @@ use iced_runtime::core::widget::Id; #[cfg(feature = "a11y")] use std::borrow::Cow; -use crate::core::event; use crate::core::keyboard; use crate::core::layout; use crate::core::mouse; @@ -933,7 +932,7 @@ where let had_input_method = shell.input_method().is_enabled(); - let mut c_event = match event.clone() { + let c_event = match event.clone() { Event::Dnd(dnd::DndEvent::Offer( id, dnd::OfferEvent::Enter { diff --git a/widget/src/stack.rs b/widget/src/stack.rs index e85bf2af..cd30a886 100644 --- a/widget/src/stack.rs +++ b/widget/src/stack.rs @@ -1,6 +1,5 @@ //! Display content on top of other content. -use crate::core::event; use crate::core::layout; use crate::core::mouse; use crate::core::overlay; diff --git a/widget/src/themer.rs b/widget/src/themer.rs index 306c8580..76448ae1 100644 --- a/widget/src/themer.rs +++ b/widget/src/themer.rs @@ -1,6 +1,5 @@ use crate::container; -use crate::core::event; use crate::core::layout; use crate::core::mouse; use crate::core::overlay; diff --git a/widget/src/toggler.rs b/widget/src/toggler.rs index 6709f1dc..b4e66887 100644 --- a/widget/src/toggler.rs +++ b/widget/src/toggler.rs @@ -37,7 +37,6 @@ use std::borrow::Cow; use iced_runtime::core::border::Radius; use crate::core::alignment; -use crate::core::border; use crate::core::layout; use crate::core::mouse; use crate::core::renderer; @@ -510,7 +509,7 @@ where let space = style.handle_margin; - let toggler_background_bounds = Rectangle { + let _toggler_background_bounds = Rectangle { x: bounds.x, y: bounds.y, width: bounds.width, @@ -530,7 +529,7 @@ where style.background, ); - let padding = (style.padding_ratio * bounds.height).round(); + let _padding = (style.padding_ratio * bounds.height).round(); let toggler_foreground_bounds = Rectangle { x: bounds.x + if self.is_toggled {