Skip to content

feat(keybind-cheatsheet): v3.6.0 — color customization, MangoWC support, Niri parser fixes#725

Open
blackbartblues wants to merge 4 commits into
noctalia-dev:mainfrom
blackbartblues:feat/keybind-cheatsheet-v3.5.0
Open

feat(keybind-cheatsheet): v3.6.0 — color customization, MangoWC support, Niri parser fixes#725
blackbartblues wants to merge 4 commits into
noctalia-dev:mainfrom
blackbartblues:feat/keybind-cheatsheet-v3.5.0

Conversation

@blackbartblues
Copy link
Copy Markdown
Contributor

@blackbartblues blackbartblues commented Apr 21, 2026

Summary

Major release for the Keybind Cheatsheet plugin, combining appearance overhaul, MangoWC compositor support, and Niri parser bug fixes.


v3.5.0 — Full per-category color customization + clipboard paste

  • Full per-category color customization: every key category (Super, Ctrl, Shift, Alt, XF86, Print, Numeric, Mouse, Default, plus description text) now has both a background-color and a text-color picker.
  • Redesigned color picker UI: replaced the single pencil button with two compact pills per category — left pill shows the background (colored circle + hex), right pill shows text color (circle with letter preview in the selected text color + hex). Pills are sized to the hex-code width; clickability is obvious from hover state so the pencil icon is gone.
  • Clipboard quick-paste: copy any hex color (#RRGGBB or #RRGGBBAA) anywhere on your system and a clipboard icon appears in each pill for one-click paste. wl-paste is polled every 1.5s while Settings is visible; polling stops on close. A hint line with a clipboard icon above the pickers explains the feature.
  • Theme awareness: empty bg for modifier keys (Super/Ctrl/Shift) falls back to Noctalia theme accent (mPrimary/mSecondary/mTertiary); empty text override falls back to the global "Key label" color.
  • Panel opacity parity: panel now follows Noctalia's panel-in-panel opacity rules.
  • Bug fix: stopped WARN scene … Unable to assign [undefined] to QColor caused by a non-existent Color.mPrimaryContainer reference.

Architecture:

  • Extracted reusable ColorPill.qml and ColorPairRow.qml components.
  • Unified all color value properties as string so the empty-string fallback sentinel works uniformly.
  • Live-preview + revert-on-cancel: edits apply instantly; the snapshot is restored on close if Apply was never pressed.
  • 9 new keyText* settings + keyTextDefault added to manifest.metadata.defaultSettings.

v3.5.1 — Niri parser fixes (closes #715)

Addresses all issues reported by @Ito-69 in discussion #715:

  • Fix 1: Parser no longer follows commented-out includes (// include "file.kdl" is skipped).
  • Fix 2: Auto-discovery of keybindings.common.kdl and keybindings.noctalia.kdl from the Niri config directory.
  • Fix 3: Key regex updated to support optional surrounding quotes ("Mod+Return" now parsed correctly).
  • Fix 4: cheatsheetDataVersion counter in Main.qml incremented on each save; Panel.qml binds to it to force re-evaluation — no more stuck "Loading…" after parse.
  • Fix 5: 4-second loading timeout in Panel.qml — if parsing fails, shows "Loading timed out. Click Refresh to retry." instead of infinite spinner. loadingTimeoutTimer properly stopped in Component.onDestruction. New i18n key panel.loading-timeout added to all 20 locale files.

v3.6.0 — MangoWC compositor support

  • Full MangoWC parser: handles bind=, axisbind=, and mousebind= directives.
  • Recursive includes: source= and source-optional= directives followed recursively; glob patterns supported.
  • Action formatting: common actions (killclient, focusdir, view, tag, spawn_shell, etc.) translated to human-readable labels.
  • Noctalia IPC detection: spawn_shell calls to noctalia-shell ipc call plugin:<name> render as "Plugin Name: Toggle".
  • Mouse/axis support: axisbind= shows scroll direction, mousebind= shows button name.
  • Panel title: "MangoWC Keymap" when running under MangoWC.
  • Settings: MangoWC config path field with format hint and example keybind.
  • Lookup tables: mangoKeyNameMap, mangoAxisMap, mangoButtonMap, mangoNoArgActions, mangoDirActions — hoisted to module level to avoid per-bind allocation.
  • i18n: panel.title-mango, settings.mango-path, settings.mango-format-hint, settings.keybind-example-mango added to all 20 locale files. English used as placeholder for non-English locales — native-speaker translations welcome.
  • Removed dead error.mango-not-supported / error.mango-detail keys from all locale files.
  • Hyprland and Niri parsers unchanged.

Translations

All 20 supported language files updated across all three change sets: de, en, es, fr, hn, hu, it, ja, ko-KR, ku, nl, nn-NO, pl, pt, ru, sv, tr, uk-UA, zh-CN, zh-TW.

Test plan

  • Plugin loads with qs -c noctalia-shell, no QML warnings.
  • Color customization: all 9 categories show bg + text pills; clipboard paste works.
  • Apply persists settings; Cancel restores snapshot.
  • Niri multi-file config: commented includes skipped, quoted keys parsed, panel refreshes after parse.
  • Niri loading timeout: 4s timeout shows error message if parse fails.
  • MangoWC: panel opens and renders categories under "MangoWC Keymap".
  • MangoWC: mousebind= and axisbind= entries show correct labels.
  • MangoWC: source= recursive includes followed; glob patterns expanded.
  • Hyprland and Niri configs parse unchanged.
  • Tested on Hyprland and Niri.

Version

3.4.03.5.03.5.13.6.0

Closes #715

@github-actions
Copy link
Copy Markdown
Contributor

Automatic Code Quality Review


File: keybind-cheatsheet/ColorPairRow.qml

  • (L) Line 49: When it comes to translations there is no need for fallback values. From: pluginApi?.tr("example") || "value". To: pluginApi?.tr("example")
+    placeholderText: row.bgValue.length === 0 ? (row.pluginApi?.tr("settings.color-auto") || "auto") : ""
  • (L) Line 64: When it comes to translations there is no need for fallback values. From: pluginApi?.tr("example") || "value". To: pluginApi?.tr("example")
+    placeholderText: row.textValue.length === 0 ? (row.pluginApi?.tr("settings.color-auto") || "auto") : ""

File: keybind-cheatsheet/Settings.qml

  • (H) Line 661: Use translations instead of hardcoded text. Instead of: "Example Label". To: pluginApi?.tr("panel.example-label")
+              text: "qs -c \"noctalia-shell\" ipc call plugin:keybind-cheatsheet toggle"
  • (H) Line 750: Do not use hardcoded values, always prefer to use the Style singleton instead
+                border.width: 1

…clipboard paste, pill UI

- Full per-category color customization: background + text color pickers for
  Super/Ctrl/Shift/Alt/XF86/Print/numeric/mouse/default plus description text
- Empty-string sentinel for Super/Ctrl/Shift overrides so Material theme accents
  (mPrimary/mSecondary/mTertiary) are used unless the user sets a concrete color
- Redesigned Color Picker UI: two-pill layout per row (bg + text), single click
  anywhere on the pill opens NColorPickerDialog, pencil icon removed
- Clipboard quick-paste: wl-paste polled every 1500 ms; when a #RRGGBB(AA) hex is
  on the clipboard, a paste icon appears inside each pill for one-click apply
- Live preview + revert-on-cancel: changes apply immediately via _applyPreview;
  Settings.onDestruction restores the Component.onCompleted snapshot if the
  user closes without saving
- Panel now follows shell opacity/blur settings like tailscale/hello-world
  (panel-in-panel pattern instead of self-painted background)
- Fixed Color.mPrimaryContainer references that produced undefined colors at
  runtime on current shell builds
- Extracted ColorPill.qml and ColorPairRow.qml from Settings.qml
- Extended edit-copy pattern to all 20+ color/text settings; saveSettings()
  persists them and calls pluginApi.saveSettings()
- New i18n keys: panel.search-placeholder (merged with upstream), settings.
  color-auto, settings.color-paste-hint, settings.keybind-ipc-command,
  localized across all 20 supported languages
- manifest: bump to 3.5.0, add 20+ color defaults, fix windowHeight default
  from 0 to 850, extend tags with Hyprland/Niri
@blackbartblues blackbartblues force-pushed the feat/keybind-cheatsheet-v3.5.0 branch from 68694ac to a2a8c41 Compare April 21, 2026 21:07
@blackbartblues blackbartblues marked this pull request as ready for review April 21, 2026 21:08
….6.0)

MangoWC compositor support:
- Full MangoWC parser: bind=, axisbind=, mousebind=, source=/source-optional= recursive includes
- Glob pattern support via mangoGlobProcess
- Lookup tables: mangoKeyNameMap, mangoAxisMap, mangoButtonMap, mangoNoArgActions, mangoDirActions
- spawn_shell IPC → friendly label (plugin:NAME toggle → "Name: Toggle")
- Panel title: "MangoWC Keymap" when CompositorService.isMango
- Settings: MangoWC config path field with format hint
- manifest.json: mangoConfigPath defaultSetting, MangoWC tag, description updated
- i18n: panel.title-mango + settings.mango-path/format-hint/keybind-example-mango in 20 locales
- Removed dead error.mango-not-supported/mango-detail keys

Niri parser fixes (discussion noctalia-dev#715):
- Fix 5: loadingTimeoutTimer cleanup in Component.onDestruction
- Fix 5: Panel loading text branches on loadingTimedOut flag
- Fix 5: panel.loading-timeout key added to all 20 i18n files

Version: 3.5.1 → 3.6.0

Closes noctalia-dev#715
@blackbartblues blackbartblues changed the title feat(keybind-cheatsheet): v3.5.0 — full color customization, clipboard paste, redesigned pill UI feat(keybind-cheatsheet): v3.6.0 — color customization, MangoWC support, Niri parser fixes Apr 22, 2026
@countgitmick
Copy link
Copy Markdown

Thanks for pulling the MangoWC work into the release. Ran through the merged parser against the test configs and want to flag a few regressions from the rewrite. Listing them with user impact so they don't read as style nits.

1. XF86 media keys render raw (will be noticed)

formatMangoKeyCombo (L1311) no longer calls formatSpecialKey, which maps XF86AudioRaiseVolume to Vol Up, XF86AudioMute to Mute, etc. Laptop users binding volume or brightness keys will see the full XF86 name in the cheatsheet instead of a friendly label.

2. Stray # comments become categories (will often be noticed)

extractMangoCategory (L1300) now returns the text after any # as a category. The original had filters: length cap of 100 chars, horizontal rule strip (────, ====), numbered list extraction (1. Foo), paren continuation reject, flow arrow reject. A config with # TODO fix later or # see docs will produce phantom categories.

3. Per-bind #"description" suffix broken

findMangoUnquotedComment (L1210) strips every # unconditionally. The original had if (str.charAt(i + 1) !== '"') return i; so bind=SUPER,T,exec,foo #"Open terminal" kept the description. After the rewrite the description is eaten before parseMangoConfig sees it. This was documented as a supported feature in #730.

4. Missing SUPER and ALT aliases

LOGO (SUPER alias) and MOD1 (ALT alias) are valid Mango modifier tokens. Rare in practice, but bind=LOGO,... will render with no modifier.

5. Default category no longer localized

Hardcoded "General" and "Mouse" bypass pluginApi?.tr("default-category"). Cosmetic, but the i18n key is still defined.

@blackbartblues
Copy link
Copy Markdown
Contributor Author

I will fix it this evening

@spiros132 spiros132 marked this pull request as draft April 25, 2026 10:10
Addresses PR noctalia-dev#725 review feedback from @countgitmick.

- formatMangoKeyCombo now applies formatSpecialKey for bind keys, so
  XF86AudioRaiseVolume renders as "Vol Up", XF86AudioMute as "Mute",
  brightness keys as "Bright Up/Down", etc.
- extractMangoCategory restored filters: length cap (100 chars),
  horizontal-rule strip (────, ====, ----), numbered-list extraction
  (1. Foo -> Foo), paren/bracket continuation reject, flow-arrow reject
  (→, ->, =>), keyword-prefixed notes reject (TODO/FIXME/NOTE/HACK/
  XXX/BUG/WIP).
- findMangoUnquotedComment skips past #" so per-bind #"description"
  suffix is preserved; parseMangoConfig extracts the trailing quoted
  description and uses it as the rendered description.
- formatMangoKeyCombo recognizes LOGO (= SUPER) and MOD1 (= ALT) as
  valid Mango modifier tokens.
- parseMangoConfig uses pluginApi.tr("default-category") for the
  fallback category instead of hardcoded "General"/"Mouse".
- Category detection moved into the pure-comment branch so "# Title"
  lines actually update currentCategory (previously dead code path).

manifest version 3.6.0 -> 3.6.1.
@blackbartblues blackbartblues marked this pull request as ready for review April 26, 2026 15:42
@blackbartblues
Copy link
Copy Markdown
Contributor Author

@spiros132 Do you want to review it and post? It would be helpful for a lot of ppl.

Copy link
Copy Markdown
Collaborator

@spiros132 spiros132 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, just check this one thing otherwise I'll merge it in :D

Comment thread keybind-cheatsheet/Main.qml Outdated

// Auto-generate description for undescribed binds when included
if (!hasDesc && includeUndescribed) {
description = verb ? (verb + (param ? " " + param : "")) : "(no description)";
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be in the translation as well or no?

Translate hardcoded "(no description)" fallback string for MangoWC
undescribed binds into the i18n system.

- Main.qml:820: replace "(no description)" with pluginApi?.tr("panel.no-description")
- Add panel.no-description key to all 20 locale files (en, de, es, fr, hn,
  hu, it, ja, ko-KR, ku, nl, nn-NO, pl, pt, ru, sv, tr, uk-UA, zh-CN, zh-TW)
  en: "(no description)", pl: "(brak opisu)", others: English placeholder
- Bump version 3.6.1 → 3.6.2
- Update CHANGELOG.md
Copy link
Copy Markdown
Collaborator

@spiros132 spiros132 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, should I merge it in or should we wait until @countgitmick checks if the mango parser works correctly?

@blackbartblues
Copy link
Copy Markdown
Contributor Author

Lets wait, whole mange parser is his doing so it should be well done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants