diff --git a/.gitignore b/.gitignore index 9703579..c003d96 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ debian/* !debian/copyright !debian/install !debian/rules -!debian/source \ No newline at end of file +!debian/source +cosmic-applets/ diff --git a/.mise.toml b/.mise.toml index 2f12f59..b38c1d6 100644 --- a/.mise.toml +++ b/.mise.toml @@ -1,3 +1,4 @@ [tools] +just = "1.46.0" rust = "1.92.0" rust-analyzer = "latest" diff --git a/Cargo.lock b/Cargo.lock index 6be355f..a758943 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -174,6 +174,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" + [[package]] name = "apply" version = "0.3.0" @@ -535,6 +541,28 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "base64" 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" dependencies = [ "dnd", - "mime", + "mime 0.1.0", "smithay-clipboard", ] @@ -834,6 +862,15 @@ dependencies = [ "x11rb", ] +[[package]] +name = "cmake" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" +dependencies = [ + "cc", +] + [[package]] name = "cocoa" version = "0.25.0" @@ -843,7 +880,7 @@ dependencies = [ "bitflags 1.3.2", "block", "cocoa-foundation", - "core-foundation", + "core-foundation 0.9.4", "core-graphics", "foreign-types", "libc", @@ -858,7 +895,7 @@ checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" dependencies = [ "bitflags 1.3.2", "block", - "core-foundation", + "core-foundation 0.9.4", "core-graphics-types", "libc", "objc", @@ -940,6 +977,16 @@ dependencies = [ "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]] name = "core-foundation-sys" version = "0.8.7" @@ -953,7 +1000,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "core-graphics-types", "foreign-types", "libc", @@ -966,7 +1013,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "libc", ] @@ -1036,6 +1083,20 @@ dependencies = [ "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]] name = "cosmic-protocols" version = "0.1.0" @@ -1105,7 +1166,7 @@ dependencies = [ "i18n-embed", "i18n-embed-fl", "libcosmic", - "open", + "reqwest", "rust-embed", "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" dependencies = [ "bitflags 2.10.0", - "mime", + "mime 0.1.0", "raw-window-handle", "smithay-client-toolkit 0.19.2", "smithay-clipboard", @@ -1404,6 +1465,21 @@ dependencies = [ "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]] name = "endi" version = "1.1.1" @@ -1716,6 +1792,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "fsevent-sys" version = "4.1.0" @@ -1870,8 +1952,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -1881,9 +1965,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi", "wasip2", + "wasm-bindgen", ] [[package]] @@ -2002,6 +2088,25 @@ dependencies = [ "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]] name = "half" version = "2.7.1" @@ -2086,6 +2191,109 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "i18n-config" version = "0.4.8" @@ -2190,7 +2398,7 @@ dependencies = [ "iced_widget", "iced_winit", "image", - "mime", + "mime 0.1.0", "thiserror 1.0.69", "window_clipboard", ] @@ -2214,9 +2422,8 @@ dependencies = [ "cosmic-client-toolkit", "dnd", "glam", - "iced_accessibility", "log", - "mime", + "mime 0.1.0", "num-traits", "once_cell", "palette", @@ -2297,7 +2504,6 @@ dependencies = [ "bytes", "cosmic-client-toolkit", "dnd", - "iced_accessibility", "iced_core", "iced_futures", "raw-window-handle", @@ -2359,7 +2565,6 @@ source = "git+https://github.com/pop-os/libcosmic.git#097c76f0e56919f4c168e8a53a dependencies = [ "cosmic-client-toolkit", "dnd", - "iced_accessibility", "iced_renderer", "iced_runtime", "log", @@ -2379,7 +2584,6 @@ source = "git+https://github.com/pop-os/libcosmic.git#097c76f0e56919f4c168e8a53a dependencies = [ "cosmic-client-toolkit", "dnd", - "iced_accessibility", "iced_futures", "iced_graphics", "iced_runtime", @@ -2610,22 +2814,19 @@ dependencies = [ ] [[package]] -name = "is-docker" -version = "0.2.0" +name = "ipnet" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" -dependencies = [ - "once_cell", -] +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] -name = "is-wsl" -version = "0.4.0" +name = "iri-string" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" dependencies = [ - "is-docker", - "once_cell", + "memchr", + "serde", ] [[package]] @@ -2776,6 +2977,7 @@ dependencies = [ "cosmic-client-toolkit", "cosmic-config", "cosmic-freedesktop-icons", + "cosmic-panel-config", "cosmic-settings-daemon", "cosmic-theme", "css-color", @@ -2784,13 +2986,11 @@ dependencies = [ "i18n-embed", "i18n-embed-fl", "iced", - "iced_accessibility", "iced_core", "iced_futures", "iced_renderer", "iced_runtime", "iced_tiny_skia", - "iced_wgpu", "iced_widget", "iced_winit", "image", @@ -2902,6 +3102,12 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "lyon" version = "1.0.16" @@ -3028,6 +3234,12 @@ dependencies = [ "smithay-clipboard", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -3486,15 +3698,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] -name = "open" -version = "5.3.3" +name = "openssl-probe" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43bb73a7fa3799b198970490a51174027ba0d4ec504b03cd08caf513d40024bc" -dependencies = [ - "is-wsl", - "libc", - "pathdiff", -] +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "option-ext" @@ -3640,12 +3847,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "pathdiff" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" - [[package]] name = "percent-encoding" version = "2.3.2" @@ -3965,6 +4166,62 @@ dependencies = [ "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]] name = "quote" version = "1.0.43" @@ -4151,6 +4408,44 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "resvg" version = "0.42.0" @@ -4200,6 +4495,20 @@ dependencies = [ "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]] name = "ron" version = "0.11.0" @@ -4305,6 +4614,81 @@ dependencies = [ "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]] name = "rustversion" version = "1.0.22" @@ -4336,6 +4720,15 @@ dependencies = [ "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]] name = "scoped-tls" version = "1.0.1" @@ -4361,6 +4754,29 @@ dependencies = [ "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]] name = "self_cell" version = "1.2.2" @@ -4683,6 +5099,12 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "svg_fmt" version = "0.4.5" @@ -4732,6 +5154,15 @@ dependencies = [ "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]] name = "synstructure" version = "0.13.2" @@ -4752,6 +5183,27 @@ dependencies = [ "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]] name = "taffy" version = "0.9.2" @@ -4920,6 +5372,16 @@ dependencies = [ "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]] name = "tokio-stream" version = "0.1.18" @@ -4931,6 +5393,19 @@ dependencies = [ "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]] name = "toml" version = "0.5.11" @@ -4987,6 +5462,51 @@ dependencies = [ "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]] name = "tracing" version = "0.1.44" @@ -5019,6 +5539,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "ttf-parser" version = "0.21.1" @@ -5145,6 +5671,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.8" @@ -5230,6 +5762,15 @@ dependencies = [ "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]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -5489,6 +6030,15 @@ dependencies = [ "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]] name = "weezl" version = "0.1.12" @@ -5648,7 +6198,7 @@ dependencies = [ "clipboard_wayland", "clipboard_x11", "dnd", - "mime", + "mime 0.1.0", "raw-window-handle", "thiserror 1.0.69", ] @@ -5757,6 +6307,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "windows-result" version = "0.1.2" @@ -6095,7 +6656,7 @@ dependencies = [ "calloop 0.13.0", "cfg_aliases 0.2.1", "concurrent-queue", - "core-foundation", + "core-foundation 0.9.4", "core-graphics", "cursor-icon", "dpi", @@ -6217,6 +6778,15 @@ dependencies = [ "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]] name = "xkbcommon" version = "0.7.0" @@ -6478,6 +7048,12 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + [[package]] name = "zerotrie" version = "0.2.3" diff --git a/Cargo.toml b/Cargo.toml index 4060d82..0b015d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,42 +7,19 @@ description = "Weather applet for COSMIC" repository = "https://git.lerch.org/lobo/cosmic-weather-applet" [dependencies] +# For weather refresh timing 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"] } +# 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] git = "https://github.com/pop-os/libcosmic.git" -# See https://github.com/pop-os/libcosmic/blob/master/Cargo.toml for available features. -features = [ - # 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" } +default-features = false +features = ["applet", "tokio", "wayland"] diff --git a/org.lerch.weather.desktop b/org.lerch.weather.desktop new file mode 100644 index 0000000..c3d925c --- /dev/null +++ b/org.lerch.weather.desktop @@ -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 diff --git a/src/app.rs b/src/app.rs index d0c1744..02e7b44 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,64 +1,33 @@ // SPDX-License-Identifier: MIT -use crate::config::Config; -use crate::fl; -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::{Limits, Subscription}; +use cosmic::widget::{self, autosize, container}; use cosmic::{iced_futures, prelude::*}; use futures_util::SinkExt; -use std::collections::HashMap; use std::time::Duration; -const REPOSITORY: &str = env!("CARGO_PKG_REPOSITORY"); -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. +/// The applet model stores app-specific state. pub struct AppModel { /// Application state which is managed by the COSMIC runtime. core: cosmic::Core, - /// Display a context drawer with the designated page if defined. - context_page: ContextPage, - /// The about page for this app. - about: About, - /// Contains items assigned to the nav bar panel. - nav: nav_bar::Model, - /// Key bindings for the application's menu bar. - key_binds: HashMap, - /// Configuration data that persists between application runs. - config: Config, - /// Time active - time: u32, - /// Toggle the watch subscription - watch_is_active: bool, + /// Current weather data + weather_text: String, + /// Loading state + is_loading: bool, } -/// Messages emitted by the application and its widgets. +/// Messages emitted by the applet. #[derive(Debug, Clone)] pub enum Message { - LaunchUrl(String), - ToggleContextPage(ContextPage), - ToggleWatch, - UpdateConfig(Config), - WatchTick(u32), + WeatherUpdate(Result), + RefreshWeather, } -/// Create a COSMIC application from the app model impl cosmic::Application for AppModel { - /// The async executor that will be used to run your application's commands. type Executor = cosmic::executor::Default; - - /// Data that your application receives to its init method. type Flags = (); - - /// Messages which the application and its widgets will emit. type Message = Message; - - /// Unique identifier in RDNN (reverse domain name notation) format. - const APP_ID: &'static str = "dev.mmurphy.Test"; + const APP_ID: &'static str = "org.lerch.weather"; fn core(&self) -> &cosmic::Core { &self.core @@ -68,305 +37,90 @@ impl cosmic::Application for AppModel { &mut self.core } - /// Initializes the application with any given flags and startup commands. fn init( core: cosmic::Core, _flags: Self::Flags, ) -> (Self, Task>) { - // Create a nav bar with three page items. - let mut nav = nav_bar::Model::default(); - - nav.insert() - .text(fl!("page-id", num = 1)) - .data::(Page::Page1) - .icon(icon::from_name("applications-science-symbolic")) - .activate(); - - nav.insert() - .text(fl!("page-id", num = 2)) - .data::(Page::Page2) - .icon(icon::from_name("applications-system-symbolic")); - - nav.insert() - .text(fl!("page-id", num = 3)) - .data::(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 { + let app = AppModel { core, - context_page: ContextPage::default(), - about, - 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, + weather_text: "Loading...".to_string(), + is_loading: true, }; - // Create a startup command that sets the window title. - let command = app.update_title(); + let command = Task::perform(fetch_weather(), |result| { + cosmic::Action::App(Message::WeatherUpdate(result)) + }); (app, command) } - /// Elements to pack at the start of the header bar. - fn header_start(&self) -> Vec> { - 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> { - 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> { - let space_s = cosmic::theme::spacing().space_s; - let content: Element<_> = match self.nav.active_data::().unwrap() { - Page::Page1 => { - let header = widget::row::with_capacity(2) - .push(widget::text::title1(fl!("welcome"))) - .push(widget::text::title3(fl!("page-id", num = 1))) - .align_y(Alignment::End) - .spacing(space_s); - - let counter_label = ["Watch: ", self.time.to_string().as_str()].concat(); - let section = cosmic::widget::settings::section().add( - 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) + let content: Element<'_, Self::Message> = if self.is_loading { + widget::text("⏳").font(cosmic::font::bold()).into() + } else { + // Split weather text on pipe separator + let parts: Vec<&str> = self.weather_text.split('|').collect(); + if parts.len() == 2 { + widget::row() + .push(widget::text(parts[0]).font(cosmic::font::bold())) + .push(widget::text("|")) + .push(widget::text(parts[1])) + .spacing(0) .into() + } else { + widget::text(&self.weather_text).into() } }; - widget::container(content) - .width(600) - .height(Length::Fill) - .apply(widget::container) - .width(Length::Fill) - .align_x(Horizontal::Center) - .align_y(Vertical::Center) - .into() + let limits = Limits::NONE.min_width(1.).min_height(1.); + + autosize::autosize( + container(content).padding(4), + cosmic::widget::Id::new("weather-autosize"), + ) + .limits(limits) + .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 { - // Add subscriptions which are always active. - let mut subscriptions = vec![ - // Watch for application configuration changes. - self.core() - .watch_config::(Self::APP_ID) - .map(|update| { - // for why in update.errors { - // tracing::error!(?why, "app config error"); - // } + Subscription::run(|| { + iced_futures::stream::channel(1, |mut emitter| async move { + let mut interval = tokio::time::interval(Duration::from_secs(15 * 60)); // 15 minutes + interval.tick().await; // Skip first tick - Message::UpdateConfig(update.config) - }), - ]; - - // 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) + loop { + interval.tick().await; + _ = emitter.send(Message::RefreshWeather).await; + } + }) + }) } - /// 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> { match message { - Message::WatchTick(time) => { - self.time = time; - } - - Message::ToggleWatch => { - 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; + Message::WeatherUpdate(result) => { + self.is_loading = false; + match result { + Ok(weather) => self.weather_text = weather, + Err(_) => self.weather_text = "❌".to_string(), } + Task::none() } - - Message::UpdateConfig(config) => { - self.config = config; + Message::RefreshWeather => { + self.is_loading = true; + 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> { - // 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> { - 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. -pub enum Page { - Page1, - Page2, - Page3, -} +async fn fetch_weather() -> Result { + let response = reqwest::get("https://wttr.lerch.org/?format=%c|%t") + .await + .map_err(|e| e.to_string())?; -/// The context page to display in the context drawer. -#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] -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), - } - } + let text = response.text().await.map_err(|e| e.to_string())?; + Ok(text.trim().to_string()) } diff --git a/src/config.rs b/src/config.rs index f0bac1c..49286f2 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,9 +1,3 @@ // SPDX-License-Identifier: MIT -use cosmic::cosmic_config::{self, CosmicConfigEntry, cosmic_config_derive::CosmicConfigEntry}; - -#[derive(Debug, Default, Clone, CosmicConfigEntry, Eq, PartialEq)] -#[version = 1] -pub struct Config { - demo: String, -} +// Config module placeholder - currently unused diff --git a/src/i18n.rs b/src/i18n.rs index 40ba9b0..bd06b65 100644 --- a/src/i18n.rs +++ b/src/i18n.rs @@ -37,7 +37,6 @@ pub static LANGUAGE_LOADER: LazyLock = LazyLock::new(|| { loader }); - /// Request a localized string by ID from the i18n/ directory. #[macro_export] macro_rules! fl { @@ -49,4 +48,3 @@ macro_rules! fl { i18n_embed_fl::fl!($crate::i18n::LANGUAGE_LOADER, $message_id, $($args), *) }}; } - diff --git a/src/main.rs b/src/main.rs index a39c9d6..91e576a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,13 +11,6 @@ fn main() -> cosmic::iced::Result { // Enable localizations to be applied. i18n::init(&requested_languages); - // Settings for configuring the application window and iced runtime. - let settings = cosmic::app::Settings::default().size_limits( - 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::(settings, ()) + // Starts the applet's event loop with `()` as the application's flags. + cosmic::applet::run::(()) }