From 3789f5eb7ba46fd53d103b6d759dc04f55013844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Maxmili=C3=A1n=20St=C5=99=C3=ADbrn=C3=BD?= Date: Fri, 20 Mar 2026 22:46:21 +0100 Subject: [PATCH] power button implemented (without the power button functionality) --- src/app.rs | 5 ++- src/widget.rs | 5 ++- src/widgets/mod.rs | 1 + src/widgets/powerbutton.rs | 90 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 src/widgets/powerbutton.rs diff --git a/src/app.rs b/src/app.rs index 4cd19af..12a8041 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,6 +1,7 @@ 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; @@ -20,6 +21,8 @@ impl App { 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()), ], } @@ -33,7 +36,7 @@ impl App { if let Some(elem) = self .widgets .iter() - .find(|widget| widget.own_window(id)) + .find(|widget| widget.has_window(id)) .map(|widget| widget.view(id)) { return elem; diff --git a/src/widget.rs b/src/widget.rs index 5c28854..17beceb 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -3,11 +3,13 @@ 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; fn subscribe(&self) -> Subscription; fn view(&self, id: iced::window::Id) -> Element<'_, Message>; - fn own_window(&self, _id: iced::window::Id) -> bool { + fn has_window(&self, _id: iced::window::Id) -> bool { false } } @@ -17,4 +19,5 @@ pub trait PanelWidget { pub enum Message { Battery(Option), Time, + ShutdownEvent(ShutdownEvents), } diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs index b847546..22184f7 100644 --- a/src/widgets/mod.rs +++ b/src/widgets/mod.rs @@ -1,3 +1,4 @@ pub mod battery; pub mod clock; +pub mod powerbutton; pub mod spacer; diff --git a/src/widgets/powerbutton.rs b/src/widgets/powerbutton.rs new file mode 100644 index 0000000..841d5c3 --- /dev/null +++ b/src/widgets/powerbutton.rs @@ -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, +} + +#[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 { + 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 { + 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(), + } + } +}