* fix(processlist): stop polling when the popout is closed
The popout's content loader deliberately stays warm across close so
re-opening is instant, and PopoutService only defers the actual unload
until session lock or monitors-off. But both DgopService references were
bound to component lifetime rather than presentation, so after closing
the popout refCount stayed above zero: dgop kept sampling the full
process list every 3s until the shell restarted or the session was
locked and unlocked.
Gate both references on shouldBeVisible instead. Ref grows an `active`
property (defaulting to true, so every other call site is unchanged) and
ProcessesView grows an `active` property that hosts keeping it loaded
while hidden can drive. ProcessListModal is unaffected — its tab loaders
already destroy the view when the window hides.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01GTGf29PYTp1kpAv5HNHBzM
* Update quickshell/Modules/ProcessList/ProcessListPopout.qml
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
Co-authored-by: BB <[email protected]>
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
The idle inhibitor ("Keep Awake") lives only in memory: SessionService holds it
as a plain `property bool idleInhibited: false` and nothing ever writes it out.
Every restart of the shell silently clears it — the user's explicit choice is
dropped with no message and no trace, and the pill just disappears from the bar.
Restarting is not an edge case. `dms restart` is a first-class CLI command, and
the unit shipped in this repo (assets/systemd/dms.service) sets
`Restart=on-failure` with `TimeoutStopSec=10`, so a shell that is slow to stop
is killed and brought back automatically. Each of those paths turns Keep Awake
off without saying so.
Every other Control Center toggle already survives a restart. Measured on
upstream master, over the state read by Modules/ControlCenter/Components/
DragDropGrid.qml and its neighbours:
doNotDisturb in SessionSpec: yes
isLightMode in SessionSpec: yes
nightModeEnabled in SessionSpec: yes
wallpaperCyclingEnabled in SessionSpec: yes
idleInhibited in SessionSpec: NO
So this follows the doNotDisturb idiom exactly rather than inventing a
mechanism: one spec entry, one property, one setter that saves.
Restore happens through two entry points because the singletons are lazily
created and their order is not fixed: `onLoaded` covers "service instantiated
before the session file is read", `Component.onCompleted` covers the opposite.
enableIdleInhibit() is idempotent, so whichever runs second is a no-op.
The default stays false and SessionStore.toJson omits defaults, so an untouched
session.json gains no new key.
Related: #1483 asks for a configurable timer. The field added here is the same
shape doNotDisturb uses with doNotDisturbUntil, so a later `idleInhibitedUntil`
slots in beside it without another migration.
Co-authored-by: Mark2Mac <[email protected]>
* feat(theme): support qtengine as a Qt platform theme
qtengine is a single platform theme plugin serving both Qt5 and Qt6 from one JSON config, so it needs neither the qt5ct/qt6ct split nor qt6ct-kde.
It reads a KDE .colors scheme by path, which the kcolorscheme template already generates, so no new matugen template is required.
DMS now merges theme.colorScheme and theme.iconTheme into $XDG_CONFIG_HOME/qtengine/config.json after each generate, on icon theme changes, and from Apply Qt Colors.
The merge preserves every other key,refuses to touch a config it cannot parse, and only names a color scheme that exists.
The write is atomic, and its mtime bump is what trips qtengine's watcher and repaints running apps.
QT_QPA_PLATFORMTHEME=qtengine is accepted without the missing-env-var toast, Apply Qt Colors no longer fails on a machine without qt5ct or qt6ct, and dms doctor reports whether the plugin is installed where Qt actually searches, per Qt major.
* fix(theme): resolve qtengine config via XDG, tighten doctor probing
---------
Co-authored-by: bbedward <[email protected]>
* feat(dock): attach bar to screen edge
* feat(dock): add bar length padding
* feat(dock): expand bar padding range
* refactor(dock): group bar corner settings
* fix(i18n): avoid attached term variant
* fix(settings): group corner style with goth corners
* fix(dankbar): attach flush bars to the screen edge
---------
Co-authored-by: bbedward <[email protected]>
* feat(settings): persist named location for theme & gamma auto modes
* chore: bump dank-qml-common for location search support
* fix(settings): keep weather location name when search fills coordinates
* style(settings): unify manual coordinates layout with weather
- settings.json/session.json now store only values that differ from
spec defaults
- Machine-specific state moves out of settings.json into session.json
- Add dms backup create/restore: tar.gz of ~/.config/DankMaterialShell
fixes#3027
* feat(theme): add extract current theme to JSON file
Adds an 'Extract' button in Settings > Theme Color that exports the
current theme (generic/dynamic/custom/registry) to a dual-mode dark+light
JSON file via the DMS file save dialog.
* refactor(theme): simplify extract button to single DankButton
* refactor(theme): move extract button inside dynamic theme section
* fix(theme): address review feedback on extract theme save
* refactor: utilize dankActionButton
---------
DankSlideout always held WlrKeyboardFocus.OnDemand regardless of modals,
causing Notepad to steal focus back when Launcher was opened.
ModalManager: clone currentModalsByScreen on mutation so QML bindings
re-evaluate when modals open/close.
DankSlideout: set keyboardFocus to None while a modal is active on the
same screen, letting the modal (launcher) claim focus exclusively.
* feat(tray): add IPC action to open tray menus
* tray: open IPC-requested menus on the focused screen only
---------
Co-authored-by: bbedward <[email protected]>
closeHoverSurfaces() called TrayMenuManager.closeAllMenus(), tearing down
every registered tray menu including ones opened by right-click. With
hoverPopouts enabled, moving the pointer after a right-click re-ran the
hit test and closed the menu before it could be reached.
Tag each menu with how it was opened and add closeHoverMenus(), which
only closes hover-opened menus. The hover controller now uses that.
Click-driven callers pass no argument, so byHover stays undefined and
`byHover === true` evaluates to false.
Fixes#2978
Claude-Session: https://claude.ai/code/session_01DYF9vdsaToU4Usu7kxPCNB
Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
* feat(Themes): add support for GTK3 dynamic theming
Instead of overriding named colors of all GTK3 themes via the config
directory file, only override named colors for each variant of the
adw-gtk3 theme (light and dark), and let GTK3 apps change themes
depending on the value of org.gnome.desktop.interface color-scheme.
* fix(Themes): apply requested changes
- remove gtk3 override if it's a symlink
- remove call to gtk.sh with old arg 'assets-only'
- append key to dconf path to respect dconf write signature
* refactor(Themes): separate 'include'/'apply' logic for GTK3 dynamic theming
* revert(Themes): reset timer between color-scheme refresh
- rename DMS_ENABLE_GTK4_REFRESH to DMS_ENABLE_GTK_REFRESH
- revert a3fba8
* feat(Themes): add 'remove' mode to gtk.sh
Allow to remove all inclusions and overrides for GTK.
* fix(Themes): backup adw-gtk3 original css in 'apply' (not 'include')
* style(Themes): rename argument 'include' to 'patch' for clarity
* feat(settings): add option to suppress config reload toast (#2730)
Add a toggle in Settings → Compositor Layout to disable the 'config reloaded' toast for Niri and MangoWC compositors. Session setting showConfigReloadToast defaults to true.
* chore: update settings search index for config reload toast
* refactor(settings): rename 'Compositor Notifications' to 'Compositor Toasts'
* fix(settings): reuse existing I18n.tr('Notifications') translation
* Add option to ignore app-requested notification timeout
Notifications may include an expireTimeout hint that currently takes
precedence over the configured Low/Normal/Critical durations, so
popups can disappear earlier (or later) than expected with no
interaction involved. Add notificationIgnoreAppTimeout (default off,
matching the notification spec) to let users force their own
durations regardless of what the app requests.
* Update settings search index for new timeout override toggle