Remove screensaver inhibitors for disconnected clients
This commit is contained in:
parent
bd5487331d
commit
1cdce673df
2 changed files with 45 additions and 17 deletions
|
|
@ -1,18 +1,23 @@
|
|||
// https://specifications.freedesktop.org/idle-inhibit-spec/latest
|
||||
// https://invent.kde.org/plasma/kscreenlocker/-/blob/master/dbus/org.freedesktop.ScreenSaver.xml
|
||||
|
||||
use std::collections::HashMap;
|
||||
use futures_lite::StreamExt;
|
||||
use std::sync::{
|
||||
atomic::{AtomicU32, Ordering},
|
||||
Arc, Mutex,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Inhibitor {
|
||||
cookie: u32,
|
||||
application_name: String,
|
||||
reason_for_inhibit: String,
|
||||
client: zbus::names::UniqueName<'static>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Screensaver {
|
||||
inhibitors: HashMap<u32, Inhibitor>,
|
||||
last_cookie: u32,
|
||||
inhibitors: Arc<Mutex<Vec<Inhibitor>>>,
|
||||
last_cookie: AtomicU32,
|
||||
}
|
||||
|
||||
#[zbus::interface(name = "org.freedesktop.ScreenSaver")]
|
||||
|
|
@ -23,33 +28,57 @@ impl Screensaver {
|
|||
reason_for_inhibit: String,
|
||||
#[zbus(header)] header: zbus::message::Header<'_>,
|
||||
) -> u32 {
|
||||
self.last_cookie += 1;
|
||||
let cookie = self.last_cookie.fetch_add(1, Ordering::Relaxed) + 1;
|
||||
if let Some(sender) = header.sender() {
|
||||
self.inhibitors.insert(
|
||||
self.last_cookie,
|
||||
Inhibitor {
|
||||
application_name,
|
||||
reason_for_inhibit,
|
||||
client: sender.to_owned(),
|
||||
},
|
||||
);
|
||||
self.inhibitors.lock().unwrap().push(Inhibitor {
|
||||
cookie,
|
||||
application_name,
|
||||
reason_for_inhibit,
|
||||
client: sender.to_owned(),
|
||||
});
|
||||
}
|
||||
self.last_cookie
|
||||
cookie
|
||||
}
|
||||
|
||||
fn un_inhibit(&mut self, cookie: u32) {
|
||||
self.inhibitors.remove(&cookie);
|
||||
let mut inhibitors = self.inhibitors.lock().unwrap();
|
||||
if let Some(idx) = inhibitors.iter().position(|x| x.cookie == cookie) {
|
||||
inhibitors.remove(idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn serve(conn: &zbus::Connection) -> zbus::Result<()> {
|
||||
let inhibitors = Arc::new(Mutex::new(Vec::new()));
|
||||
|
||||
conn.request_name_with_flags(
|
||||
"org.freedesktop.ScreenSaver",
|
||||
zbus::fdo::RequestNameFlags::ReplaceExisting.into(),
|
||||
)
|
||||
.await?;
|
||||
conn.object_server()
|
||||
.at("/org/freedesktop/ScreenSaver", Screensaver::default())
|
||||
.at(
|
||||
"/org/freedesktop/ScreenSaver",
|
||||
Screensaver {
|
||||
inhibitors: inhibitors.clone(),
|
||||
last_cookie: AtomicU32::new(0),
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
let dbus = zbus::fdo::DBusProxy::new(conn).await?;
|
||||
let mut name_owner_stream = dbus.receive_name_owner_changed().await?;
|
||||
while let Some(event) = name_owner_stream.next().await {
|
||||
let args = event.args()?;
|
||||
if args.new_owner.is_none() {
|
||||
if let zbus::names::BusName::Unique(name) = args.name {
|
||||
inhibitors
|
||||
.lock()
|
||||
.unwrap()
|
||||
.retain(|inhibitor| inhibitor.client != name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -338,7 +338,6 @@ fn main() {
|
|||
if let Err(err) = freedesktop_screensaver::serve(&connection).await {
|
||||
log::error!("failed to serve FreeDesktop screensaver interface: {}", err);
|
||||
}
|
||||
std::future::pending::<()>().await;
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue