settings: stop repeating the page title as the first card label
translations: index untitled cards by their page, not a nested row
fixes#3604fixes#3609
* powermenu: derive shortcuts and extra actions from one source
The power menu matched keys with a switch that repeated the key hints
getPowerActionData already returns, plus a second key list for release.
Look the pressed key up against the hints of the visible actions instead,
so every action with a hint gets its shortcut and the two cannot drift.
Side effects:
- Ctrl+letter no longer triggers actions. Only Ctrl+P was excluded
before, so Ctrl+R still rebooted. Ctrl combinations are navigation.
- U now triggers switch user when it is shown. Its hint already said U.
- Releasing a letter with no visible action no longer cancels a hold.
SessionService now owns the custom:N action ids as customPowerActions
and extraPowerActions, which the power menu and the launcher both use.
Actions resolve by index into that list instead of slicing the prefix.
* powermenu: add actions that reboot into a chosen efi boot entry
Settings → Power & Sleep gets a "Reboot to another OS" card that lists
the firmware's active EFI entries through efibootmgr. Each saved entry
becomes a "Reboot to <name>" action in the power menu and the launcher,
bound to 1-9 in the order it was added.
Picking one lists the entries again, and stops with a toast if the id no
longer carries the saved label. Otherwise it sets BootNext through pkexec
and reboots through SessionService, so custom reboot commands still apply.
BootEntryService reports why entries are unavailable: not booted in UEFI
mode, efibootmgr missing, or efibootmgr failing with its stderr. Saved
entries stay listed in settings whatever the status, so a synced config
on another machine can still remove them.
efibootmgr parsing and the picker's filtering live in BootEntries.js,
covered by tests/boot-entries.test.mjs.
* powermenu: ignore special keys in action shortcuts
- The island is now a bar widget so any bar can host one alongside the island layout and dot
- Routing got simpler: pick which shortcuts open here, the rest follow the shared rules
- IPC close/hide take down every surface showing the activity
- Qt 6.11 pointer prune workaround so the expanded island stays clickable
* fix: keep tray order stable when tooltipTitle changes dynamically
Revert the earlier simplistic key approach: keep getTrayItemKey()
unchanged (id::tooltipTitle) so duplicate-id disambiguation (#1542)
is preserved and persisted id::tooltipTitle entries keep matching.
Instead make persisted-key lookups tolerant of dynamic tooltipTitle:
resolveOrderIndex() in sortByPreferredOrder() does exact match first,
falling back to prefix matching an id::* entry only when the id has a
single instance. findSavedTrayKey()/isTrayIdHidden() replace direct
SessionData.isHiddenTrayId() calls and showTrayId() now receives the
actual saved key.
Prefix fallback is gated by trayItemCountForId() to single-instance
ids only, so multiple items sharing an id always match exactly and
hiding/ordering one never affects the others.
* fix: bail on ambiguous saved tray keys in fallback
* tray: use occurrence index as stable key, add one-time session migration
* tray: pin stable key per item instance so it never flips when siblings come and go
* tray: assign unique per-id sequential keys to avoid collision after sibling exit
* tray: reuse free key slots so a restarted singleton keeps its plain id
* matugen: support multiple injected palettes with settings ui
Run user-configured external commands on each theme build and merge their
JSON output into matugen's import data under a namespace, so templates can
reference e.g. {{mypalette.color0}} alongside dank16. Multiple palettes are
supported, each under its own namespace. Command output may be nested JSON
(pywal/wallust shape). A settings page manages the list; a legacy
single-object config file is still read.
* settings: map PaletteInjectTab in search index
* matugen: bound palette-inject command with timeout and WaitDelay
* fix palette column spacing (review suggested
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
* remove wallpaper kind guard (review suggestion)
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
* fixup! remove wallpaper kind guard (review suggestion)
---------
Co-authored-by: bbedward <[email protected]>
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
* feat(keybinds): redesign cheatsheet with category navigation, M3 styling, and click-to-execute
- Add category sidebar with Material Symbols icons and badge counts
- Move search field to top of sidebar with Ctrl+F shortcut
- Implement 2-column masonry layout for keybind items
- Deduplicate duplicate actions and stack multi-key combos vertically
- Collapse consecutive workspace keybindings (1-9) into range entries
- Add media & hardware icons for volume, mic, brightness, and PrtSc keycaps
- Preserve Niri window filter properties and distinguish same-app Alt-Tab binds
- Enable click-to-execute for keybind actions across supported compositors
* fix(keybinds): preserve niri action properties and disable execution on range rows
* fix(keybinds): convert niri action properties to CLI flags and disable IPC execution for window switcher binds
* fix(keybinds): pass skip-confirmation as boolean switch in niri executeAction
* fix(keybinds): handle niri spawn-sh actions in executeAction
- A new minimal and fun island instance (dot) that gets out of your way to be tossed anywhere on your screen
- Dankisland freedom is here too! It can now also be used in anywhere mode and used horizontally or vertically as you see fit!
* mux: add herdr backend
* mux: remove herdr service tests
* mux: include herdr in settings subtitle
* mux: add translator context to the multiplexers subtitle
* mux: drive the service from a backend table
Each backend (tmux, zellij, herdr) is one entry in MuxBackends.js with
its commands and parser, so the service no longer branches on muxType
in eight places and the settings dropdown lists the table keys. One
availability check runs for the selected backend and re-runs when the
backend changes. The herdr parser reads the real {sessions:[...]}
shape only.
* i18n: pick the DankCommon translation for the chosen locale
updateLocale() switches the shell translation, but the DankCommon one was
picked once at startup from the system locale and never changed. With DMS set
to English on a German system, plugin strings that fall back to I18n.tr()
(Suspend, Reboot, ...) stayed German. _pickCommonTranslation() now uses the
resolved locale and runs again from useLocale(); for English, where no common
file exists, the table is cleared.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
* i18n: clear the DankCommon table when falling back to English
_fallbackToEnglish() left the common table as it was picked for the previous
locale. Setting Language to "System default" on a system without a shell
translation (an English one, cs_CZ, ...) goes through that path, so the shell
switched to English while DankCommon strings stayed in the old language - the
same mismatch this branch fixes for the useLocale() path.
The function now resolves to "en" before re-picking, which clears the table
because no English common file exists, and it also covers the case where the
selected translation file is missing or fails to parse.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
---------
Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
saveSettings() set _selfWrite before setText(). When the serialized
settings were identical to the file, nothing was written, no
fileChanged followed, and the flag stayed set. The next external edit
of settings.json was then taken for our own write and never reloaded.
Co-authored-by: Claude Opus 5 (1M context) <[email protected]>