poweroff popup

This commit is contained in:
Jiří Maxmilián Stříbrný 2026-03-17 22:59:43 +01:00
parent e857dd93cc
commit 58166358ba

View file

@ -1,18 +1,21 @@
use iced::Color; use iced::Color;
use iced::Element; use iced::Element;
use iced::Task; use iced::Task;
use iced::widget::button;
use iced::widget::container; use iced::widget::container;
use iced::widget::row; use iced::widget::row;
use iced::widget::text; use iced::widget::text;
use iced_layershell::daemon; use iced_layershell::daemon;
use iced_layershell::reexport::Anchor; use iced_layershell::reexport::Anchor;
use iced_layershell::reexport::NewLayerShellSettings;
use iced_layershell::settings::LayerShellSettings; use iced_layershell::settings::LayerShellSettings;
use iced_layershell::settings::Settings; use iced_layershell::settings::Settings;
use iced_layershell::to_layer_message; use iced_layershell::to_layer_message;
use std::collections::HashMap;
use std::time::Duration; use std::time::Duration;
pub fn main() -> Result<(), iced_layershell::Error> { 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) .style(App::style)
.theme(App::theme) .theme(App::theme)
.subscription(App::subscription) .subscription(App::subscription)
@ -30,13 +33,21 @@ pub fn main() -> Result<(), iced_layershell::Error> {
} }
struct App { struct App {
popups: HashMap<iced::window::Id, PopupKind>,
power_off_widget: PowerOffWidget,
time_widget: TimeWidget, time_widget: TimeWidget,
battery_widget: BatteryWidget, battery_widget: BatteryWidget,
} }
enum PopupKind {
PowerOff,
}
impl Default for App { impl Default for App {
fn default() -> Self { fn default() -> Self {
let mut output = Self { let mut output = Self {
popups: HashMap::new(),
power_off_widget: PowerOffWidget(None),
time_widget: Default::default(), time_widget: Default::default(),
battery_widget: Default::default(), battery_widget: Default::default(),
}; };
@ -47,10 +58,38 @@ impl Default for App {
} }
impl 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<Message> {
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![ let content = row![
self.time_widget.view(), self.time_widget.view(),
iced::widget::space().width(iced::Length::Fill), iced::widget::space().width(iced::Length::Fill),
self.power_off_widget.view(),
iced::widget::space().width(iced::Length::Fill),
self.battery_widget.view(), self.battery_widget.view(),
] ]
.padding(iced::Padding::from([0, 5])) .padding(iced::Padding::from([0, 5]))
@ -62,12 +101,39 @@ impl App {
} }
fn update(&mut self, message: Message) -> Task<Message> { fn update(&mut self, message: Message) -> Task<Message> {
if let Message::Clock = message { match message {
self.time_widget.update(); Message::Clock => {
self.battery_widget.update(); 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 { fn style(&self, theme: &iced::Theme) -> iced::theme::Style {
@ -160,9 +226,22 @@ impl PanelWidget for TimeWidget {
} }
} }
#[to_layer_message] #[derive(Default)]
#[derive(Debug)] struct PowerOffWidget(Option<iced::window::Id>);
enum Message {
IcedEvent(iced::Event), impl PanelWidget for PowerOffWidget {
Clock, 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,
} }