- Core user is logged in tty1 while user two is in tty3, you can now seamlessly switch bewteen them
New IPC options:
- `dms ipc call sessions list`
- `dms switch-user [target]`
- New Powermenu switch users option
Fixes#2354
Root cause (tray freeze): In clickThrough mode, the PanelWindow mask uses
sectionRect() with mapToItem() to compute input regions. After DPMS resume,
the PanelWindow is recreated with width=0, and mapToItem() returns wrong
positions. The right section's implicitWidth doesn't change after creation
(fixed-size tray icons), so the mask binding is never re-evaluated when the
compositor sets the actual screen width. Adding barWindow.width as a binding
dependency ensures the mask recalculates on resize.
Root cause (wallpaper loss): Wallpaper PanelWindows are recreated by Variants
during screen reconnection before the compositor finishes output initialization.
The wallpaper Image renders at 0x0 dimensions, resulting in a black screen.
Changes:
- DankBarWindow: add barWindow.width dependency to clickThrough mask bindings
- DMSShell: add surface recovery mechanism (screen reconnect + session resume)
with progressive 2-pass timer (800ms + 2800ms) that recreates bar, Frame,
wallpaper, and dock surfaces after the compositor is ready
- WlrOutputService: re-request output state on session resume
Pulses the WiFi and Bluetooth status icons while a connection is in
progress (lock screen, DankBar control center button, control center
compound pill). The pulse is implemented as a reusable Widgets/DankBlink
component, and the wifi-connecting condition is centralized as
NetworkService.isWifiConnecting.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(Spotlight): fix submenu keyboard navigation
* feat(Launcher/Spotlight): disable persisting last mode when changed by triggers
* feat(Launcher/Spotlight): add option to disable last mode being persisted
* fix(Launcher/Spotlight): fix context menu keys navigation
* fix(NiriOverviewOverlay): fix context menu keys navigation and position
Sort networks by signal bucket of 25 with SSID as tiebreaker so minor
RSSI fluctuations between scans no longer reshuffle the list while the
user is selecting a network.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- New Spotlight toggle to show/hide chips, off by default
- Updated blur effects on all launcher inputs and footers
- Fixed previous queries resurfacing
- Upated Spotlight keyboard navigation
- Added functionality to show and shortcut to keybinds from the Launcher tab
- Update to add DMS Action keys in Keyboard Shortcuts
- Defaulted in niri/hyprland includes file as `Alt+Space`
- New (IPC): `dms ipc call spotlight-bar toggle`
- Slight UI update to follow user radius
Some monitors, especially cheaper models, are slow to power on after sleep and may not be present in Quickshell.screens
when onScreensChanged is triggered. This change adds a 3-second delay before updating currentOSDsByScreen to ensure all
screens are detected, mitigating the issue of OSDs not appearing on certain monitors after resume.
Co-authored-by: Klesh Wong <kleshwong@gmail.com>
* networkd: classify links by Type instead of name prefix
The systemd-networkd backend decided wifi-vs-ethernet by checking
whether the interface name started with "wlan" or "wlp". Anything
else (that was not on a small virtual-prefix denylist) was treated
as wired ethernet. That misclassified two common cases:
* Nebula tunnels (kernel name like "nebula.homelab", Type=none,
Kind=tun) showed up as a wired ethernet device — DMS rendered an
"Ethernet connected" indicator whenever the overlay was up, even
with no physical NIC plugged in.
* Renamed wifi interfaces (e.g. systemd link files that rename
wlan0 to a friendlier name like "wifi") were also miscategorised
as ethernet, because they no longer matched wlan*/wlp*.
networkd already publishes the real link kind in the JSON returned
by the per-link Describe method ("ether", "wlan", "loopback",
"none"). Fetch it during enumerateLinks, cache it on linkInfo, and
classify against that. The old prefix logic is kept as a fallback
for the case where Describe ever fails to populate Type.
The package-level looksVirtual() helper replaces the unexported
isVirtualInterface method so the new classification helpers and
their tests can use it without needing a live backend.
Tests cover both the Type-based and fallback paths, including the
Nebula-shaped Type=none/tun case that motivated this change.
* networkd: cache linkType across signal ticks and unit-test Describe fallback
enumerateLinks runs on every PropertiesChanged signal under
/org/freedesktop/network1, which fires on carrier flap, DHCP renew, and
each address change. The previous version rebuilt every linkInfo from
scratch on each tick, including a synchronous Describe D-Bus round-trip
per link, despite the link Type being fixed at netlink creation. Preserve
existing entries when the D-Bus path matches, refreshing only ifindex,
and only call fetchLinkType on a genuinely new entry. A link torn down
and re-created at a different path still triggers a refetch.
Extract parseDescribeType from fetchLinkType so the JSON failure path —
malformed payload, missing Type field, wrong type for Type — can be
exercised without a live D-Bus connection. The classifier's fallback to
name-prefix heuristics already had coverage; this locks in that the seam
between Describe and the classifier surfaces an empty string on every
failure mode rather than misclassifying a link.
- Replaced fullscreen hide/reveal toggles with Show Over Fullscreen layer toggles
- Added Launcher opt to Show Over Fullscreen setting
- Kept fullscreen stacking compositor-owned via top/overlay layer choices
- Fixed Hyrland Special Workspaces
- Updated DMS Advanced Configuration docs
- Note: We do not convert your existing conf configs to lua. This update only reflects DMS defaults state
- Updated README.md to reflect changes
- Updated Keyboard shortcut support
Senders that play their own audio for a notification can set the
standard org.freedesktop.Notifications "suppress-sound" boolean hint
to ask the server not to double up. NotificationService skipped its
sound only as a side effect of the dedup early-return (when an
identically-keyed popup was still visible), so transient notifications
double-sounded while lingering ones didn't — nondeterministic. Read
notif.hints["suppress-sound"] and gate the AudioService call on it.
Fixed a visual bug where the install button would overflow its container after a plugin was installed. This was caused by the width not re-evaluating correctly and StyledText's default elide/wrap properties interfering with implicit width calculations.
* feat(settings): Added Default Apps page to settings
Added a new page to settings. This page relies on xdg-mime and gio, so their existence is checked to show the page.
This logic and the mime type stuff was added to DesktopService.qml.
Slightly reordered the settings sidebar to include an Applications category
* fix(settings): read xdg-terminals.list directly
read the file directly instead of using xdg-terminal-exec which might not be installed
* feat: add Display Profiles builtin control center widget
Adds a new built-in widget that lets users switch between their configured
display profiles directly from the Control Center, without opening Settings.
- Widget shows the active profile name and cycles profiles on pill click
- Detail panel shows all profiles as a button group for direct selection
- Integrates with existing DisplayConfigState/SettingsData singletons
- Follows the same loader/instance pattern as VPN, CUPS, and Tailscale widgets
* fix: refine display profiles widget behavior