* feat(theme): add support for matugen smart mode and type
* add another dry run to get smart type preview
* fix too much keywords in search index
* revert dont extract translations
* feat gate "Auto From Wallpaper" toggle row and the available matugen scheme for the pallete drop down
* re-extract settings search index
* make portal sync no longer disables matugen smart mode
* make sure cosmic theme mode also follow change from smart mode
* add translator context for Auto (Light Mode) / Auto (Dark Mode) / Auto From Wallpaper
* fix: gate matugen smart mode checks on the dynamic theme so stock themes keep portal sync and fix tile labels in control center
Adds a user-configurable spacing between system tray icons in the bar,
available per widget via the tray context menu in Settings > Widgets
("Icon Spacing" stepper, 0-20px), with a global default fallback.
- SettingsData/SettingsSpec: new trayIconSpacing setting (default 0)
- SystemTrayBar: apply configuredIconSpacing to the horizontal Row and
vertical Column layouts, and account for it in auto-overflow item
estimation and drag-and-drop slot math (shift offsets and target
index calculation)
- WidgetsTabSection: "Icon Spacing" stepper in the tray widget context
menu, following the existing "Max Visible" pattern
- WidgetsTab: keep trayIconSpacing when restoring per-widget data
* 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]>