wip: update

clippy

chore: update togglers

clippy
This commit is contained in:
Ashley Wulber 2024-10-07 15:55:28 -04:00 committed by Ashley Wulber
parent 47edd44c33
commit de179d06f3
48 changed files with 1120 additions and 1035 deletions

253
Cargo.lock generated
View file

@ -31,6 +31,18 @@ dependencies = [
"accesskit", "accesskit",
] ]
[[package]]
name = "accesskit_macos"
version = "0.11.0"
source = "git+https://github.com/wash2/accesskit.git?branch=winit-0.29#26f729169cd849970af02be62289606c63572d2d"
dependencies = [
"accesskit",
"accesskit_consumer",
"icrate 0.1.2",
"objc2 0.5.2",
"once_cell",
]
[[package]] [[package]]
name = "accesskit_unix" name = "accesskit_unix"
version = "0.7.1" version = "0.7.1"
@ -38,8 +50,12 @@ source = "git+https://github.com/wash2/accesskit.git?branch=winit-0.29#26f729169
dependencies = [ dependencies = [
"accesskit", "accesskit",
"accesskit_consumer", "accesskit_consumer",
"async-channel",
"async-executor",
"async-task",
"atspi", "atspi",
"futures-lite 1.13.0", "futures-lite 1.13.0",
"futures-util",
"once_cell", "once_cell",
"serde", "serde",
"tokio", "tokio",
@ -47,6 +63,32 @@ dependencies = [
"zbus 3.15.2", "zbus 3.15.2",
] ]
[[package]]
name = "accesskit_windows"
version = "0.16.0"
source = "git+https://github.com/wash2/accesskit.git?branch=winit-0.29#26f729169cd849970af02be62289606c63572d2d"
dependencies = [
"accesskit",
"accesskit_consumer",
"once_cell",
"paste",
"static_assertions",
"windows 0.48.0",
]
[[package]]
name = "accesskit_winit"
version = "0.18.1"
source = "git+https://github.com/wash2/accesskit.git?branch=winit-0.29#26f729169cd849970af02be62289606c63572d2d"
dependencies = [
"accesskit",
"accesskit_macos",
"accesskit_unix",
"accesskit_windows",
"raw-window-handle",
"winit",
]
[[package]] [[package]]
name = "addr2line" name = "addr2line"
version = "0.21.0" version = "0.21.0"
@ -228,9 +270,9 @@ dependencies = [
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.89" version = "1.0.90"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95"
[[package]] [[package]]
name = "apply" name = "apply"
@ -309,7 +351,7 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd884d7c72877a94102c3715f3b1cd09ff4fac28221add3e57cfbe25c236d093" checksum = "dd884d7c72877a94102c3715f3b1cd09ff4fac28221add3e57cfbe25c236d093"
dependencies = [ dependencies = [
"async-fs", "async-fs 2.1.2",
"async-net", "async-net",
"enumflags2", "enumflags2",
"futures-channel", "futures-channel",
@ -399,6 +441,18 @@ dependencies = [
"slab", "slab",
] ]
[[package]]
name = "async-fs"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06"
dependencies = [
"async-lock 2.8.0",
"autocfg",
"blocking",
"futures-lite 1.13.0",
]
[[package]] [[package]]
name = "async-fs" name = "async-fs"
version = "2.1.2" version = "2.1.2"
@ -648,9 +702,9 @@ dependencies = [
[[package]] [[package]]
name = "avif-serialize" name = "avif-serialize"
version = "0.8.1" version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" checksum = "e335041290c43101ca215eed6f43ec437eb5a42125573f600fc3fa42b9bddd62"
dependencies = [ dependencies = [
"arrayvec", "arrayvec",
] ]
@ -797,7 +851,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68"
dependencies = [ dependencies = [
"block-sys", "block-sys",
"objc2", "objc2 0.4.1",
]
[[package]]
name = "block2"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e58aa60e59d8dbfcc36138f5f18be5f24394d33b38b24f7fd0b1caa33095f22f"
dependencies = [
"block-sys",
"objc2 0.5.2",
] ]
[[package]] [[package]]
@ -850,9 +914,9 @@ dependencies = [
[[package]] [[package]]
name = "built" name = "built"
version = "0.7.4" version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "236e6289eda5a812bc6b53c3b024039382a2895fbbeef2d748b2931546d392c4" checksum = "c360505aed52b7ec96a3636c3f039d99103c37d1d9b4f7a8c743d3ea9ffcd03b"
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
@ -901,9 +965,9 @@ dependencies = [
[[package]] [[package]]
name = "bytemuck" name = "bytemuck"
version = "1.18.0" version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d"
dependencies = [ dependencies = [
"bytemuck_derive", "bytemuck_derive",
] ]
@ -1427,7 +1491,7 @@ dependencies = [
"colorgrad", "colorgrad",
"cosmic-config", "cosmic-config",
"derive_setters", "derive_setters",
"image 0.25.2", "image 0.25.4",
"ron", "ron",
"serde", "serde",
"tracing", "tracing",
@ -1592,7 +1656,7 @@ dependencies = [
"i18n-embed", "i18n-embed",
"i18n-embed-fl", "i18n-embed-fl",
"icu", "icu",
"image 0.25.2", "image 0.25.4",
"indexmap 2.6.0", "indexmap 2.6.0",
"itertools 0.13.0", "itertools 0.13.0",
"itoa", "itoa",
@ -1660,7 +1724,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-settings-subscriptions" name = "cosmic-settings-subscriptions"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/cosmic-settings-subscriptions#ece1b2475c9eb90e0f2042b743577670e799a010" source = "git+https://github.com/pop-os/cosmic-settings-subscriptions#ff9883a029b44fb8eafb7c7a06d08b36a563e481"
dependencies = [ dependencies = [
"cosmic-dbus-networkmanager", "cosmic-dbus-networkmanager",
"futures", "futures",
@ -1704,7 +1768,7 @@ dependencies = [
"freedesktop-icons", "freedesktop-icons",
"futures-lite 2.3.0", "futures-lite 2.3.0",
"futures-util", "futures-util",
"image 0.25.2", "image 0.25.4",
"infer", "infer",
"jxl-oxide", "jxl-oxide",
"tokio", "tokio",
@ -2317,7 +2381,7 @@ dependencies = [
"bytemuck", "bytemuck",
"cfg-if", "cfg-if",
"document-features", "document-features",
"image 0.25.2", "image 0.25.4",
"num-traits", "num-traits",
"thiserror", "thiserror",
] ]
@ -2354,7 +2418,7 @@ checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"libredox 0.1.3", "libredox",
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
@ -2754,9 +2818,9 @@ dependencies = [
[[package]] [[package]]
name = "gettext-rs" name = "gettext-rs"
version = "0.7.1" version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a6716b8a0db461a2720b850ba1623e5b69e4b1aa0224cf5e1fb23a0fe49e65c" checksum = "a44e92f7dc08430aca7ed55de161253a22276dfd69c5526e5c5e95d1f7cf338a"
dependencies = [ dependencies = [
"gettext-sys", "gettext-sys",
"locale_config", "locale_config",
@ -2764,9 +2828,9 @@ dependencies = [
[[package]] [[package]]
name = "gettext-sys" name = "gettext-sys"
version = "0.21.4" version = "0.22.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7b8797f28f2dabfbe2caadb6db4f7fd739e251b5ede0a2ba49e506071edcf67" checksum = "bb45773f5b8945f12aecd04558f545964f943dacda1b1155b3d738f5469ef661"
dependencies = [ dependencies = [
"cc", "cc",
"temp-dir", "temp-dir",
@ -3145,6 +3209,7 @@ source = "git+https://github.com/pop-os/libcosmic#100f75f88edc5b602e29587fd6698d
dependencies = [ dependencies = [
"accesskit", "accesskit",
"accesskit_unix", "accesskit_unix",
"accesskit_winit",
] ]
[[package]] [[package]]
@ -3240,6 +3305,7 @@ dependencies = [
"enum-repr", "enum-repr",
"float-cmp", "float-cmp",
"futures", "futures",
"iced_accessibility",
"iced_futures", "iced_futures",
"iced_graphics", "iced_graphics",
"iced_runtime", "iced_runtime",
@ -3320,6 +3386,7 @@ version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#100f75f88edc5b602e29587fd6698dbf0038901d" source = "git+https://github.com/pop-os/libcosmic#100f75f88edc5b602e29587fd6698dbf0038901d"
dependencies = [ dependencies = [
"dnd", "dnd",
"iced_accessibility",
"iced_renderer", "iced_renderer",
"iced_runtime", "iced_runtime",
"iced_style", "iced_style",
@ -3337,6 +3404,7 @@ version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#100f75f88edc5b602e29587fd6698dbf0038901d" source = "git+https://github.com/pop-os/libcosmic#100f75f88edc5b602e29587fd6698dbf0038901d"
dependencies = [ dependencies = [
"dnd", "dnd",
"iced_accessibility",
"iced_graphics", "iced_graphics",
"iced_runtime", "iced_runtime",
"iced_style", "iced_style",
@ -3355,9 +3423,19 @@ version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319"
dependencies = [ dependencies = [
"block2", "block2 0.3.0",
"dispatch", "dispatch",
"objc2", "objc2 0.4.1",
]
[[package]]
name = "icrate"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb69199826926eb864697bddd27f73d9fddcffc004f5733131e15b465e30642"
dependencies = [
"block2 0.4.0",
"objc2 0.5.2",
] ]
[[package]] [[package]]
@ -3790,9 +3868,9 @@ dependencies = [
[[package]] [[package]]
name = "image" name = "image"
version = "0.25.2" version = "0.25.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99314c8a2152b8ddb211f924cdae532d8c5e4c8bb54728e12fff1b0cd5963a10" checksum = "bc144d44a31d753b02ce64093d532f55ff8dc4ebf2ffb8a63c0dda691385acae"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"byteorder-lite", "byteorder-lite",
@ -3813,9 +3891,9 @@ dependencies = [
[[package]] [[package]]
name = "image-webp" name = "image-webp"
version = "0.1.3" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f79afb8cbee2ef20f59ccd477a218c12a93943d075b492015ecb1bb81f8ee904" checksum = "e031e8e3d94711a9ccb5d6ea357439ef3dcbed361798bd4071dc4d9793fbe22f"
dependencies = [ dependencies = [
"byteorder-lite", "byteorder-lite",
"quick-error", "quick-error",
@ -3829,9 +3907,9 @@ checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284"
[[package]] [[package]]
name = "imgref" name = "imgref"
version = "1.10.1" version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408"
[[package]] [[package]]
name = "indenter" name = "indenter"
@ -4280,9 +4358,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.159" version = "0.2.161"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
[[package]] [[package]]
name = "libcosmic" name = "libcosmic"
@ -4301,6 +4379,7 @@ dependencies = [
"fraction", "fraction",
"freedesktop-icons", "freedesktop-icons",
"iced", "iced",
"iced_accessibility",
"iced_core", "iced_core",
"iced_futures", "iced_futures",
"iced_renderer", "iced_renderer",
@ -4310,6 +4389,7 @@ dependencies = [
"iced_tiny_skia", "iced_tiny_skia",
"iced_wgpu", "iced_wgpu",
"iced_widget", "iced_widget",
"iced_winit",
"lazy_static", "lazy_static",
"palette", "palette",
"rfd", "rfd",
@ -4354,7 +4434,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"windows-targets 0.52.6", "windows-targets 0.48.5",
] ]
[[package]] [[package]]
@ -4390,17 +4470,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "libredox"
version = "0.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607"
dependencies = [
"bitflags 2.6.0",
"libc",
"redox_syscall 0.4.1",
]
[[package]] [[package]]
name = "libredox" name = "libredox"
version = "0.1.3" version = "0.1.3"
@ -5035,7 +5104,7 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
dependencies = [ dependencies = [
"proc-macro-crate 3.2.0", "proc-macro-crate 1.3.1",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.79", "syn 2.0.79",
@ -5075,7 +5144,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d"
dependencies = [ dependencies = [
"objc-sys", "objc-sys",
"objc2-encode", "objc2-encode 3.0.0",
]
[[package]]
name = "objc2"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804"
dependencies = [
"objc-sys",
"objc2-encode 4.0.3",
] ]
[[package]] [[package]]
@ -5084,6 +5163,12 @@ version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666"
[[package]]
name = "objc2-encode"
version = "4.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8"
[[package]] [[package]]
name = "objc_exception" name = "objc_exception"
version = "0.1.2" version = "0.1.2"
@ -5125,11 +5210,11 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]] [[package]]
name = "orbclient" name = "orbclient"
version = "0.3.47" version = "0.3.48"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" checksum = "ba0b26cec2e24f08ed8bb31519a9333140a6599b867dac464bb150bdb796fd43"
dependencies = [ dependencies = [
"libredox 0.0.2", "libredox",
] ]
[[package]] [[package]]
@ -5541,18 +5626,18 @@ dependencies = [
[[package]] [[package]]
name = "profiling" name = "profiling"
version = "1.0.15" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d"
dependencies = [ dependencies = [
"profiling-procmacros", "profiling-procmacros",
] ]
[[package]] [[package]]
name = "profiling-procmacros" name = "profiling-procmacros"
version = "1.0.15" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30"
dependencies = [ dependencies = [
"quote", "quote",
"syn 2.0.79", "syn 2.0.79",
@ -5696,9 +5781,9 @@ dependencies = [
[[package]] [[package]]
name = "ravif" name = "ravif"
version = "0.11.10" version = "0.11.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f0bfd976333248de2078d350bfdf182ff96e168a24d23d2436cef320dd4bdd" checksum = "2413fd96bd0ea5cdeeb37eaf446a22e6ed7b981d792828721e74ded1980a45c6"
dependencies = [ dependencies = [
"avif-serialize", "avif-serialize",
"imgref", "imgref",
@ -5793,7 +5878,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
dependencies = [ dependencies = [
"getrandom", "getrandom",
"libredox 0.1.3", "libredox",
"thiserror", "thiserror",
] ]
@ -6068,9 +6153,9 @@ dependencies = [
[[package]] [[package]]
name = "rustversion" name = "rustversion"
version = "1.0.17" version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
[[package]] [[package]]
name = "rustybuzz" name = "rustybuzz"
@ -6210,9 +6295,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.128" version = "1.0.130"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" checksum = "610f75ff4a8e3cb29b85da56eabdd1bff5b06739059a4b8e2967fef32e5d9944"
dependencies = [ dependencies = [
"indexmap 2.6.0", "indexmap 2.6.0",
"itoa", "itoa",
@ -7384,9 +7469,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "1.10.0" version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
[[package]] [[package]]
name = "v_frame" name = "v_frame"
@ -7708,7 +7793,7 @@ dependencies = [
"js-sys", "js-sys",
"log", "log",
"naga", "naga",
"parking_lot 0.12.3", "parking_lot 0.11.2",
"profiling", "profiling",
"raw-window-handle", "raw-window-handle",
"smallvec", "smallvec",
@ -7735,7 +7820,7 @@ dependencies = [
"log", "log",
"naga", "naga",
"once_cell", "once_cell",
"parking_lot 0.12.3", "parking_lot 0.11.2",
"profiling", "profiling",
"raw-window-handle", "raw-window-handle",
"rustc-hash", "rustc-hash",
@ -7775,7 +7860,7 @@ dependencies = [
"naga", "naga",
"objc", "objc",
"once_cell", "once_cell",
"parking_lot 0.12.3", "parking_lot 0.11.2",
"profiling", "profiling",
"range-alloc", "range-alloc",
"raw-window-handle", "raw-window-handle",
@ -7827,7 +7912,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.48.0",
] ]
[[package]] [[package]]
@ -7857,6 +7942,8 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
dependencies = [ dependencies = [
"windows-implement 0.48.0",
"windows-interface 0.48.0",
"windows-targets 0.48.5", "windows-targets 0.48.5",
] ]
@ -7895,12 +7982,23 @@ version = "0.57.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
dependencies = [ dependencies = [
"windows-implement", "windows-implement 0.57.0",
"windows-interface", "windows-interface 0.57.0",
"windows-result", "windows-result",
"windows-targets 0.52.6", "windows-targets 0.52.6",
] ]
[[package]]
name = "windows-implement"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e2ee588991b9e7e6c8338edf3333fbe4da35dc72092643958ebb43f0ab2c49c"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]] [[package]]
name = "windows-implement" name = "windows-implement"
version = "0.57.0" version = "0.57.0"
@ -7912,6 +8010,17 @@ dependencies = [
"syn 2.0.79", "syn 2.0.79",
] ]
[[package]]
name = "windows-interface"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6fb8df20c9bcaa8ad6ab513f7b40104840c8867d5751126e4df3b08388d0cc7"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]] [[package]]
name = "windows-interface" name = "windows-interface"
version = "0.57.0" version = "0.57.0"
@ -8161,14 +8270,14 @@ dependencies = [
"core-foundation", "core-foundation",
"core-graphics", "core-graphics",
"cursor-icon", "cursor-icon",
"icrate", "icrate 0.0.4",
"js-sys", "js-sys",
"libc", "libc",
"log", "log",
"memmap2 0.9.5", "memmap2 0.9.5",
"ndk", "ndk",
"ndk-sys", "ndk-sys",
"objc2", "objc2 0.4.1",
"once_cell", "once_cell",
"orbclient", "orbclient",
"percent-encoding", "percent-encoding",
@ -8405,9 +8514,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6" checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6"
dependencies = [ dependencies = [
"async-broadcast 0.5.1", "async-broadcast 0.5.1",
"async-executor",
"async-fs 1.6.0",
"async-io 1.13.0",
"async-lock 2.8.0",
"async-process 1.8.1", "async-process 1.8.1",
"async-recursion", "async-recursion",
"async-task",
"async-trait", "async-trait",
"blocking",
"byteorder", "byteorder",
"derivative", "derivative",
"enumflags2", "enumflags2",
@ -8442,7 +8557,7 @@ checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725"
dependencies = [ dependencies = [
"async-broadcast 0.7.1", "async-broadcast 0.7.1",
"async-executor", "async-executor",
"async-fs", "async-fs 2.1.2",
"async-io 2.3.4", "async-io 2.3.4",
"async-lock 3.4.0", "async-lock 3.4.0",
"async-process 2.3.0", "async-process 2.3.0",

View file

@ -11,16 +11,18 @@ cosmic-randr = { git = "https://github.com/pop-os/cosmic-randr" }
tokio = { version = "1.40.0", features = ["macros"] } tokio = { version = "1.40.0", features = ["macros"] }
[workspace.dependencies.libcosmic] [workspace.dependencies.libcosmic]
git = "https://github.com/pop-os/libcosmic"
features = [ features = [
"a11y",
"dbus-config", "dbus-config",
"single-instance", "single-instance",
"multi-window", "multi-window",
"winit",
"tokio", "tokio",
"wayland", "wayland",
"wgpu", "wgpu",
"xdg-portal", "xdg-portal",
] ]
git = "https://github.com/pop-os/libcosmic"
[workspace.dependencies.cosmic-config] [workspace.dependencies.cosmic-config]
git = "https://github.com/pop-os/libcosmic" git = "https://github.com/pop-os/libcosmic"
@ -44,8 +46,8 @@ package = "smithay-client-toolkit"
# rev = "c583de8" # rev = "c583de8"
[profile.release] [profile.release]
opt-level = 3 opt-level = 1
lto = "thin" # lto = "thin"
# [patch.'https://github.com/smithay/client-toolkit/'] # [patch.'https://github.com/smithay/client-toolkit/']
# smithay-client-toolkit = { git = "https://github.com/smithay/client-toolkit//", rev = "c583de8" } # smithay-client-toolkit = { git = "https://github.com/smithay/client-toolkit//", rev = "c583de8" }

View file

@ -4,25 +4,22 @@
use crate::config::Config; use crate::config::Config;
use crate::pages::desktop::{ use crate::pages::desktop::{
self, appearance, dock, self, appearance, dock,
panel::{ panel::{self, applets_inner, inner as _panel},
self,
applets_inner::{self, APPLET_DND_ICON_ID},
inner as _panel,
},
}; };
use crate::pages::input::{self}; use crate::pages::input::{self};
use crate::pages::{self, bluetooth, display, networking, power, sound, system, time}; use crate::pages::{self, bluetooth, display, networking, power, sound, system, time};
use crate::subscription::desktop_files; use crate::subscription::desktop_files;
use crate::widget::{page_title, search_header}; use crate::widget::{page_title, search_header};
use crate::PageCommands; use crate::PageCommands;
use cosmic::app::command::set_theme;
use cosmic::app::DbusActivationMessage; use cosmic::app::DbusActivationMessage;
use cosmic::cctk::sctk::output::OutputInfo; use cosmic::cctk::sctk::output::OutputInfo;
use cosmic::cctk::wayland_client::protocol::wl_output::WlOutput; use cosmic::cctk::wayland_client::protocol::wl_output::WlOutput;
use cosmic::iced::futures::SinkExt; use cosmic::iced::futures::SinkExt;
use cosmic::iced::Subscription; use cosmic::iced::{stream, Subscription};
use cosmic::widget::{self, button, row, text_input}; use cosmic::widget::{self, button, row, text_input};
use cosmic::{ use cosmic::{
app::{Command, Core}, app::{Core, Task},
iced::{ iced::{
self, self,
event::{self, wayland, PlatformSpecific}, event::{self, wayland, PlatformSpecific},
@ -55,7 +52,7 @@ pub struct SettingsApp {
} }
impl SettingsApp { impl SettingsApp {
fn subcommand_to_page(&self, cmd: &PageCommands) -> Option<Entity> { fn subTask_to_page(&self, cmd: &PageCommands) -> Option<Entity> {
match cmd { match cmd {
PageCommands::About => self.pages.page_id::<system::about::Page>(), PageCommands::About => self.pages.page_id::<system::about::Page>(),
PageCommands::Appearance => self.pages.page_id::<desktop::appearance::Page>(), PageCommands::Appearance => self.pages.page_id::<desktop::appearance::Page>(),
@ -131,7 +128,7 @@ impl cosmic::Application for SettingsApp {
&mut self.core &mut self.core
} }
fn init(core: Core, flags: Self::Flags) -> (Self, Command<Self::Message>) { fn init(core: Core, flags: Self::Flags) -> (Self, Task<Self::Message>) {
let mut app = SettingsApp { let mut app = SettingsApp {
active_page: page::Entity::default(), active_page: page::Entity::default(),
config: Config::new(), config: Config::new(),
@ -155,8 +152,8 @@ impl cosmic::Application for SettingsApp {
app.insert_page::<time::Page>(); app.insert_page::<time::Page>();
app.insert_page::<system::Page>(); app.insert_page::<system::Page>();
let active_id = match flags.subcommand { let active_id = match flags.sub_command {
Some(p) => app.subcommand_to_page(&p), Some(p) => app.subTask_to_page(&p),
None => app None => app
.pages .pages
.find_page_by_id(&app.config.active_page) .find_page_by_id(&app.config.active_page)
@ -196,24 +193,24 @@ impl cosmic::Application for SettingsApp {
widgets widgets
} }
fn on_escape(&mut self) -> Command<Self::Message> { fn on_escape(&mut self) -> Task<Self::Message> {
if self.search_active { if self.search_active {
self.search_active = false; self.search_active = false;
self.search_clear(); self.search_clear();
} }
Command::none() Task::none()
} }
fn on_nav_select(&mut self, id: nav_bar::Id) -> Command<Self::Message> { fn on_nav_select(&mut self, id: nav_bar::Id) -> Task<Self::Message> {
if let Some(page) = self.nav_model.data::<page::Entity>(id).copied() { if let Some(page) = self.nav_model.data::<page::Entity>(id).copied() {
return self.activate_page(page); return self.activate_page(page);
} }
Command::none() Task::none()
} }
fn on_search(&mut self) -> Command<Self::Message> { fn on_search(&mut self) -> Task<Self::Message> {
self.search_active = true; self.search_active = true;
cosmic::widget::text_input::focus(self.search_id.clone()) cosmic::widget::text_input::focus(self.search_id.clone())
} }
@ -221,7 +218,7 @@ impl cosmic::Application for SettingsApp {
fn subscription(&self) -> Subscription<Message> { fn subscription(&self) -> Subscription<Message> {
// Handling of Wayland-specific events received. // Handling of Wayland-specific events received.
let wayland_events = let wayland_events =
event::listen_with(|event, _| match event { event::listen_with(|event, _, id| match event {
iced::Event::PlatformSpecific(PlatformSpecific::Wayland( iced::Event::PlatformSpecific(PlatformSpecific::Wayland(
wayland::Event::Output(wayland::OutputEvent::Created(Some(info)), o), wayland::Event::Output(wayland::OutputEvent::Created(Some(info)), o),
)) if info.name.is_some() => Some(Message::OutputAdded(info, o)), )) if info.name.is_some() => Some(Message::OutputAdded(info, o)),
@ -234,10 +231,9 @@ impl cosmic::Application for SettingsApp {
Subscription::batch(vec![ Subscription::batch(vec![
// Creates a channel that listens to messages from pages. // Creates a channel that listens to messages from pages.
// The sender is given back to the application so that it may pass it on. // The sender is given back to the application so that it may pass it on.
cosmic::iced::subscription::channel( Subscription::run_with_id(
std::any::TypeId::of::<Self>(), std::any::TypeId::of::<Self>(),
4, stream::channel(4, move |mut output| async move {
move |mut output| async move {
let (tx, mut rx) = tokio::sync::mpsc::channel::<pages::Message>(4); let (tx, mut rx) = tokio::sync::mpsc::channel::<pages::Message>(4);
let _res = output.send(Message::RegisterSubscriptionSender(tx)).await; let _res = output.send(Message::RegisterSubscriptionSender(tx)).await;
@ -247,7 +243,7 @@ impl cosmic::Application for SettingsApp {
} }
futures::future::pending().await futures::future::pending().await
}, }),
), ),
crate::subscription::daytime().map(|daytime| { crate::subscription::daytime().map(|daytime| {
Message::PageMessage(pages::Message::Appearance(appearance::Message::Daytime( Message::PageMessage(pages::Message::Appearance(appearance::Message::Daytime(
@ -289,7 +285,7 @@ impl cosmic::Application for SettingsApp {
} }
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
fn update(&mut self, message: Message) -> Command<Self::Message> { fn update(&mut self, message: Message) -> Task<Self::Message> {
match message { match message {
Message::Page(page) => return self.activate_page(page), Message::Page(page) => return self.activate_page(page),
@ -545,30 +541,30 @@ impl cosmic::Application for SettingsApp {
} }
Message::PanelConfig(config) if config.name.to_lowercase().contains("panel") => { Message::PanelConfig(config) if config.name.to_lowercase().contains("panel") => {
let mut commands = Vec::new(); let mut tasks = Vec::new();
if let Some(page) = self.pages.page_mut::<panel::Page>() { if let Some(page) = self.pages.page_mut::<panel::Page>() {
commands.push( tasks.push(
page.update(panel::Message(_panel::Message::PanelConfig(config.clone()))) page.update(panel::Message(_panel::Message::PanelConfig(config.clone())))
.map(Into::into), .map(Into::into),
); );
} }
if let Some(page) = self.pages.page_mut::<applets_inner::Page>() { if let Some(page) = self.pages.page_mut::<applets_inner::Page>() {
commands.push( tasks.push(
page.update(applets_inner::Message::PanelConfig(config)) page.update(applets_inner::Message::PanelConfig(config))
.map(Into::into), .map(Into::into),
); );
} }
return Command::batch(commands); return Task::batch(tasks);
} }
Message::PanelConfig(config) if config.name.to_lowercase().contains("dock") => { Message::PanelConfig(config) if config.name.to_lowercase().contains("dock") => {
let mut commands = Vec::new(); let mut tasks = Vec::new();
if let Some(page) = self.pages.page_mut::<dock::Page>() { if let Some(page) = self.pages.page_mut::<dock::Page>() {
commands.push( tasks.push(
page.update(dock::Message::Inner(_panel::Message::PanelConfig( page.update(dock::Message::Inner(_panel::Message::PanelConfig(
config.clone(), config.clone(),
))) )))
@ -577,7 +573,7 @@ impl cosmic::Application for SettingsApp {
} }
if let Some(page) = self.pages.page_mut::<dock::applets::Page>() { if let Some(page) = self.pages.page_mut::<dock::applets::Page>() {
commands.push( tasks.push(
page.update(dock::applets::Message(applets_inner::Message::PanelConfig( page.update(dock::applets::Message(applets_inner::Message::PanelConfig(
config, config,
))) )))
@ -585,7 +581,7 @@ impl cosmic::Application for SettingsApp {
); );
} }
return Command::batch(commands); return Task::batch(tasks);
} }
Message::PanelConfig(_) => {} Message::PanelConfig(_) => {}
@ -609,7 +605,7 @@ impl cosmic::Application for SettingsApp {
} }
} }
Message::SetTheme(t) => return cosmic::app::command::set_theme(t), Message::SetTheme(t) => return set_theme(t),
Message::OpenContextDrawer(title) => { Message::OpenContextDrawer(title) => {
self.core.window.show_context = true; self.core.window.show_context = true;
@ -638,21 +634,21 @@ impl cosmic::Application for SettingsApp {
} }
} }
Command::none() Task::none()
} }
fn dbus_activation(&mut self, msg: DbusActivationMessage) -> Command<Self::Message> { fn dbus_activation(&mut self, msg: DbusActivationMessage) -> Task<Self::Message> {
match msg.msg { match msg.msg {
cosmic::app::DbusActivationDetails::Activate cosmic::app::DbusActivationDetails::Activate
| cosmic::app::DbusActivationDetails::Open { .. } => None, | cosmic::app::DbusActivationDetails::Open { .. } => None,
cosmic::app::DbusActivationDetails::ActivateAction { action, .. } => { cosmic::app::DbusActivationDetails::ActivateAction { action, .. } => {
PageCommands::from_str(&action) PageCommands::from_str(&action)
.ok() .ok()
.and_then(|action| self.subcommand_to_page(&action)) .and_then(|action| self.subTask_to_page(&action))
.map(|e| self.activate_page(e)) .map(|e| self.activate_page(e))
} }
} }
.unwrap_or_else(Command::none) .unwrap_or_else(Task::none)
} }
fn view(&self) -> Element<Message> { fn view(&self) -> Element<Message> {
@ -699,7 +695,7 @@ impl cosmic::Application for SettingsApp {
} }
fn on_close_requested(&self, id: window::Id) -> Option<Self::Message> { fn on_close_requested(&self, id: window::Id) -> Option<Self::Message> {
if id == window::Id::MAIN { if id == self.core.main_window_id().unwrap() {
std::thread::spawn(|| { std::thread::spawn(|| {
std::thread::sleep(tokio::time::Duration::from_millis(100)); std::thread::sleep(tokio::time::Duration::from_millis(100));
std::process::exit(0); std::process::exit(0);
@ -711,17 +707,17 @@ impl cosmic::Application for SettingsApp {
impl SettingsApp { impl SettingsApp {
/// Activates a page. /// Activates a page.
fn activate_page(&mut self, page: page::Entity) -> Command<crate::Message> { fn activate_page(&mut self, page: page::Entity) -> Task<crate::Message> {
let current_page = self.active_page; let current_page = self.active_page;
self.active_page = page; self.active_page = page;
let mut leave_command = iced::Command::none(); let mut leave_task = iced::Task::none();
if current_page != page { if current_page != page {
leave_command = self leave_task = self
.pages .pages
.on_leave(current_page) .on_leave(current_page)
.unwrap_or(iced::Command::none()) .unwrap_or(iced::Task::none())
.map(Message::PageMessage) .map(Message::PageMessage)
.map(Into::into); .map(Into::into);
self.config.active_page = Box::from(&*self.pages.info[page].id); self.config.active_page = Box::from(&*self.pages.info[page].id);
@ -738,26 +734,26 @@ impl SettingsApp {
.clone() .clone()
.expect("sender should be available"); .expect("sender should be available");
let page_command = self let page_task = self
.pages .pages
.on_enter(page, sender) .on_enter(page, sender)
.map(Message::PageMessage) .map(Message::PageMessage)
.map(Into::into); .map(Into::into);
Command::batch(vec![ Task::batch(vec![
leave_command, leave_task,
page_command, page_task,
cosmic::command::future(async { Message::SetWindowTitle }), cosmic::command::future(async { Message::SetWindowTitle }),
]) ])
} }
fn set_title(&mut self) -> Command<crate::Message> { fn set_title(&mut self) -> Task<crate::Message> {
self.set_window_title( self.set_window_title(
format!( format!(
"{} - COSMIC Settings", "{} - COSMIC Settings",
self.pages.info[self.active_page].title self.pages.info[self.active_page].title
), ),
window::Id::MAIN, self.core.main_window_id().unwrap(),
) )
} }
@ -806,14 +802,14 @@ impl SettingsApp {
custom_header.map(Message::from) custom_header.map(Message::from)
} else if let Some(parent) = page_info.parent { } else if let Some(parent) = page_info.parent {
let page_header = crate::widget::sub_page_header( let page_header = crate::widget::sub_page_header(
page.title().unwrap_or_else(|| page_info.title.as_str()), page.title().unwrap_or(page_info.title.as_str()),
self.pages.info[parent].title.as_str(), self.pages.info[parent].title.as_str(),
Message::Page(parent), Message::Page(parent),
); );
let mut page_header_content: cosmic::iced_widget::Row<'_, Message, Theme> = let mut page_header_content: cosmic::iced_widget::Row<'_, Message, Theme> =
row::with_capacity(2) row::with_capacity(2)
.align_items(iced::Alignment::End) .align_y(iced::Alignment::End)
.push(page_header); .push(page_header);
if let Some(element) = page.header_view() { if let Some(element) = page.header_view() {
@ -849,7 +845,7 @@ impl SettingsApp {
widget::column::with_capacity(3) widget::column::with_capacity(3)
.push(self.page_container(header)) .push(self.page_container(header))
.push(widget::vertical_space(Length::Fixed( .push(widget::vertical_space().height(Length::Fixed(
cosmic::theme::active().cosmic().space_m().into(), cosmic::theme::active().cosmic().space_m().into(),
))) )))
.push(view) .push(view)
@ -953,7 +949,7 @@ impl SettingsApp {
widget::column::with_capacity(3) widget::column::with_capacity(3)
.push(self.page_container(page_title(&self.pages.info[self.active_page]))) .push(self.page_container(page_title(&self.pages.info[self.active_page])))
.push(widget::vertical_space(theme.cosmic().space_m())) .push(widget::vertical_space().height(theme.cosmic().space_m()))
.push(page_list) .push(page_list)
.height(Length::Fill) .height(Length::Fill)
.into() .into()
@ -975,9 +971,8 @@ impl SettingsApp {
.max_width(800) .max_width(800)
.width(Length::Fill) .width(Length::Fill)
.apply(container) .apply(container)
.center_x() .center_x(Length::Fill)
.padding([0, padding]) .padding([0, padding])
.width(Length::Fill)
.into() .into()
} }
} }

View file

@ -33,7 +33,7 @@ use tracing_subscriber::prelude::*;
#[command(propagate_version = true)] #[command(propagate_version = true)]
pub struct Args { pub struct Args {
#[command(subcommand)] #[command(subcommand)]
subcommand: Option<PageCommands>, sub_command: Option<PageCommands>,
} }
#[derive(Subcommand, Debug, Serialize, Deserialize, Clone)] #[derive(Subcommand, Debug, Serialize, Deserialize, Clone)]
@ -111,7 +111,7 @@ impl CosmicFlags for Args {
type Args = Vec<String>; type Args = Vec<String>;
fn action(&self) -> Option<&PageCommands> { fn action(&self) -> Option<&PageCommands> {
self.subcommand.as_ref() self.sub_command.as_ref()
} }
} }
@ -131,8 +131,7 @@ pub fn main() -> color_eyre::Result<()> {
let args = Args::parse(); let args = Args::parse();
let settings = cosmic::app::Settings::default() let settings = cosmic::app::Settings::default()
.size_limits(Limits::NONE.min_width(360.0).min_height(300.0)) .size_limits(Limits::NONE.min_width(360.0).min_height(300.0));
.exit_on_close(false);
cosmic::app::run_single_instance::<app::SettingsApp>(settings, args)?; cosmic::app::run_single_instance::<app::SettingsApp>(settings, args)?;

View file

@ -365,11 +365,11 @@ pub async fn start_discovery(
} }
} }
return if let Err(why) = result { if let Err(why) = result {
Message::DBusError(why.to_string()) Message::DBusError(why.to_string())
} else { } else {
Message::Nop Message::Nop
}; }
} }
pub async fn stop_discovery( pub async fn stop_discovery(
@ -521,11 +521,11 @@ pub async fn forget_device(connection: zbus::Connection, device_path: OwnedObjec
} }
} }
return if result.is_err() { if result.is_err() {
Message::DeviceFailed(device_path) Message::DeviceFailed(device_path)
} else { } else {
Message::Nop Message::Nop
}; }
} }
pub async fn change_adapter_status( pub async fn change_adapter_status(
@ -558,7 +558,7 @@ pub async fn change_adapter_status(
if let Err(why) = result { if let Err(why) = result {
tracing::error!("Failed to change the adapter state!"); tracing::error!("Failed to change the adapter state!");
return Message::DBusError(why.to_string()).into(); return Message::DBusError(why.to_string());
} }
Message::Nop Message::Nop

View file

@ -2,10 +2,9 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
use cosmic::iced::{alignment, color, Length}; use cosmic::iced::{alignment, color, Length};
use cosmic::iced_core::text::Wrap; use cosmic::iced_core::text::Wrapping;
use cosmic::prelude::CollectionWidget;
use cosmic::widget::{self, settings, text}; use cosmic::widget::{self, settings, text};
use cosmic::Command; use cosmic::Task;
use cosmic::{Apply, Element}; use cosmic::{Apply, Element};
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
use futures::channel::oneshot; use futures::channel::oneshot;
@ -78,7 +77,7 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: cosmic_settings_page::Entity, _page: cosmic_settings_page::Entity,
sender: tokio::sync::mpsc::Sender<crate::pages::Message>, sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> cosmic::Command<crate::pages::Message> { ) -> cosmic::Task<crate::pages::Message> {
// TODO start stream for new device // TODO start stream for new device
cosmic::command::future(async move { cosmic::command::future(async move {
match zbus::Connection::system().await { match zbus::Connection::system().await {
@ -88,7 +87,7 @@ impl page::Page<crate::pages::Message> for Page {
}) })
} }
fn on_leave(&mut self) -> Command<crate::pages::Message> { fn on_leave(&mut self) -> Task<crate::pages::Message> {
if let Some(cancel) = self.subscription.take() { if let Some(cancel) = self.subscription.take() {
_ = cancel.send(()); _ = cancel.send(());
} }
@ -106,7 +105,7 @@ impl page::Page<crate::pages::Message> for Page {
self.popup_setting = false; self.popup_setting = false;
self.show_device_without_alias = false; self.show_device_without_alias = false;
Command::none() Task::none()
} }
fn dialog(&self) -> Option<Element<'_, crate::pages::Message>> { fn dialog(&self) -> Option<Element<'_, crate::pages::Message>> {
@ -119,12 +118,12 @@ impl page::Page<crate::pages::Message> for Page {
"description", "description",
device = device device = device
)) ))
.wrap(Wrap::Word); .wrapping(Wrapping::Word);
let pin = widget::text::title1(itoa::Buffer::new().format(*passkey).to_owned()) let pin = widget::text::title1(itoa::Buffer::new().format(*passkey).to_owned())
.width(Length::Fill) .width(Length::Fill)
.horizontal_alignment(alignment::Horizontal::Center) .align_x(alignment::Horizontal::Center)
.wrap(Wrap::None); .wrapping(Wrapping::None);
let control = widget::column::with_capacity(2) let control = widget::column::with_capacity(2)
.push(description) .push(description)
@ -193,14 +192,14 @@ impl From<Message> for crate::pages::Message {
} }
impl Page { impl Page {
pub fn update(&mut self, message: Message) -> cosmic::Command<crate::Message> { pub fn update(&mut self, message: Message) -> cosmic::Task<crate::Message> {
let span = tracing::span!(tracing::Level::INFO, "bluetooth::update"); let span = tracing::span!(tracing::Level::INFO, "bluetooth::update");
let _span = span.enter(); let _span = span.enter();
match message { match message {
Message::Agent(message) => { Message::Agent(message) => {
let Some(message) = Arc::into_inner(message) else { let Some(message) = Arc::into_inner(message) else {
return Command::none(); return Task::none();
}; };
match message { match message {
@ -268,7 +267,7 @@ impl Page {
active, active,
)); ));
} }
let commands: Vec<Command<Message>> = self let tasks: Vec<Task<Message>> = self
.adapters .adapters
.iter_mut() .iter_mut()
.map(|(path, adapter)| { .map(|(path, adapter)| {
@ -285,7 +284,7 @@ impl Page {
}) })
.collect(); .collect();
self.update_status(); self.update_status();
return cosmic::command::batch(commands); return cosmic::command::batch(tasks);
} }
tracing::warn!("No DBus connection ready"); tracing::warn!("No DBus connection ready");
} }
@ -413,7 +412,7 @@ impl Page {
if let Some(connection) = self.connection.as_ref() { if let Some(connection) = self.connection.as_ref() {
let connection = connection.clone(); let connection = connection.clone();
if let Some((path, adapter)) = self.get_selected_adapter_mut() { if let Some((path, adapter)) = self.get_selected_adapter_mut() {
let mut fut: Vec<Command<Message>> = vec![cosmic::command::future( let mut fut: Vec<Task<Message>> = vec![cosmic::command::future(
get_devices(connection.clone(), path.clone()), get_devices(connection.clone(), path.clone()),
)]; )];
if adapter.enabled == Active::Enabled if adapter.enabled == Active::Enabled
@ -435,7 +434,7 @@ impl Page {
tracing::debug!("Forgetting to device {path}"); tracing::debug!("Forgetting to device {path}");
self.popup_device = None; self.popup_device = None;
if self.connection.is_none() { if self.connection.is_none() {
return cosmic::Command::none(); return cosmic::Task::none();
} }
if let Some(connection) = self.connection.as_ref() { if let Some(connection) = self.connection.as_ref() {
let connection = connection.clone(); let connection = connection.clone();
@ -450,13 +449,13 @@ impl Page {
Message::ConnectDevice(path) => { Message::ConnectDevice(path) => {
tracing::debug!("Connecting device {path}"); tracing::debug!("Connecting device {path}");
if self.connection.is_none() { if self.connection.is_none() {
return cosmic::Command::none(); return cosmic::Task::none();
} }
if let Some(connection) = self.connection.as_ref() { if let Some(connection) = self.connection.as_ref() {
let connection = connection.clone(); let connection = connection.clone();
if let Some(device) = self.devices.get_mut(&path) { if let Some(device) = self.devices.get_mut(&path) {
if matches!(device.enabled, Active::Enabled | Active::Enabling) { if matches!(device.enabled, Active::Enabled | Active::Enabling) {
return cosmic::Command::none(); return cosmic::Task::none();
} }
device.enabled = Active::Enabling; device.enabled = Active::Enabling;
return cosmic::command::future(connect_device(connection, path)); return cosmic::command::future(connect_device(connection, path));
@ -472,7 +471,7 @@ impl Page {
let connection = connection.clone(); let connection = connection.clone();
if let Some(device) = self.devices.get_mut(&path) { if let Some(device) = self.devices.get_mut(&path) {
if matches!(device.enabled, Active::Disabled | Active::Disabling) { if matches!(device.enabled, Active::Disabled | Active::Disabling) {
return cosmic::Command::none(); return cosmic::Task::none();
} }
device.enabled = Active::Disabling; device.enabled = Active::Disabling;
return cosmic::command::future(disconnect_device(connection, path)); return cosmic::command::future(disconnect_device(connection, path));
@ -485,7 +484,7 @@ impl Page {
tracing::warn!("Failed operation on device {path}"); tracing::warn!("Failed operation on device {path}");
if let Some(device) = self.devices.get_mut(&path) { if let Some(device) = self.devices.get_mut(&path) {
if matches!(device.enabled, Active::Disabled | Active::Disabling) { if matches!(device.enabled, Active::Disabled | Active::Disabling) {
return cosmic::Command::none(); return cosmic::Task::none();
} }
device.enabled = match device.enabled { device.enabled = match device.enabled {
Active::Disabling => Active::Enabled, Active::Disabling => Active::Enabled,
@ -499,7 +498,7 @@ impl Page {
tracing::error!("dbus connection failed. {why}"); tracing::error!("dbus connection failed. {why}");
} }
}; };
cosmic::Command::none() cosmic::Task::none()
} }
fn update_status(&mut self) { fn update_status(&mut self) {
@ -597,7 +596,7 @@ fn status() -> Section<crate::pages::Message> {
} else { } else {
text::body(&descriptions[bluetooth_heading]).into() text::body(&descriptions[bluetooth_heading]).into()
}, },
widget::horizontal_space(Length::Fill).into(), widget::horizontal_space().width(Length::Fill).into(),
if page.popup_setting { if page.popup_setting {
widget::popover( widget::popover(
widget::button::icon(widget::icon::from_name( widget::button::icon(widget::icon::from_name(
@ -622,7 +621,7 @@ fn status() -> Section<crate::pages::Message> {
.width(Length::Fixed(300.0)) .width(Length::Fixed(300.0))
.height(Length::Shrink) .height(Length::Shrink)
.padding([theme.space_xs(), theme.space_xxxs()]) .padding([theme.space_xs(), theme.space_xxxs()])
.style(cosmic::theme::Container::Dialog) .class(cosmic::theme::Container::Dialog)
}) })
.into() .into()
} else { } else {
@ -630,7 +629,9 @@ fn status() -> Section<crate::pages::Message> {
.on_press(Message::PopupSetting(true)) .on_press(Message::PopupSetting(true))
.into() .into()
}, },
widget::toggler(None, status == Active::Enabled, Message::SetActive).into(), widget::toggler(status == Active::Enabled)
.on_toggle(Message::SetActive)
.into(),
])) ]))
.apply(cosmic::Element::from) .apply(cosmic::Element::from)
.map(crate::pages::Message::Bluetooth) .map(crate::pages::Message::Bluetooth)
@ -641,11 +642,11 @@ fn popup_button(message: Option<Message>, text: &str) -> Element<'_, Message> {
let theme = cosmic::theme::active(); let theme = cosmic::theme::active();
let theme = theme.cosmic(); let theme = theme.cosmic();
widget::text::body(text) widget::text::body(text)
.vertical_alignment(alignment::Vertical::Center) .align_y(alignment::Vertical::Center)
.apply(widget::button::custom) .apply(widget::button::custom)
.padding([theme.space_xxxs(), theme.space_xs()]) .padding([theme.space_xxxs(), theme.space_xs()])
.width(Length::Fill) .width(Length::Fill)
.style(cosmic::theme::Button::MenuItem) .class(cosmic::theme::Button::MenuItem)
.on_press_maybe(message) .on_press_maybe(message)
.into() .into()
} }
@ -712,7 +713,7 @@ fn connected_devices() -> Section<crate::pages::Message> {
) )
.width(Length::Fixed(200.0)) .width(Length::Fixed(200.0))
.padding(theme.space_xxxs()) .padding(theme.space_xxxs())
.style(cosmic::theme::Container::Dialog) .class(cosmic::theme::Container::Dialog)
}) })
.into() .into()
} else { } else {
@ -729,20 +730,22 @@ fn connected_devices() -> Section<crate::pages::Message> {
.push(text::caption(battery)) .push(text::caption(battery))
.into() .into()
} else { } else {
widget::text(device.alias_or_addr()).wrap(Wrap::Word).into() widget::text(device.alias_or_addr())
.wrapping(Wrapping::Word)
.into()
}, },
widget::horizontal_space(Length::Fill).into(), widget::horizontal_space().width(Length::Fill).into(),
match device.enabled { match device.enabled {
Active::Enabled => widget::text(&descriptions[device_connected]).into(), Active::Enabled => widget::text(&descriptions[device_connected]).into(),
Active::Enabling => widget::text(&descriptions[device_connecting]) Active::Enabling => widget::text(&descriptions[device_connecting])
.style(cosmic::theme::Text::Color(color!(128, 128, 128))) .class(cosmic::theme::Text::Color(color!(128, 128, 128)))
.into(), .into(),
Active::Disabling => widget::text(&descriptions[device_disconnecting]) Active::Disabling => widget::text(&descriptions[device_disconnecting])
.style(cosmic::theme::Text::Color(color!(128, 128, 128))) .class(cosmic::theme::Text::Color(color!(128, 128, 128)))
.into(), .into(),
Active::Disabled => widget::button::text(&descriptions[device_connect]) Active::Disabled => widget::button::text(&descriptions[device_connect])
.on_press(Message::ConnectDevice(path.clone())) .on_press(Message::ConnectDevice(path.clone()))
.style(widget::button::Style::Text) .class(widget::button::ButtonClass::Text)
.into(), .into(),
}, },
device_menu, device_menu,
@ -785,14 +788,14 @@ fn available_devices() -> Section<crate::pages::Message> {
let mut items = vec![ let mut items = vec![
widget::icon::from_name(device.icon).size(16).into(), widget::icon::from_name(device.icon).size(16).into(),
text(device.alias_or_addr()).wrap(Wrap::Word).into(), text(device.alias_or_addr()).wrapping(Wrapping::Word).into(),
widget::horizontal_space(Length::Fill).into(), widget::horizontal_space().width(Length::Fill).into(),
]; ];
if device.enabled == Active::Enabling { if device.enabled == Active::Enabling {
items.push( items.push(
text(&descriptions[device_connecting]) text(&descriptions[device_connecting])
.style(cosmic::theme::Text::Color(color!(128, 128, 128))) .class(cosmic::theme::Text::Color(color!(128, 128, 128)))
.into(), .into(),
); );
} }
@ -834,16 +837,16 @@ fn multiple_adapter() -> Section<crate::pages::Message> {
widget::icon::from_name("bluetooth-symbolic") widget::icon::from_name("bluetooth-symbolic")
.size(20) .size(20)
.into(), .into(),
widget::horizontal_space(theme.space_xxs()).into(), widget::horizontal_space().width(theme.space_xxs()).into(),
text(&adapter.alias).wrap(Wrap::Word).into(), text(&adapter.alias).wrapping(Wrapping::Word).into(),
widget::horizontal_space(Length::Fill).into(), widget::horizontal_space().width(Length::Fill).into(),
widget::icon::from_name("go-next-symbolic").into(), widget::icon::from_name("go-next-symbolic").into(),
]; ];
if page.adapter_connected(path) { if page.adapter_connected(path) {
items.insert( items.insert(
4, 4,
text(&descriptions[device_connected]) text(&descriptions[device_connected])
.wrap(Wrap::Word) .wrapping(Wrapping::Word)
.into(), .into(),
); );
} }

View file

@ -9,14 +9,14 @@ use cosmic::iced::futures::{SinkExt, StreamExt};
use futures::{channel::mpsc, stream::FusedStream}; use futures::{channel::mpsc, stream::FusedStream};
use zbus::zvariant::OwnedObjectPath; use zbus::zvariant::OwnedObjectPath;
enum DevicePropertyWatcherCommand { enum DevicePropertyWatcherTask {
Add(OwnedObjectPath), Add(OwnedObjectPath),
Removed(OwnedObjectPath), Removed(OwnedObjectPath),
} }
struct DevicePropertyWatcher<'a> { struct DevicePropertyWatcher<'a> {
stream: futures::stream::SelectAll<SignalWatcher<'a>>, stream: futures::stream::SelectAll<SignalWatcher<'a>>,
rx: mpsc::Receiver<DevicePropertyWatcherCommand>, rx: mpsc::Receiver<DevicePropertyWatcherTask>,
} }
struct SignalWatcher<'a> { struct SignalWatcher<'a> {
@ -39,7 +39,7 @@ impl<'a> futures::Stream for SignalWatcher<'a> {
} }
impl<'a> DevicePropertyWatcher<'a> { impl<'a> DevicePropertyWatcher<'a> {
fn new() -> (Self, mpsc::Sender<DevicePropertyWatcherCommand>) { fn new() -> (Self, mpsc::Sender<DevicePropertyWatcherTask>) {
let stream = futures::stream::select_all(vec![]); let stream = futures::stream::select_all(vec![]);
let (tx, rx) = mpsc::channel(10); let (tx, rx) = mpsc::channel(10);
@ -92,7 +92,7 @@ pub async fn watch(
.receive_interfaces_removed() .receive_interfaces_removed()
.await?; .await?;
let (mut property_watcher, mut property_watcher_command) = DevicePropertyWatcher::new(); let (mut property_watcher, mut property_watcher_Task) = DevicePropertyWatcher::new();
for (path, interfaces) in managed_object_proxy.get_managed_objects().await? { for (path, interfaces) in managed_object_proxy.get_managed_objects().await? {
if interfaces.contains_key("org.bluez.Device1") if interfaces.contains_key("org.bluez.Device1")
@ -105,11 +105,11 @@ pub async fn watch(
while !property_watcher.rx.is_terminated() { while !property_watcher.rx.is_terminated() {
futures::select! { futures::select! {
command = property_watcher.rx.next() => match command { Task = property_watcher.rx.next() => match Task {
Some(DevicePropertyWatcherCommand::Add(path)) => { Some(DevicePropertyWatcherTask::Add(path)) => {
property_watcher.insert(&connection, path).await?; property_watcher.insert(&connection, path).await?;
} }
Some(DevicePropertyWatcherCommand::Removed(path)) => { Some(DevicePropertyWatcherTask::Removed(path)) => {
property_watcher = property_watcher.remove(&path); property_watcher = property_watcher.remove(&path);
} }
None => { None => {
@ -144,8 +144,8 @@ pub async fn watch(
Ok(device) => { Ok(device) => {
match bluetooth::Device::from_device(&device).await { match bluetooth::Device::from_device(&device).await {
Ok(device) => { Ok(device) => {
property_watcher_command property_watcher_Task
.send(DevicePropertyWatcherCommand::Add(args.object_path.to_owned().into())).await.map_err(|e| zbus::Error::Failure(e.to_string()))?; .send(DevicePropertyWatcherTask::Add(args.object_path.to_owned().into())).await.map_err(|e| zbus::Error::Failure(e.to_string()))?;
tx tx
.send(bluetooth::Message::AddedDevice(args.object_path.to_owned().into(), device)) .send(bluetooth::Message::AddedDevice(args.object_path.to_owned().into(), device))
@ -170,7 +170,7 @@ pub async fn watch(
Some(signal) => { Some(signal) => {
let args = signal.args()?; let args = signal.args()?;
if args.interfaces.contains(&"org.bluez.Device1") { if args.interfaces.contains(&"org.bluez.Device1") {
property_watcher_command.send(DevicePropertyWatcherCommand::Removed( property_watcher_Task.send(DevicePropertyWatcherTask::Removed(
args.object_path.to_owned().into(), args.object_path.to_owned().into(),
)).await.map_err(|e| zbus::Error::Failure(e.to_string()))?; )).await.map_err(|e| zbus::Error::Failure(e.to_string()))?;
tx tx

View file

@ -20,9 +20,9 @@ use cosmic::iced_widget::scrollable;
use cosmic::widget::icon::{from_name, icon}; use cosmic::widget::icon::{from_name, icon};
use cosmic::widget::{ use cosmic::widget::{
button, color_picker::ColorPickerUpdate, container, flex_row, horizontal_space, radio, row, button, color_picker::ColorPickerUpdate, container, flex_row, horizontal_space, radio, row,
settings, spin_button, text, ColorPickerModel, scrollable, settings, spin_button, text, ColorPickerModel,
}; };
use cosmic::{command, Apply, Command, Element}; use cosmic::{Apply, Element, Task};
use cosmic_panel_config::CosmicPanelConfig; use cosmic_panel_config::CosmicPanelConfig;
use cosmic_settings_page::Section; use cosmic_settings_page::Section;
use cosmic_settings_page::{self as page, section}; use cosmic_settings_page::{self as page, section};
@ -398,8 +398,8 @@ impl Page {
} }
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub fn update(&mut self, message: Message) -> Command<app::Message> { pub fn update(&mut self, message: Message) -> Task<app::Message> {
let mut commands = Vec::new(); let mut tasks = Vec::new();
let mut needs_build = false; let mut needs_build = false;
let mut needs_sync = false; let mut needs_sync = false;
@ -499,25 +499,25 @@ impl Page {
Message::AccentWindowHint(u) => { Message::AccentWindowHint(u) => {
needs_sync = true; needs_sync = true;
let (command, needs_update) = self.update_color_picker( let (task, needs_update) = self.update_color_picker(
&u, &u,
ContextView::AccentWindowHint, ContextView::AccentWindowHint,
fl!("window-hint-accent").into(), fl!("window-hint-accent").into(),
); );
commands.push(command); tasks.push(task);
commands.push(self.accent_window_hint.update::<app::Message>(u)); tasks.push(self.accent_window_hint.update::<app::Message>(u));
if needs_update { if needs_update {
let Some(config) = self.theme_builder_config.as_ref() else { let Some(config) = self.theme_builder_config.as_ref() else {
return cosmic::command::batch(commands); return cosmic::Task::batch(tasks);
}; };
let color = self.accent_window_hint.get_applied_color().map(Srgb::from); let color = self.accent_window_hint.get_applied_color().map(Srgb::from);
needs_build = self needs_build = self
.theme_builder .theme_builder
.set_window_hint(config, color.clone()) .set_window_hint(config, color)
.unwrap_or_default(); .unwrap_or_default();
} }
} }
@ -538,7 +538,7 @@ impl Page {
needs_sync = true; needs_sync = true;
let Some(config) = self.theme_builder_config.as_ref() else { let Some(config) = self.theme_builder_config.as_ref() else {
return Command::none(); return Task::none();
}; };
let active_hint = match msg { let active_hint = match msg {
@ -563,10 +563,10 @@ impl Page {
needs_sync = true; needs_sync = true;
let Some(config) = self.theme_builder_config.as_ref() else { let Some(config) = self.theme_builder_config.as_ref() else {
return Command::none(); return Task::none();
}; };
let mut gaps = self.theme_builder.gaps.clone(); let mut gaps = self.theme_builder.gaps;
gaps.1 = match msg { gaps.1 = match msg {
spin_button::Message::Increment => self.theme_builder.gaps.1.saturating_add(1), spin_button::Message::Increment => self.theme_builder.gaps.1.saturating_add(1),
@ -583,18 +583,18 @@ impl Page {
} }
Message::ApplicationBackground(u) => { Message::ApplicationBackground(u) => {
let (command, needs_update) = self.update_color_picker( let (task, needs_update) = self.update_color_picker(
&u, &u,
ContextView::ApplicationBackground, ContextView::ApplicationBackground,
fl!("app-background").into(), fl!("app-background").into(),
); );
commands.push(command); tasks.push(task);
commands.push(self.application_background.update::<app::Message>(u)); tasks.push(self.application_background.update::<app::Message>(u));
if needs_update { if needs_update {
let Some(config) = self.theme_builder_config.as_ref() else { let Some(config) = self.theme_builder_config.as_ref() else {
return cosmic::command::batch(commands); return cosmic::Task::batch(tasks);
}; };
needs_build = self needs_build = self
@ -610,18 +610,18 @@ impl Page {
} }
Message::ContainerBackground(u) => { Message::ContainerBackground(u) => {
let (command, needs_update) = self.update_color_picker( let (task, needs_update) = self.update_color_picker(
&u, &u,
ContextView::ContainerBackground, ContextView::ContainerBackground,
fl!("container-background").into(), fl!("container-background").into(),
); );
commands.push(command); tasks.push(task);
commands.push(self.container_background.update::<app::Message>(u)); tasks.push(self.container_background.update::<app::Message>(u));
if needs_update { if needs_update {
let Some(config) = self.theme_builder_config.as_ref() else { let Some(config) = self.theme_builder_config.as_ref() else {
return cosmic::command::batch(commands); return cosmic::Task::batch(tasks);
}; };
needs_build = self needs_build = self
@ -637,18 +637,18 @@ impl Page {
} }
Message::CustomAccent(u) => { Message::CustomAccent(u) => {
let (command, needs_update) = self.update_color_picker( let (task, needs_update) = self.update_color_picker(
&u, &u,
ContextView::CustomAccent, ContextView::CustomAccent,
fl!("accent-color").into(), fl!("accent-color").into(),
); );
commands.push(command); tasks.push(task);
commands.push(self.custom_accent.update::<app::Message>(u)); tasks.push(self.custom_accent.update::<app::Message>(u));
if needs_update { if needs_update {
let Some(config) = self.theme_builder_config.as_ref() else { let Some(config) = self.theme_builder_config.as_ref() else {
return cosmic::command::batch(commands); return cosmic::Task::batch(tasks);
}; };
needs_build = self needs_build = self
@ -662,18 +662,18 @@ impl Page {
} }
Message::InterfaceText(u) => { Message::InterfaceText(u) => {
let (command, needs_update) = self.update_color_picker( let (task, needs_update) = self.update_color_picker(
&u, &u,
ContextView::InterfaceText, ContextView::InterfaceText,
fl!("text-tint").into(), fl!("text-tint").into(),
); );
commands.push(command); tasks.push(task);
commands.push(self.interface_text.update::<app::Message>(u)); tasks.push(self.interface_text.update::<app::Message>(u));
if needs_update { if needs_update {
let Some(config) = self.theme_builder_config.as_ref() else { let Some(config) = self.theme_builder_config.as_ref() else {
return cosmic::command::batch(commands); return cosmic::Task::batch(tasks);
}; };
needs_build = self needs_build = self
@ -687,18 +687,18 @@ impl Page {
} }
Message::ControlComponent(u) => { Message::ControlComponent(u) => {
let (command, needs_update) = self.update_color_picker( let (task, needs_update) = self.update_color_picker(
&u, &u,
ContextView::ControlComponent, ContextView::ControlComponent,
fl!("control-tint").into(), fl!("control-tint").into(),
); );
commands.push(command); tasks.push(task);
commands.push(self.control_component.update::<app::Message>(u)); tasks.push(self.control_component.update::<app::Message>(u));
if needs_update { if needs_update {
let Some(config) = self.theme_builder_config.as_ref() else { let Some(config) = self.theme_builder_config.as_ref() else {
return cosmic::command::batch(commands); return cosmic::Task::batch(tasks);
}; };
needs_build = self needs_build = self
@ -716,7 +716,7 @@ impl Page {
self.roundness = r; self.roundness = r;
let Some(config) = self.theme_builder_config.as_ref() else { let Some(config) = self.theme_builder_config.as_ref() else {
return Command::none(); return Task::none();
}; };
let radii = self.roundness.into(); let radii = self.roundness.into();
@ -774,14 +774,14 @@ impl Page {
} }
Message::Left => { Message::Left => {
commands.push(cosmic::command::message(app::Message::SetTheme( tasks.push(cosmic::command::message(app::Message::SetTheme(
cosmic::theme::system_preference(), cosmic::theme::system_preference(),
))); )));
} }
Message::PaletteAccent(c) => { Message::PaletteAccent(c) => {
let Some(config) = self.theme_builder_config.as_ref() else { let Some(config) = self.theme_builder_config.as_ref() else {
return Command::none(); return Task::none();
}; };
needs_build = self needs_build = self
@ -856,7 +856,7 @@ impl Page {
} }
Message::StartImport => { Message::StartImport => {
commands.push(cosmic::command::future(async move { tasks.push(cosmic::command::future(async move {
let res = SelectedFiles::open_file() let res = SelectedFiles::open_file()
.modal(true) .modal(true)
.filter(FileFilter::glob(FileFilter::new("ron"), "*.ron")) .filter(FileFilter::glob(FileFilter::new("ron"), "*.ron"))
@ -878,7 +878,7 @@ impl Page {
let is_dark = self.theme_mode.is_dark; let is_dark = self.theme_mode.is_dark;
let name = format!("{}.ron", if is_dark { fl!("dark") } else { fl!("light") }); let name = format!("{}.ron", if is_dark { fl!("dark") } else { fl!("light") });
commands.push(cosmic::command::future(async move { tasks.push(cosmic::command::future(async move {
let res = SelectedFiles::save_file() let res = SelectedFiles::save_file()
.modal(true) .modal(true)
.current_name(Some(name.as_str())) .current_name(Some(name.as_str()))
@ -904,10 +904,10 @@ impl Page {
.and_then(|f| f.to_file_path().ok()); .and_then(|f| f.to_file_path().ok());
let Some(path) = path_res else { let Some(path) = path_res else {
return Command::none(); return Task::none();
}; };
commands.push(cosmic::command::future(async move { tasks.push(cosmic::command::future(async move {
let res = tokio::fs::read_to_string(path).await; let res = tokio::fs::read_to_string(path).await;
if let Some(b) = res.ok().and_then(|s| ron::de::from_str(&s).ok()) { if let Some(b) = res.ok().and_then(|s| ron::de::from_str(&s).ok()) {
Message::ImportSuccess(Box::new(b)) Message::ImportSuccess(Box::new(b))
@ -927,12 +927,12 @@ impl Page {
.and_then(|f| f.to_file_path().ok()); .and_then(|f| f.to_file_path().ok());
let Some(path) = path_res else { let Some(path) = path_res else {
return Command::none(); return Task::none();
}; };
let theme_builder = self.theme_builder.clone(); let theme_builder = self.theme_builder.clone();
commands.push(cosmic::command::future(async move { tasks.push(cosmic::command::future(async move {
let Ok(builder) = let Ok(builder) =
ron::ser::to_string_pretty(&theme_builder, PrettyConfig::default()) ron::ser::to_string_pretty(&theme_builder, PrettyConfig::default())
else { else {
@ -954,7 +954,7 @@ impl Page {
} }
// TODO: error message toast? // TODO: error message toast?
Message::ExportError | Message::ImportError => return Command::none(), Message::ExportError | Message::ImportError => return Task::none(),
Message::ExportSuccess => { Message::ExportSuccess => {
tracing::trace!("Export successful"); tracing::trace!("Export successful");
@ -987,7 +987,7 @@ impl Page {
self.no_custom_window_hint = v; self.no_custom_window_hint = v;
let Some(config) = self.theme_builder_config.as_ref() else { let Some(config) = self.theme_builder_config.as_ref() else {
return Command::none(); return Task::none();
}; };
needs_build = self needs_build = self
@ -1042,7 +1042,7 @@ impl Page {
tracing::error!("Failed to apply theme to GNOME config because the CosmicTK config does not exist."); tracing::error!("Failed to apply theme to GNOME config because the CosmicTK config does not exist.");
} }
return Command::none(); return Task::none();
} }
Message::IconsAndToolkit => { Message::IconsAndToolkit => {
@ -1052,7 +1052,7 @@ impl Page {
Message::Daytime(day_time) => { Message::Daytime(day_time) => {
self.day_time = day_time; self.day_time = day_time;
return Command::none(); return Task::none();
} }
} }
@ -1062,7 +1062,7 @@ impl Page {
let is_dark = self.theme_mode.is_dark; let is_dark = self.theme_mode.is_dark;
let current_theme = self.theme.clone(); let current_theme = self.theme.clone();
commands.push(cosmic::command::future(async move { tasks.push(cosmic::command::future(async move {
let config = if is_dark { let config = if is_dark {
Theme::dark_config() Theme::dark_config()
} else { } else {
@ -1131,7 +1131,7 @@ impl Page {
}); });
} }
cosmic::command::batch(commands) cosmic::Task::batch(tasks)
} }
fn reload_theme_mode(&mut self) { fn reload_theme_mode(&mut self) {
@ -1154,10 +1154,10 @@ impl Page {
message: &ColorPickerUpdate, message: &ColorPickerUpdate,
context_view: ContextView, context_view: ContextView,
context_title: Cow<'static, str>, context_title: Cow<'static, str>,
) -> (Command<app::Message>, bool) { ) -> (Task<app::Message>, bool) {
let mut needs_update = false; let mut needs_update = false;
let command = match message { let task = match message {
ColorPickerUpdate::AppliedColor | ColorPickerUpdate::Reset => { ColorPickerUpdate::AppliedColor | ColorPickerUpdate::Reset => {
needs_update = true; needs_update = true;
cosmic::command::message(crate::app::Message::CloseContextDrawer) cosmic::command::message(crate::app::Message::CloseContextDrawer)
@ -1165,7 +1165,7 @@ impl Page {
ColorPickerUpdate::ActionFinished => { ColorPickerUpdate::ActionFinished => {
needs_update = true; needs_update = true;
Command::none() Task::none()
} }
ColorPickerUpdate::Cancel => { ColorPickerUpdate::Cancel => {
@ -1177,10 +1177,10 @@ impl Page {
cosmic::command::message(crate::app::Message::OpenContextDrawer(context_title)) cosmic::command::message(crate::app::Message::OpenContextDrawer(context_title))
} }
_ => Command::none(), _ => Task::none(),
}; };
(command, needs_update) (task, needs_update)
} }
/// Syncs changes for dark and light theme. /// Syncs changes for dark and light theme.
@ -1406,12 +1406,12 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_: page::Entity, _: page::Entity,
_sender: tokio::sync::mpsc::Sender<crate::pages::Message>, _sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> Command<crate::pages::Message> { ) -> Task<crate::pages::Message> {
command::batch(vec![ task::batch(vec![
// Load icon themes // Load icon themes
command::future(icon_themes::fetch()).map(crate::pages::Message::Appearance), task::future(icon_themes::fetch()).map(crate::pages::Message::Appearance),
// Load font families // Load font families
command::future(async move { task::future(async move {
let (mono, interface) = font_config::load_font_families(); let (mono, interface) = font_config::load_font_families();
Message::FontConfig(font_config::Message::LoadedFonts(mono, interface)) Message::FontConfig(font_config::Message::LoadedFonts(mono, interface))
}) })
@ -1419,8 +1419,8 @@ impl page::Page<crate::pages::Message> for Page {
]) ])
} }
fn on_leave(&mut self) -> Command<crate::pages::Message> { fn on_leave(&mut self) -> Task<crate::pages::Message> {
command::message(crate::pages::Message::Appearance(Message::Left)) cosmic::command::message(crate::pages::Message::Appearance(Message::Left))
} }
fn context_drawer(&self) -> Option<Element<'_, crate::pages::Message>> { fn context_drawer(&self) -> Option<Element<'_, crate::pages::Message>> {
@ -1552,7 +1552,7 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
.width(Length::Fill) .width(Length::Fill)
.height(Length::Fixed(100.0)) .height(Length::Fixed(100.0))
) )
.style(button::Style::Image) .class(button::ButtonClass::Image)
.padding([8, 0]) .padding([8, 0])
.selected(page.theme_mode.is_dark) .selected(page.theme_mode.is_dark)
.on_press(Message::DarkMode(true)), .on_press(Message::DarkMode(true)),
@ -1560,14 +1560,14 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
] ]
.spacing(space_xxs) .spacing(space_xxs)
.width(Length::FillPortion(1)) .width(Length::FillPortion(1))
.align_items(cosmic::iced_core::Alignment::Center), .align_x(cosmic::iced_core::Alignment::Center),
cosmic::iced::widget::column![ cosmic::iced::widget::column![
button::custom( button::custom(
icon(light_mode_illustration.clone(),) icon(light_mode_illustration.clone(),)
.width(Length::Fill) .width(Length::Fill)
.height(Length::Fixed(100.0)) .height(Length::Fixed(100.0))
) )
.style(button::Style::Image) .class(button::ButtonClass::Image)
.selected(!page.theme_mode.is_dark) .selected(!page.theme_mode.is_dark)
.padding([8, 0]) .padding([8, 0])
.on_press(Message::DarkMode(false)), .on_press(Message::DarkMode(false)),
@ -1575,10 +1575,10 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
] ]
.spacing(space_xxs) .spacing(space_xxs)
.width(Length::FillPortion(1)) .width(Length::FillPortion(1))
.align_items(cosmic::iced_core::Alignment::Center) .align_x(cosmic::iced_core::Alignment::Center)
] ]
.spacing(48) // TODO: dynamic spacing based on window width .spacing(48)
.align_items(cosmic::iced_core::Alignment::Center) .align_y(cosmic::iced_core::Alignment::Center)
.width(Length::Fixed(424.0)), .width(Length::Fixed(424.0)),
) )
.width(Length::Fill) .width(Length::Fill)
@ -1690,9 +1690,7 @@ pub fn mode_and_colors() -> Section<crate::pages::Message> {
.padding([0, 0, 16, 0]) .padding([0, 0, 16, 0])
.spacing(16) .spacing(16)
) )
.direction(scrollable::Direction::Horizontal( .direction(scrollable::Direction::Horizontal(Scrollbar::new()))
scrollable::Properties::new()
))
] ]
.padding([16, space_s, 0, space_s]) .padding([16, space_s, 0, space_s])
.spacing(space_xxs), .spacing(space_xxs),
@ -1810,14 +1808,14 @@ pub fn style() -> Section<crate::pages::Message> {
.height(Length::Fixed(100.0)) .height(Length::Fixed(100.0))
) )
.selected(matches!(page.roundness, Roundness::Round)) .selected(matches!(page.roundness, Roundness::Round))
.style(button::Style::Image) .class(button::ButtonClass::Image)
.padding(8) .padding(8)
.on_press(Message::Roundness(Roundness::Round)), .on_press(Message::Roundness(Roundness::Round)),
text::body(&descriptions[round]) text::body(&descriptions[round])
] ]
.spacing(8) .spacing(8)
.width(Length::FillPortion(1)) .width(Length::FillPortion(1))
.align_items(cosmic::iced_core::Alignment::Center), .align_x(cosmic::iced_core::Alignment::Center),
cosmic::iced::widget::column![ cosmic::iced::widget::column![
button::custom( button::custom(
icon( icon(
@ -1832,14 +1830,14 @@ pub fn style() -> Section<crate::pages::Message> {
.height(Length::Fixed(100.0)) .height(Length::Fixed(100.0))
) )
.selected(matches!(page.roundness, Roundness::SlightlyRound)) .selected(matches!(page.roundness, Roundness::SlightlyRound))
.style(button::Style::Image) .class(button::ButtonClass::Image)
.padding(8) .padding(8)
.on_press(Message::Roundness(Roundness::SlightlyRound)), .on_press(Message::Roundness(Roundness::SlightlyRound)),
text::body(&descriptions[slightly_round]) text::body(&descriptions[slightly_round])
] ]
.spacing(8) .spacing(8)
.width(Length::FillPortion(1)) .width(Length::FillPortion(1))
.align_items(cosmic::iced_core::Alignment::Center), .align_x(cosmic::iced_core::Alignment::Center),
cosmic::iced::widget::column![ cosmic::iced::widget::column![
button::custom( button::custom(
icon( icon(
@ -1855,18 +1853,18 @@ pub fn style() -> Section<crate::pages::Message> {
) )
.width(Length::FillPortion(1)) .width(Length::FillPortion(1))
.selected(matches!(page.roundness, Roundness::Square)) .selected(matches!(page.roundness, Roundness::Square))
.style(button::Style::Image) .class(button::ButtonClass::Image)
.padding(8) .padding(8)
.on_press(Message::Roundness(Roundness::Square)), .on_press(Message::Roundness(Roundness::Square)),
text::body(&descriptions[square]) text::body(&descriptions[square])
] ]
.spacing(8) .spacing(8)
.align_items(cosmic::iced_core::Alignment::Center) .align_x(cosmic::iced_core::Alignment::Center)
.width(Length::FillPortion(1)) .width(Length::FillPortion(1))
] ]
.spacing(12) .spacing(12)
.width(Length::Fixed(628.0)) .width(Length::Fixed(628.0))
.align_items(cosmic::iced_core::Alignment::Center), .align_y(cosmic::iced_core::Alignment::Center),
) )
.width(Length::Fill) .width(Length::Fill)
.align_x(cosmic::iced_core::alignment::Horizontal::Center), .align_x(cosmic::iced_core::alignment::Horizontal::Center),
@ -2009,7 +2007,7 @@ pub fn reset_button() -> Section<crate::pages::Message> {
.on_press(Message::Reset) .on_press(Message::Reset)
.into() .into()
} else { } else {
horizontal_space(1).apply(Element::from) horizontal_space().width(1).apply(Element::from)
} }
.map(crate::pages::Message::Appearance) .map(crate::pages::Message::Appearance)
}) })
@ -2032,7 +2030,7 @@ pub fn color_button<'a, Message: 'a + Clone>(
)) ))
.padding(0) .padding(0)
.selected(selected) .selected(selected)
.style(button::Style::Image) .class(button::ButtonClass::Image)
.on_press_maybe(on_press) .on_press_maybe(on_press)
.width(Length::Fixed(f32::from(width))) .width(Length::Fixed(f32::from(width)))
.height(Length::Fixed(f32::from(height))) .height(Length::Fixed(f32::from(height)))

View file

@ -1,9 +1,8 @@
use cosmic::{ use cosmic::{
cosmic_config::CosmicConfigEntry, cosmic_config::CosmicConfigEntry,
iced::{alignment, Length}, iced::{alignment, Length},
iced_runtime::Command,
widget::{button, container, row}, widget::{button, container, row},
Apply, Element, Apply, Element, Task,
}; };
use cosmic_panel_config::CosmicPanelConfig; use cosmic_panel_config::CosmicPanelConfig;
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
@ -15,7 +14,7 @@ use crate::{
pages::{ pages::{
self, self,
desktop::panel::applets_inner::{ desktop::panel::applets_inner::{
self, lists, AppletsPage, ContextDrawer, ReorderWidgetState, self, lists, AppletsPage, ContextDrawer,
}, },
}, },
}; };
@ -63,7 +62,7 @@ impl AppletsPage for Page {
pub struct Message(pub applets_inner::Message); pub struct Message(pub applets_inner::Message);
impl Page { impl Page {
pub fn update(&mut self, message: Message) -> Command<app::Message> { pub fn update(&mut self, message: Message) -> Task<app::Message> {
self.inner.update(message.0) self.inner.update(message.0)
} }
} }

View file

@ -4,7 +4,7 @@ use cosmic::Apply;
use cosmic::{ use cosmic::{
cosmic_config::{ConfigSet, CosmicConfigEntry}, cosmic_config::{ConfigSet, CosmicConfigEntry},
widget::{settings, text, toggler}, widget::{settings, text, toggler},
Command, Element, Element, Task,
}; };
use cosmic_panel_config::{CosmicPanelConfig, CosmicPanelContainerConfig}; use cosmic_panel_config::{CosmicPanelConfig, CosmicPanelContainerConfig};
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
@ -31,19 +31,19 @@ pub enum Message {
} }
impl Page { impl Page {
pub fn update(&mut self, message: Message) -> Command<crate::app::Message> { pub fn update(&mut self, message: Message) -> Task<crate::app::Message> {
match message { match message {
Message::EnableDock(enabled) => { Message::EnableDock(enabled) => {
let Some(container_config) = self.inner.container_config.as_mut() else { let Some(container_config) = self.inner.container_config.as_mut() else {
return Command::none(); return Task::none();
}; };
let Some(panel_config) = self.inner.panel_config.as_ref() else { let Some(panel_config) = self.inner.panel_config.as_ref() else {
return Command::none(); return Task::none();
}; };
let Ok(helper) = CosmicPanelContainerConfig::cosmic_config() else { let Ok(helper) = CosmicPanelContainerConfig::cosmic_config() else {
return Command::none(); return Task::none();
}; };
if enabled { if enabled {
@ -64,7 +64,7 @@ impl Page {
error!("{:?}", err); error!("{:?}", err);
} }
Command::none() Task::none()
} }
Message::Inner(inner) => self Message::Inner(inner) => self
.inner .inner
@ -169,13 +169,12 @@ pub(crate) fn enable() -> Section<crate::pages::Message> {
.add(settings::item( .add(settings::item(
&descriptions[dock], &descriptions[dock],
toggler( toggler(
None,
container_config container_config
.config_list .config_list
.iter() .iter()
.any(|e| e.name.as_str() == "Dock"), .any(|e| e.name.as_str() == "Dock"),
Message::EnableDock, )
), .on_toggle(Message::EnableDock),
)) ))
.apply(Element::from) .apply(Element::from)
.map(crate::pages::Message::Dock) .map(crate::pages::Message::Dock)

View file

@ -1,8 +1,6 @@
use button::StyleSheet as ButtonStyleSheet; use button::Catalog as ButtonStyleSheet;
use cosmic::iced::alignment; use cosmic::iced::{alignment, Vector};
use cosmic::iced_style::container::StyleSheet;
use cosmic::prelude::CollectionWidget;
use cosmic::widget::{ use cosmic::widget::{
button, column, container, horizontal_space, icon, list_column, row, text, text_input, Column, button, column, container, horizontal_space, icon, list_column, row, text, text_input, Column,
}; };
@ -12,21 +10,19 @@ use cosmic::{
cosmic_config::{Config, CosmicConfigEntry}, cosmic_config::{Config, CosmicConfigEntry},
iced::{ iced::{
alignment::{Horizontal, Vertical}, alignment::{Horizontal, Vertical},
core::window,
event::{ event::{
self, self,
wayland::{self}, wayland::{self},
PlatformSpecific, PlatformSpecific,
}, },
mouse, overlay, touch, mouse, overlay, touch, Alignment, Color, Length, Point, Rectangle, Size,
wayland::actions::data_device::{ActionInner, DataFromMimeType, DndIcon},
wayland::data_device::action as data_device_action,
window, Alignment, Color, Length, Point, Rectangle, Size,
}, },
iced_runtime::{command::platform_specific, core::id::Id, Command}, iced_runtime::{core::id::Id, Task},
iced_widget::{ iced_widget::{
core::{ core::{
layout, renderer, layout, renderer,
widget::{tree, Operation, OperationOutputWrapper, Tree}, widget::{tree, Operation, Tree},
Clipboard, Shell, Widget, Clipboard, Shell, Widget,
}, },
graphics::image::image_rs::EncodableLayout, graphics::image::image_rs::EncodableLayout,
@ -39,9 +35,8 @@ use std::{
borrow::{Borrow, Cow}, borrow::{Borrow, Cow},
fmt::Debug, fmt::Debug,
mem, mem,
path::{Path, PathBuf}, path::Path,
str::FromStr, str::FromStr,
sync::Arc,
}; };
use crate::{app, pages}; use crate::{app, pages};
@ -53,12 +48,12 @@ use tracing::error;
const MIME_TYPE: &str = "text/uri-list"; const MIME_TYPE: &str = "text/uri-list";
pub type OnDndCommand<'a, Message> = Box< // pub type OnDndTask<'a, Message> = Box<
dyn Fn( // dyn Fn(
Box<dyn Send + Sync + Fn() -> platform_specific::wayland::data_device::ActionInner>, // Box<dyn Send + Sync + Fn() -> platform_specific::wayland::data_device::ActionInner>,
) -> Message // ) -> Message
+ 'a, // + 'a,
>; // >;
// radius is 8.0 // radius is 8.0
const DRAG_START_DISTANCE_SQUARED: f32 = 64.0; const DRAG_START_DISTANCE_SQUARED: f32 = 64.0;
@ -170,7 +165,7 @@ pub enum Message {
Applets(Vec<Applet<'static>>), Applets(Vec<Applet<'static>>),
PanelConfig(CosmicPanelConfig), PanelConfig(CosmicPanelConfig),
StartDnd(ReorderWidgetState), StartDnd(ReorderWidgetState),
DnDCommand(Arc<Box<dyn Send + Sync + Fn() -> ActionInner>>), // DnDTask(Arc<Box<dyn Send + Sync + Fn() -> ActionInner>>),
Search(String), Search(String),
AddApplet(Applet<'static>), AddApplet(Applet<'static>),
AddAppletDrawer, AddAppletDrawer,
@ -187,7 +182,7 @@ impl Debug for Message {
Message::Applets(_) => write!(f, "Applets"), Message::Applets(_) => write!(f, "Applets"),
Message::PanelConfig(_) => write!(f, "PanelConfig"), Message::PanelConfig(_) => write!(f, "PanelConfig"),
Message::StartDnd(_) => write!(f, "StartDnd"), Message::StartDnd(_) => write!(f, "StartDnd"),
Message::DnDCommand(_) => write!(f, "DnDCommand"), // Message::DnDTask(_) => write!(f, "DnDTask"),
Message::Save => write!(f, "ApplyReorder"), Message::Save => write!(f, "ApplyReorder"),
Message::RemoveStart(_) => write!(f, "RemoveStart"), Message::RemoveStart(_) => write!(f, "RemoveStart"),
Message::RemoveCenter(_) => write!(f, "RemoveCenter"), Message::RemoveCenter(_) => write!(f, "RemoveCenter"),
@ -270,14 +265,15 @@ impl Page {
.width(Length::Fill) .width(Length::Fill)
.into(), .into(),
button::standard(fl!("add")) button::standard(fl!("add"))
.style(button::Style::Custom { .class(button::ButtonClass::Custom {
active: Box::new(|focused, theme| { active: Box::new(|focused, theme| {
let mut style = theme.active(focused, false, &button::Style::Text); let mut style =
theme.active(focused, false, &button::ButtonClass::Text);
style.text_color = Some(theme.cosmic().accent_color().into()); style.text_color = Some(theme.cosmic().accent_color().into());
style style
}), }),
disabled: Box::new(|theme| { disabled: Box::new(|theme| {
let mut style = theme.disabled(&button::Style::Text); let mut style = theme.disabled(&button::ButtonClass::Text);
let mut text_color: Color = theme.cosmic().accent_color().into(); let mut text_color: Color = theme.cosmic().accent_color().into();
text_color.a *= 0.5; text_color.a *= 0.5;
style.text_color = Some(text_color); style.text_color = Some(text_color);
@ -299,14 +295,14 @@ impl Page {
]) ])
.padding([0, spacing.space_l]) .padding([0, spacing.space_l])
.spacing(spacing.space_xs) .spacing(spacing.space_xs)
.align_items(Alignment::Center), .align_y(Alignment::Center),
); );
} }
if !has_some { if !has_some {
list_column = list_column.add( list_column = list_column.add(
text::body(fl!("no-applets-found")) text::body(fl!("no-applets-found"))
.width(Length::Fill) .width(Length::Fill)
.horizontal_alignment(Horizontal::Center), .align_x(Horizontal::Center),
); );
} }
@ -318,13 +314,13 @@ impl Page {
.into(), .into(),
list_column.into(), list_column.into(),
]) ])
.align_items(Alignment::Center) .align_x(Alignment::Center)
.spacing(spacing.space_xxs) .spacing(spacing.space_xxs)
.into() .into()
} }
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub fn update(&mut self, message: Message) -> Command<app::Message> { pub fn update(&mut self, message: Message) -> Task<app::Message> {
match message { match message {
Message::PanelConfig(c) => { Message::PanelConfig(c) => {
self.current_config = Some(c); self.current_config = Some(c);
@ -332,7 +328,7 @@ impl Page {
Message::ReorderStart(start_list) => { Message::ReorderStart(start_list) => {
let Some(config) = self.current_config.as_mut() else { let Some(config) = self.current_config.as_mut() else {
return Command::none(); return Task::none();
}; };
let Some((list, _)) = config.plugins_wings.as_mut() else { let Some((list, _)) = config.plugins_wings.as_mut() else {
config.plugins_wings = Some(( config.plugins_wings = Some((
@ -342,13 +338,13 @@ impl Page {
.collect(), .collect(),
Vec::new(), Vec::new(),
)); ));
return Command::none(); return Task::none();
}; };
*list = start_list.into_iter().map(|a| a.id.into()).collect(); *list = start_list.into_iter().map(|a| a.id.into()).collect();
} }
Message::ReorderCenter(center_list) => { Message::ReorderCenter(center_list) => {
let Some(config) = self.current_config.as_mut() else { let Some(config) = self.current_config.as_mut() else {
return Command::none(); return Task::none();
}; };
let Some(list) = config.plugins_center.as_mut() else { let Some(list) = config.plugins_center.as_mut() else {
config.plugins_center = Some( config.plugins_center = Some(
@ -357,20 +353,20 @@ impl Page {
.map(|a: Applet| a.id.into()) .map(|a: Applet| a.id.into())
.collect(), .collect(),
); );
return Command::none(); return Task::none();
}; };
*list = center_list.into_iter().map(|a| a.id.into()).collect(); *list = center_list.into_iter().map(|a| a.id.into()).collect();
} }
Message::ReorderEnd(end_list) => { Message::ReorderEnd(end_list) => {
let Some(config) = self.current_config.as_mut() else { let Some(config) = self.current_config.as_mut() else {
return Command::none(); return Task::none();
}; };
let Some((_, list)) = config.plugins_wings.as_mut() else { let Some((_, list)) = config.plugins_wings.as_mut() else {
config.plugins_wings = Some(( config.plugins_wings = Some((
Vec::new(), Vec::new(),
end_list.into_iter().map(|a: Applet| a.id.into()).collect(), end_list.into_iter().map(|a: Applet| a.id.into()).collect(),
)); ));
return Command::none(); return Task::none();
}; };
*list = end_list.into_iter().map(|a| a.id.into()).collect(); *list = end_list.into_iter().map(|a| a.id.into()).collect();
} }
@ -379,41 +375,41 @@ impl Page {
} }
Message::StartDnd(state) => { Message::StartDnd(state) => {
self.reorder_widget_state = state; self.reorder_widget_state = state;
return Command::none(); return Task::none();
}
Message::DnDCommand(action) => {
return data_device_action(action());
} }
// Message::DnDTask(action) => {
// return data_device_action(action());
// }
Message::Save => { Message::Save => {
self.reorder_widget_state = ReorderWidgetState::default(); self.reorder_widget_state = ReorderWidgetState::default();
self.save(); self.save();
} }
Message::RemoveStart(to_remove) => { Message::RemoveStart(to_remove) => {
let Some(config) = self.current_config.as_mut() else { let Some(config) = self.current_config.as_mut() else {
return Command::none(); return Task::none();
}; };
let Some((list, _)) = config.plugins_wings.as_mut() else { let Some((list, _)) = config.plugins_wings.as_mut() else {
return Command::none(); return Task::none();
}; };
list.retain(|id| id != &to_remove); list.retain(|id| id != &to_remove);
self.save(); self.save();
} }
Message::RemoveCenter(to_remove) => { Message::RemoveCenter(to_remove) => {
let Some(config) = self.current_config.as_mut() else { let Some(config) = self.current_config.as_mut() else {
return Command::none(); return Task::none();
}; };
let Some(list) = config.plugins_center.as_mut() else { let Some(list) = config.plugins_center.as_mut() else {
return Command::none(); return Task::none();
}; };
list.retain(|id| id != &to_remove); list.retain(|id| id != &to_remove);
self.save(); self.save();
} }
Message::RemoveEnd(to_remove) => { Message::RemoveEnd(to_remove) => {
let Some(config) = self.current_config.as_mut() else { let Some(config) = self.current_config.as_mut() else {
return Command::none(); return Task::none();
}; };
let Some((_, list)) = config.plugins_wings.as_mut() else { let Some((_, list)) = config.plugins_wings.as_mut() else {
return Command::none(); return Task::none();
}; };
list.retain(|id| id != &to_remove); list.retain(|id| id != &to_remove);
self.save(); self.save();
@ -437,7 +433,7 @@ impl Page {
Message::AddApplet(applet) => { Message::AddApplet(applet) => {
// TODO ask design team // TODO ask design team
let Some(config) = self.current_config.as_mut() else { let Some(config) = self.current_config.as_mut() else {
return Command::none(); return Task::none();
}; };
let list = if let Some((list, _)) = config.plugins_wings.as_mut() { let list = if let Some((list, _)) = config.plugins_wings.as_mut() {
list list
@ -456,7 +452,7 @@ impl Page {
)))); ))));
} }
}; };
Command::none() Task::none()
} }
} }
@ -493,9 +489,9 @@ pub fn lists<
.collect() .collect()
}) })
.unwrap_or_default(), .unwrap_or_default(),
Some((window::Id::MAIN, *APPLET_DND_ICON_ID)), Some((window::Id::NONE, *APPLET_DND_ICON_ID)),
Message::StartDnd, Message::StartDnd,
|a| Message::DnDCommand(Arc::new(a)), // |a| Message::DnDTask(Arc::new(a)),
Message::RemoveStart, Message::RemoveStart,
Message::DetailStart, Message::DetailStart,
Message::ReorderStart, Message::ReorderStart,
@ -524,9 +520,9 @@ pub fn lists<
.collect() .collect()
}) })
.unwrap_or_default(), .unwrap_or_default(),
Some((window::Id::MAIN, *APPLET_DND_ICON_ID)), Some((window::Id::NONE, *APPLET_DND_ICON_ID)),
Message::StartDnd, Message::StartDnd,
|a| Message::DnDCommand(Arc::new(a)), // |a| Message::DnDTask(Arc::new(a)),
Message::RemoveCenter, Message::RemoveCenter,
Message::DetailCenter, Message::DetailCenter,
Message::ReorderCenter, Message::ReorderCenter,
@ -556,9 +552,9 @@ pub fn lists<
.collect() .collect()
}) })
.unwrap_or_default(), .unwrap_or_default(),
Some((window::Id::MAIN, *APPLET_DND_ICON_ID)), Some((window::Id::NONE, *APPLET_DND_ICON_ID)),
Message::StartDnd, Message::StartDnd,
|a| Message::DnDCommand(Arc::new(a)), // |a| Message::DnDTask(Arc::new(a)),
Message::RemoveEnd, Message::RemoveEnd,
Message::DetailEnd, Message::DetailEnd,
Message::ReorderEnd, Message::ReorderEnd,
@ -644,7 +640,7 @@ pub struct AppletReorderList<'a, Message> {
id: Id, id: Id,
info: Vec<Applet<'a>>, info: Vec<Applet<'a>>,
on_create_dnd_source: Box<dyn Fn(ReorderWidgetState) -> Message + 'a>, on_create_dnd_source: Box<dyn Fn(ReorderWidgetState) -> Message + 'a>,
on_dnd_command_produced: OnDndCommand<'a, Message>, // on_dnd_task_produced: OnDndTask<'a, Message>,
on_reorder: Box<dyn Fn(Vec<Applet<'static>>) -> Message + 'a>, on_reorder: Box<dyn Fn(Vec<Applet<'static>>) -> Message + 'a>,
on_finish: Option<Message>, on_finish: Option<Message>,
on_cancel: Option<Message>, on_cancel: Option<Message>,
@ -660,10 +656,10 @@ impl<'a, Message: 'static + Clone> AppletReorderList<'a, Message> {
info: Vec<Applet<'a>>, info: Vec<Applet<'a>>,
surface_ids: Option<(window::Id, window::Id)>, surface_ids: Option<(window::Id, window::Id)>,
on_create_dnd_source: impl Fn(ReorderWidgetState) -> Message + 'a, on_create_dnd_source: impl Fn(ReorderWidgetState) -> Message + 'a,
on_dnd_command_produced: impl Fn( // on_dnd_task_produced: impl Fn(
Box<dyn Send + Sync + Fn() -> platform_specific::wayland::data_device::ActionInner>, // Box<dyn Send + Sync + Fn() -> platform_specific::wayland::data_device::ActionInner>,
) -> Message // ) -> Message
+ 'a, // + 'a,
on_remove: impl Fn(String) -> Message + 'a, on_remove: impl Fn(String) -> Message + 'a,
on_details: impl Fn(String) -> Message + 'a, on_details: impl Fn(String) -> Message + 'a,
on_reorder: impl Fn(Vec<Applet<'static>>) -> Message + 'a, on_reorder: impl Fn(Vec<Applet<'static>>) -> Message + 'a,
@ -701,12 +697,12 @@ impl<'a, Message: 'static + Clone> AppletReorderList<'a, Message> {
.into(), .into(),
]) ])
.spacing(spacing.space_xs) .spacing(spacing.space_xs)
.align_items(Alignment::Center), .align_y(Alignment::Center),
) )
.width(Length::Fill) .width(Length::Fill)
.padding(8) .padding(8)
.style(theme::Container::Custom(Box::new(move |theme| { .class(theme::Container::Custom(Box::new(move |theme| {
let mut style = theme.appearance(&theme::Container::Primary); let mut style = container::Catalog::style(theme, &theme::Container::Primary);
style.border.radius = 8.0.into(); style.border.radius = 8.0.into();
if is_dragged { if is_dragged {
style.border.color = theme.cosmic().accent_color().into(); style.border.color = theme.cosmic().accent_color().into();
@ -722,7 +718,7 @@ impl<'a, Message: 'static + Clone> AppletReorderList<'a, Message> {
id: Id::unique(), id: Id::unique(),
info, info,
on_create_dnd_source: Box::new(on_create_dnd_source), on_create_dnd_source: Box::new(on_create_dnd_source),
on_dnd_command_produced: Box::new(on_dnd_command_produced), // on_dnd_task_produced: Box::new(on_dnd_task_produced),
on_reorder: Box::new(on_reorder), on_reorder: Box::new(on_reorder),
on_finish: Some(on_apply_reorder), on_finish: Some(on_apply_reorder),
on_cancel: Some(on_cancel), on_cancel: Some(on_cancel),
@ -732,14 +728,14 @@ impl<'a, Message: 'static + Clone> AppletReorderList<'a, Message> {
text::body(fl!("drop-here")) text::body(fl!("drop-here"))
.width(Length::Fill) .width(Length::Fill)
.height(Length::Fill) .height(Length::Fill)
.vertical_alignment(Vertical::Center) .align_y(Vertical::Center)
.horizontal_alignment(Horizontal::Center), .align_x(Horizontal::Center),
) )
.width(Length::Fill) .width(Length::Fill)
.height(Length::Fixed(48.0)) .height(Length::Fixed(48.0))
.padding(8) .padding(8)
.style(theme::Container::Custom(Box::new(move |theme| { .class(theme::Container::Custom(Box::new(move |theme| {
let mut style = theme.appearance(&theme::Container::Primary); let mut style = container::Catalog::style(theme, &theme::Container::Primary);
style.border.radius = 8.0.into(); style.border.radius = 8.0.into();
style.border.color = theme.cosmic().bg_divider().into(); style.border.color = theme.cosmic().bg_divider().into();
style.border.width = 2.0; style.border.width = 2.0;
@ -762,7 +758,7 @@ impl<'a, Message: 'static + Clone> AppletReorderList<'a, Message> {
id: Id::unique(), id: Id::unique(),
info: Vec::new(), info: Vec::new(),
on_create_dnd_source: Box::new(|_| unimplemented!()), on_create_dnd_source: Box::new(|_| unimplemented!()),
on_dnd_command_produced: Box::new(|_| unimplemented!()), // on_dnd_task_produced: Box::new(|_| unimplemented!()),
on_reorder: Box::new(|_| unimplemented!()), on_reorder: Box::new(|_| unimplemented!()),
on_finish: None, on_finish: None,
surface_ids: None, surface_ids: None,
@ -785,18 +781,18 @@ impl<'a, Message: 'static + Clone> AppletReorderList<'a, Message> {
.into(), .into(),
]) ])
.spacing(12) .spacing(12)
.align_items(Alignment::Center), .align_y(Alignment::Center),
) )
.width(Length::Fixed(state.layout.map_or(400.0, |l| l.width))) .width(Length::Fixed(state.layout.map_or(400.0, |l| l.width)))
.padding(8) .padding(8)
.style(theme::Container::Custom(Box::new(move |theme| { .class(theme::Container::Custom(Box::new(move |theme| {
let mut style = theme.appearance(&theme::Container::Primary); let mut style = container::Catalog::style(theme, &theme::Container::Primary);
style.border.radius = 8.0.into(); style.border.radius = 8.0.into();
style style
}))) })))
.into() .into()
} else { } else {
horizontal_space(1).into() horizontal_space().width(1).into()
}, },
on_cancel: None, on_cancel: None,
} }
@ -912,7 +908,7 @@ where
tree: &mut Tree, tree: &mut Tree,
layout: layout::Layout<'_>, layout: layout::Layout<'_>,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
operation: &mut dyn Operation<OperationOutputWrapper<Message>>, operation: &mut dyn Operation<()>,
) { ) {
self.inner.as_widget().operate( self.inner.as_widget().operate(
&mut tree.children[0], &mut tree.children[0],
@ -1016,7 +1012,7 @@ where
state.dragging_state = state.dragging_state =
DraggingState::Dragging(applet.clone().into_owned()); DraggingState::Dragging(applet.clone().into_owned());
// TODO emit a dnd command // TODO emit a dnd Task
state.layout = Some(layout.bounds().size()); state.layout = Some(layout.bounds().size());
let state_clone = state.clone(); let state_clone = state.clone();
shell.publish((self.on_create_dnd_source.as_ref())( shell.publish((self.on_create_dnd_source.as_ref())(
@ -1024,21 +1020,21 @@ where
)); ));
let p = applet.path.to_path_buf(); let p = applet.path.to_path_buf();
shell.publish((self.on_dnd_command_produced.as_ref())(Box::new(move || { // shell.publish((self.on_dnd_task_produced.as_ref())(Box::new(move || {
platform_specific::wayland::data_device::ActionInner::StartDnd { // platform_specific::wayland::data_device::ActionInner::StartDnd {
mime_types: vec![MIME_TYPE.to_string()], // mime_types: vec![MIME_TYPE.to_string()],
actions: DndAction::Move, // actions: DndAction::Move,
origin_id: window_id, // origin_id: window_id,
icon_id: Some(( // icon_id: Some((
DndIcon::Widget( // DndIcon::Widget(
icon_id, // icon_id,
Box::new(state_clone.clone()), // Box::new(state_clone.clone()),
), // ),
cosmic::iced::Vector::ZERO // cosmic::iced::Vector::ZERO
)), // )),
data: Box::new(AppletString(p.clone())), // data: Box::new(AppletString(p.clone())),
} // }
}))); // })));
ret = event::Status::Captured; ret = event::Status::Captured;
DraggingState::Dragging(applet.clone().into_owned()) DraggingState::Dragging(applet.clone().into_owned())
} else { } else {
@ -1071,31 +1067,31 @@ where
let point = Point::new(*x as f32, *y as f32); let point = Point::new(*x as f32, *y as f32);
if layout.bounds().contains(point) { if layout.bounds().contains(point) {
shell.publish((self.on_dnd_command_produced.as_ref())(Box::new( // shell.publish((self.on_dnd_task_produced.as_ref())(Box::new(
move || { // move || {
platform_specific::wayland::data_device::ActionInner::SetActions { // platform_specific::wayland::data_device::ActionInner::SetActions {
preferred: DndAction::Move, // preferred: DndAction::Move,
accepted: DndAction::Move, // accepted: DndAction::Move,
} // }
}, // },
))); // )));
shell.publish((self.on_dnd_command_produced.as_ref())(Box::new( // shell.publish((self.on_dnd_task_produced.as_ref())(Box::new(
move || { // move || {
platform_specific::wayland::data_device::ActionInner::Accept( // platform_specific::wayland::data_device::ActionInner::Accept(
Some(MIME_TYPE.to_string()), // Some(MIME_TYPE.to_string()),
) // )
}, // },
))); // )));
let data = if let DraggingState::Dragging(a) = &state.dragging_state { let data = if let DraggingState::Dragging(a) = &state.dragging_state {
Some(a.clone()) Some(a.clone())
} else { } else {
shell.publish((self.on_dnd_command_produced.as_ref())(Box::new( // shell.publish((self.on_dnd_task_produced.as_ref())(Box::new(
move || { // move || {
platform_specific::wayland::data_device::ActionInner::RequestDndData( // platform_specific::wayland::data_device::ActionInner::RequestDndData(
MIME_TYPE.to_string(), // MIME_TYPE.to_string(),
) // )
}, // },
))); // )));
None None
}; };
DndOfferState::HandlingOffer( DndOfferState::HandlingOffer(
@ -1146,41 +1142,35 @@ where
let point = Point::new(*x as f32, *y as f32); let point = Point::new(*x as f32, *y as f32);
if layout.bounds().contains(point) { if layout.bounds().contains(point) {
shell.publish((self.on_dnd_command_produced.as_ref())(Box::new( // shell.publish((self.on_dnd_task_produced.as_ref())(Box::new(move || {
move || { // platform_specific::wayland::data_device::ActionInner::SetActions {
platform_specific::wayland::data_device::ActionInner::SetActions { // preferred: DndAction::Move,
preferred: DndAction::Move, // accepted: DndAction::Move,
accepted: DndAction::Move, // }
} // })));
}, // shell.publish((self.on_dnd_task_produced.as_ref())(Box::new(move || {
))); // platform_specific::wayland::data_device::ActionInner::Accept(Some(
shell.publish((self.on_dnd_command_produced.as_ref())(Box::new( // MIME_TYPE.to_string(),
move || { // ))
platform_specific::wayland::data_device::ActionInner::Accept(Some( // })));
MIME_TYPE.to_string(), // shell.publish((self.on_dnd_task_produced.as_ref())(Box::new(move || {
)) // platform_specific::wayland::data_device::ActionInner::SetActions {
}, // preferred: action.intersection(DndAction::Move),
))); // accepted: action
shell.publish((self.on_dnd_command_produced.as_ref())(Box::new( // .intersection(DndAction::Move.union(DndAction::Copy)),
move || { // }
platform_specific::wayland::data_device::ActionInner::SetActions { // })));
preferred: action.intersection(DndAction::Move),
accepted: action
.intersection(DndAction::Move.union(DndAction::Copy)),
}
},
)));
// TODO maybe keep track of data and request here if we don't have it // TODO maybe keep track of data and request here if we don't have it
// also maybe just refactor DND Targets to allow easier handling... // also maybe just refactor DND Targets to allow easier handling...
if data.is_none() { if data.is_none() {
shell.publish((self.on_dnd_command_produced.as_ref())(Box::new( // shell.publish((self.on_dnd_task_produced.as_ref())(Box::new(
move || { // move || {
platform_specific::wayland::data_device::ActionInner::RequestDndData( // platform_specific::wayland::data_device::ActionInner::RequestDndData(
MIME_TYPE.to_string(), // MIME_TYPE.to_string(),
) // )
}, // },
))); // )));
} }
if let Some(applet) = data.clone() { if let Some(applet) = data.clone() {
let reordered_list: Vec<_> = self.get_reordered( let reordered_list: Vec<_> = self.get_reordered(
@ -1192,9 +1182,9 @@ where
applet, applet,
); );
if reordered_list != self.info { if reordered_list != self.info {
shell.publish((self.on_reorder.as_ref())( // shell.publish((self.on_reorder.as_ref())(
reordered_list.into_iter().map(Applet::into_owned).collect(), // reordered_list.into_iter().map(Applet::into_owned).collect(),
)); // ));
} }
} }
@ -1233,14 +1223,12 @@ where
)) => { )) => {
let point = Point::new(*x as f32, *y as f32); let point = Point::new(*x as f32, *y as f32);
if layout.bounds().contains(point) { if layout.bounds().contains(point) {
shell.publish((self.on_dnd_command_produced.as_ref())(Box::new( // shell.publish((self.on_dnd_task_produced.as_ref())(Box::new(move || {
move || { // platform_specific::wayland::data_device::ActionInner::SetActions {
platform_specific::wayland::data_device::ActionInner::SetActions { // preferred: DndAction::Move,
preferred: DndAction::Move, // accepted: DndAction::Move,
accepted: DndAction::Move, // }
} // })));
},
)));
if let Some(data) = data.clone() { if let Some(data) = data.clone() {
let reordered_list = self.get_reordered( let reordered_list = self.get_reordered(
&layout, &layout,
@ -1276,11 +1264,9 @@ where
)); ));
} }
} }
shell.publish((self.on_dnd_command_produced.as_ref())(Box::new( // shell.publish((self.on_dnd_task_produced.as_ref())(Box::new(move || {
move || { // platform_specific::wayland::data_device::ActionInner::Accept(None)
platform_specific::wayland::data_device::ActionInner::Accept(None) // })));
},
)));
DndOfferState::OutsideWidget(mime_types, DndAction::empty(), data) DndOfferState::OutsideWidget(mime_types, DndAction::empty(), data)
} }
} }
@ -1290,12 +1276,12 @@ where
event::Event::PlatformSpecific(PlatformSpecific::Wayland( event::Event::PlatformSpecific(PlatformSpecific::Wayland(
wayland::Event::DndOffer(wayland::DndOfferEvent::SourceActions(actions)), wayland::Event::DndOffer(wayland::DndOfferEvent::SourceActions(actions)),
)) => { )) => {
shell.publish((self.on_dnd_command_produced.as_ref())(Box::new( // shell.publish((self.on_dnd_task_produced.as_ref())(Box::new(move || {
move || platform_specific::wayland::data_device::ActionInner::SetActions { // platform_specific::wayland::data_device::ActionInner::SetActions {
preferred: DndAction::Move, // preferred: DndAction::Move,
accepted: DndAction::Move, // accepted: DndAction::Move,
}, // }
))); // })));
DndOfferState::HandlingOffer(mime_types, *actions, data) DndOfferState::HandlingOffer(mime_types, *actions, data)
} }
event::Event::PlatformSpecific(PlatformSpecific::Wayland( event::Event::PlatformSpecific(PlatformSpecific::Wayland(
@ -1335,26 +1321,22 @@ where
event::Event::PlatformSpecific(PlatformSpecific::Wayland( event::Event::PlatformSpecific(PlatformSpecific::Wayland(
wayland::Event::DndOffer(wayland::DndOfferEvent::DropPerformed), wayland::Event::DndOffer(wayland::DndOfferEvent::DropPerformed),
)) => { )) => {
shell.publish((self.on_dnd_command_produced.as_ref())(Box::new( // shell.publish((self.on_dnd_task_produced.as_ref())(Box::new(move || {
move || platform_specific::wayland::data_device::ActionInner::SetActions { // platform_specific::wayland::data_device::ActionInner::SetActions {
preferred: DndAction::Move, // preferred: DndAction::Move,
accepted: DndAction::Move, // accepted: DndAction::Move,
}, // }
))); // })));
shell.publish((self.on_dnd_command_produced.as_ref())(Box::new( // shell.publish((self.on_dnd_task_produced.as_ref())(Box::new(move || {
move || { // platform_specific::wayland::data_device::ActionInner::Accept(Some(
platform_specific::wayland::data_device::ActionInner::Accept(Some( // MIME_TYPE.to_string(),
MIME_TYPE.to_string(), // ))
)) // })));
}, // shell.publish((self.on_dnd_task_produced.as_ref())(Box::new(move || {
))); // platform_specific::wayland::data_device::ActionInner::RequestDndData(
shell.publish((self.on_dnd_command_produced.as_ref())(Box::new( // MIME_TYPE.to_string(),
move || { // )
platform_specific::wayland::data_device::ActionInner::RequestDndData( // })));
MIME_TYPE.to_string(),
)
},
)));
DndOfferState::Dropped DndOfferState::Dropped
} }
_ => DndOfferState::HandlingOffer(mime_types, action, data), _ => DndOfferState::HandlingOffer(mime_types, action, data),
@ -1366,9 +1348,9 @@ where
if let Some(on_finish) = self.on_finish.clone() { if let Some(on_finish) = self.on_finish.clone() {
shell.publish(on_finish); shell.publish(on_finish);
} }
shell.publish((self.on_dnd_command_produced.as_ref())(Box::new( // shell.publish((self.on_dnd_task_produced.as_ref())(Box::new(move || {
move || platform_specific::wayland::data_device::ActionInner::DndFinished, // platform_specific::wayland::data_device::ActionInner::DndFinished
))); // })));
DndOfferState::None DndOfferState::None
} }
@ -1415,11 +1397,13 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: layout::Layout<'_>, layout: layout::Layout<'_>,
renderer: &cosmic::Renderer, renderer: &cosmic::Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, cosmic::Theme, cosmic::Renderer>> { ) -> Option<overlay::Element<'b, Message, cosmic::Theme, cosmic::Renderer>> {
self.inner.as_widget_mut().overlay( self.inner.as_widget_mut().overlay(
&mut tree.children[0], &mut tree.children[0],
layout.children().next().unwrap(), layout.children().next().unwrap(),
renderer, renderer,
translation,
) )
} }
@ -1454,25 +1438,25 @@ where
} }
/// A string which can be sent to the clipboard or drag-and-dropped. /// A string which can be sent to the clipboard or drag-and-dropped.
#[derive(Debug, Clone)] // #[derive(Debug, Clone)]
pub struct AppletString(PathBuf); // pub struct AppletString(PathBuf);
impl DataFromMimeType for AppletString { // impl DataFromMimeType for AppletString {
fn from_mime_type(&self, mime_type: &str) -> Option<Vec<u8>> { // fn from_mime_type(&self, mime_type: &str) -> Option<Vec<u8>> {
if mime_type == MIME_TYPE { // if mime_type == MIME_TYPE {
let data = Some( // let data = Some(
url::Url::from_file_path(self.0.clone()) // url::Url::from_file_path(self.0.clone())
.ok()? // .ok()?
.to_string() // .to_string()
.as_bytes() // .as_bytes()
.to_vec(), // .to_vec(),
); // );
data // data
} else { // } else {
None // None
} // }
} // }
} // }
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub enum DraggingState { pub enum DraggingState {

View file

@ -6,7 +6,7 @@ use cosmic::{
widget::{ widget::{
button, container, dropdown, horizontal_space, icon, row, settings, slider, text, toggler, button, container, dropdown, horizontal_space, icon, row, settings, slider, text, toggler,
}, },
Command, Element, Element, Task,
}; };
use cosmic::Apply; use cosmic::Apply;
@ -118,11 +118,7 @@ pub(crate) fn behavior_and_position<
.title(&section.title) .title(&section.title)
.add(settings::item( .add(settings::item(
&descriptions[autohide_label], &descriptions[autohide_label],
toggler( toggler(panel_config.autohide.is_some()).on_toggle(Message::AutoHidePanel),
None,
panel_config.autohide.is_some(),
Message::AutoHidePanel,
),
)) ))
.add(settings::item( .add(settings::item(
&descriptions[position], &descriptions[position],
@ -177,11 +173,11 @@ pub(crate) fn style<
.title(&section.title) .title(&section.title)
.add(settings::item( .add(settings::item(
&descriptions[gap_label], &descriptions[gap_label],
toggler(None, panel_config.anchor_gap, Message::AnchorGap), toggler(panel_config.anchor_gap).on_toggle(Message::AnchorGap),
)) ))
.add(settings::item( .add(settings::item(
&descriptions[extend_label], &descriptions[extend_label],
toggler(None, panel_config.expand_to_edges, Message::ExtendToEdge), toggler(panel_config.expand_to_edges).on_toggle(Message::ExtendToEdge),
)) ))
.add(settings::item( .add(settings::item(
&descriptions[appearance], &descriptions[appearance],
@ -272,7 +268,7 @@ pub(crate) fn configuration<P: page::Page<crate::pages::Message> + PanelPage>(
.find(|(_, v)| v.id == page.applets_page_id()) .find(|(_, v)| v.id == page.applets_page_id())
{ {
let control = row::with_children(vec![ let control = row::with_children(vec![
horizontal_space(Length::Fill).into(), horizontal_space().width(Length::Fill).into(),
icon::from_name("go-next-symbolic").size(16).into(), icon::from_name("go-next-symbolic").size(16).into(),
]); ]);
@ -281,9 +277,9 @@ pub(crate) fn configuration<P: page::Page<crate::pages::Message> + PanelPage>(
.control(control) .control(control)
.spacing(16) .spacing(16)
.apply(container) .apply(container)
.style(theme::Container::List) .class(theme::Container::List)
.apply(button::custom) .apply(button::custom)
.style(theme::Button::Transparent) .class(theme::Button::Transparent)
.on_press(crate::pages::Message::Page(panel_applets_entity)), .on_press(crate::pages::Message::Page(panel_applets_entity)),
) )
} else { } else {
@ -334,7 +330,7 @@ pub fn reset_button<
let descriptions = &section.descriptions; let descriptions = &section.descriptions;
let inner = page.inner(); let inner = page.inner();
if inner.system_default == inner.panel_config { if inner.system_default == inner.panel_config {
Element::from(horizontal_space(1)) Element::from(horizontal_space().width(1))
} else { } else {
button::standard(&descriptions[reset_to_default]) button::standard(&descriptions[reset_to_default])
.on_press(Message::ResetPanel) .on_press(Message::ResetPanel)
@ -418,9 +414,9 @@ pub enum Message {
impl PageInner { impl PageInner {
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub fn update(&mut self, message: Message) -> Command<Message> { pub fn update(&mut self, message: Message) -> Task<Message> {
let Some(helper) = self.config_helper.as_ref() else { let Some(helper) = self.config_helper.as_ref() else {
return Command::none(); return Task::none();
}; };
match &message { match &message {
@ -458,7 +454,7 @@ impl PageInner {
}; };
let Some(panel_config) = self.panel_config.as_mut() else { let Some(panel_config) = self.panel_config.as_mut() else {
return Command::none(); return Task::none();
}; };
match message { match message {
@ -526,11 +522,11 @@ impl PageInner {
panel_config.opacity = opacity; panel_config.opacity = opacity;
if self.opacity_changing { if self.opacity_changing {
return Command::none(); return Task::none();
} }
self.opacity_changing = true; self.opacity_changing = true;
return cosmic::command::future(async move { return cosmic::Task::future(async move {
tokio::time::sleep(Duration::from_millis(125)).await; tokio::time::sleep(Duration::from_millis(125)).await;
Message::OpacityApply Message::OpacityApply
}); });
@ -544,7 +540,7 @@ impl PageInner {
Message::OutputAdded(name, output) => { Message::OutputAdded(name, output) => {
self.outputs.push(name.clone()); self.outputs.push(name.clone());
self.outputs_map.insert(output.id(), (name, output)); self.outputs_map.insert(output.id(), (name, output));
return Command::none(); return Task::none();
} }
Message::OutputRemoved(output) => { Message::OutputRemoved(output) => {
if let Some((name, _)) = self.outputs_map.remove(&output.id()) { if let Some((name, _)) = self.outputs_map.remove(&output.id()) {
@ -555,7 +551,7 @@ impl PageInner {
} }
Message::PanelConfig(c) => { Message::PanelConfig(c) => {
self.panel_config = Some(c); self.panel_config = Some(c);
return Command::none(); return Task::none();
} }
Message::ResetPanel | Message::FullReset => {} Message::ResetPanel | Message::FullReset => {}
} }
@ -570,6 +566,6 @@ impl PageInner {
_ = panel_config.set_border_radius(helper, 0); _ = panel_config.set_border_radius(helper, 0);
} }
Command::none() Task::none()
} }
} }

View file

@ -1,6 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use cosmic::{cosmic_config::CosmicConfigEntry, Command}; use cosmic::{cosmic_config::CosmicConfigEntry, Task};
use cosmic_panel_config::{CosmicPanelConfig, CosmicPanelContainerConfig}; use cosmic_panel_config::{CosmicPanelConfig, CosmicPanelContainerConfig};
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
use slotmap::SlotMap; use slotmap::SlotMap;
@ -22,7 +22,7 @@ pub struct Page {
pub struct Message(pub inner::Message); pub struct Message(pub inner::Message);
impl Page { impl Page {
pub fn update(&mut self, message: Message) -> Command<crate::app::Message> { pub fn update(&mut self, message: Message) -> Task<crate::app::Message> {
self.inner self.inner
.update(message.0) .update(message.0)
.map(Message) .map(Message)

View file

@ -14,7 +14,7 @@ use std::{
sync::Arc, sync::Arc,
}; };
use cosmic::{command, Apply, Command}; use cosmic::iced::{Color, Length};
use cosmic::{ use cosmic::{
dialog::file_chooser, dialog::file_chooser,
widget::{ widget::{
@ -23,16 +23,13 @@ use cosmic::{
settings, tab_bar, text, toggler, settings, tab_bar, text, toggler,
}, },
}; };
use cosmic::{
iced::{Color, Length},
prelude::CollectionWidget,
};
use cosmic::{iced_core::alignment, iced_runtime::core::image::Handle as ImageHandle}; use cosmic::{iced_core::alignment, iced_runtime::core::image::Handle as ImageHandle};
use cosmic::{iced_core::Alignment, widget::icon}; use cosmic::{iced_core::Alignment, widget::icon};
use cosmic::{ use cosmic::{
widget::{color_picker::ColorPickerUpdate, ColorPickerModel}, widget::{color_picker::ColorPickerUpdate, ColorPickerModel},
Element, Element,
}; };
use cosmic::{Apply, Task};
use cosmic_bg_config::Source; use cosmic_bg_config::Source;
use cosmic_settings_page::Section; use cosmic_settings_page::Section;
use cosmic_settings_page::{self as page, section}; use cosmic_settings_page::{self as page, section};
@ -208,12 +205,12 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: page::Entity, _page: page::Entity,
_sender: tokio::sync::mpsc::Sender<crate::pages::Message>, _sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> Command<crate::pages::Message> { ) -> Task<crate::pages::Message> {
let current_folder = self.config.current_folder().to_owned(); let current_folder = self.config.current_folder().to_owned();
let recurse = self.categories.selected == Some(Category::Wallpapers); let recurse = self.categories.selected == Some(Category::Wallpapers);
command::future(async move { Task::future(async move {
let (service_config, displays) = wallpaper::config().await; let (service_config, displays) = wallpaper::config().await;
let mut selection = change_folder(current_folder, recurse).await; let mut selection = change_folder(current_folder, recurse).await;
@ -418,7 +415,7 @@ impl Page {
_ => return, _ => return,
}; };
self.cached_display_handle = Some(ImageHandle::from_pixels( self.cached_display_handle = Some(ImageHandle::from_rgba(
image.width(), image.width(),
image.height(), image.height(),
image.to_vec(), image.to_vec(),
@ -545,14 +542,14 @@ impl Page {
} }
/// Changes the selection category, such as wallpaper select or color select. /// Changes the selection category, such as wallpaper select or color select.
fn change_category(&mut self, category: Category) -> Command<crate::app::Message> { fn change_category(&mut self, category: Category) -> Task<crate::app::Message> {
let mut command = Command::none(); let mut task = Task::none();
match category { match category {
Category::Wallpapers => { Category::Wallpapers => {
if self.config.current_folder.is_some() { if self.config.current_folder.is_some() {
let _ = self.config.set_current_folder(None); let _ = self.config.set_current_folder(None);
command = cosmic::command::future(async move { task = cosmic::command::future(async move {
let folder = change_folder(Config::default_folder().to_owned(), true).await; let folder = change_folder(Config::default_folder().to_owned(), true).await;
Message::ChangeFolder(folder) Message::ChangeFolder(folder)
}); });
@ -572,7 +569,7 @@ impl Page {
tracing::error!(?path, ?why, "failed to set current folder"); tracing::error!(?path, ?why, "failed to set current folder");
} }
command = cosmic::command::future(async move { task = cosmic::command::future(async move {
Message::ChangeFolder(change_folder(path, false).await) Message::ChangeFolder(change_folder(path, false).await)
}); });
} }
@ -596,7 +593,7 @@ impl Page {
} }
self.categories.selected = Some(category); self.categories.selected = Some(category);
command task
} }
/// Changes the output being configured /// Changes the output being configured
@ -669,7 +666,7 @@ impl Page {
} }
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub fn update(&mut self, message: Message) -> Command<crate::app::Message> { pub fn update(&mut self, message: Message) -> Task<crate::app::Message> {
match message { match message {
Message::UpdateState(_state) => { Message::UpdateState(_state) => {
if let Choice::Slideshow = self.selection.active { if let Choice::Slideshow = self.selection.active {
@ -701,27 +698,23 @@ impl Page {
} }
Message::ColorAdd(message) => { Message::ColorAdd(message) => {
match message { if let ColorPickerUpdate::ActionFinished = message {
ColorPickerUpdate::ActionFinished => { let _res = self
let _res = self .color_model
.color_model .update::<crate::app::Message>(ColorPickerUpdate::AppliedColor);
.update::<crate::app::Message>(ColorPickerUpdate::AppliedColor);
if let Some(color) = self.color_model.get_applied_color() { if let Some(color) = self.color_model.get_applied_color() {
let color = wallpaper::Color::Single([color.r, color.g, color.b]); let color = wallpaper::Color::Single([color.r, color.g, color.b]);
if let Err(why) = self.config.add_custom_color(color.clone()) { if let Err(why) = self.config.add_custom_color(color.clone()) {
tracing::error!(?why, "could not set custom color"); tracing::error!(?why, "could not set custom color");
}
self.selection.add_custom_color(color.clone());
self.selection.active = Choice::Color(color);
self.cached_display_handle = None;
self.context_view = None;
} }
}
_ => (), self.selection.add_custom_color(color.clone());
self.selection.active = Choice::Color(color);
self.cached_display_handle = None;
self.context_view = None;
}
}; };
return self.color_model.update::<crate::app::Message>(message); return self.color_model.update::<crate::app::Message>(message);
@ -747,7 +740,7 @@ impl Page {
let Some((path, display, selection)) = result else { let Some((path, display, selection)) = result else {
tracing::warn!("image not found for provided wallpaper"); tracing::warn!("image not found for provided wallpaper");
return Command::none(); return Task::none();
}; };
if let Err(why) = self.config.add_custom_image(path.clone()) { if let Err(why) = self.config.add_custom_image(path.clone()) {
@ -757,7 +750,7 @@ impl Page {
self.selection.add_custom_image( self.selection.add_custom_image(
path, path,
display, display,
ImageHandle::from_pixels( ImageHandle::from_rgba(
selection.width(), selection.width(),
selection.height(), selection.height(),
selection.into_vec(), selection.into_vec(),
@ -777,7 +770,7 @@ impl Page {
} }
Message::ImageAddDialog => { Message::ImageAddDialog => {
return cosmic::command::future(async { return cosmic::Task::future(async {
let dialog_result = file_chooser::open::Dialog::new() let dialog_result = file_chooser::open::Dialog::new()
.title(fl!("wallpaper", "image-dialog")) .title(fl!("wallpaper", "image-dialog"))
.accept_label(fl!("dialog-add")) .accept_label(fl!("dialog-add"))
@ -816,7 +809,7 @@ impl Page {
Message::Output(id) => { Message::Output(id) => {
self.change_output(id); self.change_output(id);
return Command::none(); return Task::none();
} }
Message::RotationFrequency(pos) => self.change_rotation_frequency(pos), Message::RotationFrequency(pos) => self.change_rotation_frequency(pos),
@ -837,20 +830,16 @@ impl Page {
self.cache_display_image(); self.cache_display_image();
} else { } else {
if let Some(output) = self.config_output() { if let Some(output) = self.config_output() {
match self.config.current_image(output) { if let Some(Source::Path(path)) = self.config.current_image(output) {
Some(Source::Path(path)) => { if let Some(entity) = self.wallpaper_id_from_path(&path) {
if let Some(entity) = self.wallpaper_id_from_path(&path) { if let Some(entry) =
if let Some(entry) = self.config_wallpaper_entry(output.to_owned(), path)
self.config_wallpaper_entry(output.to_owned(), path) {
{ self.select_wallpaper(&entry, entity, false);
self.select_wallpaper(&entry, entity, false); self.config_apply();
self.config_apply(); return Task::none();
return Command::none();
}
} }
} }
_ => (),
} }
} }
@ -863,7 +852,7 @@ impl Page {
DialogResponse::Path(path) => path, DialogResponse::Path(path) => path,
DialogResponse::Error(why) => { DialogResponse::Error(why) => {
tracing::error!(why, "dialog response error"); tracing::error!(why, "dialog response error");
return Command::none(); return Task::none();
} }
}; };
@ -886,7 +875,7 @@ impl Page {
let recurse = self.categories.selected == Some(Category::Wallpapers); let recurse = self.categories.selected == Some(Category::Wallpapers);
// Load the wallpapers from the selected folder into the view. // Load the wallpapers from the selected folder into the view.
return cosmic::command::future(async move { return cosmic::Task::future(async move {
let message = Message::ChangeFolder(change_folder(path, recurse).await); let message = Message::ChangeFolder(change_folder(path, recurse).await);
let page_message = crate::pages::Message::DesktopWallpaper(message); let page_message = crate::pages::Message::DesktopWallpaper(message);
crate::Message::PageMessage(page_message) crate::Message::PageMessage(page_message)
@ -899,7 +888,7 @@ impl Page {
DialogResponse::Path(path) => path, DialogResponse::Path(path) => path,
DialogResponse::Error(why) => { DialogResponse::Error(why) => {
tracing::error!(why, "dialog response error"); tracing::error!(why, "dialog response error");
return Command::none(); return Task::none();
} }
}; };
@ -907,7 +896,7 @@ impl Page {
tracing::info!(?path, "opening custom image"); tracing::info!(?path, "opening custom image");
// Loads a single custom image and its thumbnail for display in the backgrounds view. // Loads a single custom image and its thumbnail for display in the backgrounds view.
return cosmic::command::future(async move { return cosmic::Task::future(async move {
let result = wallpaper::load_image_with_thumbnail(path); let result = wallpaper::load_image_with_thumbnail(path);
let message = Message::ImageAdd(result.map(Arc::new)); let message = Message::ImageAdd(result.map(Arc::new));
@ -974,7 +963,7 @@ impl Page {
} }
self.config_apply(); self.config_apply();
Command::none() Task::none()
} }
/// Selects the given wallpaper entry. /// Selects the given wallpaper entry.
@ -1125,7 +1114,7 @@ pub async fn change_folder(current_folder: PathBuf, recurse: bool) -> Context {
update.display_images.insert(id, display_image); update.display_images.insert(id, display_image);
let selection_handle = ImageHandle::from_pixels( let selection_handle = ImageHandle::from_rgba(
selection_image.width(), selection_image.width(),
selection_image.height(), selection_image.height(),
selection_image.into_vec(), selection_image.into_vec(),
@ -1192,8 +1181,8 @@ pub fn settings() -> Section<crate::pages::Message> {
if page.wallpaper_service_config.same_on_all { if page.wallpaper_service_config.same_on_all {
let element = text(fl!("all-displays")) let element = text(fl!("all-displays"))
.font(cosmic::font::semibold()) .font(cosmic::font::semibold())
.horizontal_alignment(alignment::Horizontal::Center) .align_x(alignment::Horizontal::Center)
.vertical_alignment(alignment::Vertical::Center) .align_y(alignment::Vertical::Center)
.width(Length::Fill) .width(Length::Fill)
.height(Length::Fill) .height(Length::Fill)
.apply(cosmic::widget::container) .apply(cosmic::widget::container)
@ -1216,18 +1205,15 @@ pub fn settings() -> Section<crate::pages::Message> {
let mut column = list_column() let mut column = list_column()
.add(settings::item( .add(settings::item(
&descriptions[same_label], &descriptions[same_label],
toggler( toggler(page.wallpaper_service_config.same_on_all)
None, .on_toggle(Message::SameWallpaper),
page.wallpaper_service_config.same_on_all,
Message::SameWallpaper,
),
)) ))
.add(settings::item(&descriptions[fit_label], wallpaper_fit)); .add(settings::item(&descriptions[fit_label], wallpaper_fit));
if show_slideshow_toggle { if show_slideshow_toggle {
column = column.add(settings::item( column = column.add(settings::item(
&descriptions[slide_label], &descriptions[slide_label],
toggler(None, slideshow_enabled, Message::Slideshow), toggler(slideshow_enabled).on_toggle(Message::Slideshow),
)); ));
} }
@ -1269,7 +1255,7 @@ pub fn settings() -> Section<crate::pages::Message> {
children.push( children.push(
row::with_capacity(2) row::with_capacity(2)
.align_items(Alignment::Center) .align_y(Alignment::Center)
// Show a folder icon if the active category is a custom folder. // Show a folder icon if the active category is a custom folder.
.push_maybe( .push_maybe(
if let Some(Category::RecentFolder(_)) = page.categories.selected { if let Some(Category::RecentFolder(_)) = page.categories.selected {
@ -1279,7 +1265,7 @@ pub fn settings() -> Section<crate::pages::Message> {
}, },
) )
.push(category_selection) .push(category_selection)
.push(cosmic::widget::horizontal_space(Length::Fill)) .push(cosmic::widget::horizontal_space().width(Length::Fill))
.push_maybe(add_button) .push_maybe(add_button)
.into(), .into(),
); );
@ -1346,7 +1332,7 @@ pub fn settings() -> Section<crate::pages::Message> {
// .width(Length::Fill) // .width(Length::Fill)
// .height(Length::Fill) // .height(Length::Fill)
// .center_x() // .center_x()
// .style(cosmic::theme::style::Container::Background); // .class(cosmic::theme::style::Container::Background);
// cosmic::widget::column::with_capacity(2) // cosmic::widget::column::with_capacity(2)
// .push(header) // .push(header)

View file

@ -7,7 +7,7 @@ use cosmic::iced_core::Border;
use cosmic::iced_core::{self, gradient::Linear, Background, Color, Degrees, Length}; use cosmic::iced_core::{self, gradient::Linear, Background, Color, Degrees, Length};
use cosmic::iced_runtime::core::image::Handle as ImageHandle; use cosmic::iced_runtime::core::image::Handle as ImageHandle;
use cosmic::prelude::*; use cosmic::prelude::*;
use cosmic::widget::{button, container, space}; use cosmic::widget::{button, container, Space};
use cosmic::{iced, Element}; use cosmic::{iced, Element};
use cosmic_settings_wallpaper as wallpaper; use cosmic_settings_wallpaper as wallpaper;
use slotmap::DefaultKey; use slotmap::DefaultKey;
@ -34,7 +34,7 @@ pub fn color_button(
button::custom_image_button(content, on_remove) button::custom_image_button(content, on_remove)
.padding(0) .padding(0)
.selected(selected) .selected(selected)
.style(button::Style::Image) .class(button::ButtonClass::Image)
.on_press(Message::ColorSelect(color)) .on_press(Message::ColorSelect(color))
.into() .into()
} }
@ -47,9 +47,9 @@ pub fn color_image<'a, M: 'a>(
height: u16, height: u16,
border_radius: Option<f32>, border_radius: Option<f32>,
) -> Element<'a, M> { ) -> Element<'a, M> {
container(space::Space::new(width, height)) container(Space::new(width, height))
.style(cosmic::theme::Container::custom(move |theme| { .class(cosmic::theme::Container::custom(move |theme| {
container::Appearance { container::Style {
icon_color: None, icon_color: None,
text_color: None, text_color: None,
background: Some(match &color { background: Some(match &color {
@ -173,8 +173,7 @@ fn flex_select_row(elements: Vec<Element<Message>>) -> Element<Message> {
.column_spacing(COLUMN_SPACING) .column_spacing(COLUMN_SPACING)
.row_spacing(ROW_SPACING) .row_spacing(ROW_SPACING)
.apply(container) .apply(container)
.width(Length::Fill) .center_x(Length::Fill)
.center_x()
.into() .into()
} }

View file

@ -113,7 +113,7 @@ impl Page {
self.focus_follows_cursor = value; self.focus_follows_cursor = value;
if let Err(err) = self if let Err(err) = self
.comp_config .comp_config
.set("focus_follows_cursor", &self.focus_follows_cursor) .set("focus_follows_cursor", self.focus_follows_cursor)
{ {
error!(?err, "Failed to set config 'focus_follows_cursor'"); error!(?err, "Failed to set config 'focus_follows_cursor'");
} }
@ -141,7 +141,7 @@ impl Page {
self.cursor_follows_focus = value; self.cursor_follows_focus = value;
if let Err(err) = self if let Err(err) = self
.comp_config .comp_config
.set("cursor_follows_focus", &self.cursor_follows_focus) .set("cursor_follows_focus", self.cursor_follows_focus)
{ {
error!(?err, "Failed to set config 'cursor_follows_focus'"); error!(?err, "Failed to set config 'cursor_follows_focus'");
} }
@ -283,11 +283,7 @@ pub fn focus_navigation() -> Section<crate::pages::Message> {
.title(&section.title) .title(&section.title)
.add(settings::item( .add(settings::item(
&descriptions[focus_follows_cursor], &descriptions[focus_follows_cursor],
toggler( toggler(page.focus_follows_cursor).on_toggle(Message::SetFocusFollowsCursor),
None,
page.focus_follows_cursor,
Message::SetFocusFollowsCursor,
),
)) ))
.add(settings::item( .add(settings::item(
&descriptions[focus_follows_cursor_delay], &descriptions[focus_follows_cursor_delay],
@ -301,11 +297,7 @@ pub fn focus_navigation() -> Section<crate::pages::Message> {
)) ))
.add(settings::item( .add(settings::item(
&descriptions[cursor_follows_focus], &descriptions[cursor_follows_focus],
toggler( toggler(page.cursor_follows_focus).on_toggle(Message::SetCursorFollowsFocus),
None,
page.cursor_follows_focus,
Message::SetCursorFollowsFocus,
),
)) ))
.apply(Element::from) .apply(Element::from)
.map(crate::pages::Message::WindowManagement) .map(crate::pages::Message::WindowManagement)

View file

@ -359,7 +359,7 @@ impl<'a, Message: Clone> Widget<Message, cosmic::Theme, Renderer> for Arrangemen
core::text::Renderer::fill_text( core::text::Renderer::fill_text(
renderer, renderer,
core::Text { core::Text {
content: itoa::Buffer::new().format(id), content: itoa::Buffer::new().format(id).to_string(),
size: core::Pixels(24.0), size: core::Pixels(24.0),
line_height: core::text::LineHeight::Relative(1.2), line_height: core::text::LineHeight::Relative(1.2),
font: cosmic::font::bold(), font: cosmic::font::bold(),
@ -367,7 +367,7 @@ impl<'a, Message: Clone> Widget<Message, cosmic::Theme, Renderer> for Arrangemen
horizontal_alignment: alignment::Horizontal::Center, horizontal_alignment: alignment::Horizontal::Center,
vertical_alignment: alignment::Vertical::Center, vertical_alignment: alignment::Vertical::Center,
shaping: text::Shaping::Basic, shaping: text::Shaping::Basic,
wrap: text::Wrap::Word, wrapping: text::Wrapping::Word,
}, },
core::Point { core::Point {
x: id_bounds.center_x(), x: id_bounds.center_x(),

View file

@ -7,12 +7,11 @@ pub mod arrangement;
use crate::{app, pages}; use crate::{app, pages};
use arrangement::Arrangement; use arrangement::Arrangement;
use cosmic::iced::{time, Alignment, Length}; use cosmic::iced::{time, Alignment, Length};
use cosmic::iced_widget::scrollable::{Direction, Properties, RelativeOffset}; use cosmic::iced_widget::scrollable::{Direction, RelativeOffset, Scrollbar};
use cosmic::prelude::CollectionWidget;
use cosmic::widget::{ use cosmic::widget::{
self, column, container, dropdown, list_column, segmented_button, tab_bar, text, toggler, self, column, container, dropdown, list_column, segmented_button, tab_bar, text, toggler,
}; };
use cosmic::{command, Apply, Command, Element}; use cosmic::{Apply, Element, Task};
use cosmic_config::{ConfigGet, ConfigSet}; use cosmic_config::{ConfigGet, ConfigSet};
use cosmic_randr_shell::{List, Output, OutputKey, Transform}; use cosmic_randr_shell::{List, Output, OutputKey, Transform};
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
@ -237,7 +236,7 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: page::Entity, _page: page::Entity,
sender: tokio::sync::mpsc::Sender<crate::pages::Message>, sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> Command<crate::pages::Message> { ) -> Task<crate::pages::Message> {
if let Some(task) = self.background_service.take() { if let Some(task) = self.background_service.take() {
task.abort(); task.abort();
} }
@ -264,15 +263,15 @@ impl page::Page<crate::pages::Message> for Page {
}); });
})); }));
command::future(on_enter()) cosmic::command::future(on_enter())
} }
fn on_leave(&mut self) -> Command<crate::pages::Message> { fn on_leave(&mut self) -> Task<crate::pages::Message> {
if let Some(task) = self.background_service.take() { if let Some(task) = self.background_service.take() {
task.abort(); task.abort();
} }
Command::none() Task::none()
} }
#[cfg(feature = "test")] #[cfg(feature = "test")]
@ -280,8 +279,8 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: page::Entity, _page: page::Entity,
sender: tokio::sync::mpsc::Sender<crate::pages::Message>, sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> Command<crate::pages::Message> { ) -> Task<crate::pages::Message> {
command::future(async move { cosmic::command::future(async move {
let mut randr = List::default(); let mut randr = List::default();
let test_mode = randr.modes.insert(cosmic_randr_shell::Mode { let test_mode = randr.modes.insert(cosmic_randr_shell::Mode {
@ -341,7 +340,7 @@ impl page::Page<crate::pages::Message> for Page {
/// To make a setting activate this dialog. Call the `set_dialog` method with /// To make a setting activate this dialog. Call the `set_dialog` method with
/// the Randr enum value which undos the current change. Makde sure the /// the Randr enum value which undos the current change. Makde sure the
/// return value is returned with the `exec_value` return value within a batch /// return value is returned with the `exec_value` return value within a batch
/// command. /// Task.
fn dialog(&self) -> Option<Element<pages::Message>> { fn dialog(&self) -> Option<Element<pages::Message>> {
self.dialog?; self.dialog?;
let element = widget::dialog(fl!("dialog", "title")) let element = widget::dialog(fl!("dialog", "title"))
@ -360,7 +359,7 @@ impl page::Page<crate::pages::Message> for Page {
} }
impl Page { impl Page {
pub fn update(&mut self, message: Message) -> Command<app::Message> { pub fn update(&mut self, message: Message) -> Task<app::Message> {
match message { match message {
Message::RandrResult(result) => { Message::RandrResult(result) => {
if let Some(Err(why)) = Arc::into_inner(result) { if let Some(Err(why)) = Arc::into_inner(result) {
@ -375,10 +374,10 @@ impl Page {
Message::DialogCancel => { Message::DialogCancel => {
let Some(request) = self.dialog else { let Some(request) = self.dialog else {
return Command::none(); return Task::none();
}; };
let Some(output) = self.list.outputs.get(self.active_display) else { let Some(output) = self.list.outputs.get(self.active_display) else {
return Command::none(); return Task::none();
}; };
self.dialog = None; self.dialog = None;
self.dialog_countdown = 0; self.dialog_countdown = 0;
@ -393,11 +392,11 @@ impl Page {
Message::DialogCountdown => { Message::DialogCountdown => {
if self.dialog_countdown == 0 { if self.dialog_countdown == 0 {
if self.dialog.is_some() { if self.dialog.is_some() {
return command::message(app::Message::from(Message::DialogCancel)); return cosmic::command::message(app::Message::from(Message::DialogCancel));
} }
} else { } else {
self.dialog_countdown -= 1; self.dialog_countdown -= 1;
return command::future(async move { return cosmic::command::future(async move {
tokio::time::sleep(time::Duration::from_secs(1)).await; tokio::time::sleep(time::Duration::from_secs(1)).await;
Message::DialogCountdown Message::DialogCountdown
}); });
@ -417,7 +416,7 @@ impl Page {
Mirroring::Mirror(from_display) => { Mirroring::Mirror(from_display) => {
let Some(output) = self.list.outputs.get(self.active_display) else { let Some(output) = self.list.outputs.get(self.active_display) else {
return Command::none(); return Task::none();
}; };
return self.exec_randr(output, Randr::Mirror(from_display)); return self.exec_randr(output, Randr::Mirror(from_display));
@ -425,7 +424,7 @@ impl Page {
Mirroring::Project(to_display) => { Mirroring::Project(to_display) => {
let Some(output) = self.list.outputs.get(to_display) else { let Some(output) = self.list.outputs.get(to_display) else {
return Command::none(); return Task::none();
}; };
return self.exec_randr(output, Randr::Mirror(self.active_display)); return self.exec_randr(output, Randr::Mirror(self.active_display));
@ -494,7 +493,7 @@ impl Page {
self.comp_config_descale_xwayland = descale; self.comp_config_descale_xwayland = descale;
if let Err(err) = self if let Err(err) = self
.comp_config .comp_config
.set("descale_xwayland", &self.comp_config_descale_xwayland) .set("descale_xwayland", self.comp_config_descale_xwayland)
{ {
error!(?err, "Failed to set config 'descale_xwayland'"); error!(?err, "Failed to set config 'descale_xwayland'");
} }
@ -564,29 +563,25 @@ impl Page {
/// Sets the dialog to be shown to the user. Will not show a dialog if the /// Sets the dialog to be shown to the user. Will not show a dialog if the
/// current request does not change anything. /// current request does not change anything.
fn set_dialog( fn set_dialog(&mut self, revert_request: Randr, current_request: &Randr) -> Task<app::Message> {
&mut self,
revert_request: Randr,
current_request: &Randr,
) -> Command<app::Message> {
if revert_request == *current_request { if revert_request == *current_request {
return Command::none(); return Task::none();
} }
self.dialog = Some(revert_request); self.dialog = Some(revert_request);
self.dialog_countdown = 10; self.dialog_countdown = 10;
command::future(async { cosmic::command::future(async {
tokio::time::sleep(time::Duration::from_secs(1)).await; tokio::time::sleep(time::Duration::from_secs(1)).await;
app::Message::from(Message::DialogCountdown) app::Message::from(Message::DialogCountdown)
}) })
} }
/// Changes the color depth of the active display. /// Changes the color depth of the active display.
pub fn set_color_depth(&mut self, _depth: ColorDepth) -> Command<app::Message> { pub fn set_color_depth(&mut self, _depth: ColorDepth) -> Task<app::Message> {
unimplemented!() unimplemented!()
} }
/// Changes the color profile of the active display. /// Changes the color profile of the active display.
pub fn set_color_profile(&mut self, _profile: usize) -> Command<app::Message> { pub fn set_color_profile(&mut self, _profile: usize) -> Task<app::Message> {
unimplemented!() unimplemented!()
} }
@ -713,11 +708,11 @@ impl Page {
} }
/// Change display orientation. /// Change display orientation.
pub fn set_orientation(&mut self, transform: Transform) -> Command<app::Message> { pub fn set_orientation(&mut self, transform: Transform) -> Task<app::Message> {
let request = Randr::Transform(transform); let request = Randr::Transform(transform);
let mut commands = Vec::with_capacity(2); let mut tasks = Vec::with_capacity(2);
commands.push(match self.cache.orientation_selected { tasks.push(match self.cache.orientation_selected {
Some(orientation) => self.set_dialog( Some(orientation) => self.set_dialog(
Randr::Transform(match orientation { Randr::Transform(match orientation {
1 => Transform::Rotate90, 1 => Transform::Rotate90,
@ -727,11 +722,11 @@ impl Page {
}), }),
&request, &request,
), ),
None => Command::none(), None => Task::none(),
}); });
let Some(output) = self.list.outputs.get(self.active_display) else { let Some(output) = self.list.outputs.get(self.active_display) else {
return Command::none(); return Task::none();
}; };
self.cache.orientation_selected = match transform { self.cache.orientation_selected = match transform {
@ -741,22 +736,22 @@ impl Page {
_ => Some(3), _ => Some(3),
}; };
commands.push(self.exec_randr(output, Randr::Transform(transform))); tasks.push(self.exec_randr(output, Randr::Transform(transform)));
Command::batch(commands) Task::batch(tasks)
} }
/// Changes the position of the display. /// Changes the position of the display.
pub fn set_position(&mut self, display: OutputKey, x: i32, y: i32) -> Command<app::Message> { pub fn set_position(&mut self, display: OutputKey, x: i32, y: i32) -> Task<app::Message> {
let Some(output) = self.list.outputs.get_mut(display) else { let Some(output) = self.list.outputs.get_mut(display) else {
return Command::none(); return Task::none();
}; };
output.position = (x, y); output.position = (x, y);
if cfg!(feature = "test") { if cfg!(feature = "test") {
tracing::debug!("set position {x},{y}"); tracing::debug!("set position {x},{y}");
return Command::none(); return Task::none();
} }
let output = &self.list.outputs[display]; let output = &self.list.outputs[display];
@ -764,9 +759,9 @@ impl Page {
} }
/// Changes the refresh rate of the active display. /// Changes the refresh rate of the active display.
pub fn set_refresh_rate(&mut self, option: usize) -> Command<app::Message> { pub fn set_refresh_rate(&mut self, option: usize) -> Task<app::Message> {
let Some(output) = self.list.outputs.get(self.active_display) else { let Some(output) = self.list.outputs.get(self.active_display) else {
return Command::none(); return Task::none();
}; };
if let Some(ref resolution) = self.config.resolution { if let Some(ref resolution) = self.config.resolution {
@ -779,26 +774,26 @@ impl Page {
} }
} }
Command::none() Task::none()
} }
/// Change the resolution of the active display. /// Change the resolution of the active display.
pub fn set_resolution(&mut self, option: usize) -> Command<app::Message> { pub fn set_resolution(&mut self, option: usize) -> Task<app::Message> {
let mut commands = Vec::with_capacity(2); let mut tasks = Vec::with_capacity(2);
let Some(output) = self.list.outputs.get(self.active_display) else { let Some(output) = self.list.outputs.get(self.active_display) else {
return Command::none(); return Task::none();
}; };
let Some((&resolution, rates)) = self.cache.modes.iter().rev().nth(option) else { let Some((&resolution, rates)) = self.cache.modes.iter().rev().nth(option) else {
return Command::none(); return Task::none();
}; };
self.cache.refresh_rates.clear(); self.cache.refresh_rates.clear();
cache_rates(&mut self.cache.refresh_rates, rates); cache_rates(&mut self.cache.refresh_rates, rates);
let Some(&rate) = rates.first() else { let Some(&rate) = rates.first() else {
return Command::none(); return Task::none();
}; };
let request = Randr::Resolution(resolution.0, resolution.1); let request = Randr::Resolution(resolution.0, resolution.1);
@ -811,18 +806,18 @@ impl Page {
self.config.resolution = Some(resolution); self.config.resolution = Some(resolution);
self.cache.refresh_rate_selected = Some(0); self.cache.refresh_rate_selected = Some(0);
self.cache.resolution_selected = Some(option); self.cache.resolution_selected = Some(option);
commands.push(self.exec_randr(output, Randr::Resolution(resolution.0, resolution.1))); tasks.push(self.exec_randr(output, Randr::Resolution(resolution.0, resolution.1)));
commands.push(self.set_dialog(revert_request, &request)); tasks.push(self.set_dialog(revert_request, &request));
Command::batch(commands) Task::batch(tasks)
} }
/// Set the scale of the active display. /// Set the scale of the active display.
pub fn set_scale(&mut self, option: usize) -> Command<app::Message> { pub fn set_scale(&mut self, option: usize) -> Task<app::Message> {
let mut commands = Vec::with_capacity(2); let mut tasks = Vec::with_capacity(2);
let Some(output) = self.list.outputs.get(self.active_display) else { let Some(output) = self.list.outputs.get(self.active_display) else {
return Command::none(); return Task::none();
}; };
let scale = (option * 25 + 50) as u32; let scale = (option * 25 + 50) as u32;
@ -832,18 +827,18 @@ impl Page {
self.cache.scale_selected = Some(option); self.cache.scale_selected = Some(option);
self.config.scale = scale; self.config.scale = scale;
commands.push(self.exec_randr(output, Randr::Scale(scale))); tasks.push(self.exec_randr(output, Randr::Scale(scale)));
commands.push(self.set_dialog(revert_request, &request)); tasks.push(self.set_dialog(revert_request, &request));
Command::batch(commands) Task::batch(tasks)
} }
/// Enables or disables the active display. /// Enables or disables the active display.
pub fn toggle_display(&mut self, enable: bool) -> Command<app::Message> { pub fn toggle_display(&mut self, enable: bool) -> Task<app::Message> {
let mut commands = Vec::with_capacity(2); let mut tasks = Vec::with_capacity(2);
let request = Randr::Toggle(enable); let request = Randr::Toggle(enable);
let Some(output) = self.list.outputs.get_mut(self.active_display) else { let Some(output) = self.list.outputs.get_mut(self.active_display) else {
return Command::none(); return Task::none();
}; };
let revert_request = Randr::Toggle(output.enabled); let revert_request = Randr::Toggle(output.enabled);
@ -852,44 +847,40 @@ impl Page {
output.enabled = enable; output.enabled = enable;
let output = &self.list.outputs[self.active_display]; let output = &self.list.outputs[self.active_display];
commands.push(self.exec_randr(output, request)); tasks.push(self.exec_randr(output, request));
commands.push(self.set_dialog(revert_request, &current_request)); tasks.push(self.set_dialog(revert_request, &current_request));
Command::batch(commands) Task::batch(tasks)
} }
/// Applies a display configuration via `cosmic-randr`. /// Applies a display configuration via `cosmic-randr`.
fn exec_randr(&self, output: &Output, request: Randr) -> Command<app::Message> { fn exec_randr(&self, output: &Output, request: Randr) -> Task<app::Message> {
let mut commands = Vec::with_capacity(2); let mut tasks = Vec::with_capacity(2);
// Removes the dialog if no change is being made // Removes the dialog if no change is being made
if Some(request) == self.dialog { if Some(request) == self.dialog {
commands.push(command::message(app::Message::from( tasks.push(cosmic::command::message(app::Message::from(
Message::DialogComplete, Message::DialogComplete,
))); )));
} }
let name = &*output.name; let name = &*output.name;
let mut command = tokio::process::Command::new("cosmic-randr"); let mut task = tokio::process::Command::new("cosmic-randr");
match request { match request {
Randr::Mirror(from_id) => { Randr::Mirror(from_id) => {
let Some(from_output) = self.list.outputs.get(from_id) else { let Some(from_output) = self.list.outputs.get(from_id) else {
return Command::none(); return Task::none();
}; };
command task.arg("mirror").arg(&output.name).arg(&from_output.name);
.arg("mirror")
.arg(&output.name)
.arg(&from_output.name);
} }
Randr::Position(x, y) => { Randr::Position(x, y) => {
let Some(current) = output.current.and_then(|id| self.list.modes.get(id)) else { let Some(current) = output.current.and_then(|id| self.list.modes.get(id)) else {
return Command::none(); return Task::none();
}; };
command task.arg("mode")
.arg("mode")
.arg("--pos-x") .arg("--pos-x")
.arg(itoa::Buffer::new().format(x)) .arg(itoa::Buffer::new().format(x))
.arg("--pos-y") .arg("--pos-y")
@ -901,14 +892,13 @@ impl Page {
Randr::RefreshRate(rate) => { Randr::RefreshRate(rate) => {
let Some(current) = output.current.and_then(|id| self.list.modes.get(id)) else { let Some(current) = output.current.and_then(|id| self.list.modes.get(id)) else {
return Command::none(); return Task::none();
}; };
command task.arg("mode")
.arg("mode")
.arg("--refresh") .arg("--refresh")
.arg( .arg(
&[ [
itoa::Buffer::new().format(rate / 1000), itoa::Buffer::new().format(rate / 1000),
".", ".",
itoa::Buffer::new().format(rate % 1000), itoa::Buffer::new().format(rate % 1000),
@ -921,8 +911,7 @@ impl Page {
} }
Randr::Resolution(width, height) => { Randr::Resolution(width, height) => {
command task.arg("mode")
.arg("mode")
.arg(name) .arg(name)
.arg(itoa::Buffer::new().format(width)) .arg(itoa::Buffer::new().format(width))
.arg(itoa::Buffer::new().format(height)); .arg(itoa::Buffer::new().format(height));
@ -930,14 +919,13 @@ impl Page {
Randr::Scale(scale) => { Randr::Scale(scale) => {
let Some(current) = output.current.and_then(|id| self.list.modes.get(id)) else { let Some(current) = output.current.and_then(|id| self.list.modes.get(id)) else {
return Command::none(); return Task::none();
}; };
command task.arg("mode")
.arg("mode")
.arg("--scale") .arg("--scale")
.arg( .arg(
&[ [
itoa::Buffer::new().format(scale / 100), itoa::Buffer::new().format(scale / 100),
".", ".",
itoa::Buffer::new().format(scale % 100), itoa::Buffer::new().format(scale % 100),
@ -950,18 +938,16 @@ impl Page {
} }
Randr::Toggle(enable) => { Randr::Toggle(enable) => {
command task.arg(if enable { "enable" } else { "disable" })
.arg(if enable { "enable" } else { "disable" })
.arg(name); .arg(name);
} }
Randr::Transform(transform) => { Randr::Transform(transform) => {
let Some(current) = output.current.and_then(|id| self.list.modes.get(id)) else { let Some(current) = output.current.and_then(|id| self.list.modes.get(id)) else {
return Command::none(); return Task::none();
}; };
command task.arg("mode")
.arg("mode")
.arg("--transform") .arg("--transform")
.arg(&*format!("{transform}")) .arg(&*format!("{transform}"))
.arg(name) .arg(name)
@ -970,11 +956,11 @@ impl Page {
} }
} }
commands.push(cosmic::command::future(async move { tasks.push(cosmic::command::future(async move {
tracing::debug!(?command, "executing"); tracing::debug!(?task, "executing");
app::Message::from(Message::RandrResult(Arc::new(command.status().await))) app::Message::from(Message::RandrResult(Arc::new(task.status().await)))
})); }));
Command::batch(commands) Task::batch(tasks)
} }
} }
@ -1011,10 +997,9 @@ pub fn display_arrangement() -> Section<crate::pages::Message> {
.apply(widget::scrollable) .apply(widget::scrollable)
.id(page.display_arrangement_scrollable.clone()) .id(page.display_arrangement_scrollable.clone())
.width(Length::Shrink) .width(Length::Shrink)
.direction(Direction::Horizontal(Properties::new())) .direction(Direction::Horizontal(Scrollbar::new()))
.apply(container) .apply(container)
.center_x() .center_x(Length::Fill)
.width(Length::Fill)
}) })
.apply(widget::list::container) .apply(widget::list::container)
.into() .into()
@ -1106,7 +1091,7 @@ pub fn display_configuration() -> Section<crate::pages::Message> {
let mut column = list_column() let mut column = list_column()
.add(widget::settings::item( .add(widget::settings::item(
&descriptions[enable_label], &descriptions[enable_label],
toggler(None, active_output.enabled, Message::DisplayToggle), toggler(active_output.enabled).on_toggle(Message::DisplayToggle),
)) ))
.add(widget::settings::item( .add(widget::settings::item(
&descriptions[mirroring_label], &descriptions[mirroring_label],

View file

@ -6,7 +6,7 @@ use crate::pages;
use cosmic::iced_core::{Alignment, Length, Padding}; use cosmic::iced_core::{Alignment, Length, Padding};
use cosmic::prelude::CollectionWidget; use cosmic::prelude::CollectionWidget;
use cosmic::widget::{button, column, icon, list_column, row, toggler}; use cosmic::widget::{button, column, icon, list_column, row, toggler};
use cosmic::{Apply, Command, Element}; use cosmic::{Apply, Element, Task};
use std::sync::Arc; use std::sync::Arc;
pub fn view( pub fn view(
@ -25,7 +25,7 @@ pub fn view(
.push(cosmic::widget::Space::new(Length::Fill, 12)) .push(cosmic::widget::Space::new(Length::Fill, 12))
.push_maybe(button.map(|(text, message)| { .push_maybe(button.map(|(text, message)| {
button::text(text) button::text(text)
.style(cosmic::theme::Button::Link) .class(cosmic::theme::Button::Link)
.trailing_icon(icon::from_name("go-next-symbolic").size(16)) .trailing_icon(icon::from_name("go-next-symbolic").size(16))
.padding(0) .padding(0)
.on_press(message) .on_press(message)
@ -55,7 +55,7 @@ impl super::Page {
.control( .control(
row() row()
.align_items(Alignment::Center) .align_items(Alignment::Center)
.push(toggler(None, self.config.night_light_enabled, |enable| { .push(toggler(self.config.night_light_enabled, |enable| {
Message::NightLight(NightLight::Toggle(enable)) Message::NightLight(NightLight::Toggle(enable))
})) }))
.push( .push(

View file

@ -6,9 +6,9 @@ use cosmic::{
cosmic_config::{self, ConfigSet}, cosmic_config::{self, ConfigSet},
iced::{self, Length}, iced::{self, Length},
iced_core::Border, iced_core::Border,
iced_style, theme, theme,
widget::{self, button, container, icon, radio, row, settings, ListColumn}, widget::{self, button, container, icon, radio, row, settings, ListColumn},
Apply, Command, Element, Apply, Element, Task,
}; };
use cosmic_comp_config::XkbConfig; use cosmic_comp_config::XkbConfig;
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
@ -154,15 +154,15 @@ fn popover_menu_row(
) -> cosmic::Element<'static, Message> { ) -> cosmic::Element<'static, Message> {
widget::text::body(label) widget::text::body(label)
.apply(widget::container) .apply(widget::container)
.style(cosmic::theme::Container::custom(|theme| { .class(cosmic::theme::Container::custom(|theme| {
iced_style::container::Appearance { widget::container::Style {
background: None, background: None,
..container::StyleSheet::appearance(theme, &cosmic::theme::Container::List) ..container::Catalog::style(theme, &cosmic::theme::Container::List)
} }
})) }))
.apply(button::custom) .apply(button::custom)
.on_press(()) .on_press(())
.style(theme::Button::Transparent) .class(theme::Button::Transparent)
.apply(Element::from) .apply(Element::from)
.map(move |()| Message::SourceContext(message(id))) .map(move |()| Message::SourceContext(message(id)))
} }
@ -173,36 +173,32 @@ fn popover_menu(id: DefaultKey) -> cosmic::Element<'static, Message> {
id, id,
fl!("keyboard-sources", "move-up"), fl!("keyboard-sources", "move-up"),
SourceContext::MoveUp, SourceContext::MoveUp,
) ),
.into(),
popover_menu_row( popover_menu_row(
id, id,
fl!("keyboard-sources", "move-down"), fl!("keyboard-sources", "move-down"),
SourceContext::MoveDown, SourceContext::MoveDown,
) ),
.into(),
cosmic::widget::divider::horizontal::default().into(), cosmic::widget::divider::horizontal::default().into(),
popover_menu_row( popover_menu_row(
id, id,
fl!("keyboard-sources", "settings"), fl!("keyboard-sources", "settings"),
SourceContext::Settings, SourceContext::Settings,
) ),
.into(),
popover_menu_row( popover_menu_row(
id, id,
fl!("keyboard-sources", "view-layout"), fl!("keyboard-sources", "view-layout"),
SourceContext::ViewLayout, SourceContext::ViewLayout,
) ),
.into(), popover_menu_row(id, fl!("keyboard-sources", "remove"), SourceContext::Remove),
popover_menu_row(id, fl!("keyboard-sources", "remove"), SourceContext::Remove).into(),
]) ])
.padding(8) .padding(8)
.width(Length::Shrink) .width(Length::Shrink)
.height(Length::Shrink) .height(Length::Shrink)
.apply(cosmic::widget::container) .apply(cosmic::widget::container)
.style(cosmic::theme::Container::custom(|theme| { .class(cosmic::theme::Container::custom(|theme| {
let cosmic = theme.cosmic(); let cosmic = theme.cosmic();
container::Appearance { container::Style {
icon_color: Some(theme.cosmic().background.on.into()), icon_color: Some(theme.cosmic().background.on.into()),
text_color: Some(theme.cosmic().background.on.into()), text_color: Some(theme.cosmic().background.on.into()),
background: Some(iced::Color::from(theme.cosmic().background.base).into()), background: Some(iced::Color::from(theme.cosmic().background.base).into()),
@ -291,7 +287,7 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: page::Entity, _page: page::Entity,
_sender: tokio::sync::mpsc::Sender<crate::pages::Message>, _sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> Command<crate::pages::Message> { ) -> Task<crate::pages::Message> {
self.xkb = super::get_config(&self.config, "xkb_config"); self.xkb = super::get_config(&self.config, "xkb_config");
match ( match (
xkb_data::keyboard_layouts(), xkb_data::keyboard_layouts(),
@ -389,12 +385,12 @@ impl page::Page<crate::pages::Message> for Page {
} }
} }
Command::none() Task::none()
} }
} }
impl Page { impl Page {
pub fn update(&mut self, message: Message) -> Command<crate::app::Message> { pub fn update(&mut self, message: Message) -> Task<crate::app::Message> {
match message { match message {
Message::InputSourceSearch(search) => { Message::InputSourceSearch(search) => {
self.input_source_search = search; self.input_source_search = search;
@ -502,7 +498,7 @@ impl Page {
} }
} }
Command::none() Task::none()
} }
pub fn add_input_source_view(&self) -> Element<'_, crate::pages::Message> { pub fn add_input_source_view(&self) -> Element<'_, crate::pages::Message> {
@ -512,10 +508,12 @@ impl Page {
.on_input(Message::InputSourceSearch) .on_input(Message::InputSourceSearch)
.on_clear(Message::InputSourceSearch(String::new())); .on_clear(Message::InputSourceSearch(String::new()));
let toggler = settings::item::builder(fl!("show-extended-input-sources")).toggler( let toggler = settings::item::builder(fl!("show-extended-input-sources"))
self.show_extended_input_sources, .toggler(
Message::SetShowExtendedInputSources, self.show_extended_input_sources,
); Message::SetShowExtendedInputSources,
)
.label(fl!("show-extended-input-sources"));
let mut list = widget::list_column(); let mut list = widget::list_column();
@ -674,15 +672,15 @@ fn special_character_entry() -> Section<crate::pages::Message> {
settings::section() settings::section()
.title(&section.title) .title(&section.title)
.add(crate::widget::go_next_item( .add(crate::widget::go_next_item(
&*descriptions[alternate], &descriptions[alternate],
Message::OpenSpecialCharacterContext(SpecialKey::AlternateCharacters), Message::OpenSpecialCharacterContext(SpecialKey::AlternateCharacters),
)) ))
.add(crate::widget::go_next_item( .add(crate::widget::go_next_item(
&*descriptions[compose], &descriptions[compose],
Message::OpenSpecialCharacterContext(SpecialKey::Compose), Message::OpenSpecialCharacterContext(SpecialKey::Compose),
)) ))
.add(crate::widget::go_next_item( .add(crate::widget::go_next_item(
&*descriptions[caps], &descriptions[caps],
Message::OpenSpecialCharacterContext(SpecialKey::CapsLock), Message::OpenSpecialCharacterContext(SpecialKey::CapsLock),
)) ))
.apply(cosmic::Element::from) .apply(cosmic::Element::from)
@ -749,7 +747,7 @@ fn keyboard_typing_assist() -> Section<crate::pages::Message> {
.max_width(250); .max_width(250);
row::with_capacity(3) row::with_capacity(3)
.align_items(iced::Alignment::Center) .align_y(iced::Alignment::Center)
.spacing(theme.cosmic().space_s()) .spacing(theme.cosmic().space_s())
.push(widget::text::body(&descriptions[short])) .push(widget::text::body(&descriptions[short]))
.push(delay_slider) .push(delay_slider)
@ -769,7 +767,7 @@ fn keyboard_typing_assist() -> Section<crate::pages::Message> {
.max_width(250); .max_width(250);
row::with_capacity(3) row::with_capacity(3)
.align_items(iced::Alignment::Center) .align_y(iced::Alignment::Center)
.spacing(theme.cosmic().space_s()) .spacing(theme.cosmic().space_s())
.push(widget::text::body(&descriptions[slow])) .push(widget::text::body(&descriptions[slow]))
.push(rate_slider) .push(rate_slider)

View file

@ -1,8 +1,7 @@
use cosmic::iced::alignment::Horizontal; use cosmic::iced::alignment::Horizontal;
use cosmic::iced::{Alignment, Length}; use cosmic::iced::{Alignment, Length};
use cosmic::prelude::CollectionWidget;
use cosmic::widget::{self, button, icon, settings, text}; use cosmic::widget::{self, button, icon, settings, text};
use cosmic::{command, theme, Apply, Command, Element}; use cosmic::{theme, Apply, Element, Task};
use cosmic_config::{ConfigGet, ConfigSet}; use cosmic_config::{ConfigGet, ConfigSet};
use cosmic_settings_config::shortcuts::{self, Action, Binding, Shortcuts}; use cosmic_settings_config::shortcuts::{self, Action, Binding, Shortcuts};
use slab::Slab; use slab::Slab;
@ -240,7 +239,7 @@ impl Model {
} }
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub(super) fn update(&mut self, message: ShortcutMessage) -> Command<crate::app::Message> { pub(super) fn update(&mut self, message: ShortcutMessage) -> Task<crate::app::Message> {
match message { match message {
ShortcutMessage::AddKeybinding => { ShortcutMessage::AddKeybinding => {
if let Some(short_id) = self.shortcut_context { if let Some(short_id) = self.shortcut_context {
@ -390,18 +389,18 @@ impl Model {
self.shortcut_context = Some(id); self.shortcut_context = Some(id);
self.replace_dialog = None; self.replace_dialog = None;
let mut commands = vec![command::message(crate::app::Message::OpenContextDrawer( let mut tasks = vec![cosmic::command::message(
description.into(), crate::app::Message::OpenContextDrawer(description.into()),
))]; )];
if let Some(model) = self.shortcut_models.get(0) { if let Some(model) = self.shortcut_models.get(0) {
if let Some(shortcut) = model.bindings.get(0) { if let Some(shortcut) = model.bindings.get(0) {
commands.push(widget::text_input::focus(shortcut.id.clone())); tasks.push(widget::text_input::focus(shortcut.id.clone()));
commands.push(widget::text_input::select_all(shortcut.id.clone())); tasks.push(widget::text_input::select_all(shortcut.id.clone()));
} }
} }
return Command::batch(commands); return Task::batch(tasks);
} }
ShortcutMessage::SubmitBinding(id) => { ShortcutMessage::SubmitBinding(id) => {
@ -415,7 +414,7 @@ impl Model {
Ok(new_binding) => { Ok(new_binding) => {
if !new_binding.is_set() { if !new_binding.is_set() {
shortcut.input.clear(); shortcut.input.clear();
return Command::none(); return Task::none();
} }
if let Some(action) = self.config_contains(&new_binding) { if let Some(action) = self.config_contains(&new_binding) {
let action_str = if let Action::Spawn(_) = &action { let action_str = if let Action::Spawn(_) = &action {
@ -425,7 +424,7 @@ impl Model {
}; };
self.replace_dialog = self.replace_dialog =
Some((id, new_binding, action, action_str)); Some((id, new_binding, action, action_str));
return Command::none(); return Task::none();
} }
apply_binding = Some(new_binding); apply_binding = Some(new_binding);
@ -459,7 +458,7 @@ impl Model {
} }
} }
Command::none() Task::none()
} }
pub(super) fn view(&self) -> Element<ShortcutMessage> { pub(super) fn view(&self) -> Element<ShortcutMessage> {
@ -486,8 +485,8 @@ fn context_drawer(
let model = &shortcuts[id]; let model = &shortcuts[id];
let action = show_action.then(|| { let action = show_action.then(|| {
let description = if let Action::Spawn(command) = &model.action { let description = if let Action::Spawn(task) = &model.action {
Cow::Borrowed(command.as_str()) Cow::Borrowed(task.as_str())
} else { } else {
Cow::Owned(super::localize_action(&model.action)) Cow::Owned(super::localize_action(&model.action))
}; };
@ -573,7 +572,7 @@ fn shortcut_item(custom: bool, id: usize, data: &ShortcutModel) -> Element<Short
text::body(fl!("disabled")).into() text::body(fl!("disabled")).into()
} else { } else {
widget::column::with_children(bindings) widget::column::with_children(bindings)
.align_items(Alignment::End) .align_x(Alignment::End)
.into() .into()
}; };
@ -591,16 +590,16 @@ fn shortcut_item(custom: bool, id: usize, data: &ShortcutModel) -> Element<Short
widget::button::icon(icon::from_name("edit-delete-symbolic")) widget::button::icon(icon::from_name("edit-delete-symbolic"))
.on_press(LocalMessage::Remove) .on_press(LocalMessage::Remove)
})) }))
.align_items(Alignment::Center) .align_y(Alignment::Center)
.spacing(8); .spacing(8);
settings::item::builder(&data.description) settings::item::builder(&data.description)
.flex_control(control) .flex_control(control)
.spacing(16) .spacing(16)
.apply(widget::container) .apply(widget::container)
.style(theme::Container::List) .class(theme::Container::List)
.apply(widget::button::custom) .apply(widget::button::custom)
.style(theme::Button::Transparent) .class(theme::Button::Transparent)
.on_press(LocalMessage::Show) .on_press(LocalMessage::Show)
.apply(Element::from) .apply(Element::from)
.map(move |message| match message { .map(move |message| match message {

View file

@ -4,7 +4,7 @@ use super::{ShortcutBinding, ShortcutMessage, ShortcutModel};
use cosmic::iced::alignment::Horizontal; use cosmic::iced::alignment::Horizontal;
use cosmic::iced::Length; use cosmic::iced::Length;
use cosmic::widget::{self, button, icon}; use cosmic::widget::{self, button, icon};
use cosmic::{Apply, Command, Element}; use cosmic::{Apply, Element, Task};
use cosmic_settings_config::shortcuts::{Action, Shortcuts}; use cosmic_settings_config::shortcuts::{Action, Shortcuts};
use cosmic_settings_config::Binding; use cosmic_settings_config::Binding;
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
@ -15,7 +15,7 @@ pub struct Page {
model: super::Model, model: super::Model,
add_shortcut: AddShortcut, add_shortcut: AddShortcut,
replace_dialog: Vec<(Binding, Action, String)>, replace_dialog: Vec<(Binding, Action, String)>,
command_id: widget::Id, task_id: widget::Id,
name_id: widget::Id, name_id: widget::Id,
} }
@ -25,7 +25,7 @@ impl Default for Page {
model: super::Model::default().custom().actions(bindings), model: super::Model::default().custom().actions(bindings),
add_shortcut: AddShortcut::default(), add_shortcut: AddShortcut::default(),
replace_dialog: Vec::new(), replace_dialog: Vec::new(),
command_id: widget::Id::unique(), task_id: widget::Id::unique(),
name_id: widget::Id::unique(), name_id: widget::Id::unique(),
} }
} }
@ -37,8 +37,8 @@ pub enum Message {
AddKeybinding, AddKeybinding,
/// Add a new custom shortcut to the config /// Add a new custom shortcut to the config
AddShortcut, AddShortcut,
/// Update the command text input /// Update the Task text input
CommandInput(String), TaskInput(String),
/// Toggle editing of the key text input /// Toggle editing of the key text input
EditCombination, EditCombination,
/// Toggle editability of the key text input /// Toggle editability of the key text input
@ -63,7 +63,7 @@ pub enum Message {
struct AddShortcut { struct AddShortcut {
pub active: bool, pub active: bool,
pub name: String, pub name: String,
pub command: String, pub task: String,
pub keys: Slab<(String, widget::Id, bool)>, pub keys: Slab<(String, widget::Id, bool)>,
} }
@ -71,7 +71,7 @@ impl AddShortcut {
pub fn enable(&mut self) { pub fn enable(&mut self) {
self.active = true; self.active = true;
self.name.clear(); self.name.clear();
self.command.clear(); self.task.clear();
if self.keys.is_empty() { if self.keys.is_empty() {
self.keys self.keys
@ -87,10 +87,10 @@ impl AddShortcut {
} }
impl Page { impl Page {
pub fn update(&mut self, message: Message) -> Command<crate::app::Message> { pub fn update(&mut self, message: Message) -> Task<crate::app::Message> {
match message { match message {
Message::CommandInput(text) => { Message::TaskInput(text) => {
self.add_shortcut.command = text; self.add_shortcut.task = text;
} }
Message::KeyInput(id, text) => { Message::KeyInput(id, text) => {
@ -121,7 +121,7 @@ impl Page {
self.add_shortcut self.add_shortcut
.keys .keys
.insert((String::new(), new_id.clone(), true)); .insert((String::new(), new_id.clone(), true));
return Command::batch(vec![ return Task::batch(vec![
widget::text_input::focus(new_id.clone()), widget::text_input::focus(new_id.clone()),
widget::text_input::select_all(new_id), widget::text_input::select_all(new_id),
]); ]);
@ -129,10 +129,10 @@ impl Page {
Message::AddShortcut => { Message::AddShortcut => {
let name = self.add_shortcut.name.trim(); let name = self.add_shortcut.name.trim();
let command = self.add_shortcut.command.trim(); let task = self.add_shortcut.task.trim();
if name.is_empty() || command.is_empty() { if name.is_empty() || task.is_empty() {
return Command::none(); return Task::none();
} }
let mut addable_bindings = Vec::new(); let mut addable_bindings = Vec::new();
@ -143,11 +143,11 @@ impl Page {
} }
let Ok(binding) = Binding::from_str(keys) else { let Ok(binding) = Binding::from_str(keys) else {
return Command::none(); return Task::none();
}; };
if !binding.is_set() { if !binding.is_set() {
return Command::none(); return Task::none();
} }
if let Some(action) = self.model.config_contains(&binding) { if let Some(action) = self.model.config_contains(&binding) {
@ -169,7 +169,7 @@ impl Page {
Message::EditCombination => { Message::EditCombination => {
let (_, id, editing) = &mut self.add_shortcut.keys[0]; let (_, id, editing) = &mut self.add_shortcut.keys[0];
*editing = true; *editing = true;
return Command::batch(vec![ return Task::batch(vec![
widget::text_input::focus(id.clone()), widget::text_input::focus(id.clone()),
widget::text_input::select_all(id.clone()), widget::text_input::select_all(id.clone()),
]); ]);
@ -177,7 +177,7 @@ impl Page {
Message::NameSubmit => { Message::NameSubmit => {
if !self.add_shortcut.name.trim().is_empty() { if !self.add_shortcut.name.trim().is_empty() {
return widget::text_input::focus(self.command_id.clone()); return widget::text_input::focus(self.task_id.clone());
} }
} }
@ -209,7 +209,7 @@ impl Page {
Message::ShortcutContext => { Message::ShortcutContext => {
self.add_shortcut.enable(); self.add_shortcut.enable();
return Command::batch(vec![ return Task::batch(vec![
cosmic::command::message(crate::app::Message::OpenContextDrawer( cosmic::command::message(crate::app::Message::OpenContextDrawer(
fl!("custom-shortcuts", "context").into(), fl!("custom-shortcuts", "context").into(),
)), )),
@ -218,7 +218,7 @@ impl Page {
} }
} }
Command::none() Task::none()
} }
fn add_keybinding_context(&self) -> Element<'_, Message> { fn add_keybinding_context(&self) -> Element<'_, Message> {
@ -228,11 +228,11 @@ impl Page {
.on_submit(Message::NameSubmit) .on_submit(Message::NameSubmit)
.id(self.name_id.clone()); .id(self.name_id.clone());
let command_input = widget::text_input("", &self.add_shortcut.command) let task_input = widget::text_input("", &self.add_shortcut.task)
.padding([6, 12]) .padding([6, 12])
.on_input(Message::CommandInput) .on_input(Message::TaskInput)
.on_submit(Message::EditCombination) .on_submit(Message::EditCombination)
.id(self.command_id.clone()); .id(self.task_id.clone());
let name_control = widget::column() let name_control = widget::column()
.spacing(4) .spacing(4)
@ -242,7 +242,7 @@ impl Page {
let command_control = widget::column() let command_control = widget::column()
.spacing(4) .spacing(4)
.push(widget::text::body(fl!("command"))) .push(widget::text::body(fl!("command")))
.push(command_input); .push(task_input);
let input_fields = widget::column() let input_fields = widget::column()
.spacing(12) .spacing(12)
@ -288,7 +288,7 @@ impl Page {
fn add_shortcut(&mut self, mut binding: Binding) { fn add_shortcut(&mut self, mut binding: Binding) {
self.add_shortcut.active = !self.replace_dialog.is_empty(); self.add_shortcut.active = !self.replace_dialog.is_empty();
binding.description = Some(self.add_shortcut.name.clone()); binding.description = Some(self.add_shortcut.name.clone());
let new_action = Action::Spawn(self.add_shortcut.command.clone()); let new_action = Action::Spawn(self.add_shortcut.task.clone());
self.model.config_add(new_action, binding); self.model.config_add(new_action, binding);
} }
} }
@ -350,14 +350,14 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: cosmic_settings_page::Entity, _page: cosmic_settings_page::Entity,
_sender: tokio::sync::mpsc::Sender<crate::pages::Message>, _sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> Command<crate::pages::Message> { ) -> Task<crate::pages::Message> {
self.model.on_enter(); self.model.on_enter();
Command::none() Task::none()
} }
fn on_leave(&mut self) -> Command<crate::pages::Message> { fn on_leave(&mut self) -> Task<crate::pages::Message> {
self.model.on_clear(); self.model.on_clear();
Command::none() Task::none()
} }
} }
@ -367,11 +367,11 @@ fn bindings(_defaults: &Shortcuts, keybindings: &Shortcuts) -> Slab<ShortcutMode
keybindings keybindings
.iter() .iter()
.fold(Slab::new(), |mut slab, (binding, action)| { .fold(Slab::new(), |mut slab, (binding, action)| {
if let Action::Spawn(command) = action { if let Action::Spawn(task) = action {
let description = binding let description = binding
.description .description
.clone() .clone()
.unwrap_or_else(|| command.to_owned()); .unwrap_or_else(|| task.to_owned());
let new_binding = ShortcutBinding { let new_binding = ShortcutBinding {
id: widget::Id::unique(), id: widget::Id::unique(),

View file

@ -1,5 +1,5 @@
use super::{ShortcutMessage, ShortcutModel}; use super::{ShortcutMessage, ShortcutModel};
use cosmic::{Command, Element}; use cosmic::{Element, Task};
use cosmic_settings_config::shortcuts::action::ResizeDirection; use cosmic_settings_config::shortcuts::action::ResizeDirection;
use cosmic_settings_config::shortcuts::Action; use cosmic_settings_config::shortcuts::Action;
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
@ -23,7 +23,7 @@ impl Default for Page {
} }
impl Page { impl Page {
pub fn update(&mut self, message: ShortcutMessage) -> Command<crate::app::Message> { pub fn update(&mut self, message: ShortcutMessage) -> Task<crate::app::Message> {
self.model.update(message) self.model.update(message)
} }
} }
@ -56,15 +56,15 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: cosmic_settings_page::Entity, _page: cosmic_settings_page::Entity,
_sender: tokio::sync::mpsc::Sender<crate::pages::Message>, _sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> Command<crate::pages::Message> { ) -> Task<crate::pages::Message> {
self.model.on_enter(); self.model.on_enter();
Command::none() Task::none()
} }
fn on_leave(&mut self) -> Command<crate::pages::Message> { fn on_leave(&mut self) -> Task<crate::pages::Message> {
self.model.on_clear(); self.model.on_clear();
Command::none() Task::none()
} }
} }

View file

@ -11,7 +11,7 @@ pub mod tiling;
use cosmic::iced::Length; use cosmic::iced::Length;
use cosmic::widget::{self, icon, settings, text}; use cosmic::widget::{self, icon, settings, text};
use cosmic::{command, theme, Apply, Command, Element}; use cosmic::{theme, Apply, Element, Task};
use cosmic_config::ConfigGet; use cosmic_config::ConfigGet;
use cosmic_settings_config::shortcuts::action::{ use cosmic_settings_config::shortcuts::action::{
Direction, FocusDirection, Orientation, ResizeDirection, Direction, FocusDirection, Orientation, ResizeDirection,
@ -136,7 +136,7 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: cosmic_settings_page::Entity, _page: cosmic_settings_page::Entity,
_sender: tokio::sync::mpsc::Sender<crate::pages::Message>, _sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> Command<crate::pages::Message> { ) -> Task<crate::pages::Message> {
if self.shortcuts_context.is_none() { if self.shortcuts_context.is_none() {
self.shortcuts_context = cosmic_settings_config::shortcuts::context().ok(); self.shortcuts_context = cosmic_settings_config::shortcuts::context().ok();
} }
@ -193,10 +193,10 @@ impl page::Page<crate::pages::Message> for Page {
self.search.shortcuts = defaults; self.search.shortcuts = defaults;
} }
Command::none() Task::none()
} }
fn on_leave(&mut self) -> Command<crate::pages::Message> { fn on_leave(&mut self) -> Task<crate::pages::Message> {
self.search.actions.clear(); self.search.actions.clear();
self.search.localized.clear(); self.search.localized.clear();
self.search.input.clear(); self.search.input.clear();
@ -206,40 +206,42 @@ impl page::Page<crate::pages::Message> for Page {
self.modified.move_windows = 0; self.modified.move_windows = 0;
self.modified.nav = 0; self.modified.nav = 0;
self.modified.system = 0; self.modified.system = 0;
Command::none() Task::none()
} }
} }
impl Page { impl Page {
pub fn update(&mut self, message: Message) -> Command<crate::app::Message> { pub fn update(&mut self, message: Message) -> Task<crate::app::Message> {
match message { match message {
Message::Category(category) => match category { Message::Category(category) => match category {
Category::Custom => { Category::Custom => {
command::message(crate::app::Message::Page(self.sub_pages.custom)) cosmic::command::message(crate::app::Message::Page(self.sub_pages.custom))
} }
Category::ManageWindow => { Category::ManageWindow => cosmic::command::message(crate::app::Message::Page(
command::message(crate::app::Message::Page(self.sub_pages.manage_window)) self.sub_pages.manage_window,
} )),
Category::MoveWindow => { Category::MoveWindow => {
command::message(crate::app::Message::Page(self.sub_pages.move_window)) cosmic::command::message(crate::app::Message::Page(self.sub_pages.move_window))
} }
Category::Nav => command::message(crate::app::Message::Page(self.sub_pages.nav)), Category::Nav => {
cosmic::command::message(crate::app::Message::Page(self.sub_pages.nav))
}
Category::System => { Category::System => {
command::message(crate::app::Message::Page(self.sub_pages.system)) cosmic::command::message(crate::app::Message::Page(self.sub_pages.system))
} }
Category::WindowTiling => { Category::WindowTiling => cosmic::command::message(crate::app::Message::Page(
command::message(crate::app::Message::Page(self.sub_pages.window_tiling)) self.sub_pages.window_tiling,
} )),
}, },
Message::Search(input) => { Message::Search(input) => {
self.search(input); self.search(input);
Command::none() Task::none()
} }
Message::SearchShortcut(message) => self.search_model.update(message), Message::SearchShortcut(message) => self.search_model.update(message),
@ -369,8 +371,7 @@ fn shortcuts() -> Section<crate::pages::Message> {
.on_input(Message::Search) .on_input(Message::Search)
.apply(widget::container) .apply(widget::container)
.padding([2, 0, 0, 0]) .padding([2, 0, 0, 0])
.center_x() .center_x(Length::Fill);
.width(Length::Fill);
// If the search input is not empty, show the category view, else the search results. // If the search input is not empty, show the category view, else the search results.
let content = if page.search.input.is_empty() { let content = if page.search.input.is_empty() {
@ -436,9 +437,9 @@ fn category_item(category: Category, name: &str, modified: u16) -> Element<Messa
.control(control) .control(control)
.spacing(16) .spacing(16)
.apply(widget::container) .apply(widget::container)
.style(theme::Container::List) .class(theme::Container::List)
.apply(widget::button::custom) .apply(widget::button::custom)
.style(theme::Button::Transparent) .class(theme::Button::Transparent)
.on_press(Message::Category(category)) .on_press(Message::Category(category))
.into() .into()
} }
@ -661,7 +662,7 @@ fn localize_action(action: &Action) -> String {
SystemAction::WorkspaceOverview => fl!("system-shortcut", "workspace-overview"), SystemAction::WorkspaceOverview => fl!("system-shortcut", "workspace-overview"),
}, },
Action::Spawn(command) => command.clone(), Action::Spawn(task) => task.clone(),
} }
} }
@ -669,6 +670,6 @@ fn localize_custom_action(action: &Action, binding: &Binding) -> String {
if let Some(description) = &binding.description { if let Some(description) = &binding.description {
description.to_string() description.to_string()
} else { } else {
localize_action(&action) localize_action(action)
} }
} }

View file

@ -1,5 +1,5 @@
use super::{ShortcutMessage, ShortcutModel}; use super::{ShortcutMessage, ShortcutModel};
use cosmic::{Command, Element}; use cosmic::{Element, Task};
use cosmic_settings_config::shortcuts::action::Direction; use cosmic_settings_config::shortcuts::action::Direction;
use cosmic_settings_config::shortcuts::Action; use cosmic_settings_config::shortcuts::Action;
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
@ -23,7 +23,7 @@ impl Default for Page {
} }
impl Page { impl Page {
pub fn update(&mut self, message: ShortcutMessage) -> Command<crate::app::Message> { pub fn update(&mut self, message: ShortcutMessage) -> Task<crate::app::Message> {
self.model.update(message) self.model.update(message)
} }
} }
@ -56,15 +56,15 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: cosmic_settings_page::Entity, _page: cosmic_settings_page::Entity,
_sender: tokio::sync::mpsc::Sender<crate::pages::Message>, _sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> Command<crate::pages::Message> { ) -> Task<crate::pages::Message> {
self.model.on_enter(); self.model.on_enter();
Command::none() Task::none()
} }
fn on_leave(&mut self) -> Command<crate::pages::Message> { fn on_leave(&mut self) -> Task<crate::pages::Message> {
self.model.on_clear(); self.model.on_clear();
Command::none() Task::none()
} }
} }

View file

@ -1,5 +1,5 @@
use super::{ShortcutMessage, ShortcutModel}; use super::{ShortcutMessage, ShortcutModel};
use cosmic::{Command, Element}; use cosmic::{Element, Task};
use cosmic_settings_config::shortcuts::action::{Direction, FocusDirection}; use cosmic_settings_config::shortcuts::action::{Direction, FocusDirection};
use cosmic_settings_config::shortcuts::Action; use cosmic_settings_config::shortcuts::Action;
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
@ -23,7 +23,7 @@ impl Default for Page {
} }
impl Page { impl Page {
pub fn update(&mut self, message: ShortcutMessage) -> Command<crate::app::Message> { pub fn update(&mut self, message: ShortcutMessage) -> Task<crate::app::Message> {
self.model.update(message) self.model.update(message)
} }
} }
@ -56,15 +56,15 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: cosmic_settings_page::Entity, _page: cosmic_settings_page::Entity,
_sender: tokio::sync::mpsc::Sender<crate::pages::Message>, _sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> Command<crate::pages::Message> { ) -> Task<crate::pages::Message> {
self.model.on_enter(); self.model.on_enter();
Command::none() Task::none()
} }
fn on_leave(&mut self) -> Command<crate::pages::Message> { fn on_leave(&mut self) -> Task<crate::pages::Message> {
self.model.on_clear(); self.model.on_clear();
Command::none() Task::none()
} }
} }

View file

@ -1,5 +1,5 @@
use super::{ShortcutMessage, ShortcutModel}; use super::{ShortcutMessage, ShortcutModel};
use cosmic::{Command, Element}; use cosmic::{Element, Task};
use cosmic_settings_config::shortcuts::action::System as SystemAction; use cosmic_settings_config::shortcuts::action::System as SystemAction;
use cosmic_settings_config::shortcuts::Action; use cosmic_settings_config::shortcuts::Action;
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
@ -23,7 +23,7 @@ impl Default for Page {
} }
impl Page { impl Page {
pub fn update(&mut self, message: ShortcutMessage) -> Command<crate::app::Message> { pub fn update(&mut self, message: ShortcutMessage) -> Task<crate::app::Message> {
self.model.update(message) self.model.update(message)
} }
} }
@ -56,15 +56,15 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: cosmic_settings_page::Entity, _page: cosmic_settings_page::Entity,
_sender: tokio::sync::mpsc::Sender<crate::pages::Message>, _sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> Command<crate::pages::Message> { ) -> Task<crate::pages::Message> {
self.model.on_enter(); self.model.on_enter();
Command::none() Task::none()
} }
fn on_leave(&mut self) -> Command<crate::pages::Message> { fn on_leave(&mut self) -> Task<crate::pages::Message> {
self.model.on_clear(); self.model.on_clear();
Command::none() Task::none()
} }
} }

View file

@ -1,5 +1,5 @@
use super::{ShortcutMessage, ShortcutModel}; use super::{ShortcutMessage, ShortcutModel};
use cosmic::{Command, Element}; use cosmic::{Element, Task};
use cosmic_settings_config::shortcuts::action::Orientation; use cosmic_settings_config::shortcuts::action::Orientation;
use cosmic_settings_config::shortcuts::Action; use cosmic_settings_config::shortcuts::Action;
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
@ -23,7 +23,7 @@ impl Default for Page {
} }
impl Page { impl Page {
pub fn update(&mut self, message: ShortcutMessage) -> Command<crate::app::Message> { pub fn update(&mut self, message: ShortcutMessage) -> Task<crate::app::Message> {
self.model.update(message) self.model.update(message)
} }
} }
@ -56,15 +56,15 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: cosmic_settings_page::Entity, _page: cosmic_settings_page::Entity,
_sender: tokio::sync::mpsc::Sender<crate::pages::Message>, _sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> Command<crate::pages::Message> { ) -> Task<crate::pages::Message> {
self.model.on_enter(); self.model.on_enter();
Command::none() Task::none()
} }
fn on_leave(&mut self) -> Command<crate::pages::Message> { fn on_leave(&mut self) -> Task<crate::pages::Message> {
self.model.on_clear(); self.model.on_clear();
Command::none() Task::none()
} }
} }

View file

@ -1,7 +1,7 @@
use crate::app; use crate::app;
use cosmic::{ use cosmic::{
cosmic_config::{self, ConfigGet, ConfigSet}, cosmic_config::{self, ConfigGet, ConfigSet},
Command, Task,
}; };
use cosmic_comp_config::input::{ use cosmic_comp_config::input::{
AccelConfig, AccelProfile, ClickMethod, InputConfig, ScrollConfig, ScrollMethod, TapButtonMap, AccelConfig, AccelProfile, ClickMethod, InputConfig, ScrollConfig, ScrollMethod, TapButtonMap,
@ -96,7 +96,7 @@ impl Page {
} }
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub fn update(&mut self, message: Message) -> Command<app::Message> { pub fn update(&mut self, message: Message) -> Task<app::Message> {
match message { match message {
Message::SetAcceleration(value, touchpad) => { Message::SetAcceleration(value, touchpad) => {
let profile = if value { let profile = if value {
@ -155,7 +155,7 @@ impl Page {
select_model.activate(entity); select_model.activate(entity);
let Some(left_entity) = select_model.entity_at(1) else { let Some(left_entity) = select_model.entity_at(1) else {
return Command::none(); return Task::none();
}; };
let left_handed = select_model.active() == left_entity; let left_handed = select_model.active() == left_entity;
@ -176,7 +176,7 @@ impl Page {
} }
} }
Command::none() Task::none()
} }
} }

View file

@ -80,7 +80,7 @@ fn mouse() -> Section<crate::pages::Message> {
.max_width(250); .max_width(250);
row::with_capacity(2) row::with_capacity(2)
.align_items(Alignment::Center) .align_y(Alignment::Center)
.spacing(theme.cosmic().space_s()) .spacing(theme.cosmic().space_s())
.push(text::body(format!("{:.0}", value.round()))) .push(text::body(format!("{:.0}", value.round())))
.push(slider) .push(slider)
@ -140,7 +140,7 @@ fn scrolling() -> Section<crate::pages::Message> {
.max_width(250); .max_width(250);
row::with_capacity(2) row::with_capacity(2)
.align_items(Alignment::Center) .align_y(Alignment::Center)
.spacing(theme.cosmic().space_s()) .spacing(theme.cosmic().space_s())
.push(text::body(format!("{:.0}", value.round()))) .push(text::body(format!("{:.0}", value.round())))
.push(slider) .push(slider)

View file

@ -103,7 +103,7 @@ fn touchpad() -> Section<crate::pages::Message> {
.max_width(250); .max_width(250);
row::with_capacity(2) row::with_capacity(2)
.align_items(Alignment::Center) .align_y(Alignment::Center)
.spacing(theme.cosmic().space_s()) .spacing(theme.cosmic().space_s())
.push(text::body(format!("{:.0}", value.round()))) .push(text::body(format!("{:.0}", value.round())))
.push(slider) .push(slider)
@ -249,7 +249,7 @@ fn scrolling() -> Section<crate::pages::Message> {
.max_width(250); .max_width(250);
row::with_capacity(2) row::with_capacity(2)
.align_items(Alignment::Center) .align_y(Alignment::Center)
.spacing(theme.cosmic().space_s()) .spacing(theme.cosmic().space_s())
.push(text::body(format!("{:.0}", value.round()))) .push(text::body(format!("{:.0}", value.round())))
.push(slider) .push(slider)

View file

@ -8,7 +8,7 @@ pub mod wired;
use std::{ffi::OsStr, process::Stdio, sync::Arc}; use std::{ffi::OsStr, process::Stdio, sync::Arc};
use anyhow::Context; use anyhow::Context;
use cosmic::{widget, Apply, Command, Element}; use cosmic::{widget, Apply, Element, Task};
use cosmic_dbus_networkmanager::{ use cosmic_dbus_networkmanager::{
interface::enums::{DeviceState, DeviceType}, interface::enums::{DeviceState, DeviceType},
nm::NetworkManager, nm::NetworkManager,
@ -223,9 +223,9 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: page::Entity, _page: page::Entity,
sender: tokio::sync::mpsc::Sender<crate::pages::Message>, sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> cosmic::Command<crate::pages::Message> { ) -> cosmic::Task<crate::pages::Message> {
if self.nm_task.is_none() { if self.nm_task.is_none() {
return cosmic::command::future(async move { return cosmic::Task::future(async move {
zbus::Connection::system() zbus::Connection::system()
.await .await
.context("failed to create system dbus connection") .context("failed to create system dbus connection")
@ -237,17 +237,17 @@ impl page::Page<crate::pages::Message> for Page {
}); });
} }
Command::none() Task::none()
} }
fn on_leave(&mut self) -> Command<crate::pages::Message> { fn on_leave(&mut self) -> Task<crate::pages::Message> {
self.devices = Vec::new(); self.devices = Vec::new();
if let Some(cancel) = self.nm_task.take() { if let Some(cancel) = self.nm_task.take() {
_ = cancel.send(()); _ = cancel.send(());
} }
Command::none() Task::none()
} }
} }
@ -269,7 +269,7 @@ impl page::AutoBind<crate::pages::Message> for Page {
} }
impl Page { impl Page {
pub fn update(&mut self, message: Message) -> Command<crate::app::Message> { pub fn update(&mut self, message: Message) -> Task<crate::app::Message> {
let span = tracing::span!(tracing::Level::INFO, "networking::update"); let span = tracing::span!(tracing::Level::INFO, "networking::update");
let _span = span.enter(); let _span = span.enter();
@ -283,12 +283,12 @@ impl Page {
} }
Message::OpenPage { page, device } => { Message::OpenPage { page, device } => {
let mut commands = Vec::<Command<crate::app::Message>>::new(); let mut tasks = Vec::<Task<crate::app::Message>>::new();
commands.push(cosmic::command::message(crate::app::Message::Page(page))); tasks.push(cosmic::command::message(crate::app::Message::Page(page)));
if let Some(device) = device { if let Some(device) = device {
commands.push(cosmic::command::message(crate::app::Message::PageMessage( tasks.push(cosmic::command::message(crate::app::Message::PageMessage(
match device { match device {
DeviceVariant::WiFi(device) => { DeviceVariant::WiFi(device) => {
crate::pages::Message::WiFi(wifi::Message::SelectDevice(device)) crate::pages::Message::WiFi(wifi::Message::SelectDevice(device))
@ -300,7 +300,7 @@ impl Page {
))); )));
} }
return cosmic::command::batch(commands); return cosmic::Task::batch(tasks);
} }
Message::UpdateDevices(devices) => { Message::UpdateDevices(devices) => {
@ -308,7 +308,7 @@ impl Page {
} }
} }
Command::none() Task::none()
} }
fn connect( fn connect(
@ -319,7 +319,7 @@ impl Page {
if self.nm_task.is_none() { if self.nm_task.is_none() {
self.nm_task = Some(crate::utils::forward_event_loop( self.nm_task = Some(crate::utils::forward_event_loop(
sender, sender,
|event| crate::pages::Message::Networking(event), crate::pages::Message::Networking,
move |mut tx| async move { move |mut tx| async move {
let network_manager = match NetworkManager::new(&conn).await { let network_manager = match NetworkManager::new(&conn).await {
Ok(n) => n, Ok(n) => n,

View file

@ -9,10 +9,9 @@ use anyhow::Context;
use ashpd::desktop::file_chooser::FileFilter; use ashpd::desktop::file_chooser::FileFilter;
use cosmic::{ use cosmic::{
iced::{alignment, Length}, iced::{alignment, Length},
iced_core::text::Wrap, iced_core::text::Wrapping,
prelude::CollectionWidget,
widget::{self, icon}, widget::{self, icon},
Apply, Command, Element, Apply, Element, Task,
}; };
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
use cosmic_settings_subscriptions::network_manager::{ use cosmic_settings_subscriptions::network_manager::{
@ -140,7 +139,7 @@ impl VpnConnectionSettings {
.map_or(false, |ct| match ct { .map_or(false, |ct| match ct {
ConnectionType::Password => true, ConnectionType::Password => true,
}) })
.then(|| self.password_flag) .then_some(self.password_flag)
.flatten() .flatten()
} }
} }
@ -331,7 +330,7 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: cosmic_settings_page::Entity, _page: cosmic_settings_page::Entity,
sender: tokio::sync::mpsc::Sender<crate::pages::Message>, sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> cosmic::Command<crate::pages::Message> { ) -> cosmic::Task<crate::pages::Message> {
if self.nm_task.is_none() { if self.nm_task.is_none() {
return cosmic::command::future(async move { return cosmic::command::future(async move {
zbus::Connection::system() zbus::Connection::system()
@ -344,10 +343,10 @@ impl page::Page<crate::pages::Message> for Page {
}); });
} }
Command::none() Task::none()
} }
fn on_leave(&mut self) -> Command<crate::pages::Message> { fn on_leave(&mut self) -> Task<crate::pages::Message> {
self.view_more_popup = None; self.view_more_popup = None;
self.nm_state = None; self.nm_state = None;
self.withheld_active_conns = None; self.withheld_active_conns = None;
@ -358,12 +357,12 @@ impl page::Page<crate::pages::Message> for Page {
_ = cancel.send(()); _ = cancel.send(());
} }
Command::none() Task::none()
} }
} }
impl Page { impl Page {
pub fn update(&mut self, message: Message) -> Command<crate::app::Message> { pub fn update(&mut self, message: Message) -> Task<crate::app::Message> {
let span = tracing::span!(tracing::Level::INFO, "vpn::update"); let span = tracing::span!(tracing::Level::INFO, "vpn::update");
let _span = span.enter(); let _span = span.enter();
@ -380,7 +379,7 @@ impl Page {
if let Some(NmState { ref conn, .. }) = self.nm_state { if let Some(NmState { ref conn, .. }) = self.nm_state {
let conn = conn.clone(); let conn = conn.clone();
self.update_active_conns(state); self.update_active_conns(state);
return cosmic::command::batch(vec![ return cosmic::Task::batch(vec![
connection_settings(conn.clone()), connection_settings(conn.clone()),
update_devices(conn), update_devices(conn),
]); ]);
@ -403,7 +402,7 @@ impl Page {
network_manager::Event::ActiveConns | network_manager::Event::Devices, network_manager::Event::ActiveConns | network_manager::Event::Devices,
) => { ) => {
if let Some(NmState { ref conn, .. }) = self.nm_state { if let Some(NmState { ref conn, .. }) = self.nm_state {
return cosmic::command::batch(vec![ return cosmic::Task::batch(vec![
update_state(conn.clone()), update_state(conn.clone()),
update_devices(conn.clone()), update_devices(conn.clone()),
connection_settings(conn.clone()), connection_settings(conn.clone()),
@ -427,7 +426,7 @@ impl Page {
.collect(), .collect(),
}); });
return cosmic::command::batch(vec![ return cosmic::Task::batch(vec![
connection_settings(conn.clone()), connection_settings(conn.clone()),
update_devices(conn), update_devices(conn),
]); ]);
@ -556,7 +555,7 @@ impl Page {
Message::Refresh => { Message::Refresh => {
if let Some(NmState { ref conn, .. }) = self.nm_state { if let Some(NmState { ref conn, .. }) = self.nm_state {
return cosmic::command::batch(vec![ return cosmic::Task::batch(vec![
update_state(conn.clone()), update_state(conn.clone()),
update_devices(conn.clone()), update_devices(conn.clone()),
connection_settings(conn.clone()), connection_settings(conn.clone()),
@ -575,7 +574,7 @@ impl Page {
Message::ConnectWithPassword => { Message::ConnectWithPassword => {
let Some(dialog) = self.dialog.take() else { let Some(dialog) = self.dialog.take() else {
return Command::none(); return Task::none();
}; };
if let VpnDialog::Password { if let VpnDialog::Password {
@ -624,7 +623,7 @@ impl Page {
} }
} }
Command::none() Task::none()
} }
fn activate_with_password( fn activate_with_password(
@ -632,7 +631,7 @@ impl Page {
connection_name: String, connection_name: String,
username: String, username: String,
password: SecureString, password: SecureString,
) -> Command<Message> { ) -> Task<Message> {
cosmic::command::future(async move { cosmic::command::future(async move {
if let Err(why) = nmcli::set_username(&connection_name, &username).await { if let Err(why) = nmcli::set_username(&connection_name, &username).await {
return Message::Error(ErrorKind::WithPassword("username"), why.to_string()); return Message::Error(ErrorKind::WithPassword("username"), why.to_string());
@ -773,13 +772,13 @@ fn devices_view() -> Section<crate::pages::Message> {
) )
}; };
let identifier = widget::text::body(id).wrap(Wrap::Glyph); let identifier = widget::text::body(id).wrapping(Wrapping::Glyph);
let connect: Element<'_, Message> = if let Some(msg) = connect_msg { let connect: Element<'_, Message> = if let Some(msg) = connect_msg {
widget::button::text(connect_txt).on_press(msg).into() widget::button::text(connect_txt).on_press(msg).into()
} else { } else {
widget::text::body(connect_txt) widget::text::body(connect_txt)
.vertical_alignment(alignment::Vertical::Center) .align_y(alignment::Vertical::Center)
.into() .into()
}; };
@ -812,7 +811,7 @@ fn devices_view() -> Section<crate::pages::Message> {
)) ))
.width(Length::Fixed(200.0)) .width(Length::Fixed(200.0))
.apply(widget::container) .apply(widget::container)
.style(cosmic::style::Container::Dialog) .class(cosmic::style::Container::Dialog)
}) })
.apply(|e| Some(Element::from(e))) .apply(|e| Some(Element::from(e)))
} else { } else {
@ -824,12 +823,12 @@ fn devices_view() -> Section<crate::pages::Message> {
let controls = widget::row::with_capacity(2) let controls = widget::row::with_capacity(2)
.push(connect) .push(connect)
.push_maybe(view_more) .push_maybe(view_more)
.align_items(alignment::Alignment::Center) .align_y(alignment::Alignment::Center)
.spacing(spacing.space_xxs); .spacing(spacing.space_xxs);
let widget = widget::settings::item_row(vec![ let widget = widget::settings::item_row(vec![
identifier.into(), identifier.into(),
widget::horizontal_space(Length::Fill).into(), widget::horizontal_space().width(Length::Fill).into(),
controls.into(), controls.into(),
]); ]);
@ -846,20 +845,20 @@ fn devices_view() -> Section<crate::pages::Message> {
}) })
} }
fn popup_button<'a>(message: Message, text: &'a str) -> Element<'a, Message> { fn popup_button(message: Message, text: &str) -> Element<'_, Message> {
let theme = cosmic::theme::active(); let theme = cosmic::theme::active();
let theme = theme.cosmic(); let theme = theme.cosmic();
widget::text::body(text) widget::text::body(text)
.vertical_alignment(alignment::Vertical::Center) .align_y(alignment::Vertical::Center)
.apply(widget::button::custom) .apply(widget::button::custom)
.padding([theme.space_xxxs(), theme.space_xs()]) .padding([theme.space_xxxs(), theme.space_xs()])
.width(Length::Fill) .width(Length::Fill)
.style(cosmic::theme::Button::MenuItem) .class(cosmic::theme::Button::MenuItem)
.on_press(message) .on_press(message)
.into() .into()
} }
fn update_state(conn: zbus::Connection) -> Command<crate::app::Message> { fn update_state(conn: zbus::Connection) -> Task<crate::app::Message> {
cosmic::command::future(async move { cosmic::command::future(async move {
match NetworkManagerState::new(&conn).await { match NetworkManagerState::new(&conn).await {
Ok(state) => Message::UpdateState(state), Ok(state) => Message::UpdateState(state),
@ -868,7 +867,7 @@ fn update_state(conn: zbus::Connection) -> Command<crate::app::Message> {
}) })
} }
fn update_devices(conn: zbus::Connection) -> Command<crate::app::Message> { fn update_devices(conn: zbus::Connection) -> Task<crate::app::Message> {
cosmic::command::future(async move { cosmic::command::future(async move {
let filter = let filter =
|device_type| matches!(device_type, network_manager::devices::DeviceType::WireGuard); |device_type| matches!(device_type, network_manager::devices::DeviceType::WireGuard);
@ -880,9 +879,9 @@ fn update_devices(conn: zbus::Connection) -> Command<crate::app::Message> {
}) })
} }
fn add_network() -> Command<crate::app::Message> { fn add_network() -> Task<crate::app::Message> {
let Some(dir) = dirs::download_dir().or_else(dirs::home_dir) else { let Some(dir) = dirs::download_dir().or_else(dirs::home_dir) else {
return Command::none(); return Task::none();
}; };
cosmic::dialog::file_chooser::open::Dialog::new() cosmic::dialog::file_chooser::open::Dialog::new()
@ -935,7 +934,7 @@ fn add_network() -> Command<crate::app::Message> {
.apply(cosmic::command::future) .apply(cosmic::command::future)
} }
fn connection_settings(conn: zbus::Connection) -> Command<crate::app::Message> { fn connection_settings(conn: zbus::Connection) -> Task<crate::app::Message> {
let settings = async move { let settings = async move {
let settings = network_manager::dbus::settings::NetworkManagerSettings::new(&conn).await?; let settings = network_manager::dbus::settings::NetworkManagerSettings::new(&conn).await?;

View file

@ -15,7 +15,7 @@ pub async fn set_username(connection_name: &str, username: &str) -> Result<(), S
pub async fn set_password_flags_none(connection_name: &str) -> Result<(), String> { pub async fn set_password_flags_none(connection_name: &str) -> Result<(), String> {
tokio::process::Command::new("nmcli") tokio::process::Command::new("nmcli")
.args(&[ .args([
"con", "con",
"mod", "mod",
connection_name, connection_name,
@ -30,10 +30,10 @@ pub async fn set_password_flags_none(connection_name: &str) -> Result<(), String
pub async fn set_password(connection_name: &str, password: &str) -> Result<(), String> { pub async fn set_password(connection_name: &str, password: &str) -> Result<(), String> {
tokio::process::Command::new("nmcli") tokio::process::Command::new("nmcli")
.args(&[ .args([
"con", "con",
"mod", "mod",
&connection_name, connection_name,
"vpn.secrets", "vpn.secrets",
&format!("password={password}"), &format!("password={password}"),
]) ])

View file

@ -9,10 +9,9 @@ use std::{
use anyhow::Context; use anyhow::Context;
use cosmic::{ use cosmic::{
iced::{alignment, Length}, iced::{alignment, Length},
iced_core::text::Wrap, iced_core::text::Wrapping,
prelude::CollectionWidget,
widget::{self, icon}, widget::{self, icon},
Apply, Command, Element, Apply, Element, Task,
}; };
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
use cosmic_settings_subscriptions::network_manager::{ use cosmic_settings_subscriptions::network_manager::{
@ -199,9 +198,9 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: cosmic_settings_page::Entity, _page: cosmic_settings_page::Entity,
sender: tokio::sync::mpsc::Sender<crate::pages::Message>, sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> cosmic::Command<crate::pages::Message> { ) -> cosmic::Task<crate::pages::Message> {
if self.nm_task.is_none() { if self.nm_task.is_none() {
return cosmic::command::future(async move { return cosmic::Task::future(async move {
zbus::Connection::system() zbus::Connection::system()
.await .await
.context("failed to create system dbus connection") .context("failed to create system dbus connection")
@ -213,10 +212,10 @@ impl page::Page<crate::pages::Message> for Page {
}); });
} }
Command::none() Task::none()
} }
fn on_leave(&mut self) -> Command<crate::pages::Message> { fn on_leave(&mut self) -> Task<crate::pages::Message> {
self.active_device = None; self.active_device = None;
self.view_more_popup = None; self.view_more_popup = None;
self.nm_state = None; self.nm_state = None;
@ -229,12 +228,12 @@ impl page::Page<crate::pages::Message> for Page {
_ = cancel.send(()); _ = cancel.send(());
} }
Command::none() Task::none()
} }
} }
impl Page { impl Page {
pub fn update(&mut self, message: Message) -> Command<crate::app::Message> { pub fn update(&mut self, message: Message) -> Task<crate::app::Message> {
let span = tracing::span!(tracing::Level::INFO, "vpn::update"); let span = tracing::span!(tracing::Level::INFO, "vpn::update");
let _span = span.enter(); let _span = span.enter();
@ -295,7 +294,7 @@ impl Page {
| network_manager::Event::WirelessAccessPoints, | network_manager::Event::WirelessAccessPoints,
) => { ) => {
if let Some(NmState { ref conn, .. }) = self.nm_state { if let Some(NmState { ref conn, .. }) = self.nm_state {
return cosmic::command::batch(vec![ return cosmic::Task::batch(vec![
update_state(conn.clone()), update_state(conn.clone()),
update_devices(conn.clone()), update_devices(conn.clone()),
]); ]);
@ -353,7 +352,7 @@ impl Page {
Message::ConnectWithPassword => { Message::ConnectWithPassword => {
let Some(dialog) = self.dialog.take() else { let Some(dialog) = self.dialog.take() else {
return Command::none(); return Task::none();
}; };
if let WiFiDialog::Password { ssid, password, .. } = dialog { if let WiFiDialog::Password { ssid, password, .. } = dialog {
@ -446,7 +445,7 @@ impl Page {
} }
} }
Command::none() Task::none()
} }
fn connect( fn connect(
@ -532,10 +531,8 @@ fn devices_view() -> Section<crate::pages::Message> {
let theme = cosmic::theme::active(); let theme = cosmic::theme::active();
let spacing = &theme.cosmic().spacing; let spacing = &theme.cosmic().spacing;
let wifi_enable = let wifi_enable = widget::settings::item::builder(&section.descriptions[wifi_txt])
widget::settings::item::builder(&section.descriptions[wifi_txt]).control( .control(widget::toggler(state.wifi_enabled).on_toggle(Message::WiFiEnable));
widget::toggler(None, state.wifi_enabled, Message::WiFiEnable),
);
let mut view = widget::column::with_capacity(4) let mut view = widget::column::with_capacity(4)
.push(widget::list_column().add(wifi_enable)) .push(widget::list_column().add(wifi_enable))
@ -544,7 +541,7 @@ fn devices_view() -> Section<crate::pages::Message> {
.push(icon::from_name("airplane-mode-symbolic")) .push(icon::from_name("airplane-mode-symbolic"))
.push(widget::text::body(&section.descriptions[airplane_mode_txt])) .push(widget::text::body(&section.descriptions[airplane_mode_txt]))
.spacing(8) .spacing(8)
.align_items(alignment::Alignment::Center) .align_y(alignment::Alignment::Center)
.apply(widget::container) .apply(widget::container)
.width(Length::Fill) .width(Length::Fill)
.align_x(alignment::Horizontal::Center) .align_x(alignment::Horizontal::Center)
@ -612,14 +609,16 @@ fn devices_view() -> Section<crate::pages::Message> {
is_encrypted is_encrypted
.then(|| widget::icon::from_name("connection-secure-symbolic")), .then(|| widget::icon::from_name("connection-secure-symbolic")),
) )
.push(widget::text::body(network.ssid.as_ref()).wrap(Wrap::Glyph)) .push(
widget::text::body(network.ssid.as_ref()).wrapping(Wrapping::Glyph),
)
.spacing(spacing.space_xxs); .spacing(spacing.space_xxs);
let connect: Element<'_, Message> = if let Some(msg) = connect_msg { let connect: Element<'_, Message> = if let Some(msg) = connect_msg {
widget::button::text(connect_txt).on_press(msg).into() widget::button::text(connect_txt).on_press(msg).into()
} else { } else {
widget::text::body(connect_txt) widget::text::body(connect_txt)
.vertical_alignment(alignment::Vertical::Center) .align_y(alignment::Vertical::Center)
.into() .into()
}; };
@ -654,7 +653,7 @@ fn devices_view() -> Section<crate::pages::Message> {
})) }))
.width(Length::Fixed(170.0)) .width(Length::Fixed(170.0))
.apply(widget::container) .apply(widget::container)
.style(cosmic::style::Container::Dialog) .class(cosmic::style::Container::Dialog)
}) })
.apply(|e| Some(Element::from(e))) .apply(|e| Some(Element::from(e)))
} else if is_known { } else if is_known {
@ -668,12 +667,12 @@ fn devices_view() -> Section<crate::pages::Message> {
let controls = widget::row::with_capacity(2) let controls = widget::row::with_capacity(2)
.push(connect) .push(connect)
.push_maybe(view_more) .push_maybe(view_more)
.align_items(alignment::Alignment::Center) .align_y(alignment::Alignment::Center)
.spacing(spacing.space_xxs); .spacing(spacing.space_xxs);
let widget = widget::settings::item_row(vec![ let widget = widget::settings::item_row(vec![
identifier.into(), identifier.into(),
widget::horizontal_space(Length::Fill).into(), widget::horizontal_space().width(Length::Fill).into(),
controls.into(), controls.into(),
]); ]);
@ -714,20 +713,20 @@ fn is_connected(state: &NetworkManagerState, network: &AccessPoint) -> bool {
}) })
} }
fn popup_button<'a>(message: Message, text: &'a str) -> Element<'a, Message> { fn popup_button(message: Message, text: &str) -> Element<'_, Message> {
let theme = cosmic::theme::active(); let theme = cosmic::theme::active();
let theme = theme.cosmic(); let theme = theme.cosmic();
widget::text::body(text) widget::text::body(text)
.vertical_alignment(alignment::Vertical::Center) .align_y(alignment::Vertical::Center)
.apply(widget::button::custom) .apply(widget::button::custom)
.padding([theme.space_xxxs(), theme.space_xs()]) .padding([theme.space_xxxs(), theme.space_xs()])
.width(Length::Fill) .width(Length::Fill)
.style(cosmic::theme::Button::MenuItem) .class(cosmic::theme::Button::MenuItem)
.on_press(message) .on_press(message)
.into() .into()
} }
fn connection_settings(conn: zbus::Connection) -> Command<crate::app::Message> { fn connection_settings(conn: zbus::Connection) -> Task<crate::app::Message> {
let settings = async move { let settings = async move {
let settings = network_manager::dbus::settings::NetworkManagerSettings::new(&conn).await?; let settings = network_manager::dbus::settings::NetworkManagerSettings::new(&conn).await?;
@ -785,7 +784,7 @@ fn connection_settings(conn: zbus::Connection) -> Command<crate::app::Message> {
}) })
} }
pub fn update_state(conn: zbus::Connection) -> Command<crate::app::Message> { pub fn update_state(conn: zbus::Connection) -> Task<crate::app::Message> {
cosmic::command::future(async move { cosmic::command::future(async move {
match NetworkManagerState::new(&conn).await { match NetworkManagerState::new(&conn).await {
Ok(state) => Message::UpdateState(state), Ok(state) => Message::UpdateState(state),
@ -794,7 +793,7 @@ pub fn update_state(conn: zbus::Connection) -> Command<crate::app::Message> {
}) })
} }
pub fn update_devices(conn: zbus::Connection) -> Command<crate::app::Message> { pub fn update_devices(conn: zbus::Connection) -> Task<crate::app::Message> {
cosmic::command::future(async move { cosmic::command::future(async move {
let filter = let filter =
|device_type| matches!(device_type, network_manager::devices::DeviceType::Wifi); |device_type| matches!(device_type, network_manager::devices::DeviceType::Wifi);

View file

@ -6,10 +6,9 @@ use std::{collections::BTreeSet, sync::Arc};
use anyhow::Context; use anyhow::Context;
use cosmic::{ use cosmic::{
iced::{alignment, Length}, iced::{alignment, Length},
iced_core::text::Wrap, iced_core::text::Wrapping,
prelude::CollectionWidget,
widget::{self, icon}, widget::{self, icon},
Apply, Command, Element, Apply, Element, Task,
}; };
use cosmic_dbus_networkmanager::interface::enums::DeviceState; use cosmic_dbus_networkmanager::interface::enums::DeviceState;
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
@ -155,7 +154,7 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: cosmic_settings_page::Entity, _page: cosmic_settings_page::Entity,
sender: tokio::sync::mpsc::Sender<crate::pages::Message>, sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> cosmic::Command<crate::pages::Message> { ) -> cosmic::Task<crate::pages::Message> {
if self.nm_task.is_none() { if self.nm_task.is_none() {
return cosmic::command::future(async move { return cosmic::command::future(async move {
zbus::Connection::system() zbus::Connection::system()
@ -169,10 +168,10 @@ impl page::Page<crate::pages::Message> for Page {
}); });
} }
Command::none() Task::none()
} }
fn on_leave(&mut self) -> Command<crate::pages::Message> { fn on_leave(&mut self) -> Task<crate::pages::Message> {
self.active_device = None; self.active_device = None;
self.view_more_popup = None; self.view_more_popup = None;
self.nm_state = None; self.nm_state = None;
@ -184,7 +183,7 @@ impl page::Page<crate::pages::Message> for Page {
_ = cancel.send(()); _ = cancel.send(());
} }
Command::none() Task::none()
} }
fn title(&self) -> Option<&str> { fn title(&self) -> Option<&str> {
@ -195,7 +194,7 @@ impl page::Page<crate::pages::Message> for Page {
} }
impl Page { impl Page {
pub fn update(&mut self, message: Message) -> Command<crate::app::Message> { pub fn update(&mut self, message: Message) -> Task<crate::app::Message> {
let span = tracing::span!(tracing::Level::INFO, "vpn::update"); let span = tracing::span!(tracing::Level::INFO, "vpn::update");
let _span = span.enter(); let _span = span.enter();
@ -232,7 +231,7 @@ impl Page {
network_manager::Event::ActiveConns | network_manager::Event::Devices, network_manager::Event::ActiveConns | network_manager::Event::Devices,
) => { ) => {
if let Some(NmState { ref conn, .. }) = self.nm_state { if let Some(NmState { ref conn, .. }) = self.nm_state {
return cosmic::command::batch(vec![ return cosmic::Task::batch(vec![
update_state(conn.clone()), update_state(conn.clone()),
update_devices(conn.clone()), update_devices(conn.clone()),
]); ]);
@ -337,7 +336,7 @@ impl Page {
Message::Refresh => { Message::Refresh => {
if let Some(NmState { ref conn, .. }) = self.nm_state { if let Some(NmState { ref conn, .. }) = self.nm_state {
return cosmic::command::batch(vec![ return cosmic::Task::batch(vec![
update_state(conn.clone()), update_state(conn.clone()),
update_devices(conn.clone()), update_devices(conn.clone()),
]); ]);
@ -357,7 +356,7 @@ impl Page {
} }
} }
Command::none() Task::none()
} }
fn connect( fn connect(
@ -451,7 +450,7 @@ impl Page {
device: &'a network_manager::devices::DeviceInfo, device: &'a network_manager::devices::DeviceInfo,
) -> Element<'a, Message> { ) -> Element<'a, Message> {
let has_multiple_connection_profiles = device.known_connections.len() > 1; let has_multiple_connection_profiles = device.known_connections.len() > 1;
let header_txt = format!("{}", wired_conns_txt); let header_txt = wired_conns_txt.to_string();
device device
.known_connections .known_connections
@ -478,13 +477,13 @@ impl Page {
) )
}; };
let identifier = widget::text::body(&connection.id).wrap(Wrap::Glyph); let identifier = widget::text::body(&connection.id).wrapping(Wrapping::Glyph);
let connect: Element<'_, Message> = if let Some(msg) = connect_msg { let connect: Element<'_, Message> = if let Some(msg) = connect_msg {
widget::button::text(connect_txt).on_press(msg).into() widget::button::text(connect_txt).on_press(msg).into()
} else { } else {
widget::text::body(connect_txt) widget::text::body(connect_txt)
.vertical_alignment(alignment::Vertical::Center) .align_y(alignment::Vertical::Center)
.into() .into()
}; };
@ -504,23 +503,23 @@ impl Page {
.push_maybe(is_connected.then(|| { .push_maybe(is_connected.then(|| {
popup_button( popup_button(
Message::Deactivate(connection.uuid.clone()), Message::Deactivate(connection.uuid.clone()),
&disconnect_txt, disconnect_txt,
) )
})) }))
.push(popup_button( .push(popup_button(
Message::Settings(connection.uuid.clone()), Message::Settings(connection.uuid.clone()),
&settings_txt, settings_txt,
)) ))
.push_maybe(has_multiple_connection_profiles.then(|| { .push_maybe(has_multiple_connection_profiles.then(|| {
popup_button( popup_button(
Message::RemoveProfileRequest(connection.uuid.clone()), Message::RemoveProfileRequest(connection.uuid.clone()),
&remove_txt, remove_txt,
) )
})) }))
.width(Length::Fixed(200.0)) .width(Length::Fixed(200.0))
.apply(widget::container) .apply(widget::container)
.padding(spacing.space_xxxs) .padding(spacing.space_xxxs)
.style(cosmic::style::Container::Dialog) .class(cosmic::style::Container::Dialog)
}) })
.apply(|e| Some(Element::from(e))) .apply(|e| Some(Element::from(e)))
} else { } else {
@ -532,12 +531,12 @@ impl Page {
let controls = widget::row::with_capacity(2) let controls = widget::row::with_capacity(2)
.push(connect) .push(connect)
.push_maybe(view_more) .push_maybe(view_more)
.align_items(alignment::Alignment::Center) .align_y(alignment::Alignment::Center)
.spacing(spacing.space_xxs); .spacing(spacing.space_xxs);
let widget = widget::settings::item_row(vec![ let widget = widget::settings::item_row(vec![
identifier.into(), identifier.into(),
widget::horizontal_space(Length::Fill).into(), widget::horizontal_space().width(Length::Fill).into(),
controls.into(), controls.into(),
]); ]);
@ -575,7 +574,7 @@ fn devices_view() -> Section<crate::pages::Message> {
let active_device = page let active_device = page
.active_device .active_device
.as_ref() .as_ref()
.or_else(|| (nm_state.devices.len() == 1).then(|| nm_state.devices.get(0))?); .or_else(|| (nm_state.devices.len() == 1).then(|| nm_state.devices.first())?);
view = match active_device { view = match active_device {
Some(device) => view.push(page.device_view( Some(device) => view.push(page.device_view(
@ -600,20 +599,20 @@ fn devices_view() -> Section<crate::pages::Message> {
}) })
} }
fn popup_button<'a>(message: Message, text: &'a str) -> Element<'a, Message> { fn popup_button(message: Message, text: &str) -> Element<'_, Message> {
let theme = cosmic::theme::active(); let theme = cosmic::theme::active();
let theme = theme.cosmic(); let theme = theme.cosmic();
widget::text::body(text) widget::text::body(text)
.vertical_alignment(alignment::Vertical::Center) .align_y(alignment::Vertical::Center)
.apply(widget::button::custom) .apply(widget::button::custom)
.padding([theme.space_xxxs(), theme.space_xs()]) .padding([theme.space_xxxs(), theme.space_xs()])
.width(Length::Fill) .width(Length::Fill)
.style(cosmic::theme::Button::MenuItem) .class(cosmic::theme::Button::MenuItem)
.on_press(message) .on_press(message)
.into() .into()
} }
fn update_state(conn: zbus::Connection) -> Command<crate::app::Message> { fn update_state(conn: zbus::Connection) -> Task<crate::app::Message> {
cosmic::command::future(async move { cosmic::command::future(async move {
match NetworkManagerState::new(&conn).await { match NetworkManagerState::new(&conn).await {
Ok(state) => Message::UpdateState(state), Ok(state) => Message::UpdateState(state),
@ -622,7 +621,7 @@ fn update_state(conn: zbus::Connection) -> Command<crate::app::Message> {
}) })
} }
fn update_devices(conn: zbus::Connection) -> Command<crate::app::Message> { fn update_devices(conn: zbus::Connection) -> Task<crate::app::Message> {
cosmic::command::future(async move { cosmic::command::future(async move {
let filter = let filter =
|device_type| matches!(device_type, network_manager::devices::DeviceType::Ethernet); |device_type| matches!(device_type, network_manager::devices::DeviceType::Ethernet);

View file

@ -494,3 +494,31 @@ impl ConnectedDevice {
vec![] vec![]
} }
} }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_can_format_battery_remaining() {
let cases = [
(59, "Less than a minute until empty"),
(300, "5 minutes until empty"),
(305, "5 minutes until empty"),
(330, "5 minutes until empty"),
(360, "6 minutes until empty"),
(3660, "1 hour and 1 minute until empty"),
(10800, "3 hours until empty"),
(969400, "11 days, 5 hours and 16 minutes until empty"),
];
for case in cases {
let (actual, expected) = case;
let battery = Battery {
remaining_duration: Duration::new(actual, 0).unwrap(),
on_battery: true,
..Default::default()
};
assert_eq!(battery.remaining_time(), expected);
}
}
}

View file

@ -6,10 +6,9 @@ use backend::{Battery, ConnectedDevice, PowerProfile};
use chrono::TimeDelta; use chrono::TimeDelta;
use cosmic::iced::{Alignment, Length}; use cosmic::iced::{Alignment, Length};
use cosmic::iced_widget::{column, row}; use cosmic::iced_widget::{column, row};
use cosmic::prelude::CollectionWidget;
use cosmic::widget::{self, radio, settings, text}; use cosmic::widget::{self, radio, settings, text};
use cosmic::Apply; use cosmic::Apply;
use cosmic::Command; use cosmic::Task;
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
use itertools::Itertools; use itertools::Itertools;
use slab::Slab; use slab::Slab;
@ -43,19 +42,19 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: cosmic_settings_page::Entity, _page: cosmic_settings_page::Entity,
_sender: tokio::sync::mpsc::Sender<crate::pages::Message>, _sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> cosmic::Command<crate::pages::Message> { ) -> cosmic::Task<crate::pages::Message> {
let futures: Vec<Command<Message>> = vec![ let futures: Vec<Task<Message>> = vec![
cosmic::command::future(async move { cosmic::Task::future(async move {
let battery = Battery::update_battery().await; let battery = Battery::update_battery().await;
Message::UpdateBattery(battery) Message::UpdateBattery(battery)
}), }),
cosmic::command::future(async move { cosmic::Task::future(async move {
let devices = ConnectedDevice::update_connected_devices().await; let devices = ConnectedDevice::update_connected_devices().await;
Message::UpdateConnectedDevices(devices) Message::UpdateConnectedDevices(devices)
}), }),
]; ];
cosmic::command::batch(futures).map(crate::pages::Message::Power) cosmic::Task::batch(futures).map(crate::pages::Message::Power)
} }
} }
@ -106,7 +105,7 @@ fn battery_info() -> Section<crate::pages::Message> {
.push(text::heading(&section.title)) .push(text::heading(&section.title))
.push( .push(
row!(battery_icon, battery_label) row!(battery_icon, battery_label)
.align_items(Alignment::Center) .align_y(Alignment::Center)
.spacing(cosmic::theme::active().cosmic().space_xxxs()), .spacing(cosmic::theme::active().cosmic().space_xxxs()),
) )
.into() .into()
@ -146,18 +145,18 @@ fn connected_devices() -> Section<crate::pages::Message> {
text::heading(&connected_device.model), text::heading(&connected_device.model),
row!(battery_icon, battery_percent_and_time) row!(battery_icon, battery_percent_and_time)
.spacing(4) .spacing(4)
.align_items(Alignment::Center), .align_y(Alignment::Center),
) )
.height(Length::Shrink) .height(Length::Shrink)
) )
.align_items(Alignment::Center) .align_y(Alignment::Center)
.spacing(16) .spacing(16)
.padding([8, 16]) .padding([8, 16])
.width(Length::Fill) .width(Length::Fill)
.height(Length::Fill), .height(Length::Fill),
) )
.height(64) .height(64)
.style(cosmic::theme::Container::List) .class(cosmic::theme::Container::List)
.into() .into()
}) })
.collect(); .collect();
@ -173,15 +172,21 @@ fn connected_devices() -> Section<crate::pages::Message> {
.chunks(2) .chunks(2)
.into_iter() .into_iter()
.map(|mut device_row| { .map(|mut device_row| {
row!( cosmic::Element::from(
device_row.next().unwrap_or( row!(
widget::horizontal_space(Length::Fill).into() device_row.next().unwrap_or(
), widget::horizontal_space()
device_row.next().unwrap_or( .width(Length::Fill)
widget::horizontal_space(Length::Fill).into() .into()
), ),
device_row.next().unwrap_or(
widget::horizontal_space()
.width(Length::Fill)
.into()
),
)
.spacing(8),
) )
.spacing(8)
}), }),
) )
.spacing(8), .spacing(8),
@ -217,7 +222,7 @@ fn profiles() -> Section<crate::pages::Message> {
widget::column::with_capacity(2) widget::column::with_capacity(2)
.push(text::body(profile.title())) .push(text::body(profile.title()))
.push(text::caption(profile.description())), .push(text::caption(profile.description())),
profile.clone(), profile,
Some(current_profile), Some(current_profile),
Message::PowerProfileChange, Message::PowerProfileChange,
) )

View file

@ -5,7 +5,7 @@ use std::{collections::BTreeMap, time::Duration};
use cosmic::{ use cosmic::{
widget::{self, settings}, widget::{self, settings},
Command, Element, Element, Task,
}; };
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
use cosmic_settings_subscriptions::{pipewire, pulse}; use cosmic_settings_subscriptions::{pipewire, pulse};
@ -127,7 +127,7 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: cosmic_settings_page::Entity, _page: cosmic_settings_page::Entity,
sender: tokio::sync::mpsc::Sender<crate::pages::Message>, sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> Command<crate::pages::Message> { ) -> Task<crate::pages::Message> {
if self.pulse_thread.is_none() { if self.pulse_thread.is_none() {
let sender = sender.clone(); let sender = sender.clone();
@ -182,10 +182,10 @@ impl page::Page<crate::pages::Message> for Page {
self.pipewire_thread = Some((cancel_tx, terminate)); self.pipewire_thread = Some((cancel_tx, terminate));
} }
Command::none() Task::none()
} }
fn on_leave(&mut self) -> Command<crate::pages::Message> { fn on_leave(&mut self) -> Task<crate::pages::Message> {
if let Some(cancellation) = self.pulse_thread.take() { if let Some(cancellation) = self.pulse_thread.take() {
_ = cancellation.send(()); _ = cancellation.send(());
} }
@ -197,7 +197,7 @@ impl page::Page<crate::pages::Message> for Page {
*self = Page::default(); *self = Page::default();
Command::none() Task::none()
} }
} }
@ -292,13 +292,13 @@ impl Page {
} }
} }
pub fn update(&mut self, message: Message) -> Command<crate::app::Message> { pub fn update(&mut self, message: Message) -> Task<crate::app::Message> {
match message { match message {
Message::SourceVolumeChanged(volume) => { Message::SourceVolumeChanged(volume) => {
self.source_volume = volume; self.source_volume = volume;
self.source_volume_text = volume.to_string(); self.source_volume_text = volume.to_string();
if self.source_volume_debounce { if self.source_volume_debounce {
return Command::none(); return Task::none();
} }
let mut command = None; let mut command = None;
@ -316,8 +316,8 @@ impl Page {
} }
Message::Pulse(pulse::Event::SourceVolume(volume)) => { Message::Pulse(pulse::Event::SourceVolume(volume)) => {
if self.source_volume_debounce { if self.sink_volume_debounce {
return Command::none(); return Task::none();
} }
self.source_volume = volume; self.source_volume = volume;
@ -328,7 +328,7 @@ impl Page {
self.sink_volume = volume; self.sink_volume = volume;
self.sink_volume_text = volume.to_string(); self.sink_volume_text = volume.to_string();
if self.sink_volume_debounce { if self.sink_volume_debounce {
return Command::none(); return Task::none();
} }
let mut command = None; let mut command = None;
@ -347,7 +347,7 @@ impl Page {
Message::Pulse(pulse::Event::SinkVolume(volume)) => { Message::Pulse(pulse::Event::SinkVolume(volume)) => {
if self.sink_volume_debounce { if self.sink_volume_debounce {
return Command::none(); return Task::none();
} }
self.sink_volume = volume; self.sink_volume = volume;
@ -481,7 +481,7 @@ impl Page {
self.active_sink = Some(pos); self.active_sink = Some(pos);
pactl_set_default_sink(device.identifier.clone()); pactl_set_default_sink(device.identifier.clone());
self.set_default_sink(device.identifier.clone()); self.set_default_sink(device.identifier.clone());
return Command::none(); return Task::none();
} }
} }
} }
@ -496,7 +496,7 @@ impl Page {
self.active_source = Some(pos); self.active_source = Some(pos);
pactl_set_default_source(device.identifier.clone()); pactl_set_default_source(device.identifier.clone());
self.set_default_source(device.identifier.clone()); self.set_default_source(device.identifier.clone());
return Command::none(); return Task::none();
} }
} }
} }
@ -592,7 +592,7 @@ impl Page {
} }
} }
} }
Command::none() Task::none()
} }
} }
@ -609,7 +609,7 @@ fn input() -> Section<crate::pages::Message> {
.descriptions(descriptions) .descriptions(descriptions)
.view::<Page>(move |_binder, page, section| { .view::<Page>(move |_binder, page, section| {
let volume_control = widget::row::with_capacity(3) let volume_control = widget::row::with_capacity(3)
.align_items(cosmic::iced::Alignment::Center) .align_y(cosmic::iced::Alignment::Center)
.spacing(4) .spacing(4)
.push( .push(
widget::button::icon(widget::icon::from_name(if page.source_mute { widget::button::icon(widget::icon::from_name(if page.source_mute {
@ -667,7 +667,7 @@ fn output() -> Section<crate::pages::Message> {
.descriptions(descriptions) .descriptions(descriptions)
.view::<Page>(move |_binder, page, section| { .view::<Page>(move |_binder, page, section| {
let volume_control = widget::row::with_capacity(3) let volume_control = widget::row::with_capacity(3)
.align_items(cosmic::iced::Alignment::Center) .align_y(cosmic::iced::Alignment::Center)
.spacing(4) .spacing(4)
.push( .push(
widget::button::icon(if page.sink_mute { widget::button::icon(if page.sink_mute {
@ -748,17 +748,17 @@ fn output() -> Section<crate::pages::Message> {
fn sort_pulse_devices(descriptions: &mut Vec<String>, node_ids: &mut Vec<NodeId>) { fn sort_pulse_devices(descriptions: &mut Vec<String>, node_ids: &mut Vec<NodeId>) {
let mut tmp: Vec<(String, NodeId)> = std::mem::take(descriptions) let mut tmp: Vec<(String, NodeId)> = std::mem::take(descriptions)
.into_iter() .into_iter()
.zip(std::mem::take(node_ids).into_iter()) .zip(std::mem::take(node_ids))
.collect(); .collect();
tmp.sort_unstable_by(|(ak, _), (bk, _)| ak.cmp(&bk)); tmp.sort_unstable_by(|(ak, _), (bk, _)| ak.cmp(bk));
(*descriptions, *node_ids) = tmp.into_iter().collect(); (*descriptions, *node_ids) = tmp.into_iter().collect();
} }
async fn pactl_set_card_profile(id: String, profile: String) { async fn pactl_set_card_profile(id: String, profile: String) {
_ = tokio::process::Command::new("pactl") _ = tokio::process::Command::new("pactl")
.args(&["set-card-profile", id.as_str(), profile.as_str()]) .args(["set-card-profile", id.as_str(), profile.as_str()])
.status() .status()
.await .await
} }
@ -766,7 +766,7 @@ async fn pactl_set_card_profile(id: String, profile: String) {
fn pactl_set_default_sink(id: String) { fn pactl_set_default_sink(id: String) {
tokio::task::spawn(async move { tokio::task::spawn(async move {
_ = tokio::process::Command::new("pactl") _ = tokio::process::Command::new("pactl")
.args(&["set-default-sink", id.as_str()]) .args(["set-default-sink", id.as_str()])
.status() .status()
.await; .await;
}); });
@ -775,7 +775,7 @@ fn pactl_set_default_sink(id: String) {
fn pactl_set_default_source(id: String) { fn pactl_set_default_source(id: String) {
tokio::task::spawn(async move { tokio::task::spawn(async move {
_ = tokio::process::Command::new("pactl") _ = tokio::process::Command::new("pactl")
.args(&["set-default-source", id.as_str()]) .args(["set-default-source", id.as_str()])
.status() .status()
.await; .await;
}); });
@ -785,7 +785,7 @@ fn wpctl_set_mute(id: u32, mute: bool) {
tokio::task::spawn(async move { tokio::task::spawn(async move {
let default = id.to_string(); let default = id.to_string();
_ = tokio::process::Command::new("wpctl") _ = tokio::process::Command::new("wpctl")
.args(&["set-mute", default.as_str(), if mute { "1" } else { "0" }]) .args(["set-mute", default.as_str(), if mute { "1" } else { "0" }])
.status() .status()
.await; .await;
}); });
@ -796,7 +796,7 @@ fn wpctl_set_volume(id: u32, volume: u32) {
let id = id.to_string(); let id = id.to_string();
let volume = format!("{}.{:02}", volume / 100, volume % 100); let volume = format!("{}.{:02}", volume / 100, volume % 100);
_ = tokio::process::Command::new("wpctl") _ = tokio::process::Command::new("wpctl")
.args(&["set-volume", id.as_str(), volume.as_str()]) .args(["set-volume", id.as_str(), volume.as_str()])
.status() .status()
.await; .await;
}); });

View file

@ -4,7 +4,7 @@
use cosmic_settings_page::{self as page, section, Section}; use cosmic_settings_page::{self as page, section, Section};
use cosmic::widget::{editable_input, list_column, settings, text}; use cosmic::widget::{editable_input, list_column, settings, text};
use cosmic::{command, Apply, Command}; use cosmic::{Apply, Task};
use cosmic_settings_system::about::Info; use cosmic_settings_system::about::Info;
use slab::Slab; use slab::Slab;
use slotmap::SlotMap; use slotmap::SlotMap;
@ -47,10 +47,10 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: page::Entity, _page: page::Entity,
_sender: tokio::sync::mpsc::Sender<crate::pages::Message>, _sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> Command<crate::pages::Message> { ) -> Task<crate::pages::Message> {
command::future(async move { Task::future(
crate::pages::Message::About(Message::Info(Box::new(Info::load()))) async move { crate::pages::Message::About(Message::Info(Box::new(Info::load()))) },
}) )
} }
} }

View file

@ -7,9 +7,9 @@ use chrono::{Datelike, Timelike};
use cosmic::{ use cosmic::{
cosmic_config::{self, ConfigGet, ConfigSet}, cosmic_config::{self, ConfigGet, ConfigSet},
iced::Length, iced::Length,
iced_core::text::Wrap, iced_core::text::Wrapping,
widget::{self, dropdown, settings}, widget::{self, dropdown, settings},
Apply, Command, Element, Apply, Element, Task,
}; };
use cosmic_settings_page::Section; use cosmic_settings_page::Section;
use cosmic_settings_page::{self as page, section}; use cosmic_settings_page::{self as page, section};
@ -133,8 +133,8 @@ impl page::Page<crate::pages::Message> for Page {
&mut self, &mut self,
_page: cosmic_settings_page::Entity, _page: cosmic_settings_page::Entity,
_sender: tokio::sync::mpsc::Sender<crate::pages::Message>, _sender: tokio::sync::mpsc::Sender<crate::pages::Message>,
) -> Command<crate::pages::Message> { ) -> Task<crate::pages::Message> {
cosmic::command::future(async move { cosmic::Task::future(async move {
let client = match zbus::Connection::system().await { let client = match zbus::Connection::system().await {
Ok(client) => client, Ok(client) => client,
Err(why) => { Err(why) => {
@ -174,7 +174,7 @@ impl page::Page<crate::pages::Message> for Page {
} }
impl Page { impl Page {
pub fn update(&mut self, message: Message) -> Command<crate::Message> { pub fn update(&mut self, message: Message) -> Task<crate::Message> {
match message { match message {
Message::TimezoneContext => { Message::TimezoneContext => {
self.timezone_search.clear(); self.timezone_search.clear();
@ -229,7 +229,7 @@ impl Page {
self.timezone = Some(timezone_id); self.timezone = Some(timezone_id);
if let Some(timezone) = self.timezone_list.get(timezone_id).cloned() { if let Some(timezone) = self.timezone_list.get(timezone_id).cloned() {
return cosmic::command::future(async move { return cosmic::Task::future(async move {
let client = match zbus::Connection::system().await { let client = match zbus::Connection::system().await {
Ok(client) => client, Ok(client) => client,
Err(why) => { Err(why) => {
@ -278,7 +278,7 @@ impl Page {
Message::None => (), Message::None => (),
} }
Command::none() Task::none()
} }
fn set_ntp(&mut self, enable: bool) { fn set_ntp(&mut self, enable: bool) {
@ -333,11 +333,11 @@ impl Page {
fn timezone_context_item<'a>(&self, id: usize, timezone: &'a str) -> Element<'a, Message> { fn timezone_context_item<'a>(&self, id: usize, timezone: &'a str) -> Element<'a, Message> {
widget::button::custom(widget::settings::item_row(vec![ widget::button::custom(widget::settings::item_row(vec![
widget::text::body(timezone).wrap(Wrap::Word).into(), widget::text::body(timezone).wrapping(Wrapping::Word).into(),
widget::horizontal_space(Length::Fill).into(), widget::horizontal_space().width(Length::Fill).into(),
])) ]))
.on_press(Message::Timezone(id)) .on_press(Message::Timezone(id))
.style(cosmic::theme::Button::Icon) .class(cosmic::theme::Button::Icon)
.into() .into()
} }
@ -460,13 +460,13 @@ fn timezone() -> Section<crate::pages::Message> {
.map(|id| &*page.timezone_list[id]) .map(|id| &*page.timezone_list[id])
.unwrap_or_default(), .unwrap_or_default(),
) )
.wrap(Wrap::Word), .wrapping(Wrapping::Word),
) )
.push(widget::icon::from_name("go-next-symbolic").size(16).icon()) .push(widget::icon::from_name("go-next-symbolic").size(16).icon())
.apply(widget::container) .apply(widget::container)
.style(cosmic::theme::Container::List) .class(cosmic::theme::Container::List)
.apply(widget::button::custom) .apply(widget::button::custom)
.style(cosmic::theme::Button::Transparent) .class(cosmic::theme::Button::Transparent)
.on_press(Message::TimezoneContext); .on_press(Message::TimezoneContext);
settings::section() settings::section()

View file

@ -9,14 +9,14 @@ use cosmic::iced::{
use futures::{channel::mpsc, stream::FusedStream}; use futures::{channel::mpsc, stream::FusedStream};
use zbus::zvariant::OwnedObjectPath; use zbus::zvariant::OwnedObjectPath;
enum DevicePropertyWatcherCommand { enum DevicePropertyWatcherTask {
Add(OwnedObjectPath), Add(OwnedObjectPath),
Removed(OwnedObjectPath), Removed(OwnedObjectPath),
} }
struct DevicePropertyWatcher<'a> { struct DevicePropertyWatcher<'a> {
stream: futures::stream::SelectAll<SignalWatcher<'a>>, stream: futures::stream::SelectAll<SignalWatcher<'a>>,
rx: mpsc::Receiver<DevicePropertyWatcherCommand>, rx: mpsc::Receiver<DevicePropertyWatcherTask>,
} }
struct SignalWatcher<'a> { struct SignalWatcher<'a> {
@ -39,7 +39,7 @@ impl<'a> futures::Stream for SignalWatcher<'a> {
} }
impl<'a> DevicePropertyWatcher<'a> { impl<'a> DevicePropertyWatcher<'a> {
fn new() -> (Self, mpsc::Sender<DevicePropertyWatcherCommand>) { fn new() -> (Self, mpsc::Sender<DevicePropertyWatcherTask>) {
let stream = futures::stream::select_all(vec![]); let stream = futures::stream::select_all(vec![]);
let (tx, rx) = mpsc::channel(10); let (tx, rx) = mpsc::channel(10);
@ -87,7 +87,7 @@ pub async fn watch(mut tx: futures::channel::mpsc::Sender<bluetooth::Message>) {
.receive_interfaces_removed() .receive_interfaces_removed()
.await?; .await?;
let (mut property_watcher, mut property_watcher_command) = DevicePropertyWatcher::new(); let (mut property_watcher, mut property_watcher_task) = DevicePropertyWatcher::new();
for (path, interfaces) in managed_object_proxy.get_managed_objects().await? { for (path, interfaces) in managed_object_proxy.get_managed_objects().await? {
if interfaces.contains_key("org.bluez.Device1") if interfaces.contains_key("org.bluez.Device1")
@ -100,11 +100,11 @@ pub async fn watch(mut tx: futures::channel::mpsc::Sender<bluetooth::Message>) {
while !property_watcher.rx.is_terminated() { while !property_watcher.rx.is_terminated() {
futures::select! { futures::select! {
command = property_watcher.rx.next() => match command { Task = property_watcher.rx.next() => match Task {
Some(DevicePropertyWatcherCommand::Add(path)) => { Some(DevicePropertyWatcherTask::Add(path)) => {
property_watcher.insert(&connection, path).await?; property_watcher.insert(&connection, path).await?;
} }
Some(DevicePropertyWatcherCommand::Removed(path)) => { Some(DevicePropertyWatcherTask::Removed(path)) => {
property_watcher = property_watcher.remove(&path); property_watcher = property_watcher.remove(&path);
} }
None => { None => {
@ -139,8 +139,8 @@ pub async fn watch(mut tx: futures::channel::mpsc::Sender<bluetooth::Message>) {
Ok(device) => { Ok(device) => {
match bluetooth::Device::from_device(&device).await { match bluetooth::Device::from_device(&device).await {
Ok(device) => { Ok(device) => {
property_watcher_command property_watcher_task
.send(DevicePropertyWatcherCommand::Add(args.object_path.to_owned().into())).await.map_err(|e| zbus::Error::Failure(e.to_string()))?; .send(DevicePropertyWatcherTask::Add(args.object_path.to_owned().into())).await.map_err(|e| zbus::Error::Failure(e.to_string()))?;
tx tx
.send(bluetooth::Message::AddedDevice(args.object_path.to_owned().into(), device)) .send(bluetooth::Message::AddedDevice(args.object_path.to_owned().into(), device))
@ -165,7 +165,7 @@ pub async fn watch(mut tx: futures::channel::mpsc::Sender<bluetooth::Message>) {
Some(signal) => { Some(signal) => {
let args = signal.args()?; let args = signal.args()?;
if args.interfaces.contains(&"org.bluez.Device1") { if args.interfaces.contains(&"org.bluez.Device1") {
property_watcher_command.send(DevicePropertyWatcherCommand::Removed( property_watcher_task.send(DevicePropertyWatcherTask::Removed(
args.object_path.to_owned().into(), args.object_path.to_owned().into(),
)).await.map_err(|e| zbus::Error::Failure(e.to_string()))?; )).await.map_err(|e| zbus::Error::Failure(e.to_string()))?;
tx tx

View file

@ -3,20 +3,23 @@ use std::any::TypeId;
use ashpd::desktop::location::{Location, LocationProxy}; use ashpd::desktop::location::{Location, LocationProxy};
use chrono::Datelike; use chrono::Datelike;
use cosmic::iced::{ use cosmic::iced::{
self,
futures::{channel::mpsc::Sender, future, SinkExt, StreamExt}, futures::{channel::mpsc::Sender, future, SinkExt, StreamExt},
stream, Subscription,
}; };
use sunrise::sunrise_sunset; use sunrise::sunrise_sunset;
use tokio::select; use tokio::select;
pub fn daytime() -> cosmic::iced::Subscription<bool> { pub fn daytime() -> cosmic::iced::Subscription<bool> {
struct Sunset; struct Sunset;
iced::subscription::channel(TypeId::of::<Sunset>(), 2, |tx| async { Subscription::run_with_id(
if let Err(err) = inner(tx).await { TypeId::of::<Sunset>(),
tracing::error!("Sunset subscription error: {:?}", err); stream::channel(2, |tx| async {
} if let Err(err) = inner(tx).await {
future::pending().await tracing::error!("Sunset subscription error: {:?}", err);
}) }
future::pending().await
}),
)
} }
enum Event { enum Event {

View file

@ -1,5 +1,5 @@
use cosmic::{ use cosmic::{
iced::subscription, iced::{stream, Subscription},
iced_futures::futures::{self, SinkExt}, iced_futures::futures::{self, SinkExt},
}; };
use notify::{Config, Event, RecommendedWatcher, RecursiveMode, Watcher}; use notify::{Config, Event, RecommendedWatcher, RecursiveMode, Watcher};
@ -25,13 +25,16 @@ pub enum DesktopFileEvent {
pub fn desktop_files<I: 'static + Hash + Copy + Send + Sync + Debug>( pub fn desktop_files<I: 'static + Hash + Copy + Send + Sync + Debug>(
id: I, id: I,
) -> cosmic::iced::Subscription<DesktopFileEvent> { ) -> cosmic::iced::Subscription<DesktopFileEvent> {
subscription::channel(id, 50, move |mut output| async move { Subscription::run_with_id(
let mut state = State::Ready; id,
stream::channel(50, move |mut output| async move {
let mut state = State::Ready;
loop { loop {
state = start_watching(state, &mut output).await; state = start_watching(state, &mut output).await;
} }
}) }),
)
} }
async fn start_watching( async fn start_watching(

View file

@ -4,10 +4,10 @@
use cosmic::{iced_core::Border, theme}; use cosmic::{iced_core::Border, theme};
#[must_use] #[must_use]
pub fn display_container_frame() -> cosmic::theme::Container { pub fn display_container_frame() -> cosmic::theme::Container<'static> {
theme::Container::custom(|theme| { theme::Container::custom(|theme| {
let cosmic = theme.cosmic(); let cosmic = theme.cosmic();
cosmic::widget::container::Appearance { cosmic::widget::container::Style {
icon_color: None, icon_color: None,
text_color: None, text_color: None,
background: Some(cosmic::iced::Background::Color(cosmic::iced::Color::WHITE)), background: Some(cosmic::iced::Background::Color(cosmic::iced::Color::WHITE)),
@ -22,10 +22,10 @@ pub fn display_container_frame() -> cosmic::theme::Container {
} }
#[must_use] #[must_use]
pub fn display_container_screen() -> cosmic::theme::Container { pub fn display_container_screen() -> cosmic::theme::Container<'static> {
theme::Container::custom(|theme| { theme::Container::custom(|theme| {
let cosmic = theme.cosmic(); let cosmic = theme.cosmic();
cosmic::widget::container::Appearance { cosmic::widget::container::Style {
icon_color: None, icon_color: None,
text_color: None, text_color: None,
background: Some(cosmic::iced::Background::Color(cosmic::iced::Color::BLACK)), background: Some(cosmic::iced::Background::Color(cosmic::iced::Color::BLACK)),

View file

@ -5,8 +5,7 @@ use std::borrow::Cow;
use cosmic::cosmic_theme::Spacing; use cosmic::cosmic_theme::Spacing;
use cosmic::iced::{alignment, Length}; use cosmic::iced::{alignment, Length};
use cosmic::iced_core::text::Wrap; use cosmic::iced_core::text::Wrapping;
use cosmic::prelude::CollectionWidget;
use cosmic::widget::color_picker::ColorPickerUpdate; use cosmic::widget::color_picker::ColorPickerUpdate;
use cosmic::widget::{ use cosmic::widget::{
self, button, column, container, divider, horizontal_space, icon, row, settings, text, self, button, column, container, divider, horizontal_space, icon, row, settings, text,
@ -44,7 +43,7 @@ pub fn color_picker_context_view<'a, Message: Clone + 'static>(
.align_x(alignment::Horizontal::Center), .align_x(alignment::Horizontal::Center),
) )
.padding(spacing.space_l) .padding(spacing.space_l)
.align_items(cosmic::iced_core::Alignment::Center) .align_x(cosmic::iced_core::Alignment::Center)
.spacing(spacing.space_m) .spacing(spacing.space_m)
.width(Length::Fill) .width(Length::Fill)
.apply(Element::from) .apply(Element::from)
@ -76,21 +75,21 @@ pub fn search_header<Message>(
.into(), .into(),
); );
column_children.push(vertical_space(Length::Fixed(8.)).into()); column_children.push(vertical_space().height(Length::Fixed(8.)).into());
column_children.push(divider::horizontal::heavy().into()); column_children.push(divider::horizontal::heavy().into());
column::with_children(column_children).into() column::with_children(column_children).into()
} }
pub fn search_page_link<Message: 'static>(title: &str) -> button::TextButton<Message> { pub fn search_page_link<Message: 'static>(title: &str) -> button::TextButton<Message> {
button::text(title).style(button::Style::Link) button::text(title).class(button::ButtonClass::Link)
} }
#[must_use] #[must_use]
pub fn page_title<Message: 'static>(page: &page::Info) -> Element<Message> { pub fn page_title<Message: 'static>(page: &page::Info) -> Element<Message> {
row::with_capacity(2) row::with_capacity(2)
.push(text::title3(page.title.as_str())) .push(text::title3(page.title.as_str()))
.push(horizontal_space(Length::Fill)) .push(horizontal_space().width(Length::Fill))
.into() .into()
} }
@ -104,15 +103,15 @@ pub fn unimplemented_page<Message: 'static>() -> Element<'static, Message> {
#[must_use] #[must_use]
pub fn display_container<'a, Message: 'a>(widget: Element<'a, Message>) -> Element<'a, Message> { pub fn display_container<'a, Message: 'a>(widget: Element<'a, Message>) -> Element<'a, Message> {
let display = container(widget) let display = container(widget)
.style(crate::theme::display_container_screen()) .class(crate::theme::display_container_screen())
.apply(container) .apply(container)
.padding(4) .padding(4)
.style(crate::theme::display_container_frame()); .class(crate::theme::display_container_frame());
row::with_capacity(3) row::with_capacity(3)
.push(horizontal_space(Length::Fill)) .push(horizontal_space().width(Length::Fill))
.push(display) .push(display)
.push(horizontal_space(Length::Fill)) .push(horizontal_space().width(Length::Fill))
.padding([0, 0, 8, 0]) .padding([0, 0, 8, 0])
.into() .into()
} }
@ -155,10 +154,10 @@ pub fn page_list_item<'a, Message: 'static + Clone>(
.apply(container) .apply(container)
.padding([space_s, space_m]) .padding([space_s, space_m])
.align_x(alignment::Horizontal::Center) .align_x(alignment::Horizontal::Center)
.style(theme::Container::List) .class(theme::Container::List)
.apply(button::custom) .apply(button::custom)
.padding(0) .padding(0)
.style(theme::Button::Transparent) .class(theme::Button::Transparent)
.on_press(message) .on_press(message)
.into() .into()
} }
@ -174,7 +173,7 @@ pub fn sub_page_header<'a, Message: 'static + Clone>(
.padding(0) .padding(0)
.label(parent_page) .label(parent_page)
.spacing(4) .spacing(4)
.style(button::Style::Link) .class(button::ButtonClass::Link)
.on_press(on_press); .on_press(on_press);
let sub_page_header = row::with_capacity(2).push(text::title3(sub_page)); let sub_page_header = row::with_capacity(2).push(text::title3(sub_page));
@ -189,14 +188,14 @@ pub fn sub_page_header<'a, Message: 'static + Clone>(
pub fn go_next_item<Msg: Clone + 'static>(description: &str, msg: Msg) -> cosmic::Element<'_, Msg> { pub fn go_next_item<Msg: Clone + 'static>(description: &str, msg: Msg) -> cosmic::Element<'_, Msg> {
settings::item_row(vec![ settings::item_row(vec![
text::body(description).wrap(Wrap::Word).into(), text::body(description).wrapping(Wrapping::Word).into(),
horizontal_space(Length::Fill).into(), horizontal_space().width(Length::Fill).into(),
icon::from_name("go-next-symbolic").size(16).icon().into(), icon::from_name("go-next-symbolic").size(16).icon().into(),
]) ])
.apply(widget::container) .apply(widget::container)
.style(cosmic::theme::Container::List) .class(cosmic::theme::Container::List)
.apply(button::custom) .apply(button::custom)
.style(theme::Button::Transparent) .class(theme::Button::Transparent)
.on_press(msg) .on_press(msg)
.into() .into()
} }

View file

@ -3,8 +3,8 @@
use crate::section::{self, Section}; use crate::section::{self, Section};
use crate::{Content, Info, Page}; use crate::{Content, Info, Page};
use cosmic::iced_runtime::command::Command;
use cosmic::Element; use cosmic::Element;
use cosmic::Task;
use regex::Regex; use regex::Regex;
use slotmap::{SecondaryMap, SlotMap, SparseSecondaryMap}; use slotmap::{SecondaryMap, SlotMap, SparseSecondaryMap};
use std::{ use std::{
@ -157,8 +157,8 @@ impl<Message: 'static> Binder<Message> {
page.downcast_mut::<P>() page.downcast_mut::<P>()
} }
/// Returns a command when a page is left /// Returns a Task when a page is left
pub fn on_leave(&mut self, id: crate::Entity) -> Option<Command<Message>> { pub fn on_leave(&mut self, id: crate::Entity) -> Option<Task<Message>> {
if let Some(page) = self.page.get_mut(id) { if let Some(page) = self.page.get_mut(id) {
return Some(page.on_leave()); return Some(page.on_leave());
} }
@ -170,12 +170,12 @@ impl<Message: 'static> Binder<Message> {
&mut self, &mut self,
id: crate::Entity, id: crate::Entity,
sender: tokio::sync::mpsc::Sender<Message>, sender: tokio::sync::mpsc::Sender<Message>,
) -> Command<Message> { ) -> Task<Message> {
if let Some(page) = self.page.get_mut(id) { if let Some(page) = self.page.get_mut(id) {
return page.on_enter(id, sender); return page.on_enter(id, sender);
} }
Command::none() Task::none()
} }
#[must_use] #[must_use]

View file

@ -5,7 +5,7 @@ mod binder;
pub use binder::{AutoBind, Binder}; pub use binder::{AutoBind, Binder};
mod insert; mod insert;
use cosmic::{Command, Element}; use cosmic::{Element, Task};
use downcast_rs::{impl_downcast, Downcast}; use downcast_rs::{impl_downcast, Downcast};
pub use insert::Insert; pub use insert::Insert;
@ -54,8 +54,8 @@ pub trait Page<Message: 'static>: Downcast {
} }
/// Response from a file chooser dialog request. /// Response from a file chooser dialog request.
fn file_chooser(&mut self, _selected: Vec<url::Url>) -> Command<Message> { fn file_chooser(&mut self, _selected: Vec<url::Url>) -> Task<Message> {
Command::none() Task::none()
} }
/// Alter the contents of the page's header view. /// Alter the contents of the page's header view.
@ -63,19 +63,19 @@ pub trait Page<Message: 'static>: Downcast {
None None
} }
/// Reload page metadata via a Command. /// Reload page metadata via a Task.
#[allow(unused)] #[allow(unused)]
fn on_enter( fn on_enter(
&mut self, &mut self,
page: crate::Entity, page: crate::Entity,
sender: tokio::sync::mpsc::Sender<Message>, sender: tokio::sync::mpsc::Sender<Message>,
) -> Command<Message> { ) -> Task<Message> {
Command::none() Task::none()
} }
/// Emit a command when the page is left /// Emit a command when the page is left
fn on_leave(&mut self) -> Command<Message> { fn on_leave(&mut self) -> Task<Message> {
Command::none() Task::none()
} }
/// The title to display in the page header. /// The title to display in the page header.