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://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)]
|
#[derive(Debug)]
|
||||||
struct Inhibitor {
|
struct Inhibitor {
|
||||||
|
cookie: u32,
|
||||||
application_name: String,
|
application_name: String,
|
||||||
reason_for_inhibit: String,
|
reason_for_inhibit: String,
|
||||||
client: zbus::names::UniqueName<'static>,
|
client: zbus::names::UniqueName<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct Screensaver {
|
pub struct Screensaver {
|
||||||
inhibitors: HashMap<u32, Inhibitor>,
|
inhibitors: Arc<Mutex<Vec<Inhibitor>>>,
|
||||||
last_cookie: u32,
|
last_cookie: AtomicU32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[zbus::interface(name = "org.freedesktop.ScreenSaver")]
|
#[zbus::interface(name = "org.freedesktop.ScreenSaver")]
|
||||||
|
|
@ -23,33 +28,57 @@ impl Screensaver {
|
||||||
reason_for_inhibit: String,
|
reason_for_inhibit: String,
|
||||||
#[zbus(header)] header: zbus::message::Header<'_>,
|
#[zbus(header)] header: zbus::message::Header<'_>,
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
self.last_cookie += 1;
|
let cookie = self.last_cookie.fetch_add(1, Ordering::Relaxed) + 1;
|
||||||
if let Some(sender) = header.sender() {
|
if let Some(sender) = header.sender() {
|
||||||
self.inhibitors.insert(
|
self.inhibitors.lock().unwrap().push(Inhibitor {
|
||||||
self.last_cookie,
|
cookie,
|
||||||
Inhibitor {
|
application_name,
|
||||||
application_name,
|
reason_for_inhibit,
|
||||||
reason_for_inhibit,
|
client: sender.to_owned(),
|
||||||
client: sender.to_owned(),
|
});
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
self.last_cookie
|
cookie
|
||||||
}
|
}
|
||||||
|
|
||||||
fn un_inhibit(&mut self, cookie: u32) {
|
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<()> {
|
pub async fn serve(conn: &zbus::Connection) -> zbus::Result<()> {
|
||||||
|
let inhibitors = Arc::new(Mutex::new(Vec::new()));
|
||||||
|
|
||||||
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(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
conn.object_server()
|
conn.object_server()
|
||||||
.at("/org/freedesktop/ScreenSaver", Screensaver::default())
|
.at(
|
||||||
|
"/org/freedesktop/ScreenSaver",
|
||||||
|
Screensaver {
|
||||||
|
inhibitors: inhibitors.clone(),
|
||||||
|
last_cookie: AtomicU32::new(0),
|
||||||
|
},
|
||||||
|
)
|
||||||
.await?;
|
.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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -338,7 +338,6 @@ fn main() {
|
||||||
if let Err(err) = freedesktop_screensaver::serve(&connection).await {
|
if let Err(err) = freedesktop_screensaver::serve(&connection).await {
|
||||||
log::error!("failed to serve FreeDesktop screensaver interface: {}", err);
|
log::error!("failed to serve FreeDesktop screensaver interface: {}", err);
|
||||||
}
|
}
|
||||||
std::future::pending::<()>().await;
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue