From 58166358ba26a277d59fafd852ca7b10f1dbd442 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: Tue, 17 Mar 2026 22:59:43 +0100 Subject: [PATCH] poweroff popup --- src/main.rs | 103 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 91 insertions(+), 12 deletions(-) diff --git a/src/main.rs b/src/main.rs index d106a32..6a2f76f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,21 @@ use iced::Color; use iced::Element; use iced::Task; +use iced::widget::button; use iced::widget::container; use iced::widget::row; use iced::widget::text; use iced_layershell::daemon; use iced_layershell::reexport::Anchor; +use iced_layershell::reexport::NewLayerShellSettings; use iced_layershell::settings::LayerShellSettings; use iced_layershell::settings::Settings; use iced_layershell::to_layer_message; +use std::collections::HashMap; use std::time::Duration; pub fn main() -> Result<(), iced_layershell::Error> { - daemon(App::default, || "rbaw".into(), App::update, App::view) + daemon(App::default, App::name, App::update, App::view) .style(App::style) .theme(App::theme) .subscription(App::subscription) @@ -30,13 +33,21 @@ pub fn main() -> Result<(), iced_layershell::Error> { } struct App { + popups: HashMap, + power_off_widget: PowerOffWidget, time_widget: TimeWidget, battery_widget: BatteryWidget, } +enum PopupKind { + PowerOff, +} + impl Default for App { fn default() -> Self { let mut output = Self { + popups: HashMap::new(), + power_off_widget: PowerOffWidget(None), time_widget: Default::default(), battery_widget: Default::default(), }; @@ -47,10 +58,38 @@ impl Default for App { } impl App { - fn view(&self, _id: iced::window::Id) -> Element<'_, Message> { + fn name() -> String { + "wayland_panel".into() + } + + fn close_popup(&mut self, id: iced::window::Id) -> Task { + self.popups.remove(&id); + return Task::done(Message::RemoveWindow(id)); + } + + fn view(&self, id: iced::window::Id) -> Element<'_, Message> { + if let Some(kind) = self.popups.get(&id) { + return match kind { + PopupKind::PowerOff => container( + row![ + text("Shut down?"), + button("✓").on_press(Message::PowerOffConfirm), + button("✗").on_press(Message::PowerOffCancel), + ] + .spacing(8) + .align_y(iced::Alignment::Center), + ) + .center(iced::Length::Fill) + .into(), + }; + } + + // default: the bar let content = row![ self.time_widget.view(), iced::widget::space().width(iced::Length::Fill), + self.power_off_widget.view(), + iced::widget::space().width(iced::Length::Fill), self.battery_widget.view(), ] .padding(iced::Padding::from([0, 5])) @@ -62,12 +101,39 @@ impl App { } fn update(&mut self, message: Message) -> Task { - if let Message::Clock = message { - self.time_widget.update(); - self.battery_widget.update(); - } + match message { + Message::Clock => { + self.time_widget.update(); + self.battery_widget.update(); - Task::none() + Task::none() + } + Message::PowerOff => { + let id = iced::window::Id::unique(); + self.popups.insert(id, PopupKind::PowerOff); + + self.power_off_widget.0 = 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, + }) + } + Message::PowerOffConfirm => { + std::process::Command::new("poweroff").spawn().ok(); + Task::none() + } + Message::PowerOffCancel => self.close_popup(self.power_off_widget.0.unwrap()), + _ => Task::none(), + } } fn style(&self, theme: &iced::Theme) -> iced::theme::Style { @@ -160,9 +226,22 @@ impl PanelWidget for TimeWidget { } } -#[to_layer_message] -#[derive(Debug)] -enum Message { - IcedEvent(iced::Event), - Clock, +#[derive(Default)] +struct PowerOffWidget(Option); + +impl PanelWidget for PowerOffWidget { + fn update(&mut self) {} + + fn view(&self) -> Element<'_, Message> { + button("⏻").on_press(Message::PowerOff).into() + } +} + +#[to_layer_message(multi)] +#[derive(Debug, Clone)] +pub enum Message { + Clock, + PowerOff, + PowerOffConfirm, + PowerOffCancel, }