Use Event for screensaver inhibit state

This commit is contained in:
Ian Douglas Scott 2024-10-28 18:12:24 -07:00
parent 97d88fa111
commit 7a3004bc0d
2 changed files with 34 additions and 24 deletions

View file

@ -7,6 +7,8 @@ use std::sync::{
Arc, Mutex, Arc, Mutex,
}; };
use crate::{Event, EventSender};
#[derive(Debug)] #[derive(Debug)]
pub struct Inhibitor { pub struct Inhibitor {
cookie: u32, cookie: u32,
@ -18,6 +20,7 @@ pub struct Inhibitor {
pub struct Screensaver { pub struct Screensaver {
inhibitors: Arc<Mutex<Vec<Inhibitor>>>, inhibitors: Arc<Mutex<Vec<Inhibitor>>>,
last_cookie: AtomicU32, last_cookie: AtomicU32,
event_sender: EventSender,
} }
#[zbus::interface(name = "org.freedesktop.ScreenSaver")] #[zbus::interface(name = "org.freedesktop.ScreenSaver")]
@ -37,7 +40,11 @@ impl Screensaver {
reason_for_inhibit, reason_for_inhibit,
cookie cookie
); );
self.inhibitors.lock().unwrap().push(Inhibitor { let mut inhibitors = self.inhibitors.lock().unwrap();
if inhibitors.is_empty() {
let _ = self.event_sender.send(Event::ScreensaverInhibit(false));
}
inhibitors.push(Inhibitor {
cookie, cookie,
application_name, application_name,
reason_for_inhibit, reason_for_inhibit,
@ -62,10 +69,9 @@ impl Screensaver {
} }
} }
pub async fn serve( pub async fn serve(conn: &zbus::Connection, event_sender: EventSender) -> zbus::Result<()> {
conn: &zbus::Connection, let inhibitors = Arc::new(Mutex::new(Vec::new()));
inhibitors: Arc<Mutex<Vec<Inhibitor>>>,
) -> zbus::Result<()> {
conn.request_name_with_flags( conn.request_name_with_flags(
"org.freedesktop.ScreenSaver", "org.freedesktop.ScreenSaver",
zbus::fdo::RequestNameFlags::ReplaceExisting.into(), zbus::fdo::RequestNameFlags::ReplaceExisting.into(),
@ -76,6 +82,7 @@ pub async fn serve(
"/org/freedesktop/ScreenSaver", "/org/freedesktop/ScreenSaver",
Screensaver { Screensaver {
inhibitors: inhibitors.clone(), inhibitors: inhibitors.clone(),
event_sender: event_sender.clone(),
last_cookie: AtomicU32::new(0), last_cookie: AtomicU32::new(0),
}, },
) )
@ -87,10 +94,13 @@ pub async fn serve(
let args = event.args()?; let args = event.args()?;
if args.new_owner.is_none() { if args.new_owner.is_none() {
if let zbus::names::BusName::Unique(name) = args.name { if let zbus::names::BusName::Unique(name) = args.name {
inhibitors let mut inhibitors = inhibitors.lock().unwrap();
.lock() if !inhibitors.is_empty() {
.unwrap() inhibitors.retain(|inhibitor| inhibitor.client != name);
.retain(|inhibitor| inhibitor.client != name); if inhibitors.is_empty() {
let _ = event_sender.send(Event::ScreensaverInhibit(false));
}
}
} }
} }
} }

View file

@ -5,10 +5,7 @@ use calloop_wayland_source::WaylandSource;
use cosmic_config::{calloop::ConfigWatchSource, CosmicConfigEntry}; use cosmic_config::{calloop::ConfigWatchSource, CosmicConfigEntry};
use cosmic_idle_config::CosmicIdleConfig; use cosmic_idle_config::CosmicIdleConfig;
use futures_lite::stream::StreamExt; use futures_lite::stream::StreamExt;
use std::{ use std::process::Command;
process::Command,
sync::{Arc, Mutex},
};
use upower_dbus::UPowerProxy; use upower_dbus::UPowerProxy;
use wayland_client::{ use wayland_client::{
delegate_noop, delegate_noop,
@ -35,8 +32,11 @@ mod freedesktop_screensaver;
#[derive(Debug)] #[derive(Debug)]
enum Event { enum Event {
OnBattery(bool), OnBattery(bool),
ScreensaverInhibit(bool),
} }
type EventSender = channel::Sender<Event>;
struct IdleNotification { struct IdleNotification {
notification: ext_idle_notification_v1::ExtIdleNotificationV1, notification: ext_idle_notification_v1::ExtIdleNotificationV1,
time: u32, time: u32,
@ -58,7 +58,7 @@ impl Drop for IdleNotification {
} }
} }
async fn receive_battery_task(sender: channel::Sender<Event>) -> zbus::Result<()> { async fn receive_battery_task(sender: EventSender) -> zbus::Result<()> {
let connection = zbus::Connection::system().await?; let connection = zbus::Connection::system().await?;
let upower = UPowerProxy::new(&connection).await?; let upower = UPowerProxy::new(&connection).await?;
let mut stream = upower.receive_on_battery_changed().await; let mut stream = upower.receive_on_battery_changed().await;
@ -95,12 +95,12 @@ struct State {
screen_off_idle_notification: Option<IdleNotification>, screen_off_idle_notification: Option<IdleNotification>,
suspend_idle_notification: Option<IdleNotification>, suspend_idle_notification: Option<IdleNotification>,
on_battery: bool, on_battery: bool,
screensaver_inhibitors: Arc<Mutex<Vec<freedesktop_screensaver::Inhibitor>>>, screensaver_inhibit: bool,
} }
impl State { impl State {
fn update_screen_off_idle(&mut self, is_idle: bool) { fn update_screen_off_idle(&mut self, is_idle: bool) {
if !self.screensaver_inhibitors.lock().unwrap().is_empty() { if self.screensaver_inhibit {
return; return;
} }
for output in &mut self.outputs { for output in &mut self.outputs {
@ -114,7 +114,7 @@ impl State {
} }
fn update_suspend_idle(&mut self, is_idle: bool) { fn update_suspend_idle(&mut self, is_idle: bool) {
if !self.screensaver_inhibitors.lock().unwrap().is_empty() { if self.screensaver_inhibit {
return; return;
} }
if is_idle { if is_idle {
@ -154,6 +154,9 @@ impl State {
Event::OnBattery(value) => { Event::OnBattery(value) => {
self.on_battery = value; self.on_battery = value;
} }
Event::ScreensaverInhibit(value) => {
self.screensaver_inhibit = value;
}
} }
} }
} }
@ -224,8 +227,6 @@ fn main() {
conf conf
}); });
let screensaver_inhibitors = Arc::new(Mutex::new(Vec::new()));
let mut state = State { let mut state = State {
inner: StateInner { inner: StateInner {
compositor, compositor,
@ -242,7 +243,7 @@ fn main() {
outputs, outputs,
conf, conf,
on_battery: false, on_battery: false,
screensaver_inhibitors: screensaver_inhibitors.clone(), screensaver_inhibit: false,
}; };
state.recreate_notification(); state.recreate_notification();
@ -264,9 +265,10 @@ fn main() {
let (executor, scheduler) = calloop::futures::executor().unwrap(); let (executor, scheduler) = calloop::futures::executor().unwrap();
let (sender, receiver) = channel::channel(); let (sender, receiver) = channel::channel();
let sender_clone = sender.clone();
scheduler scheduler
.schedule(async move { .schedule(async move {
if let Err(err) = receive_battery_task(sender).await { if let Err(err) = receive_battery_task(sender_clone).await {
log::error!("Getting battery status from upower: {}", err); log::error!("Getting battery status from upower: {}", err);
} }
}) })
@ -274,9 +276,7 @@ fn main() {
scheduler scheduler
.schedule(async move { .schedule(async move {
if let Ok(connection) = zbus::Connection::session().await { if let Ok(connection) = zbus::Connection::session().await {
if let Err(err) = if let Err(err) = freedesktop_screensaver::serve(&connection, sender).await {
freedesktop_screensaver::serve(&connection, screensaver_inhibitors).await
{
log::error!("failed to serve FreeDesktop screensaver interface: {}", err); log::error!("failed to serve FreeDesktop screensaver interface: {}", err);
} }
} }