// One shortcut the user invented, in the pinned Custom group. // // ShortcutRow renders a bind the compositor reported; this renders a stored // `customBinds` entry, which is a different thing and deliberately not the same // component. A custom bind has an action to describe (the compositor reports // every Lua bind as "__lua" plus a bytecode offset, so the description has to // come from the entry), it is removable, and it is never "overridden" -- a // rebind rewrites the entry in place rather than adding to the override map. // // The row reports and never decides: conflicts, the write and the reload all // belong to Keybinds, and the page owns the one capture at a time. import QtQuick import qs.config import qs.services SettingRow { id: root required property var entry property bool capturing: false // Shown inside the capture field -- the page puts a refused chord here. property string message: "" signal rebindRequested signal removeRequested signal captured(string chord) signal canceled readonly property string chord: String(root.entry?.chord ?? "") readonly property string action: Keybinds.describeAction(root.entry) // A stored entry is an intention; the keymap is the fact. hypr/keybinds.lua // skips an entry whose action does not resolve or whose chord a shipped // bind already holds, and a shortcut that quietly does nothing is exactly // what a settings page must not draw as working. readonly property bool live: root.action !== "" && Keybinds.customBindApplied(root.entry) label: String(root.entry?.label ?? "") detail: root.action === "" ? "This shortcut names an action Panama no longer has — remove it" : (root.live ? root.action : root.action + " · not answering yet — the compositor reloads on save") labelColor: root.action === "" ? Theme.danger : Theme.fg controlWidth: root.capturing ? 250 : (removeConfirm.armed ? 330 : 250) Row { anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter visible: !root.capturing spacing: 8 SettingsButton { anchors.verticalCenter: parent.verticalCenter text: "Rebind" enabled: !Keybinds.reloading onClicked: root.rebindRequested() } ConfirmAction { id: removeConfirm anchors.verticalCenter: parent.verticalCenter actionId: "custom-bind-remove:" + root.chord armText: "Remove…" confirmText: "Remove it" enabled: !Keybinds.reloading onConfirmed: root.removeRequested() } KeycapChord { anchors.verticalCenter: parent.verticalCenter chord: root.chord } } Loader { anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter width: 240 height: 30 active: root.capturing // Focus has to travel through the Loader for the capture inside it to // ever see a key press. focus: root.capturing sourceComponent: ShortcutCapture { focus: true message: root.message onCaptured: chord => root.captured(chord) onCanceled: root.canceled() } } }