diff --git a/README.md b/README.md index c6bb932..451701e 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ![License](https://img.shields.io/badge/license-MIT-purple) ![Status](https://img.shields.io/badge/status-work_in_progress-yellow) -[KDE & apps](#configs) · [Packages](#package-sections) · [Setup](docs/setup.md) +[KDE & apps](#configs) · [Shortcuts](docs/shortcuts.md) · [Packages](#package-sections) · [Setup](docs/setup.md) diff --git a/docs/shortcuts.md b/docs/shortcuts.md new file mode 100644 index 0000000..4515bfe --- /dev/null +++ b/docs/shortcuts.md @@ -0,0 +1,473 @@ +# KDE shortcuts + +Generated from the repo’s captured `kglobalshortcutsrc`. This describes +Fiw’s bindings as configured; applying them is a separate installer action. +It covers KDE global shortcuts, not every shortcut inside individual applications. + +**67 assigned actions · 193 unassigned actions · 260 total** + +`Meta` is the Super/Windows key. In the full tables, multiple keys for +one action are alternatives. Grouped summary keys match the named actions +in order. “Unassigned” means explicitly disabled in this capture; +a key in the KDE default column is not an active binding. The default +column is copied from KDE’s stored values, not inferred from a release. + +## Everyday bindings + +| Keys | Action | +|---|---| +| Meta | Open application launcher | +| Meta+Space | Open KRunner | +| Meta+Q | Open Kitty | +| Alt+S
Meta+Shift+S | Select a screenshot region | +| Print
Alt+D | Screenshot monitor under pointer | +| Meta+V | Show clipboard history at pointer | +| Meta+1
Meta+2
Meta+3 | Switch to desktop 1 / 2 / 3 | +| Meta+!
Meta+@
Meta+# | Move window to desktop 1 / 2 / 3 | +| Meta+Ctrl+Left
Meta+Ctrl+Right
Meta+Ctrl+Up
Meta+Ctrl+Down | Switch desktop left / right / up / down | +| Meta+Left
Meta+Right
Meta+Up
Meta+Down | Tile window left / right / up / down | +| Meta+Shift+Left
Meta+Shift+Right | Move window to previous / next screen | +| Meta+F | Maximize window | +| Meta+W | Toggle Overview | +| Meta+G | Toggle desktop grid | +| Meta+A
Meta+Shift+A | Next / previous activity | +| Screensaver
Meta+L | Lock session | +| Ctrl+Alt+Del | Show logout screen | + +Screenshot bindings use `fiw-shot`: copy to clipboard, then offer Save +or Edit in the notification. They need Spectacle, `wl-copy` and +`notify-send`; Kitty and KRunner bindings need their respective apps. +The native Spectacle bindings are unassigned to avoid competing actions. + +The desktop-move bindings are stored as literal symbols (`!`, `@`, `#`). +On a US layout these usually mean Shift+1/2/3; other layouts can differ. +The keyboard-layout preset contains US English, Russian and Spanish; +`Meta+Alt+Space` cycles through them. Shortcut restoration does not +create three virtual desktops or activities on a new installation. + +## Captured choices + +Forward window switching is currently unassigned; reverse switching +uses `Alt+Shift+Tab` and `Meta+Shift+Tab`. + +Other currently unassigned shortcuts include Peek at Desktop (`Meta+D` +in the default column), Minimize (`Meta+PgDown`), Restore +(`Meta+Backspace`) and the window menu (`Alt+F3`). FiwNode’s four +recorded global actions are unassigned. `Meta+1/2/3` are used for +desktops, with the corresponding task-manager shortcuts disabled. + +## All assigned actions + +### Keyboard Layout Switcher + +| Action | Current keys | Stored KDE default | +|---|---|---| +| Switch to Next Keyboard Layout | Meta+Alt+Space | Meta+Alt+K | + +### Accessibility + +| Action | Current keys | Stored KDE default | +|---|---|---| +| Toggle Screen Reader On and Off | Meta+Alt+S | Meta+Alt+S | + +### Audio Volume + +| Action | Current keys | Stored KDE default | +|---|---|---| +| Decrease Microphone Volume | Microphone Volume Down | Microphone Volume Down | +| Decrease Volume | Volume Down | Volume Down | +| Decrease Volume by 1% | Shift+Volume Down | Shift+Volume Down | +| Increase Microphone Volume | Microphone Volume Up | Microphone Volume Up | +| Increase Volume | Volume Up | Volume Up | +| Increase Volume by 1% | Shift+Volume Up | Shift+Volume Up | +| Mute Microphone | Microphone Mute
Meta+Volume Mute | Microphone Mute
Meta+Volume Mute | +| Mute | Volume Mute | Volume Mute | + +### Session Management + +| Action | Current keys | Stored KDE default | +|---|---|---| +| Lock Session | Screensaver
Meta+L | Screensaver
Meta+L | +| Show Logout Screen | Ctrl+Alt+Del | Ctrl+Alt+Del | + +### KWin + +| Action | Current keys | Stored KDE default | +|---|---|---| +| Activate Window Demanding Attention | Meta+Ctrl+A | Meta+Ctrl+A | +| Toggle Present Windows (Current desktop) | Ctrl+F9
Meta+F9 | Ctrl+F9
Meta+F9 | +| Toggle Present Windows (All desktops) | Launch (C)
Ctrl+F10
Meta+F10 | Launch (C)
Ctrl+F10
Meta+F10 | +| Toggle Present Windows (Window class) | Ctrl+F7
Meta+F7 | Ctrl+F7
Meta+F7 | +| Toggle Grid View | Meta+G | Meta+G | +| Kill Window | Meta+Ctrl+Esc | Meta+Ctrl+Esc | +| Toggle Overview | Meta+W | Meta+W | +| Switch One Desktop Down | Meta+Ctrl+Down | Meta+Ctrl+Down | +| Switch One Desktop Up | Meta+Ctrl+Up | Meta+Ctrl+Up | +| Switch One Desktop to the Left | Meta+Ctrl+Left | Meta+Ctrl+Left | +| Switch One Desktop to the Right | Meta+Ctrl+Right | Meta+Ctrl+Right | +| Switch to Desktop 1 | Meta+1 | Ctrl+F1
Meta+F1 | +| Switch to Desktop 2 | Meta+2 | Ctrl+F2
Meta+F2 | +| Switch to Desktop 3 | Meta+3 | Ctrl+F3
Meta+F3 | +| Walk Through Windows (Reverse) | Alt+Shift+Tab
Meta+Shift+Tab | Alt+Shift+Tab
Meta+Shift+Tab | +| Close Window | Alt+F4 | Alt+F4 | +| Maximize Window | Meta+F | Meta+PgUp | +| Quick Tile Window to the Bottom | Meta+Down | Meta+Down | +| Quick Tile Window to the Left | Meta+Left | Meta+Left | +| Quick Tile Window to the Right | Meta+Right | Meta+Right | +| Quick Tile Window to the Top | Meta+Up | Meta+Up | +| Window to Desktop 1 | Meta+! | Unassigned | +| Window to Desktop 2 | Meta+@ | Unassigned | +| Window to Desktop 3 | Meta+# | Unassigned | +| Move Window to Next Screen | Meta+Shift+Right | Meta+Shift+Right | +| Move Window to Previous Screen | Meta+Shift+Left | Meta+Shift+Left | +| Zoom to Actual Size | Meta+0 | Meta+0 | +| Zoom In | Meta++
Meta+= | Meta++
Meta+= | +| Zoom Out | Meta+- | Meta+- | + +### Media Controller + +| Action | Current keys | Stored KDE default | +|---|---|---| +| Media playback next | Media Next | Media Next | +| Pause media playback | Media Pause | Media Pause | +| Play/Pause media playback | Media Play | Media Play | +| Media playback previous | Media Previous | Media Previous | +| Media playback seek backward 5s | Media Rewind | Media Rewind | +| Media playback seek forward 5s | Media Fast Forward | Media Fast Forward | +| Stop media playback | Media Stop | Media Stop | + +### Power Management + +| Action | Current keys | Stored KDE default | +|---|---|---| +| Decrease Keyboard Brightness | Keyboard Brightness Down | Keyboard Brightness Down | +| Decrease Screen Brightness | Monitor Brightness Down | Monitor Brightness Down | +| Decrease Screen Brightness by 1% | Shift+Monitor Brightness Down | Shift+Monitor Brightness Down | +| Hibernate | Hibernate | Hibernate | +| Increase Keyboard Brightness | Keyboard Brightness Up | Keyboard Brightness Up | +| Increase Screen Brightness | Monitor Brightness Up | Monitor Brightness Up | +| Increase Screen Brightness by 1% | Shift+Monitor Brightness Up | Shift+Monitor Brightness Up | +| Power Down | Power Down | Power Down | +| Power Off | Power Off | Power Off | +| Suspend | Sleep | Sleep | +| Toggle Keyboard Backlight | Keyboard Light On/Off | Keyboard Light On/Off | + +### plasmashell + +| Action | Current keys | Stored KDE default | +|---|---|---| +| Activate Application Launcher | Meta | Meta
Alt+F1 | +| Walk through activities | Meta+A | Unassigned | +| Walk through activities (Reverse) | Meta+Shift+A | Unassigned | +| Show Clipboard Items at Mouse Position | Meta+V | Meta+V | + +### Screenshot region helper + +| Action | Current keys | Stored KDE default | +|---|---|---| +| Screenshot region helper | Alt+S
Meta+Shift+S | — | + +### Screenshot monitor helper + +| Action | Current keys | Stored KDE default | +|---|---|---| +| Screenshot monitor helper | Print
Alt+D | — | + +### Kitty launcher + +| Action | Current keys | Stored KDE default | +|---|---|---| +| Kitty launcher | Meta+Q | — | + +### KRunner launcher + +| Action | Current keys | Stored KDE default | +|---|---|---| +| KRunner launcher | Meta+Space | — | + +## All unassigned actions + +These entries are restored as unassigned, including actions with a +stored KDE default. Expand each section to review the full capture. + +
+Keyboard Layout Switcher (4) + +| Action | Stored KDE default | +|---|---| +| Switch keyboard layout to English (US) | Unassigned | +| Switch keyboard layout to Russian | Unassigned | +| Switch keyboard layout to Spanish | Unassigned | +| Switch to Last-Used Keyboard Layout | Meta+Alt+L | + +
+ +
+FiwNode (4) + +| Action | Stored KDE default | +|---|---| +| FiwNode: next | Meta+Alt+N | +| FiwNode: show and search | Meta+Alt+F | +| FiwNode: stop | Meta+Alt+S | +| FiwNode: play / pause | Meta+Alt+P | + +
+ +
+Audio Volume (1) + +| Action | Stored KDE default | +|---|---| +| Push to talk | Unassigned | + +
+ +
+Session Management (6) + +| Action | Stored KDE default | +|---|---| +| Shut Down Without Confirmation | Unassigned | +| Log Out Without Confirmation | Unassigned | +| Log Out | Unassigned | +| Reboot | Unassigned | +| Reboot Without Confirmation | Unassigned | +| Shut Down | Unassigned | + +
+ +
+KWin (138) + +| Action | Stored KDE default | +|---|---| +| Cycle through Overview and Grid View | Unassigned | +| Cycle through Grid View and Overview | Unassigned | +| Decrease Opacity of Active Window by 5% | Unassigned | +| Toggle Tiles Editor | Meta+T | +| Toggle Present Windows (Window class on current desktop) | Unassigned | +| Increase Opacity of Active Window by 5% | Unassigned | +| Move the tablet to the next output | Unassigned | +| Move Mouse to Center | Meta+F6 | +| Move Mouse to Focus | Meta+F5 | +| Move Zoomed Area Downwards | Unassigned | +| Move Zoomed Area to Left | Unassigned | +| Move Zoomed Area to Right | Unassigned | +| Move Zoomed Area Upwards | Unassigned | +| Setup Window Shortcut | Unassigned | +| Peek at Desktop | Meta+D | +| Switch to Window Below | Meta+Alt+Down | +| Switch to Window to the Left | Meta+Alt+Left | +| Switch to Window to the Right | Meta+Alt+Right | +| Switch to Window Above | Meta+Alt+Up | +| Switch to Desktop 10 | Unassigned | +| Switch to Desktop 11 | Unassigned | +| Switch to Desktop 12 | Unassigned | +| Switch to Desktop 13 | Unassigned | +| Switch to Desktop 14 | Unassigned | +| Switch to Desktop 15 | Unassigned | +| Switch to Desktop 16 | Unassigned | +| Switch to Desktop 17 | Unassigned | +| Switch to Desktop 18 | Unassigned | +| Switch to Desktop 19 | Unassigned | +| Switch to Desktop 20 | Unassigned | +| Switch to Desktop 21 | Unassigned | +| Switch to Desktop 22 | Unassigned | +| Switch to Desktop 23 | Unassigned | +| Switch to Desktop 24 | Unassigned | +| Switch to Desktop 25 | Unassigned | +| Switch to Desktop 4 | Ctrl+F4
Meta+F4 | +| Switch to Desktop 5 | Unassigned | +| Switch to Desktop 6 | Unassigned | +| Switch to Desktop 7 | Unassigned | +| Switch to Desktop 8 | Unassigned | +| Switch to Desktop 9 | Unassigned | +| Switch to Next Desktop | Unassigned | +| Switch to Next Screen | Unassigned | +| Switch to Previous Desktop | Unassigned | +| Switch to Previous Screen | Unassigned | +| Switch to Screen 0 | Unassigned | +| Switch to Screen 1 | Unassigned | +| Switch to Screen 2 | Unassigned | +| Switch to Screen 3 | Unassigned | +| Switch to Screen 4 | Unassigned | +| Switch to Screen 5 | Unassigned | +| Switch to Screen 6 | Unassigned | +| Switch to Screen 7 | Unassigned | +| Switch to Screen Above | Unassigned | +| Switch to Screen Below | Unassigned | +| Switch to Screen to the Left | Unassigned | +| Switch to Screen to the Right | Unassigned | +| Suspend/Resume Night Light | Unassigned | +| Toggle Window Raise/Lower | Unassigned | +| Walk Through Windows | Alt+Tab
Meta+Tab | +| Walk Through Windows Alternative | Unassigned | +| Walk Through Windows Alternative (Reverse) | Unassigned | +| Walk Through Windows of Current Application | Alt+`
Meta+` | +| Walk Through Windows of Current Application (Reverse) | Alt+~
Meta+~ | +| Walk Through Windows of Current Application Alternative | Unassigned | +| Walk Through Windows of Current Application Alternative (Reverse) | Unassigned | +| Keep Window Above Others | Unassigned | +| Keep Window Below Others | Unassigned | +| Custom Quick Tile Window to the Bottom | Unassigned | +| Custom Quick Tile Window to the Left | Unassigned | +| Custom Quick Tile Window to the Right | Unassigned | +| Custom Quick Tile Window to the Top | Unassigned | +| Make Window Fullscreen | Unassigned | +| Expand Window Horizontally | Unassigned | +| Expand Window Vertically | Unassigned | +| Lower Window | Unassigned | +| Maximize Window Horizontally | Unassigned | +| Maximize Window Vertically | Unassigned | +| Minimize Window | Meta+PgDown | +| Move Window | Unassigned | +| Move Window to the Center | Unassigned | +| Toggle Window Titlebar and Frame | Unassigned | +| Keep Window on All Desktops | Unassigned | +| Window One Desktop Down | Meta+Ctrl+Shift+Down | +| Window One Desktop Up | Meta+Ctrl+Shift+Up | +| Window One Desktop to the Left | Meta+Ctrl+Shift+Left | +| Window One Desktop to the Right | Meta+Ctrl+Shift+Right | +| Move Window One Screen Down | Unassigned | +| Move Window One Screen Up | Unassigned | +| Move Window One Screen to the Left | Unassigned | +| Move Window One Screen to the Right | Unassigned | +| Window Menu | Alt+F3 | +| Move Window Down | Unassigned | +| Move Window Left | Unassigned | +| Move Window Right | Unassigned | +| Move Window Up | Unassigned | +| Quick Tile Window to the Bottom Left | Unassigned | +| Quick Tile Window to the Bottom Right | Unassigned | +| Quick Tile Window to the Top Left | Unassigned | +| Quick Tile Window to the Top Right | Unassigned | +| Raise Window | Unassigned | +| Resize Window | Unassigned | +| Restore Window | Meta+Backspace | +| Shrink Window Horizontally | Unassigned | +| Shrink Window Vertically | Unassigned | +| Window to Desktop 10 | Unassigned | +| Window to Desktop 11 | Unassigned | +| Window to Desktop 12 | Unassigned | +| Window to Desktop 13 | Unassigned | +| Window to Desktop 14 | Unassigned | +| Window to Desktop 15 | Unassigned | +| Window to Desktop 16 | Unassigned | +| Window to Desktop 17 | Unassigned | +| Window to Desktop 18 | Unassigned | +| Window to Desktop 19 | Unassigned | +| Window to Desktop 20 | Unassigned | +| Window to Desktop 21 | Unassigned | +| Window to Desktop 22 | Unassigned | +| Window to Desktop 23 | Unassigned | +| Window to Desktop 24 | Unassigned | +| Window to Desktop 25 | Unassigned | +| Window to Desktop 4 | Unassigned | +| Window to Desktop 5 | Unassigned | +| Window to Desktop 6 | Unassigned | +| Window to Desktop 7 | Unassigned | +| Window to Desktop 8 | Unassigned | +| Window to Desktop 9 | Unassigned | +| Window to Next Desktop | Unassigned | +| Window to Previous Desktop | Unassigned | +| Move Window to Screen 0 | Unassigned | +| Move Window to Screen 1 | Unassigned | +| Move Window to Screen 2 | Unassigned | +| Move Window to Screen 3 | Unassigned | +| Move Window to Screen 4 | Unassigned | +| Move Window to Screen 5 | Unassigned | +| Move Window to Screen 6 | Unassigned | +| Move Window to Screen 7 | Unassigned | +| Disable Active Input Capture | Meta+Shift+Esc | + +
+ +
+Media Controller (5) + +| Action | Stored KDE default | +|---|---| +| Media volume down | Unassigned | +| Media volume up | Unassigned | +| Play media playback | Unassigned | +| Media playback seek backward 30s | Unassigned | +| Media playback seek forward 30s | Unassigned | + +
+ +
+Power Management (2) + +| Action | Stored KDE default | +|---|---| +| Turn Off Screen | Unassigned | +| Switch Power Profile | Battery
Meta+B | + +
+ +
+plasmashell (25) + +| Action | Stored KDE default | +|---|---| +| Next Wallpaper Image | Unassigned | +| Activate Task Manager Entry 1 | Meta+1 | +| Activate Task Manager Entry 10 | Unassigned | +| Activate Task Manager Entry 2 | Meta+2 | +| Activate Task Manager Entry 3 | Meta+3 | +| Activate Task Manager Entry 4 | Meta+4 | +| Activate Task Manager Entry 5 | Meta+5 | +| Activate Task Manager Entry 6 | Meta+6 | +| Activate Task Manager Entry 7 | Meta+7 | +| Activate Task Manager Entry 8 | Meta+8 | +| Activate Task Manager Entry 9 | Meta+9 | +| Clear Notification History | Unassigned | +| Clear Clipboard History | Unassigned | +| Automatic Action Popup Menu | Meta+Ctrl+X | +| Move keyboard focus between panels | Meta+Alt+P | +| Next History Item | Unassigned | +| Previous History Item | Unassigned | +| Edit Contents… | Unassigned | +| Show Activity Switcher | Meta+Q | +| Manually Invoke Action on Current Clipboard | Unassigned | +| Show Desktop | Ctrl+F12 | +| Show Barcode… | Unassigned | +| Switch to Next Activity | Unassigned | +| Switch to Previous Activity | Unassigned | +| Toggle do not disturb | Unassigned | + +
+ +
+services][org.kde.kscreen.desktop (1) + +| Action | Stored KDE default | +|---|---| +| ShowOSD | — | + +
+ +
+services][org.kde.spectacle.desktop (7) + +| Action | Stored KDE default | +|---|---| +| ActiveWindowScreenShot | — | +| CurrentMonitorScreenShot | — | +| FullScreenScreenShot | — | +| OpenWithoutScreenshot | — | +| RectangularRegionScreenShot | — | +| WindowUnderCursorScreenShot | — | +| _launch | — | + +
+ +## Refresh the reference + +```sh +python3 tools/shortcuts.py +``` + +Run this after reviewing a shortcut capture or changing the preset. +The generator reads repo files only and does not change live KDE settings. diff --git a/tools/shortcuts.py b/tools/shortcuts.py new file mode 100644 index 0000000..ee481e9 --- /dev/null +++ b/tools/shortcuts.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 +"""Generate a readable reference from the captured KDE global shortcuts.""" +from collections import defaultdict +from pathlib import Path + +from capture import sections + +REPO = Path(__file__).resolve().parents[1] +SOURCE = REPO / 'configs/kde-shortcuts/kconfig/.config/kglobalshortcutsrc' + + +def bindings(value): + return [key.strip() for key in value.replace(r'\t', '\t').split('\t') + if key.strip() and key.strip().lower() != 'none'] + + +def records(path=SOURCE): + for group, values in sections(path.read_text()).items(): + for action, value in values.items(): + if action.startswith('_') and action != '_launch': + continue + fields = value.split(',', 2) + current = bindings(fields[0]) + default = bindings(fields[1]) if len(fields) > 1 else None + label = fields[2] if len(fields) > 2 else action + yield group, action, label, current, default + + +def cell(value): + return value.replace('&', '&').replace('<', '<').replace('>', '>').replace('|', '|').replace('`', '`') + + +def keys(values): + if values is None: + return '—' + return '
'.join('' + cell(value) + '' for value in values) or 'Unassigned' + + +def generate(): + entries = list(records()) + active = [r for r in entries if r[3]] + inactive = [r for r in entries if not r[3]] + by_key = defaultdict(list) + for group, action, label, current, default in active: + for key in current: + by_key[key].append(group + ' / ' + action) + duplicates = {key: owners for key, owners in by_key.items() if len(owners) > 1} + lines = ['# KDE shortcuts', '', + 'Generated from the repo’s captured `kglobalshortcutsrc`. This describes', + 'Fiw’s bindings as configured; applying them is a separate installer action.', + 'It covers KDE global shortcuts, not every shortcut inside individual applications.', '', + f'**{len(active)} assigned actions · {len(inactive)} unassigned actions · {len(entries)} total**', '', + '`Meta` is the Super/Windows key. In the full tables, multiple keys for', + 'one action are alternatives. Grouped summary keys match the named actions', + 'in order. “Unassigned” means explicitly disabled in this capture;', + 'a key in the KDE default column is not an active binding. The default', + 'column is copied from KDE’s stored values, not inferred from a release.', '', + '## Everyday bindings', '', + '| Keys | Action |', '|---|---|', + 'Screenshot bindings use `fiw-shot`: copy to clipboard, then offer Save', + 'or Edit in the notification. They need Spectacle, `wl-copy` and', + '`notify-send`; Kitty and KRunner bindings need their respective apps.', + 'The native Spectacle bindings are unassigned to avoid competing actions.', '', + 'The desktop-move bindings are stored as literal symbols (`!`, `@`, `#`).', + 'On a US layout these usually mean Shift+1/2/3; other layouts can differ.', + 'The keyboard-layout preset contains US English, Russian and Spanish;', + '`Meta+Alt+Space` cycles through them. Shortcut restoration does not', + 'create three virtual desktops or activities on a new installation.', '', + '## Captured choices', ''] + lookup = {(r[0], r[1]): r for r in entries} + highlights = [ + ('Open application launcher', '[plasmashell]', ['activate application launcher']), + ('Open KRunner', '[services][org.kde.krunner.desktop]', ['_launch']), + ('Open Kitty', '[services][net.local.kitty.desktop]', ['_launch']), + ('Select a screenshot region', '[services][net.local.fiw-shot-region.desktop]', ['_launch']), + ('Screenshot monitor under pointer', '[services][net.local.fiw-shot-screen.desktop]', ['_launch']), + ('Show clipboard history at pointer', '[plasmashell]', ['show-on-mouse-pos']), + ('Switch to desktop 1 / 2 / 3', '[kwin]', ['Switch to Desktop 1', 'Switch to Desktop 2', 'Switch to Desktop 3']), + ('Move window to desktop 1 / 2 / 3', '[kwin]', ['Window to Desktop 1', 'Window to Desktop 2', 'Window to Desktop 3']), + ('Switch desktop left / right / up / down', '[kwin]', ['Switch One Desktop to the Left', 'Switch One Desktop to the Right', 'Switch One Desktop Up', 'Switch One Desktop Down']), + ('Tile window left / right / up / down', '[kwin]', ['Window Quick Tile Left', 'Window Quick Tile Right', 'Window Quick Tile Top', 'Window Quick Tile Bottom']), + ('Move window to previous / next screen', '[kwin]', ['Window to Previous Screen', 'Window to Next Screen']), + ('Maximize window', '[kwin]', ['Window Maximize']), + ('Toggle Overview', '[kwin]', ['Overview']), + ('Toggle desktop grid', '[kwin]', ['Grid View']), + ('Next / previous activity', '[plasmashell]', ['next activity', 'previous activity']), + ('Lock session', '[ksmserver]', ['Lock Session']), + ('Show logout screen', '[ksmserver]', ['Log Out']), + ] + at = lines.index('Screenshot bindings use `fiw-shot`: copy to clipboard, then offer Save') + summary = [] + for label, group, actions in highlights: + current = [key for action in actions for key in lookup.get((group, action), (None, None, None, [], None))[3]] + summary.append('| ' + keys(current) + ' | ' + cell(label) + ' |') + lines[at:at] = summary + [''] + forward = lookup[('[kwin]', 'Walk Through Windows')][3] + lines += [('Forward window switching is currently unassigned; reverse switching' if not forward else + 'Forward window switching uses ' + keys(forward) + '; reverse switching'), + 'uses `Alt+Shift+Tab` and `Meta+Shift+Tab`.', '', + 'Other currently unassigned shortcuts include Peek at Desktop (`Meta+D`', + 'in the default column), Minimize (`Meta+PgDown`), Restore', + '(`Meta+Backspace`) and the window menu (`Alt+F3`). FiwNode’s four', + 'recorded global actions are unassigned. `Meta+1/2/3` are used for', + 'desktops, with the corresponding task-manager shortcuts disabled.', ''] + if duplicates: + lines += ['Keys assigned to multiple captured actions:', ''] + for key, owners in duplicates.items(): + lines.append('- ' + keys([key]) + ': ' + cell('; '.join(owners))) + lines.append('') + lines += ['## All assigned actions', ''] + grouped = defaultdict(list) + for record in entries: + grouped[record[0]].append(record) + friendly = sections(SOURCE.read_text()) + launch_names = {'[services][net.local.fiw-shot-region.desktop]': 'Screenshot region helper', + '[services][net.local.fiw-shot-screen.desktop]': 'Screenshot monitor helper', + '[services][net.local.kitty.desktop]': 'Kitty launcher', + '[services][org.kde.krunner.desktop]': 'KRunner launcher'} + for group, rows in grouped.items(): + assigned = [r for r in rows if r[3]] + if not assigned: + continue + title = launch_names.get(group, friendly[group].get('_k_friendly_name', group.strip('[]'))) + lines += ['### ' + cell(title), '', '| Action | Current keys | Stored KDE default |', '|---|---|---|'] + for _, action, label, current, default in assigned: + label = launch_names.get(group, label) if action == '_launch' else label + lines.append('| ' + cell(label) + ' | ' + keys(current) + ' | ' + keys(default) + ' |') + lines.append('') + lines += ['## All unassigned actions', '', + 'These entries are restored as unassigned, including actions with a', + 'stored KDE default. Expand each section to review the full capture.', ''] + for group, rows in grouped.items(): + disabled = [r for r in rows if not r[3]] + if not disabled: + continue + title = friendly[group].get('_k_friendly_name', group.strip('[]')) + lines += ['
', '' + cell(title) + f' ({len(disabled)})', '', + '| Action | Stored KDE default |', '|---|---|'] + for _, action, label, current, default in disabled: + lines.append('| ' + cell(label) + ' | ' + keys(default) + ' |') + lines += ['', '
', ''] + lines += ['## Refresh the reference', '', '```sh', 'python3 tools/shortcuts.py', '```', '', + 'Run this after reviewing a shortcut capture or changing the preset.', + 'The generator reads repo files only and does not change live KDE settings.', ''] + dest = REPO / 'docs/shortcuts.md' + dest.write_text('\n'.join(lines)) + print(f'Wrote docs/shortcuts.md: {len(active)} assigned, {len(inactive)} unassigned, {len(duplicates)} duplicate keys.') + + +if __name__ == '__main__': + generate()