Published at Oct 11, 2025
macOS users have long relied on the built-in caffeinate command to keep their screens awake when needed. Lately, I’ve been exploring System76’s COSMIC Desktop, and despite some user interface concerns, I’ve found it mostly pleasant to use. Various desktop environments have widgets that replicate this screen-wake functionality, and I wanted the same capability in COSMIC. That’s why I built a native desktop applet for it. By reading this article, hopefully you’ll gain deeper insight into how desktop Linux operates behind the scenes.
D-Bus is an inter-process communication (IPC) framework that enables different
programs on the same machine to exchange information with one another. It’s
particularly prevalent in Linux and Unix-like systems, offering a uniform
protocol for applications and system services to transmit messages, exchange
data, and synchronize their operations. Prior to developing this applet, I was
always intrigued by these “D-Bus” references that kept appearing in my
journalctl
logs and error messages. My basic interpretation was that it
functions as a message broker, similar to RabbitMQ or MQTT, but specifically
designed for Linux desktop environments. Not surprisingly, your desktop
environment has a role in managing your computer’s sleep and wake cycles, and
most desktop environments provide standard D-Bus interfaces that third-party
applications can utilize. Those interfaces are standardized by Freedesktop.org.
Specifically, many contemporary desktop environments implement
org.freedesktop.ScreenSaver
, which lets you prevent the screensaver from
activating (and thus prevent the system from sleeping).
org.freedesktop.ScreenSaver
offers
two virtual methods:
Inhibit
and UnInhibit
. To stop your computer from entering sleep mode, your
application invokes the inhibit method, which returns a 32-bit integer—referred
to as a cookie from your desktop environment. You retain this cookie, and when
you’re ready to allow the screensaver to activate again, you pass that same
cookie to the UnInhibit
method.
Given that COSMIC desktop is built with Rust and relies on libcosmic
as its
GUI framework, COSMIC applets are designed to use this same library. The most
practical crate available is zbus
, which
includes a procedural macro that streamlines the implementation of calling code.
You simply define the method signatures within a trait, and the proc-macro
handles the trait implementation.
#[proxy(
interface = "org.freedesktop.ScreenSaver",
default_service = "org.freedesktop.ScreenSaver",
default_path = "/ScreenSaver"
)]
trait ScreenSaver {
/// Inhibit the screensaver
fn inhibit(&self, application_name: &str, reason: &str) -> Result<u32>;
/// Uninhibit the screensaver using the cookie from a previous inhibit call
fn un_inhibit(&self, cookie: u32) -> Result<()>;
}
Keep in mind that an asynchronous variant of this API exists as well, though since these virtual interface method calls execute immediately, it’s typically unnecessary.
This generates a ScreenSaverProxyBlocking
struct, which we instantiate like
so:
let conn = Connection::session()?;
let proxy = ScreenSaverProxyBlocking::new(&conn)?;
Then we invoke its methods:
// inhibit screensaver
let cookie = proxy.inhibit(
env!("CARGO_PKG_NAME"),
concat!("Inhibited via ", env!("CARGO_PKG_NAME")),
)?;
// un-inhibit screensaver
proxy.un_inhibit(cookie)?;
That’s all there is to it! It’s remarkably straightforward. Whenever you need to modify your Linux desktop’s behavior, explore D-Bus to see what methods are available for your use.