This commit is contained in:
commit
27f8cc3ab8
13 changed files with 723 additions and 3 deletions
|
|
@ -1 +0,0 @@
|
|||
/nix/store/774f2myazjrl15013q55gc6bibqnr8vr-source
|
||||
|
|
@ -1 +0,0 @@
|
|||
/nix/store/f1fvmylh0lvki8f5b9p2l1s9g4bm69vx-source
|
||||
|
|
@ -1 +0,0 @@
|
|||
/nix/store/wygnldpfirbkskf6qpjbghvaqh3kkczb-source
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1 +1,2 @@
|
|||
target
|
||||
.direnv
|
||||
|
|
|
|||
373
Cargo.lock
generated
373
Cargo.lock
generated
|
|
@ -94,6 +94,137 @@ dependencies = [
|
|||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-broadcast"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
"event-listener-strategy",
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-channel"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2"
|
||||
dependencies = [
|
||||
"concurrent-queue",
|
||||
"event-listener-strategy",
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-executor"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a"
|
||||
dependencies = [
|
||||
"async-task",
|
||||
"concurrent-queue",
|
||||
"fastrand",
|
||||
"futures-lite",
|
||||
"pin-project-lite",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-io"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"futures-io",
|
||||
"futures-lite",
|
||||
"parking",
|
||||
"polling",
|
||||
"rustix 1.1.4",
|
||||
"slab",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-lock"
|
||||
version = "3.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
"event-listener-strategy",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-process"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"async-io",
|
||||
"async-lock",
|
||||
"async-signal",
|
||||
"async-task",
|
||||
"blocking",
|
||||
"cfg-if",
|
||||
"event-listener",
|
||||
"futures-lite",
|
||||
"rustix 1.1.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-recursion"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-signal"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c"
|
||||
dependencies = [
|
||||
"async-io",
|
||||
"async-lock",
|
||||
"atomic-waker",
|
||||
"cfg-if",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"rustix 1.1.4",
|
||||
"signal-hook-registry",
|
||||
"slab",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-task"
|
||||
version = "4.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic-waker"
|
||||
version = "1.1.2"
|
||||
|
|
@ -148,6 +279,19 @@ dependencies = [
|
|||
"objc2 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blocking"
|
||||
version = "1.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"async-task",
|
||||
"futures-io",
|
||||
"futures-lite",
|
||||
"piper",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.20.2"
|
||||
|
|
@ -549,6 +693,12 @@ version = "0.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76"
|
||||
|
||||
[[package]]
|
||||
name = "endi"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099"
|
||||
|
||||
[[package]]
|
||||
name = "enumflags2"
|
||||
version = "0.7.12"
|
||||
|
|
@ -556,6 +706,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef"
|
||||
dependencies = [
|
||||
"enumflags2_derive",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -610,6 +761,27 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "event-listener"
|
||||
version = "5.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab"
|
||||
dependencies = [
|
||||
"concurrent-queue",
|
||||
"parking",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "event-listener-strategy"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.3.0"
|
||||
|
|
@ -747,6 +919,19 @@ version = "0.3.32"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
|
||||
|
||||
[[package]]
|
||||
name = "futures-lite"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"parking",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.32"
|
||||
|
|
@ -976,6 +1161,12 @@ version = "0.5.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "hexf-parse"
|
||||
version = "0.2.1"
|
||||
|
|
@ -1516,6 +1707,15 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "metal"
|
||||
version = "0.32.0"
|
||||
|
|
@ -1923,6 +2123,16 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-stream"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "owned_ttf_parser"
|
||||
version = "0.25.1"
|
||||
|
|
@ -1932,6 +2142,12 @@ dependencies = [
|
|||
"ttf-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.5"
|
||||
|
|
@ -1993,6 +2209,17 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "piper"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1"
|
||||
dependencies = [
|
||||
"atomic-waker",
|
||||
"fastrand",
|
||||
"futures-io",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.32"
|
||||
|
|
@ -2316,12 +2543,33 @@ dependencies = [
|
|||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
|
||||
dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "skrifa"
|
||||
version = "0.37.0"
|
||||
|
|
@ -2699,6 +2947,17 @@ dependencies = [
|
|||
"core_maths",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uds_windows"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e"
|
||||
dependencies = [
|
||||
"memoffset",
|
||||
"tempfile",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.18"
|
||||
|
|
@ -2741,6 +3000,17 @@ version = "0.2.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"serde_core",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
|
|
@ -3040,7 +3310,9 @@ dependencies = [
|
|||
"chrono",
|
||||
"iced",
|
||||
"iced_layershell",
|
||||
"tokio",
|
||||
"winit",
|
||||
"zbus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3663,6 +3935,67 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5"
|
||||
|
||||
[[package]]
|
||||
name = "zbus"
|
||||
version = "5.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca82f95dbd3943a40a53cfded6c2d0a2ca26192011846a1810c4256ef92c60bc"
|
||||
dependencies = [
|
||||
"async-broadcast",
|
||||
"async-executor",
|
||||
"async-io",
|
||||
"async-lock",
|
||||
"async-process",
|
||||
"async-recursion",
|
||||
"async-task",
|
||||
"async-trait",
|
||||
"blocking",
|
||||
"enumflags2",
|
||||
"event-listener",
|
||||
"futures-core",
|
||||
"futures-lite",
|
||||
"hex",
|
||||
"libc",
|
||||
"ordered-stream",
|
||||
"rustix 1.1.4",
|
||||
"serde",
|
||||
"serde_repr",
|
||||
"tracing",
|
||||
"uds_windows",
|
||||
"uuid",
|
||||
"windows-sys 0.61.2",
|
||||
"winnow",
|
||||
"zbus_macros",
|
||||
"zbus_names",
|
||||
"zvariant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus_macros"
|
||||
version = "5.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "897e79616e84aac4b2c46e9132a4f63b93105d54fe8c0e8f6bffc21fa8d49222"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"zbus_names",
|
||||
"zvariant",
|
||||
"zvariant_utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus_names"
|
||||
version = "4.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffd8af6d5b78619bab301ff3c560a5bd22426150253db278f164d6cf3b72c50f"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"winnow",
|
||||
"zvariant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeno"
|
||||
version = "0.3.3"
|
||||
|
|
@ -3694,3 +4027,43 @@ name = "zmij"
|
|||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||
|
||||
[[package]]
|
||||
name = "zvariant"
|
||||
version = "5.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5708299b21903bbe348e94729f22c49c55d04720a004aa350f1f9c122fd2540b"
|
||||
dependencies = [
|
||||
"endi",
|
||||
"enumflags2",
|
||||
"serde",
|
||||
"winnow",
|
||||
"zvariant_derive",
|
||||
"zvariant_utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zvariant_derive"
|
||||
version = "5.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b59b012ebe9c46656f9cc08d8da8b4c726510aef12559da3e5f1bf72780752c"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"zvariant_utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zvariant_utils"
|
||||
version = "3.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f75c23a64ef8f40f13a6989991e643554d9bef1d682a281160cf0c1bc389c5e9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"syn",
|
||||
"winnow",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ edition = "2024"
|
|||
chrono = "0.4.44"
|
||||
iced = { version = "0.14.0", default-features = false, features = ["wgpu", "wayland", "tokio"] }
|
||||
iced_layershell = { version = "0.15.0", default-features = false }
|
||||
tokio = { version = "1.50.0", features = ["time"] }
|
||||
winit = { version = "0.30.12", default-features = false, features = ["wayland"] }
|
||||
zbus = "5.14.0"
|
||||
|
||||
[profile.release]
|
||||
opt-level = 3
|
||||
|
|
|
|||
76
src/app.rs
Normal file
76
src/app.rs
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
use crate::widget::{Message, PanelWidget};
|
||||
use crate::widgets::battery::BatteryWidget;
|
||||
use crate::widgets::clock::ClockWidget;
|
||||
use crate::widgets::powerbutton::ShutdownWidget;
|
||||
use crate::widgets::spacer::Spacer;
|
||||
|
||||
use iced::Color;
|
||||
use iced::Element;
|
||||
use iced::Subscription;
|
||||
use iced::Task;
|
||||
|
||||
pub struct App {
|
||||
widgets: Vec<Box<dyn PanelWidget>>,
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub const WINDOW_HEIGHT: u32 = 32;
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
widgets: vec![
|
||||
Box::new(ClockWidget::new()),
|
||||
Box::new(Spacer::new(iced::Length::Fill)),
|
||||
Box::new(ShutdownWidget::new()),
|
||||
Box::new(Spacer::new(iced::Length::Fill)),
|
||||
Box::new(BatteryWidget::new()),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name() -> String {
|
||||
"wayland_panel".into()
|
||||
}
|
||||
|
||||
pub fn view(&self, id: iced::window::Id) -> Element<'_, Message> {
|
||||
if let Some(elem) = self
|
||||
.widgets
|
||||
.iter()
|
||||
.find(|widget| widget.has_window(id))
|
||||
.map(|widget| widget.view(id))
|
||||
{
|
||||
return elem;
|
||||
}
|
||||
|
||||
iced::widget::Row::with_children(self.widgets.iter().map(|widget| widget.view(id)))
|
||||
.padding(iced::Padding::from([0, 5]))
|
||||
.height(iced::Length::Fill)
|
||||
.width(iced::Length::Fill)
|
||||
.align_y(iced::Alignment::Center)
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: Message) -> Task<Message> {
|
||||
let mut output = Vec::new();
|
||||
for widget in &mut self.widgets {
|
||||
output.push(widget.update(&message));
|
||||
}
|
||||
|
||||
Task::batch(output)
|
||||
}
|
||||
|
||||
pub fn style(&self, theme: &iced::Theme) -> iced::theme::Style {
|
||||
iced::theme::Style {
|
||||
background_color: Color::TRANSPARENT,
|
||||
text_color: theme.palette().text,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn theme(&self, _id: iced::window::Id) -> iced::Theme {
|
||||
iced::Theme::GruvboxDark
|
||||
}
|
||||
|
||||
pub fn subscription(&self) -> iced::Subscription<Message> {
|
||||
Subscription::batch(self.widgets.iter().map(|w| w.subscribe()))
|
||||
}
|
||||
}
|
||||
23
src/widget.rs
Normal file
23
src/widget.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
use iced::Element;
|
||||
use iced::Subscription;
|
||||
use iced::Task;
|
||||
use iced_layershell::to_layer_message;
|
||||
|
||||
use crate::widgets::powerbutton::ShutdownEvents;
|
||||
|
||||
pub trait PanelWidget {
|
||||
fn update(&mut self, message: &Message) -> Task<Message>;
|
||||
fn subscribe(&self) -> Subscription<Message>;
|
||||
fn view(&self, id: iced::window::Id) -> Element<'_, Message>;
|
||||
fn has_window(&self, _id: iced::window::Id) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[to_layer_message(multi)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Message {
|
||||
Battery(Option<f64>),
|
||||
Time,
|
||||
ShutdownEvent(ShutdownEvents),
|
||||
}
|
||||
94
src/widgets/battery.rs
Normal file
94
src/widgets/battery.rs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
use crate::widget::{Message, PanelWidget};
|
||||
use iced::Element;
|
||||
use iced::Subscription;
|
||||
use iced::Task;
|
||||
use iced::futures::SinkExt;
|
||||
use iced::futures::StreamExt;
|
||||
use iced::widget::text;
|
||||
use std::time::Duration;
|
||||
|
||||
#[zbus::proxy(
|
||||
interface = "org.freedesktop.UPower.Device",
|
||||
default_service = "org.freedesktop.UPower",
|
||||
default_path = "/org/freedesktop/UPower/devices/DisplayDevice"
|
||||
)]
|
||||
trait UPowerDevice {
|
||||
#[zbus(property)]
|
||||
fn percentage(&self) -> zbus::Result<f64>;
|
||||
}
|
||||
|
||||
pub struct BatteryWidget {
|
||||
capacity: Option<f64>,
|
||||
}
|
||||
|
||||
impl BatteryWidget {
|
||||
pub fn new() -> Self {
|
||||
Self { capacity: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl PanelWidget for BatteryWidget {
|
||||
fn update(&mut self, message: &Message) -> Task<Message> {
|
||||
if let Message::Battery(capacity) = message {
|
||||
self.capacity = *capacity;
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn subscribe(&self) -> Subscription<Message> {
|
||||
Subscription::run(|| {
|
||||
iced::stream::channel(16, async |mut tx| {
|
||||
loop {
|
||||
let Ok(conn) = zbus::Connection::system().await else {
|
||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||
continue;
|
||||
};
|
||||
let Ok(proxy) = UPowerDeviceProxy::new(&conn).await else {
|
||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||
continue;
|
||||
};
|
||||
|
||||
if let Ok(pct) = proxy.percentage().await {
|
||||
tx.send(Message::Battery(Some(pct))).await.ok();
|
||||
}
|
||||
|
||||
let mut changes = proxy.receive_percentage_changed().await;
|
||||
while let Some(change) = changes.next().await {
|
||||
if let Ok(pct) = change.get().await {
|
||||
tx.send(Message::Battery(Some(pct))).await.ok();
|
||||
}
|
||||
}
|
||||
|
||||
tx.send(Message::Battery(None)).await.ok();
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn view(&self, _id: iced::window::Id) -> Element<'_, Message> {
|
||||
match self.capacity {
|
||||
Some(cap) => text!("{} {}", cap, Self::icon(cap)),
|
||||
None => text!(""),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
impl BatteryWidget {
|
||||
fn icon(capacity: f64) -> &'static str {
|
||||
match capacity {
|
||||
0f64..6f64 => "",
|
||||
6f64..11f64 => "",
|
||||
11f64..21f64 => "",
|
||||
21f64..31f64 => "",
|
||||
31f64..41f64 => "",
|
||||
41f64..51f64 => "",
|
||||
51f64..61f64 => "",
|
||||
61f64..71f64 => "",
|
||||
71f64..81f64 => "",
|
||||
81f64..91f64 => "",
|
||||
91f64..=100f64 => "",
|
||||
_ => "",
|
||||
}
|
||||
}
|
||||
}
|
||||
35
src/widgets/clock.rs
Normal file
35
src/widgets/clock.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
use crate::widget::{Message, PanelWidget};
|
||||
use iced::Task;
|
||||
use std::time::Duration;
|
||||
|
||||
pub struct ClockWidget {
|
||||
current_time: chrono::DateTime<chrono::Local>,
|
||||
}
|
||||
|
||||
impl ClockWidget {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
current_time: chrono::Local::now(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PanelWidget for ClockWidget {
|
||||
fn update(&mut self, message: &Message) -> Task<Message> {
|
||||
let Message::Time = message else {
|
||||
return Task::none();
|
||||
};
|
||||
|
||||
self.current_time = chrono::Local::now();
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn subscribe(&self) -> iced::Subscription<Message> {
|
||||
iced::time::every(Duration::from_secs(1)).map(|_| Message::Time)
|
||||
}
|
||||
|
||||
fn view(&self, _id: iced::window::Id) -> iced::Element<'_, Message> {
|
||||
let formatted_time = self.current_time.format("%H:%M");
|
||||
iced::widget::text!("{}", formatted_time).into()
|
||||
}
|
||||
}
|
||||
4
src/widgets/mod.rs
Normal file
4
src/widgets/mod.rs
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
pub mod battery;
|
||||
pub mod clock;
|
||||
pub mod powerbutton;
|
||||
pub mod spacer;
|
||||
90
src/widgets/powerbutton.rs
Normal file
90
src/widgets/powerbutton.rs
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
use crate::widget::{Message, PanelWidget};
|
||||
use iced::{
|
||||
Subscription, Task,
|
||||
widget::{button, row, text},
|
||||
};
|
||||
use iced_layershell::reexport::{Anchor, NewLayerShellSettings};
|
||||
|
||||
pub struct ShutdownWidget {
|
||||
window: Option<iced::window::Id>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ShutdownEvents {
|
||||
PowerButtonPressed,
|
||||
ShutdownConfirmed,
|
||||
ShutdownCanceled,
|
||||
}
|
||||
|
||||
impl ShutdownWidget {
|
||||
pub fn new() -> Self {
|
||||
Self { window: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl PanelWidget for ShutdownWidget {
|
||||
fn update(&mut self, message: &crate::widget::Message) -> iced::Task<crate::widget::Message> {
|
||||
let Message::ShutdownEvent(event) = message else {
|
||||
return Task::none();
|
||||
};
|
||||
|
||||
match event {
|
||||
ShutdownEvents::PowerButtonPressed => match self.window {
|
||||
Some(child) => {
|
||||
self.window = None;
|
||||
Task::done(Message::RemoveWindow(child))
|
||||
}
|
||||
None => {
|
||||
let id = iced::window::Id::unique();
|
||||
self.window = Some(id);
|
||||
|
||||
Task::done(Message::NewLayerShell {
|
||||
settings: NewLayerShellSettings {
|
||||
size: Some((220, 40)),
|
||||
anchor: Anchor::Top,
|
||||
layer: iced_layershell::reexport::Layer::Overlay,
|
||||
keyboard_interactivity:
|
||||
iced_layershell::reexport::KeyboardInteractivity::OnDemand,
|
||||
exclusive_zone: None,
|
||||
..Default::default()
|
||||
},
|
||||
id,
|
||||
})
|
||||
}
|
||||
},
|
||||
ShutdownEvents::ShutdownConfirmed => Task::none(),
|
||||
ShutdownEvents::ShutdownCanceled => match self.window {
|
||||
Some(child) => {
|
||||
self.window = None;
|
||||
Task::done(Message::RemoveWindow(child))
|
||||
}
|
||||
None => Task::none(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn subscribe(&self) -> iced::Subscription<crate::widget::Message> {
|
||||
Subscription::none()
|
||||
}
|
||||
|
||||
fn has_window(&self, id: iced::window::Id) -> bool {
|
||||
self.window == Some(id)
|
||||
}
|
||||
|
||||
fn view(&self, id: iced::window::Id) -> iced::Element<'_, crate::widget::Message> {
|
||||
match self.window {
|
||||
Some(child_id) if id == child_id => row![
|
||||
text("Shut down?"),
|
||||
button("✓").on_press(Message::ShutdownEvent(ShutdownEvents::ShutdownConfirmed)),
|
||||
button("✗").on_press(Message::ShutdownEvent(ShutdownEvents::ShutdownCanceled)),
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Alignment::Center)
|
||||
.into(),
|
||||
|
||||
_ => button("⏻")
|
||||
.on_press(Message::ShutdownEvent(ShutdownEvents::PowerButtonPressed))
|
||||
.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
25
src/widgets/spacer.rs
Normal file
25
src/widgets/spacer.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
use crate::widget::PanelWidget;
|
||||
|
||||
pub struct Spacer {
|
||||
space: iced::Length,
|
||||
}
|
||||
|
||||
impl Spacer {
|
||||
pub fn new(space: iced::Length) -> Self {
|
||||
Self { space }
|
||||
}
|
||||
}
|
||||
|
||||
impl PanelWidget for Spacer {
|
||||
fn update(&mut self, _message: &crate::widget::Message) -> iced::Task<crate::widget::Message> {
|
||||
iced::Task::none()
|
||||
}
|
||||
|
||||
fn subscribe(&self) -> iced::Subscription<crate::widget::Message> {
|
||||
iced::Subscription::none()
|
||||
}
|
||||
|
||||
fn view(&self, _id: iced::window::Id) -> iced::Element<'_, crate::widget::Message> {
|
||||
iced::widget::space().width(self.space).into()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue