* feat: add cycleProfile IPC command for display outputs
Adds `dms ipc outputs cycleProfile` which cycles through configured display
profiles in order, wrapping around from the last back to the first.
Useful for binding to a compositor keybind (e.g. Super+P in niri/Hyprland)
without needing an external wrapper script.
* feat: add Mod+P default keybind for cycling display profiles
Binds Super+P to `dms ipc outputs cycleProfile` in both the niri and
Hyprland default keybind configs. Mod+Shift+P is already reserved for
powering off monitors on both compositors, so Mod+P is a natural fit.
* fix: preserve pre-existing connection profiles on cancelled WiFi activation
When a pre-existing WiFi connection activation is cancelled, do not
remove the connection profile — only remove profiles for newly created
connections.
* feat: retrieve WiFi/VPN secrets from D-Bus secret service with unlock
Wireless, 802.1x, VPN, and WireGuard secrets are now looked up from
org.freedesktop.Secret before prompting the user. If the keyring is
locked, the unlock prompt is triggered via Prompt.Prompt() and the
lookup retried after the vault is unlocked.
* feat(tailscale): add Tailscale control center widget
Full-stack Tailscale integration for DMS control center:
Backend (Go):
- Event-driven manager via WatchIPNBus (no polling)
- Reconnects with exponential backoff when tailscaled unavailable
- Typed conversion from ipnstate.Status to QML-friendly IPC types
- Testable via tailscaleClient interface with mock watcher
- Manager cleanup in cleanupManagers()
- 19 unit tests
Frontend (QML):
- TailscaleService with WebSocket subscription
- TailscaleWidget with peer list, filter chips, search
- Copy-to-clipboard for IPs and DNS names
- Daemon lifecycle handling (offline/stopped states)
Dependencies:
- Add tailscale.com v1.96.1 (official local API client)
- Bump Go to 1.26.1 (required by tailscale.com)
* cleanups
---------
Co-authored-by: bbedward <bbedward@gmail.com>
- Introduces Standalone & Connected Modes
- Updated Animations & Motion effects for both modes
- Numerous QOL tweaks and updates throughout the system
- Highly inspired to the OG Caelestia Shell / @Soramanew
Move system update flow to GO, with a CLI (convenient AIO tool) and
server integration. All lifecycle, scheduling, execution occurs on
backend side.
Run some backends via pkexec, some via terminal like paru/yay.
Incorporate flatpak as an option to update.
Add terminal override setting in GUI, in addition to $TERMINAL env
variable.
fixes#2307fixes#822fixes#1102fixes#1812fixes#1087fixes#1743
The unconditional startup scan introduced duplicate tray icons on normal boot because apps were still registering their own SNI items when the scan ran.
Use CLOCK_BOOTTIME − CLOCK_MONOTONIC to detect whether the system has ever been suspended. The startup scan now only runs when the difference exceeds 5 s, meaning at least one suspend/resume cycle has occurred.
On a fresh boot the difference is ≈ 0 and the scan is skipped entirely.
* Fix ddc brightness not applying because process exits before debounce timer runs
* Added sync.WaitGroup to DDCBackend and use it instead of loop in wait logic, added timeout in case i2c hangs.
* go fmt
---------
Co-authored-by: bbedward <bbedward@gmail.com>
outputs
fixes#2199 , possibly regresses #1235 - but I think the original bug
was lastAppliedTemp being incorrectly set, this allows compositors to
cache last applied gamma
gamma: add a bunch of defensive mechanisms for output changes
related to #2197
gamma: ensure gamma is re-evaluate on resume
fixes#1036
* fix: add TrayRecoveryService with bidirectional SNI dedup (Go server)
Add TrayRecoveryService manager that re-registers lost tray icons after
resume from suspend via native DBus scanning in the Go server.
The service resolves every registered SNI item (both well-known names and
:1.xxx connection IDs) to a canonical connection ID, building a unified
registeredConnIDs set before either scan section runs. This prevents
duplicates in both directions:
- If an app registered via well-known name, the connection-ID section
skips its :1.xxx entry.
- If an app registered via connection ID, the well-known-name section
skips its well-known name (checked through registeredConnIDs).
- After successfully registering via well-known name, registeredConnIDs
is updated immediately so the connection-ID section won't probe the
same app in the same run.
A startup scan (3 s delay) covers the common case where the DMS process
is killed during suspend and restarted by systemd (Type=dbus), so the
loginctl PrepareForSleep watcher alone is not sufficient. The startup
scan is harmless on a normal boot — it finds all items already registered
and exits early.
Go port of quickshell commit 1470aa3.
* fix: 'interface{}' can be replaced by 'any'
* TrayRecoveryService: Remove objPath parameter from registerSNI