initial implementation

This commit is contained in:
Emil Lerch 2026-01-26 12:42:19 -08:00
parent 1097204729
commit 934e0d24fa
Signed by: lobo
GPG key ID: A7B62D657EF764F8
9 changed files with 712 additions and 406 deletions

3
.gitignore vendored
View file

@ -11,4 +11,5 @@ debian/*
!debian/copyright !debian/copyright
!debian/install !debian/install
!debian/rules !debian/rules
!debian/source !debian/source
cosmic-applets/

View file

@ -1,3 +1,4 @@
[tools] [tools]
just = "1.46.0"
rust = "1.92.0" rust = "1.92.0"
rust-analyzer = "latest" rust-analyzer = "latest"

660
Cargo.lock generated
View file

@ -174,6 +174,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "anyhow"
version = "1.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
[[package]] [[package]]
name = "apply" name = "apply"
version = "0.3.0" version = "0.3.0"
@ -535,6 +541,28 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "aws-lc-rs"
version = "1.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b7b6141e96a8c160799cc2d5adecd5cbbe5054cb8c7c4af53da0f83bb7ad256"
dependencies = [
"aws-lc-sys",
"zeroize",
]
[[package]]
name = "aws-lc-sys"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c34dda4df7017c8db52132f0f8a2e0f8161649d15723ed63fc00c82d0f2081a"
dependencies = [
"cc",
"cmake",
"dunce",
"fs_extra",
]
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.22.1" version = "0.22.1"
@ -821,7 +849,7 @@ version = "0.2.2"
source = "git+https://github.com/pop-os/window_clipboard.git?tag=pop-0.13-2#6b9faab87bea9cebec6ae036906fd67fed254f5f" source = "git+https://github.com/pop-os/window_clipboard.git?tag=pop-0.13-2#6b9faab87bea9cebec6ae036906fd67fed254f5f"
dependencies = [ dependencies = [
"dnd", "dnd",
"mime", "mime 0.1.0",
"smithay-clipboard", "smithay-clipboard",
] ]
@ -834,6 +862,15 @@ dependencies = [
"x11rb", "x11rb",
] ]
[[package]]
name = "cmake"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "cocoa" name = "cocoa"
version = "0.25.0" version = "0.25.0"
@ -843,7 +880,7 @@ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
"block", "block",
"cocoa-foundation", "cocoa-foundation",
"core-foundation", "core-foundation 0.9.4",
"core-graphics", "core-graphics",
"foreign-types", "foreign-types",
"libc", "libc",
@ -858,7 +895,7 @@ checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7"
dependencies = [ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
"block", "block",
"core-foundation", "core-foundation 0.9.4",
"core-graphics-types", "core-graphics-types",
"libc", "libc",
"objc", "objc",
@ -940,6 +977,16 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "core-foundation"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]] [[package]]
name = "core-foundation-sys" name = "core-foundation-sys"
version = "0.8.7" version = "0.8.7"
@ -953,7 +1000,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081"
dependencies = [ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
"core-foundation", "core-foundation 0.9.4",
"core-graphics-types", "core-graphics-types",
"foreign-types", "foreign-types",
"libc", "libc",
@ -966,7 +1013,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf"
dependencies = [ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
"core-foundation", "core-foundation 0.9.4",
"libc", "libc",
] ]
@ -1036,6 +1083,20 @@ dependencies = [
"xdg", "xdg",
] ]
[[package]]
name = "cosmic-panel-config"
version = "0.1.0"
source = "git+https://github.com/pop-os/cosmic-panel#8eb8a1b6305213ec7402cb2ec24bef6b501b978a"
dependencies = [
"anyhow",
"cosmic-config",
"serde",
"smithay-client-toolkit 0.20.0",
"tracing",
"wayland-protocols-wlr",
"xdg-shell-wrapper-config",
]
[[package]] [[package]]
name = "cosmic-protocols" name = "cosmic-protocols"
version = "0.1.0" version = "0.1.0"
@ -1105,7 +1166,7 @@ dependencies = [
"i18n-embed", "i18n-embed",
"i18n-embed-fl", "i18n-embed-fl",
"libcosmic", "libcosmic",
"open", "reqwest",
"rust-embed", "rust-embed",
"tokio", "tokio",
] ]
@ -1339,7 +1400,7 @@ version = "0.1.0"
source = "git+https://github.com/pop-os/window_clipboard.git?tag=pop-0.13-2#6b9faab87bea9cebec6ae036906fd67fed254f5f" source = "git+https://github.com/pop-os/window_clipboard.git?tag=pop-0.13-2#6b9faab87bea9cebec6ae036906fd67fed254f5f"
dependencies = [ dependencies = [
"bitflags 2.10.0", "bitflags 2.10.0",
"mime", "mime 0.1.0",
"raw-window-handle", "raw-window-handle",
"smithay-client-toolkit 0.19.2", "smithay-client-toolkit 0.19.2",
"smithay-clipboard", "smithay-clipboard",
@ -1404,6 +1465,21 @@ dependencies = [
"linux-raw-sys 0.6.5", "linux-raw-sys 0.6.5",
] ]
[[package]]
name = "dunce"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
[[package]]
name = "encoding_rs"
version = "0.8.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "endi" name = "endi"
version = "1.1.1" version = "1.1.1"
@ -1716,6 +1792,12 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "fs_extra"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
[[package]] [[package]]
name = "fsevent-sys" name = "fsevent-sys"
version = "4.1.0" version = "4.1.0"
@ -1870,8 +1952,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"js-sys",
"libc", "libc",
"wasi", "wasi",
"wasm-bindgen",
] ]
[[package]] [[package]]
@ -1881,9 +1965,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"js-sys",
"libc", "libc",
"r-efi", "r-efi",
"wasip2", "wasip2",
"wasm-bindgen",
] ]
[[package]] [[package]]
@ -2002,6 +2088,25 @@ dependencies = [
"svg_fmt", "svg_fmt",
] ]
[[package]]
name = "h2"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54"
dependencies = [
"atomic-waker",
"bytes",
"fnv",
"futures-core",
"futures-sink",
"http",
"indexmap",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]] [[package]]
name = "half" name = "half"
version = "2.7.1" version = "2.7.1"
@ -2086,6 +2191,109 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
[[package]]
name = "http"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
dependencies = [
"bytes",
"itoa",
]
[[package]]
name = "http-body"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
dependencies = [
"bytes",
"http",
]
[[package]]
name = "http-body-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
dependencies = [
"bytes",
"futures-core",
"http",
"http-body",
"pin-project-lite",
]
[[package]]
name = "httparse"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
[[package]]
name = "hyper"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11"
dependencies = [
"atomic-waker",
"bytes",
"futures-channel",
"futures-core",
"h2",
"http",
"http-body",
"httparse",
"itoa",
"pin-project-lite",
"pin-utils",
"smallvec",
"tokio",
"want",
]
[[package]]
name = "hyper-rustls"
version = "0.27.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
dependencies = [
"http",
"hyper",
"hyper-util",
"rustls",
"rustls-pki-types",
"tokio",
"tokio-rustls",
"tower-service",
]
[[package]]
name = "hyper-util"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f"
dependencies = [
"base64",
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"http",
"http-body",
"hyper",
"ipnet",
"libc",
"percent-encoding",
"pin-project-lite",
"socket2 0.6.1",
"system-configuration",
"tokio",
"tower-service",
"tracing",
"windows-registry",
]
[[package]] [[package]]
name = "i18n-config" name = "i18n-config"
version = "0.4.8" version = "0.4.8"
@ -2190,7 +2398,7 @@ dependencies = [
"iced_widget", "iced_widget",
"iced_winit", "iced_winit",
"image", "image",
"mime", "mime 0.1.0",
"thiserror 1.0.69", "thiserror 1.0.69",
"window_clipboard", "window_clipboard",
] ]
@ -2214,9 +2422,8 @@ dependencies = [
"cosmic-client-toolkit", "cosmic-client-toolkit",
"dnd", "dnd",
"glam", "glam",
"iced_accessibility",
"log", "log",
"mime", "mime 0.1.0",
"num-traits", "num-traits",
"once_cell", "once_cell",
"palette", "palette",
@ -2297,7 +2504,6 @@ dependencies = [
"bytes", "bytes",
"cosmic-client-toolkit", "cosmic-client-toolkit",
"dnd", "dnd",
"iced_accessibility",
"iced_core", "iced_core",
"iced_futures", "iced_futures",
"raw-window-handle", "raw-window-handle",
@ -2359,7 +2565,6 @@ source = "git+https://github.com/pop-os/libcosmic.git#097c76f0e56919f4c168e8a53a
dependencies = [ dependencies = [
"cosmic-client-toolkit", "cosmic-client-toolkit",
"dnd", "dnd",
"iced_accessibility",
"iced_renderer", "iced_renderer",
"iced_runtime", "iced_runtime",
"log", "log",
@ -2379,7 +2584,6 @@ source = "git+https://github.com/pop-os/libcosmic.git#097c76f0e56919f4c168e8a53a
dependencies = [ dependencies = [
"cosmic-client-toolkit", "cosmic-client-toolkit",
"dnd", "dnd",
"iced_accessibility",
"iced_futures", "iced_futures",
"iced_graphics", "iced_graphics",
"iced_runtime", "iced_runtime",
@ -2610,22 +2814,19 @@ dependencies = [
] ]
[[package]] [[package]]
name = "is-docker" name = "ipnet"
version = "0.2.0" version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
dependencies = [
"once_cell",
]
[[package]] [[package]]
name = "is-wsl" name = "iri-string"
version = "0.4.0" version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a"
dependencies = [ dependencies = [
"is-docker", "memchr",
"once_cell", "serde",
] ]
[[package]] [[package]]
@ -2776,6 +2977,7 @@ dependencies = [
"cosmic-client-toolkit", "cosmic-client-toolkit",
"cosmic-config", "cosmic-config",
"cosmic-freedesktop-icons", "cosmic-freedesktop-icons",
"cosmic-panel-config",
"cosmic-settings-daemon", "cosmic-settings-daemon",
"cosmic-theme", "cosmic-theme",
"css-color", "css-color",
@ -2784,13 +2986,11 @@ dependencies = [
"i18n-embed", "i18n-embed",
"i18n-embed-fl", "i18n-embed-fl",
"iced", "iced",
"iced_accessibility",
"iced_core", "iced_core",
"iced_futures", "iced_futures",
"iced_renderer", "iced_renderer",
"iced_runtime", "iced_runtime",
"iced_tiny_skia", "iced_tiny_skia",
"iced_wgpu",
"iced_widget", "iced_widget",
"iced_winit", "iced_winit",
"image", "image",
@ -2902,6 +3102,12 @@ version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38"
[[package]]
name = "lru-slab"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
[[package]] [[package]]
name = "lyon" name = "lyon"
version = "1.0.16" version = "1.0.16"
@ -3028,6 +3234,12 @@ dependencies = [
"smithay-clipboard", "smithay-clipboard",
] ]
[[package]]
name = "mime"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.8.9" version = "0.8.9"
@ -3486,15 +3698,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]] [[package]]
name = "open" name = "openssl-probe"
version = "5.3.3" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43bb73a7fa3799b198970490a51174027ba0d4ec504b03cd08caf513d40024bc" checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
dependencies = [
"is-wsl",
"libc",
"pathdiff",
]
[[package]] [[package]]
name = "option-ext" name = "option-ext"
@ -3640,12 +3847,6 @@ version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "pathdiff"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
[[package]] [[package]]
name = "percent-encoding" name = "percent-encoding"
version = "2.3.2" version = "2.3.2"
@ -3965,6 +4166,62 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "quinn"
version = "0.11.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20"
dependencies = [
"bytes",
"cfg_aliases 0.2.1",
"pin-project-lite",
"quinn-proto",
"quinn-udp",
"rustc-hash 2.1.1",
"rustls",
"socket2 0.6.1",
"thiserror 2.0.18",
"tokio",
"tracing",
"web-time",
]
[[package]]
name = "quinn-proto"
version = "0.11.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31"
dependencies = [
"aws-lc-rs",
"bytes",
"getrandom 0.3.4",
"lru-slab",
"rand 0.9.2",
"ring",
"rustc-hash 2.1.1",
"rustls",
"rustls-pki-types",
"slab",
"thiserror 2.0.18",
"tinyvec",
"tracing",
"web-time",
]
[[package]]
name = "quinn-udp"
version = "0.5.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd"
dependencies = [
"cfg_aliases 0.2.1",
"libc",
"once_cell",
"socket2 0.6.1",
"tracing",
"windows-sys 0.60.2",
]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.43" version = "1.0.43"
@ -4151,6 +4408,44 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
[[package]]
name = "reqwest"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04e9018c9d814e5f30cc16a0f03271aeab3571e609612d9fe78c1aa8d11c2f62"
dependencies = [
"base64",
"bytes",
"encoding_rs",
"futures-core",
"h2",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-rustls",
"hyper-util",
"js-sys",
"log",
"mime 0.3.17",
"percent-encoding",
"pin-project-lite",
"quinn",
"rustls",
"rustls-pki-types",
"rustls-platform-verifier",
"sync_wrapper",
"tokio",
"tokio-rustls",
"tower",
"tower-http",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]] [[package]]
name = "resvg" name = "resvg"
version = "0.42.0" version = "0.42.0"
@ -4200,6 +4495,20 @@ dependencies = [
"bytemuck", "bytemuck",
] ]
[[package]]
name = "ring"
version = "0.17.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
dependencies = [
"cc",
"cfg-if",
"getrandom 0.2.17",
"libc",
"untrusted",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "ron" name = "ron"
version = "0.11.0" version = "0.11.0"
@ -4305,6 +4614,81 @@ dependencies = [
"windows-sys 0.61.2", "windows-sys 0.61.2",
] ]
[[package]]
name = "rustls"
version = "0.23.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b"
dependencies = [
"aws-lc-rs",
"once_cell",
"rustls-pki-types",
"rustls-webpki",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-native-certs"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63"
dependencies = [
"openssl-probe",
"rustls-pki-types",
"schannel",
"security-framework",
]
[[package]]
name = "rustls-pki-types"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd"
dependencies = [
"web-time",
"zeroize",
]
[[package]]
name = "rustls-platform-verifier"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784"
dependencies = [
"core-foundation 0.10.1",
"core-foundation-sys",
"jni",
"log",
"once_cell",
"rustls",
"rustls-native-certs",
"rustls-platform-verifier-android",
"rustls-webpki",
"security-framework",
"security-framework-sys",
"webpki-root-certs",
"windows-sys 0.61.2",
]
[[package]]
name = "rustls-platform-verifier-android"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
[[package]]
name = "rustls-webpki"
version = "0.103.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53"
dependencies = [
"aws-lc-rs",
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]] [[package]]
name = "rustversion" name = "rustversion"
version = "1.0.22" version = "1.0.22"
@ -4336,6 +4720,15 @@ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]]
name = "schannel"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1"
dependencies = [
"windows-sys 0.61.2",
]
[[package]] [[package]]
name = "scoped-tls" name = "scoped-tls"
version = "1.0.1" version = "1.0.1"
@ -4361,6 +4754,29 @@ dependencies = [
"tiny-skia", "tiny-skia",
] ]
[[package]]
name = "security-framework"
version = "3.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef"
dependencies = [
"bitflags 2.10.0",
"core-foundation 0.10.1",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]] [[package]]
name = "self_cell" name = "self_cell"
version = "1.2.2" version = "1.2.2"
@ -4683,6 +5099,12 @@ version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]] [[package]]
name = "svg_fmt" name = "svg_fmt"
version = "0.4.5" version = "0.4.5"
@ -4732,6 +5154,15 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "sync_wrapper"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
dependencies = [
"futures-core",
]
[[package]] [[package]]
name = "synstructure" name = "synstructure"
version = "0.13.2" version = "0.13.2"
@ -4752,6 +5183,27 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "system-configuration"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
dependencies = [
"bitflags 2.10.0",
"core-foundation 0.9.4",
"system-configuration-sys",
]
[[package]]
name = "system-configuration-sys"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]] [[package]]
name = "taffy" name = "taffy"
version = "0.9.2" version = "0.9.2"
@ -4920,6 +5372,16 @@ dependencies = [
"syn 2.0.114", "syn 2.0.114",
] ]
[[package]]
name = "tokio-rustls"
version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
dependencies = [
"rustls",
"tokio",
]
[[package]] [[package]]
name = "tokio-stream" name = "tokio-stream"
version = "0.1.18" version = "0.1.18"
@ -4931,6 +5393,19 @@ dependencies = [
"tokio", "tokio",
] ]
[[package]]
name = "tokio-util"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"pin-project-lite",
"tokio",
]
[[package]] [[package]]
name = "toml" name = "toml"
version = "0.5.11" version = "0.5.11"
@ -4987,6 +5462,51 @@ dependencies = [
"winnow 0.7.14", "winnow 0.7.14",
] ]
[[package]]
name = "tower"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4"
dependencies = [
"futures-core",
"futures-util",
"pin-project-lite",
"sync_wrapper",
"tokio",
"tower-layer",
"tower-service",
]
[[package]]
name = "tower-http"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8"
dependencies = [
"bitflags 2.10.0",
"bytes",
"futures-util",
"http",
"http-body",
"iri-string",
"pin-project-lite",
"tower",
"tower-layer",
"tower-service",
]
[[package]]
name = "tower-layer"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
[[package]]
name = "tower-service"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
[[package]] [[package]]
name = "tracing" name = "tracing"
version = "0.1.44" version = "0.1.44"
@ -5019,6 +5539,12 @@ dependencies = [
"once_cell", "once_cell",
] ]
[[package]]
name = "try-lock"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]] [[package]]
name = "ttf-parser" name = "ttf-parser"
version = "0.21.1" version = "0.21.1"
@ -5145,6 +5671,12 @@ version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]] [[package]]
name = "url" name = "url"
version = "2.5.8" version = "2.5.8"
@ -5230,6 +5762,15 @@ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]]
name = "want"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
dependencies = [
"try-lock",
]
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.1+wasi-snapshot-preview1" version = "0.11.1+wasi-snapshot-preview1"
@ -5489,6 +6030,15 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "webpki-root-certs"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36a29fc0408b113f68cf32637857ab740edfafdf460c326cd2afaa2d84cc05dc"
dependencies = [
"rustls-pki-types",
]
[[package]] [[package]]
name = "weezl" name = "weezl"
version = "0.1.12" version = "0.1.12"
@ -5648,7 +6198,7 @@ dependencies = [
"clipboard_wayland", "clipboard_wayland",
"clipboard_x11", "clipboard_x11",
"dnd", "dnd",
"mime", "mime 0.1.0",
"raw-window-handle", "raw-window-handle",
"thiserror 1.0.69", "thiserror 1.0.69",
] ]
@ -5757,6 +6307,17 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-registry"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720"
dependencies = [
"windows-link",
"windows-result 0.4.1",
"windows-strings",
]
[[package]] [[package]]
name = "windows-result" name = "windows-result"
version = "0.1.2" version = "0.1.2"
@ -6095,7 +6656,7 @@ dependencies = [
"calloop 0.13.0", "calloop 0.13.0",
"cfg_aliases 0.2.1", "cfg_aliases 0.2.1",
"concurrent-queue", "concurrent-queue",
"core-foundation", "core-foundation 0.9.4",
"core-graphics", "core-graphics",
"cursor-icon", "cursor-icon",
"dpi", "dpi",
@ -6217,6 +6778,15 @@ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
[[package]]
name = "xdg-shell-wrapper-config"
version = "0.1.0"
source = "git+https://github.com/pop-os/cosmic-panel#8eb8a1b6305213ec7402cb2ec24bef6b501b978a"
dependencies = [
"serde",
"wayland-protocols-wlr",
]
[[package]] [[package]]
name = "xkbcommon" name = "xkbcommon"
version = "0.7.0" version = "0.7.0"
@ -6478,6 +7048,12 @@ dependencies = [
"synstructure", "synstructure",
] ]
[[package]]
name = "zeroize"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
[[package]] [[package]]
name = "zerotrie" name = "zerotrie"
version = "0.2.3" version = "0.2.3"

View file

@ -7,42 +7,19 @@ description = "Weather applet for COSMIC"
repository = "https://git.lerch.org/lobo/cosmic-weather-applet" repository = "https://git.lerch.org/lobo/cosmic-weather-applet"
[dependencies] [dependencies]
# For weather refresh timing
futures-util = "0.3.31" futures-util = "0.3.31"
i18n-embed = { version = "0.16", features = [
"fluent-system",
"desktop-requester",
] }
i18n-embed-fl = "0.10"
open = "5.3.2"
rust-embed = "8.8.0"
tokio = { version = "1.48.0", features = ["full"] } tokio = { version = "1.48.0", features = ["full"] }
# Localization
i18n-embed = { version = "0.16", features = [ ] }
i18n-embed-fl = "0.10"
rust-embed = "8.8.0"
# Web requests for weather
reqwest = { version = "0.13.1", features = [] }
[dependencies.libcosmic] [dependencies.libcosmic]
git = "https://github.com/pop-os/libcosmic.git" git = "https://github.com/pop-os/libcosmic.git"
# See https://github.com/pop-os/libcosmic/blob/master/Cargo.toml for available features. default-features = false
features = [ features = ["applet", "tokio", "wayland"]
# Accessibility support
"a11y",
# About widget for the app
"about",
# Uses cosmic-settings-daemon to watch for config file changes
"dbus-config",
# Support creating additional application windows.
"multi-window",
# On app startup, focuses an existing instance if the app is already open
"single-instance",
# Uses tokio as the executor for the runtime
"tokio",
# Windowing support for X11, Windows, Mac, & Redox
"winit",
# Add Wayland support to winit
"wayland",
# GPU-accelerated rendering
"wgpu",
]
# Uncomment to test a locally-cloned libcosmic
# [patch.'https://github.com/pop-os/libcosmic']
# libcosmic = { path = "../libcosmic" }
# cosmic-config = { path = "../libcosmic/cosmic-config" }
# cosmic-theme = { path = "../libcosmic/cosmic-theme" }

12
org.lerch.weather.desktop Normal file
View file

@ -0,0 +1,12 @@
[Desktop Entry]
Type=Application
Name=Weather Applet
Comment=Weather applet for COSMIC
Exec=cosmic-weather-applet
Icon=weather-clear
Categories=System;
NoDisplay=true
X-CosmicApplet=true
X-CosmicShrinkable=true
X-CosmicHoverPopup=Auto
X-OverflowPriority=10

View file

@ -1,64 +1,33 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
use crate::config::Config; use cosmic::iced::{Limits, Subscription};
use crate::fl; use cosmic::widget::{self, autosize, container};
use cosmic::app::context_drawer;
use cosmic::cosmic_config::{self, CosmicConfigEntry};
use cosmic::iced::alignment::{Horizontal, Vertical};
use cosmic::iced::{Alignment, Length, Subscription};
use cosmic::widget::{self, about::About, icon, menu, nav_bar};
use cosmic::{iced_futures, prelude::*}; use cosmic::{iced_futures, prelude::*};
use futures_util::SinkExt; use futures_util::SinkExt;
use std::collections::HashMap;
use std::time::Duration; use std::time::Duration;
const REPOSITORY: &str = env!("CARGO_PKG_REPOSITORY"); /// The applet model stores app-specific state.
const APP_ICON: &[u8] = include_bytes!("../resources/icons/hicolor/scalable/apps/icon.svg");
/// The application model stores app-specific state used to describe its interface and
/// drive its logic.
pub struct AppModel { pub struct AppModel {
/// Application state which is managed by the COSMIC runtime. /// Application state which is managed by the COSMIC runtime.
core: cosmic::Core, core: cosmic::Core,
/// Display a context drawer with the designated page if defined. /// Current weather data
context_page: ContextPage, weather_text: String,
/// The about page for this app. /// Loading state
about: About, is_loading: bool,
/// Contains items assigned to the nav bar panel.
nav: nav_bar::Model,
/// Key bindings for the application's menu bar.
key_binds: HashMap<menu::KeyBind, MenuAction>,
/// Configuration data that persists between application runs.
config: Config,
/// Time active
time: u32,
/// Toggle the watch subscription
watch_is_active: bool,
} }
/// Messages emitted by the application and its widgets. /// Messages emitted by the applet.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Message { pub enum Message {
LaunchUrl(String), WeatherUpdate(Result<String, String>),
ToggleContextPage(ContextPage), RefreshWeather,
ToggleWatch,
UpdateConfig(Config),
WatchTick(u32),
} }
/// Create a COSMIC application from the app model
impl cosmic::Application for AppModel { impl cosmic::Application for AppModel {
/// The async executor that will be used to run your application's commands.
type Executor = cosmic::executor::Default; type Executor = cosmic::executor::Default;
/// Data that your application receives to its init method.
type Flags = (); type Flags = ();
/// Messages which the application and its widgets will emit.
type Message = Message; type Message = Message;
const APP_ID: &'static str = "org.lerch.weather";
/// Unique identifier in RDNN (reverse domain name notation) format.
const APP_ID: &'static str = "dev.mmurphy.Test";
fn core(&self) -> &cosmic::Core { fn core(&self) -> &cosmic::Core {
&self.core &self.core
@ -68,305 +37,90 @@ impl cosmic::Application for AppModel {
&mut self.core &mut self.core
} }
/// Initializes the application with any given flags and startup commands.
fn init( fn init(
core: cosmic::Core, core: cosmic::Core,
_flags: Self::Flags, _flags: Self::Flags,
) -> (Self, Task<cosmic::Action<Self::Message>>) { ) -> (Self, Task<cosmic::Action<Self::Message>>) {
// Create a nav bar with three page items. let app = AppModel {
let mut nav = nav_bar::Model::default();
nav.insert()
.text(fl!("page-id", num = 1))
.data::<Page>(Page::Page1)
.icon(icon::from_name("applications-science-symbolic"))
.activate();
nav.insert()
.text(fl!("page-id", num = 2))
.data::<Page>(Page::Page2)
.icon(icon::from_name("applications-system-symbolic"));
nav.insert()
.text(fl!("page-id", num = 3))
.data::<Page>(Page::Page3)
.icon(icon::from_name("applications-games-symbolic"));
// Create the about widget
let about = About::default()
.name(fl!("app-title"))
.icon(widget::icon::from_svg_bytes(APP_ICON))
.version(env!("CARGO_PKG_VERSION"))
.links([(fl!("repository"), REPOSITORY)])
.license(env!("CARGO_PKG_LICENSE"));
// Construct the app model with the runtime's core.
let mut app = AppModel {
core, core,
context_page: ContextPage::default(), weather_text: "Loading...".to_string(),
about, is_loading: true,
nav,
key_binds: HashMap::new(),
// Optional configuration file for an application.
config: cosmic_config::Config::new(Self::APP_ID, Config::VERSION)
.map(|context| match Config::get_entry(&context) {
Ok(config) => config,
Err((_errors, config)) => {
// for why in errors {
// tracing::error!(%why, "error loading app config");
// }
config
}
})
.unwrap_or_default(),
time: 0,
watch_is_active: false,
}; };
// Create a startup command that sets the window title. let command = Task::perform(fetch_weather(), |result| {
let command = app.update_title(); cosmic::Action::App(Message::WeatherUpdate(result))
});
(app, command) (app, command)
} }
/// Elements to pack at the start of the header bar.
fn header_start(&self) -> Vec<Element<'_, Self::Message>> {
let menu_bar = menu::bar(vec![menu::Tree::with_children(
menu::root(fl!("view")).apply(Element::from),
menu::items(
&self.key_binds,
vec![menu::Item::Button(fl!("about"), None, MenuAction::About)],
),
)]);
vec![menu_bar.into()]
}
/// Enables the COSMIC application to create a nav bar with this model.
fn nav_model(&self) -> Option<&nav_bar::Model> {
Some(&self.nav)
}
/// Display a context drawer if the context page is requested.
fn context_drawer(&self) -> Option<context_drawer::ContextDrawer<'_, Self::Message>> {
if !self.core.window.show_context {
return None;
}
Some(match self.context_page {
ContextPage::About => context_drawer::about(
&self.about,
|url| Message::LaunchUrl(url.to_string()),
Message::ToggleContextPage(ContextPage::About),
),
})
}
/// Describes the interface based on the current state of the application model.
///
/// Application events will be processed through the view. Any messages emitted by
/// events received by widgets will be passed to the update method.
fn view(&self) -> Element<'_, Self::Message> { fn view(&self) -> Element<'_, Self::Message> {
let space_s = cosmic::theme::spacing().space_s; let content: Element<'_, Self::Message> = if self.is_loading {
let content: Element<_> = match self.nav.active_data::<Page>().unwrap() { widget::text("").font(cosmic::font::bold()).into()
Page::Page1 => { } else {
let header = widget::row::with_capacity(2) // Split weather text on pipe separator
.push(widget::text::title1(fl!("welcome"))) let parts: Vec<&str> = self.weather_text.split('|').collect();
.push(widget::text::title3(fl!("page-id", num = 1))) if parts.len() == 2 {
.align_y(Alignment::End) widget::row()
.spacing(space_s); .push(widget::text(parts[0]).font(cosmic::font::bold()))
.push(widget::text("|"))
let counter_label = ["Watch: ", self.time.to_string().as_str()].concat(); .push(widget::text(parts[1]))
let section = cosmic::widget::settings::section().add( .spacing(0)
cosmic::widget::settings::item::builder(counter_label).control(
widget::button::text(if self.watch_is_active {
"Stop"
} else {
"Start"
})
.on_press(Message::ToggleWatch),
),
);
widget::column::with_capacity(2)
.push(header)
.push(section)
.spacing(space_s)
.height(Length::Fill)
.into()
}
Page::Page2 => {
let header = widget::row::with_capacity(2)
.push(widget::text::title1(fl!("welcome")))
.push(widget::text::title3(fl!("page-id", num = 2)))
.align_y(Alignment::End)
.spacing(space_s);
widget::column::with_capacity(1)
.push(header)
.spacing(space_s)
.height(Length::Fill)
.into()
}
Page::Page3 => {
let header = widget::row::with_capacity(2)
.push(widget::text::title1(fl!("welcome")))
.push(widget::text::title3(fl!("page-id", num = 3)))
.align_y(Alignment::End)
.spacing(space_s);
widget::column::with_capacity(1)
.push(header)
.spacing(space_s)
.height(Length::Fill)
.into() .into()
} else {
widget::text(&self.weather_text).into()
} }
}; };
widget::container(content) let limits = Limits::NONE.min_width(1.).min_height(1.);
.width(600)
.height(Length::Fill) autosize::autosize(
.apply(widget::container) container(content).padding(4),
.width(Length::Fill) cosmic::widget::Id::new("weather-autosize"),
.align_x(Horizontal::Center) )
.align_y(Vertical::Center) .limits(limits)
.into() .into()
} }
/// Register subscriptions for this application.
///
/// Subscriptions are long-running async tasks running in the background which
/// emit messages to the application through a channel. They can be dynamically
/// stopped and started conditionally based on application state, or persist
/// indefinitely.
fn subscription(&self) -> Subscription<Self::Message> { fn subscription(&self) -> Subscription<Self::Message> {
// Add subscriptions which are always active. Subscription::run(|| {
let mut subscriptions = vec![ iced_futures::stream::channel(1, |mut emitter| async move {
// Watch for application configuration changes. let mut interval = tokio::time::interval(Duration::from_secs(15 * 60)); // 15 minutes
self.core() interval.tick().await; // Skip first tick
.watch_config::<Config>(Self::APP_ID)
.map(|update| {
// for why in update.errors {
// tracing::error!(?why, "app config error");
// }
Message::UpdateConfig(update.config) loop {
}), interval.tick().await;
]; _ = emitter.send(Message::RefreshWeather).await;
}
// Conditionally enables a timer that emits a message every second. })
if self.watch_is_active { })
subscriptions.push(Subscription::run(|| {
iced_futures::stream::channel(1, |mut emitter| async move {
let mut time = 1;
let mut interval = tokio::time::interval(Duration::from_secs(1));
loop {
interval.tick().await;
_ = emitter.send(Message::WatchTick(time)).await;
time += 1;
}
})
}));
}
Subscription::batch(subscriptions)
} }
/// Handles messages emitted by the application and its widgets.
///
/// Tasks may be returned for asynchronous execution of code in the background
/// on the application's async runtime.
fn update(&mut self, message: Self::Message) -> Task<cosmic::Action<Self::Message>> { fn update(&mut self, message: Self::Message) -> Task<cosmic::Action<Self::Message>> {
match message { match message {
Message::WatchTick(time) => { Message::WeatherUpdate(result) => {
self.time = time; self.is_loading = false;
} match result {
Ok(weather) => self.weather_text = weather,
Message::ToggleWatch => { Err(_) => self.weather_text = "".to_string(),
self.watch_is_active = !self.watch_is_active;
}
Message::ToggleContextPage(context_page) => {
if self.context_page == context_page {
// Close the context drawer if the toggled context page is the same.
self.core.window.show_context = !self.core.window.show_context;
} else {
// Open the context drawer to display the requested context page.
self.context_page = context_page;
self.core.window.show_context = true;
} }
Task::none()
} }
Message::RefreshWeather => {
Message::UpdateConfig(config) => { self.is_loading = true;
self.config = config; Task::perform(fetch_weather(), |result| {
cosmic::Action::App(Message::WeatherUpdate(result))
})
} }
Message::LaunchUrl(url) => match open::that_detached(&url) {
Ok(()) => {}
Err(err) => {
eprintln!("failed to open {url:?}: {err}");
}
},
}
Task::none()
}
/// Called when a nav item is selected.
fn on_nav_select(&mut self, id: nav_bar::Id) -> Task<cosmic::Action<Self::Message>> {
// Activate the page in the model.
self.nav.activate(id);
self.update_title()
}
}
impl AppModel {
/// Updates the header and window titles.
pub fn update_title(&mut self) -> Task<cosmic::Action<Message>> {
let mut window_title = fl!("app-title");
if let Some(page) = self.nav.text(self.nav.active()) {
window_title.push_str("");
window_title.push_str(page);
}
if let Some(id) = self.core.main_window_id() {
self.set_window_title(window_title, id)
} else {
Task::none()
} }
} }
} }
/// The page to display in the application. async fn fetch_weather() -> Result<String, String> {
pub enum Page { let response = reqwest::get("https://wttr.lerch.org/?format=%c|%t")
Page1, .await
Page2, .map_err(|e| e.to_string())?;
Page3,
}
/// The context page to display in the context drawer. let text = response.text().await.map_err(|e| e.to_string())?;
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] Ok(text.trim().to_string())
pub enum ContextPage {
#[default]
About,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum MenuAction {
About,
}
impl menu::action::MenuAction for MenuAction {
type Message = Message;
fn message(&self) -> Self::Message {
match self {
MenuAction::About => Message::ToggleContextPage(ContextPage::About),
}
}
} }

View file

@ -1,9 +1,3 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
use cosmic::cosmic_config::{self, CosmicConfigEntry, cosmic_config_derive::CosmicConfigEntry}; // Config module placeholder - currently unused
#[derive(Debug, Default, Clone, CosmicConfigEntry, Eq, PartialEq)]
#[version = 1]
pub struct Config {
demo: String,
}

View file

@ -37,7 +37,6 @@ pub static LANGUAGE_LOADER: LazyLock<FluentLanguageLoader> = LazyLock::new(|| {
loader loader
}); });
/// Request a localized string by ID from the i18n/ directory. /// Request a localized string by ID from the i18n/ directory.
#[macro_export] #[macro_export]
macro_rules! fl { macro_rules! fl {
@ -49,4 +48,3 @@ macro_rules! fl {
i18n_embed_fl::fl!($crate::i18n::LANGUAGE_LOADER, $message_id, $($args), *) i18n_embed_fl::fl!($crate::i18n::LANGUAGE_LOADER, $message_id, $($args), *)
}}; }};
} }

View file

@ -11,13 +11,6 @@ fn main() -> cosmic::iced::Result {
// Enable localizations to be applied. // Enable localizations to be applied.
i18n::init(&requested_languages); i18n::init(&requested_languages);
// Settings for configuring the application window and iced runtime. // Starts the applet's event loop with `()` as the application's flags.
let settings = cosmic::app::Settings::default().size_limits( cosmic::applet::run::<app::AppModel>(())
cosmic::iced::Limits::NONE
.min_width(360.0)
.min_height(180.0),
);
// Starts the application's event loop with `()` as the application's flags.
cosmic::app::run::<app::AppModel>(settings, ())
} }