Skip to content

Retire swayidle and move blanking policy into an internal inactivity engine #21

@Staphylococcus

Description

@Staphylococcus

This issue tracks the architectural follow-up to the GNOME idle-inhibition work originally discussed in #6.

Problem

LG Buddy still treats swayidle as a delegated runtime backend. That made sense in the historical shell-script implementation, but it is a poor fit for the Rust runtime and for the product boundary we actually want.

Today the architecture is still too event-plumbing-centric:

  • gnome.rs adapts GNOME session signals
  • swayidle is delegated as an external timeout/resume driver
  • session::runner effectively wires provider events straight into blank/unblank behavior

That is the wrong separation of concerns for LG Buddy.

LG Buddy's real product goal is not "follow the desktop's idle state". It is:

  • protect the OLED panel by blanking after inactivity
  • restore intelligently when activity resumes
  • react to machine/session lifecycle correctly on sleep/wake

Direction

Retire swayidle as a first-class runtime dependency and move to an architecture where:

  • backend adapters only observe and normalize provider events
  • an internal LG Buddy decision module owns blank/unblank policy
  • generic lifecycle events come from logind D-Bus
  • native idle/activity sources come from backend-specific integrations

Proposed separation of concerns

Generic lifecycle layer

A generic logind watcher should provide:

  • BeforeSleep
  • AfterResume
  • possibly Lock / Unlock

These are machine/session lifecycle concerns, not DE-specific idle concerns.

Backend adapter layer

Backend-specific modules should only translate provider signals into a common internal stream.

Examples:

  • gnome.rs
    • GNOME/Mutter activity, wake, and other session observations
  • future wayland_idle.rs
    • native Wayland idle/activity integration, likely via ext-idle-notify

These modules should report facts, not policy.

Internal decision module

LG Buddy should own a dedicated inactivity/panel-protection engine that decides:

  • when inactivity has crossed the blanking threshold
  • when a blank action should fire
  • when restore should fire
  • which signals affect panel protection vs richer restore semantics
  • how marker ownership interacts with restore policy

This module should consume normalized observations such as:

  • activity observed
  • wake requested
  • before sleep
  • after resume

and produce explicit actions such as:

  • blank now
  • restore now
  • no-op

Why this matters

The original GNOME idle-inhibition issue exposed that desktop-assigned idle state is not always a good proxy for panel protection. GNOME idle inhibitors can suppress the idle transition entirely, which means LG Buddy never blanks the screen even though the user is effectively inactive and the OLED is left exposed to static UI.

That suggests blanking must be driven by LG Buddy-owned inactivity policy using system/compositor-provided activity monitoring, not by blindly following a DE's high-level idle assignment.

Migration goals

  • stop treating swayidle as the architectural model for non-GNOME sessions
  • move toward native runtime integration instead of delegated shell-style supervision
  • keep provider-specific richness where useful (WakeRequested, early activity, etc.)
  • make blanking policy a core LG Buddy concern rather than an accidental property of backend wiring

Rough target shape

  • logind.rs: generic D-Bus lifecycle watcher
  • gnome.rs: GNOME/Mutter event adapter
  • wayland_idle.rs: native Wayland idle/activity adapter
  • inactivity.rs (or similar): LG Buddy-owned decision module
  • session::runner: integration/wiring layer only

Out of scope for this issue

This issue is about setting the architecture and separation of concerns that future backend work should follow.


Migrated from #7 before repository ownership transfer.
Original issue: #7
Original author: @Staphylococcus
Original created: 2026-04-15T19:44:19Z
Original comments at migration time: none.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions