Skip to content

Would you take PRs for persistent screen-share permission, suspend/resume handling, and some bugfixes? #17

Description

@d1ggs

Hi, I've been running a fork (d1ggs/lumux) with a few changes I think belong upstream. Before opening PRs I wanted to check what you'd actually want. Everything below is tested on my setup (GNOME on Debian 13, bridge + gradient lightstrip) and has unit tests.

Full disclosure before anything else: I developed this with heavy use of AI tooling (Claude Code). I directed the work, reviewed the changes, and verified everything live on my hardware, but most of the code was AI-written. If this project doesn't accept AI-assisted contributions, that's completely fine, feel free to close this issue. In that case treat the notes below as bug reports, since the underlying issues exist regardless of how I fixed them.

1. Stop the monitor picker from appearing on every launch

Lumux requests the ScreenCast portal session without persistence, so the "share which monitor?" dialog shows up on every start. This is especially annoying with autostart. The portal already supports remembering the grant: pass persist_mode: 2 in SelectSources, store the restore_token that Start returns, and send it back next time. Two details I ran into while implementing it:

  • If the stored token is malformed, SelectSources raises InvalidArgument instead of falling back to the picker (the spec only promises graceful fallback for well-formed tokens that can't be restored), so there is a retry path that clears the token.
  • Persisting the token exposed a race in SettingsManager.save(), which is now atomic (tempfile + os.replace) and holds a lock.

2. Lights off on suspend, sync resumes on wake

Subscribes to logind's PrepareForSleep with a delay inhibitor, turns the lights off when the machine sleeps, and restarts video sync after wake. Getting the lights off reliably was harder than expected: NetworkManager reacts to the same signal and takes the network down within about 150ms, so REST calls from the sleep handler never arrive. What works is streaming black frames over the already-open DTLS socket immediately (within the first ~40ms), since the bridge keeps a lamp at its last streamed color once the session times out during sleep. The REST teardown still runs afterwards as best effort. I went through six suspend/test cycles before landing on this; the dead ends are in the commit history if you want the details.

Two things to consider: it needs --system-talk-name=org.freedesktop.login1 in the manifest (Flathub manifest too), and I could only test on GNOME/systemd/NetworkManager with a single entertainment area. Could go behind a setting if you'd rather.

3. Independent bugfixes

  • A pending reading-mode auto-activation timer can survive turn_off() and re-light the lamps about a second later. The current_mode != OFF guard in _finish_switch_to_reading doesn't catch this case because turn_off() leaves the mode as OFF.
  • bridge_client swallows all failures (except BridgeError: return False), which made the suspend work very hard to debug. Added logging and optional per-call timeouts.
  • channel.members[].service.rid in the entertainment config are entertainment service ids, not light ids. Added a resolve_light_ids() helper that pairs them through each device's services list, same technique as _refresh_spatial_data.
  • The sync button label goes stale when the mode changes through anything other than a button click. Now driven by the mode-changed callback.

Let me know which of these you'd take and in what shape, and I'll open the PRs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions