dbus: Take lid-inhibitor-locks on systemd systems

This commit is contained in:
Victoria Brekenfeld 2025-07-29 15:57:38 +02:00 committed by Victoria Brekenfeld
parent 8648d4450e
commit f2fc1e9480
5 changed files with 70 additions and 1 deletions

11
Cargo.lock generated
View file

@ -841,6 +841,7 @@ dependencies = [
"libdisplay-info",
"libsystemd",
"log-panics",
"logind-zbus",
"once_cell",
"ordered-float",
"parking_lot 0.12.3",
@ -3060,6 +3061,16 @@ dependencies = [
"log",
]
[[package]]
name = "logind-zbus"
version = "5.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "469c962578b549a82f3d0cc72d0f77d1123780fa7121e2b03d78b0780f6ccac6"
dependencies = [
"serde",
"zbus",
]
[[package]]
name = "loom"
version = "0.7.2"

View file

@ -66,6 +66,7 @@ reis = { version = "0.5", features = ["calloop"] }
# CLI arguments
clap_lex = "0.7"
parking_lot = "0.12.3"
logind-zbus = { version = "5.3.2", optional = true }
[dependencies.id_tree]
branch = "feature/copy_clone"
@ -100,7 +101,7 @@ optional = true
[features]
debug = ["egui", "egui_plot", "smithay-egui", "anyhow/backtrace"]
default = ["systemd"]
systemd = ["libsystemd"]
systemd = ["libsystemd", "logind-zbus"]
profile-with-tracy = ["profiling/profile-with-tracy", "tracy-client/default"]
[profile.dev.package.tiny-skia]

17
src/dbus/logind.rs Normal file
View file

@ -0,0 +1,17 @@
use std::os::fd::OwnedFd;
use logind_zbus::manager::{InhibitType::HandleLidSwitch, ManagerProxyBlocking};
use zbus::blocking::Connection;
pub fn inhibit_lid() -> anyhow::Result<OwnedFd> {
let conn = Connection::system()?;
let proxy = ManagerProxyBlocking::new(&conn)?;
let fd = proxy.inhibit(
HandleLidSwitch,
"cosmic-comp",
"External output connected",
"block",
)?;
Ok(fd.into())
}

View file

@ -4,6 +4,8 @@ use calloop::{InsertError, LoopHandle, RegistrationToken};
use std::collections::HashMap;
use zbus::blocking::{fdo::DBusProxy, Connection};
#[cfg(feature = "systemd")]
pub mod logind;
mod power;
pub fn init(evlh: &LoopHandle<'static, State>) -> Result<Vec<RegistrationToken>> {

View file

@ -112,6 +112,9 @@ use smithay::{
};
use time::UtcOffset;
#[cfg(feature = "systemd")]
use std::os::fd::OwnedFd;
use std::{
cell::RefCell,
cmp::min,
@ -249,6 +252,9 @@ pub struct Common {
pub atspi_state: AtspiState,
pub atspi_ei: crate::wayland::handlers::atspi::AtspiEiState,
#[cfg(feature = "systemd")]
inhibit_lid_fd: Option<OwnedFd>,
}
#[derive(Debug)]
@ -504,6 +510,7 @@ impl<'a> LockedBackend<'a> {
}
loop_handle.insert_idle(move |state| {
state.update_inhibitor_locks();
state.common.update_xwayland_scale();
state.common.update_xwayland_primary_output();
});
@ -707,6 +714,9 @@ impl State {
atspi_state,
atspi_ei: Default::default(),
#[cfg(feature = "systemd")]
inhibit_lid_fd: None,
},
backend: BackendData::Unset,
ready: Once::new(),
@ -726,6 +736,34 @@ impl State {
security_context: None,
}
}
fn update_inhibitor_locks(&mut self) {
#[cfg(feature = "systemd")]
{
use tracing::{debug, error};
let outputs = self.backend.lock().all_outputs();
let should_handle_lid = outputs.iter().any(|o| o.is_internal()) && outputs.len() >= 2;
if should_handle_lid {
if self.common.inhibit_lid_fd.is_none() {
match crate::dbus::logind::inhibit_lid() {
Ok(fd) => {
debug!("Inhibiting lid switch");
self.common.inhibit_lid_fd = Some(fd);
}
Err(err) => {
error!("Failed to inhibit lid switch: {}", err);
}
}
}
} else {
if self.common.inhibit_lid_fd.take().is_some() {
debug!("Removing inhibitor-lock on lid switch")
}
}
}
}
}
fn primary_scanout_output_compare<'a>(