power management start

This commit is contained in:
Jiří Maxmilián Stříbrný 2026-03-22 22:56:41 +01:00
parent 3789f5eb7b
commit 99b2e565b9
7 changed files with 281 additions and 2 deletions

154
Cargo.lock generated
View file

@ -67,6 +67,56 @@ dependencies = [
"libc",
]
[[package]]
name = "anstream"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
[[package]]
name = "anstyle-parse"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys 0.61.2",
]
[[package]]
name = "anyhow"
version = "1.0.102"
@ -418,6 +468,65 @@ dependencies = [
"windows-link",
]
[[package]]
name = "clap"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_complete"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19c9f1dde76b736e3681f28cec9d5a61299cbaae0fce80a68e43724ad56031eb"
dependencies = [
"clap",
]
[[package]]
name = "clap_derive"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
[[package]]
name = "clap_mangen"
version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e30ffc187e2e3aeafcd1c6e2aa416e29739454c0ccaa419226d5ecd181f2d78"
dependencies = [
"clap",
"roff",
]
[[package]]
name = "clipboard-win"
version = "5.4.1"
@ -468,6 +577,12 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "colorchoice"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
[[package]]
name = "combine"
version = "4.6.7"
@ -1468,6 +1583,12 @@ dependencies = [
"serde_core",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
[[package]]
name = "itoa"
version = "1.0.17"
@ -2104,6 +2225,12 @@ version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "once_cell_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
[[package]]
name = "orbclient"
version = "0.3.51"
@ -2261,6 +2388,20 @@ dependencies = [
"portable-atomic",
]
[[package]]
name = "ppd"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c9336eeb6b2ea4e61900f44b539ca0d095593a19ba8e831825c30e906aa475c"
dependencies = [
"clap",
"clap_complete",
"clap_mangen",
"serde",
"thiserror 2.0.18",
"zbus",
]
[[package]]
name = "presser"
version = "0.3.1"
@ -2404,6 +2545,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
[[package]]
name = "roff"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf2048e0e979efb2ca7b91c4f1a8d77c91853e9b987c94c555668a8994915ad"
[[package]]
name = "roxmltree"
version = "0.20.0"
@ -3000,6 +3147,12 @@ version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.22.0"
@ -3310,6 +3463,7 @@ dependencies = [
"chrono",
"iced",
"iced_layershell",
"ppd",
"tokio",
"winit",
"zbus",

View file

@ -7,6 +7,7 @@ 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 }
ppd = "0.1.7"
tokio = { version = "1.50.0", features = ["time"] }
winit = { version = "0.30.12", default-features = false, features = ["wayland"] }
zbus = "5.14.0"

View file

@ -19,9 +19,9 @@ impl App {
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::Fixed(5.))),
Box::new(ClockWidget::new()),
Box::new(Spacer::new(iced::Length::Fill)),
Box::new(BatteryWidget::new()),
],

View file

@ -3,6 +3,7 @@ use iced::Subscription;
use iced::Task;
use iced_layershell::to_layer_message;
use crate::widgets::power_management::PowerManagement;
use crate::widgets::powerbutton::ShutdownEvents;
pub trait PanelWidget {
@ -20,4 +21,5 @@ pub enum Message {
Battery(Option<f64>),
Time,
ShutdownEvent(ShutdownEvents),
PowerManagement(PowerManagement),
}

View file

@ -0,0 +1,69 @@
use iced::{Subscription, Task, futures::SinkExt};
use niri_ipc::{Event, Request, Response, Window, socket::Socket};
use crate::widget::{Message, PanelWidget};
pub struct FocusedWindowWidget {
focused_window: Option<u64>,
}
impl FocusedWindowWidget {
pub fn new() -> Self {
Self {
focused_window: None,
}
}
}
impl PanelWidget for FocusedWindowWidget {
fn update(&mut self, message: &Message) -> iced::Task<Message> {
let Message::FocusChanged(i) = message else {
return Task::none();
};
self.focused_window = *i;
Task::none()
}
fn subscribe(&self) -> Subscription<Message> {
Subscription::run(|| {
iced::stream::channel(16, async move |mut tx| {
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
use tokio::net::UnixStream;
let socket_path = std::env::var("NIRI_SOCKET").unwrap();
let mut stream = UnixStream::connect(socket_path).await.unwrap();
// Send the EventStream request as newline-delimited JSON
let request = serde_json::to_string(&niri_ipc::Request::EventStream).unwrap();
stream
.write_all(format!("{request}\n").as_bytes())
.await
.unwrap();
let mut reader = BufReader::new(stream);
let mut line = String::new();
loop {
line.clear();
reader.read_line(&mut line).await.unwrap();
// First line back is the Reply, subsequent lines are Events
if let Ok(event) = serde_json::from_str::<niri_ipc::Event>(line.trim())
&& let niri_ipc::Event::WindowFocusChanged { id } = event
{
let _ = tx.send(Message::FocusChanged(id)).await;
}
}
})
})
}
fn view(&self, _id: iced::window::Id) -> iced::Element<'_, Message> {
iced::widget::text!(
"{}",
self.focused_window
.map_or("None".into(), |f| format!("{}", f))
)
.into()
}
}

View file

@ -1,4 +1,5 @@
pub mod battery;
pub mod clock;
pub mod power_management;
pub mod powerbutton;
pub mod spacer;

View file

@ -0,0 +1,52 @@
use iced::{Subscription, Task};
use ppd::PpdProxy;
use zbus::connection::Connection;
use crate::widget::{Message, PanelWidget};
pub struct PowerManagementWidget {
window: Option<iced::window::Id>,
current_mode: usize,
names: Vec<Box<str>>,
}
#[derive(Debug, Clone)]
pub enum PowerManagement {
ToggleWindow,
SetMode(SetMode),
}
#[derive(Debug, Clone)]
pub enum SetMode {
Saver,
Medium,
Performant,
}
impl PowerManagementWidget {
pub fn new() -> Self {
let conn = Connection::system().await.unwrap();
}
}
impl PanelWidget for PowerManagementWidget {
fn update(&mut self, message: &crate::widget::Message) -> iced::Task<crate::widget::Message> {
let Message::PowerManagement(msg) = message else {
return Task::none();
};
Task::none()
}
fn subscribe(&self) -> iced::Subscription<crate::widget::Message> {
Subscription::none()
}
fn view(&self, id: iced::window::Id) -> iced::Element<'_, crate::widget::Message> {
todo!()
}
fn has_window(&self, id: iced::window::Id) -> bool {
self.window == Some(id)
}
}