From ae7f6bd16520c440cff82cdf257ac96aa144b3ba Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Tue, 12 May 2026 09:28:07 +0200 Subject: [PATCH 1/7] fix keybind cheatsheet --- .../ii/cheatsheet/CheatsheetKeybinds.qml | 228 +++++++----------- .../ii/services/HyprlandKeybinds.qml | 41 +--- 2 files changed, 99 insertions(+), 170 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/ii/cheatsheet/CheatsheetKeybinds.qml b/dots/.config/quickshell/ii/modules/ii/cheatsheet/CheatsheetKeybinds.qml index e15a5b2ad..ff194e562 100644 --- a/dots/.config/quickshell/ii/modules/ii/cheatsheet/CheatsheetKeybinds.qml +++ b/dots/.config/quickshell/ii/modules/ii/cheatsheet/CheatsheetKeybinds.qml @@ -2,18 +2,22 @@ pragma ComponentBehavior: Bound import qs.services import qs.modules.common +import qs.modules.common.functions import qs.modules.common.widgets import QtQuick import QtQuick.Layouts +import Quickshell Item { id: root - readonly property var keybinds: HyprlandKeybinds.keybinds - property real spacing: 20 + readonly property var keybinds: HyprlandKeybinds.keybinds.filter(function(keybind) { + return keybind.has_description; + }) + property real columnSpacing: 40 property real titleSpacing: 7 property real padding: 4 - implicitWidth: row.implicitWidth + padding * 2 - implicitHeight: row.implicitHeight + padding * 2 + implicitWidth: QsWindow.window.screen.width * 0.7 + implicitHeight: QsWindow.window.screen.height * 0.7 // Excellent symbol explaination and source : // http://xahlee.info/comp/unicode_computing_symbols.html // https://www.nerdfonts.com/cheat-sheet @@ -56,7 +60,7 @@ Item { "Page_↑/↓": "⇞/⇟", }) - property var keyBlacklist: ["Super_L"] + property var keyBlacklist: ["SUPER_L", "SUPER_R"] property var keySubstitutions: Object.assign({ "Super": "", "mouse_up": "Scroll ↓", // ikr, weird @@ -77,139 +81,91 @@ Item { Config.options.cheatsheet.useMouseSymbol ? mouseSymbolMap : {}, ) - Row { // Keybind columns - id: row - spacing: root.spacing - - Repeater { - model: keybinds.children - - delegate: Column { // Keybind sections - spacing: root.spacing - required property var modelData - anchors.top: row.top - - Repeater { - model: modelData.children - - delegate: Item { // Section with real keybinds - id: keybindSection - required property var modelData - implicitWidth: sectionColumn.implicitWidth - implicitHeight: sectionColumn.implicitHeight - - Column { - id: sectionColumn - anchors.centerIn: parent - spacing: root.titleSpacing - - StyledText { - id: sectionTitle - font { - family: Appearance.font.family.title - pixelSize: Appearance.font.pixelSize.title - variableAxes: Appearance.font.variableAxes.title - } - color: Appearance.colors.colOnLayer0 - text: keybindSection.modelData.name - } - - GridLayout { - id: keybindGrid - columns: 2 - columnSpacing: 4 - rowSpacing: 4 - - Repeater { - model: { - var result = []; - for (var i = 0; i < keybindSection.modelData.keybinds.length; i++) { - const keybind = keybindSection.modelData.keybinds[i]; - - if (!Config.options.cheatsheet.splitButtons) { - for (var j = 0; j < keybind.mods.length; j++) { - keybind.mods[j] = keySubstitutions[keybind.mods[j]] || keybind.mods[j]; - } - keybind.mods = [keybind.mods.join(' ') ] - keybind.mods[0] += !keyBlacklist.includes(keybind.key) && keybind.mods[0].length ? ' ' : '' - keybind.mods[0] += !keyBlacklist.includes(keybind.key) ? (keySubstitutions[keybind.key] || keybind.key) : '' - } - - result.push({ - "type": "keys", - "mods": keybind.mods, - "key": keybind.key, - }); - result.push({ - "type": "comment", - "comment": keybind.comment, - }); - } - return result; - } - delegate: Item { - required property var modelData - implicitWidth: keybindLoader.implicitWidth - implicitHeight: keybindLoader.implicitHeight - - Loader { - id: keybindLoader - sourceComponent: (modelData.type === "keys") ? keysComponent : commentComponent - } - - Component { - id: keysComponent - Row { - spacing: 4 - Repeater { - model: modelData.mods - delegate: KeyboardKey { - required property var modelData - key: keySubstitutions[modelData] || modelData - pixelSize: Config.options.cheatsheet.fontSize.key - } - } - StyledText { - id: keybindPlus - visible: Config.options.cheatsheet.splitButtons && !keyBlacklist.includes(modelData.key) && modelData.mods.length > 0 - text: "+" - } - KeyboardKey { - id: keybindKey - visible: Config.options.cheatsheet.splitButtons && !keyBlacklist.includes(modelData.key) - key: keySubstitutions[modelData.key] || modelData.key - pixelSize: Config.options.cheatsheet.fontSize.key - color: Appearance.colors.colOnLayer0 - } - } - } - - Component { - id: commentComponent - Item { - id: commentItem - implicitWidth: commentText.implicitWidth + 8 * 2 - implicitHeight: commentText.implicitHeight - - StyledText { - id: commentText - anchors.centerIn: parent - font.pixelSize: Config.options.cheatsheet.fontSize.comment || Appearance.font.pixelSize.smaller - text: modelData.comment - } - } - } - } - - } - } - } - } - + StyledFlickable { + id: flickable + anchors.fill: parent + anchors.margins: Appearance.rounding.small + contentHeight: height + contentWidth: flow.implicitWidth + Flow { + id: flow + height: flickable.height + flow: Flow.TopToBottom + spacing: 4 + Repeater { + model: root.keybinds + delegate: BindLine { + required property var modelData + keyData: modelData + } + } + } + } + + function modMaskToStringList(modMask: int): list { + var list = []; + if (modMask & (1 << 0)) { list.push("Shift"); } + if (modMask & (1 << 1)) { list.push("Caps"); } + if (modMask & (1 << 2)) { list.push("Ctrl"); } + if (modMask & (1 << 3)) { list.push("Alt"); } + if (modMask & (1 << 4)) { list.push("Mod2"); } + if (modMask & (1 << 5)) { list.push("Mod3"); } + if (modMask & (1 << 6)) { list.push("Super"); } + if (modMask & (1 << 7)) { list.push("Mod5"); } + return list; + } + + property int maxBindWidth: 0 + + component BindLine: Row { + required property var keyData + Row { + spacing: 16 + Row { + id: modRow + Component.onCompleted: root.maxBindWidth = Math.max(root.maxBindWidth, implicitWidth) + width: root.maxBindWidth + spacing: 4 + Repeater { + model: { + const modList = root.modMaskToStringList(keyData.modmask) + if (modList.length == 0) return [] + if (Config.options.cheatsheet.splitButtons) return modList; + return [modList.join(" ")] + } + delegate: KeyboardKey { + required property var modelData + key: root.keySubstitutions[modelData] || modelData + pixelSize: Config.options.cheatsheet.fontSize.key + } + } + StyledText { + id: keybindPlus + anchors.verticalCenter: parent.verticalCenter + visible: !keyBlacklist.includes(keyData.key) && keyData.modmask > 0 + text: "+" + } + KeyboardKey { + id: keybindKey + anchors.verticalCenter: parent.verticalCenter + visible: !keyBlacklist.includes(keyData.key) + key: StringUtils.toTitleCase(root.keySubstitutions[keyData.key] || keyData.key) + pixelSize: Config.options.cheatsheet.fontSize.key + color: Appearance.colors.colOnLayer0 + } + } + Item { + anchors.verticalCenter: parent.verticalCenter + implicitWidth: commentText.implicitWidth + root.columnSpacing + implicitHeight: commentText.implicitHeight + StyledText { + id: commentText + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + font.pixelSize: Config.options.cheatsheet.fontSize.comment || Appearance.font.pixelSize.smaller + text: keyData.description } } - } } - } diff --git a/dots/.config/quickshell/ii/services/HyprlandKeybinds.qml b/dots/.config/quickshell/ii/services/HyprlandKeybinds.qml index 3381926b9..f24c6e055 100644 --- a/dots/.config/quickshell/ii/services/HyprlandKeybinds.qml +++ b/dots/.config/quickshell/ii/services/HyprlandKeybinds.qml @@ -14,54 +14,27 @@ import Quickshell.Hyprland */ Singleton { id: root - property string keybindParserPath: FileUtils.trimFileProtocol(`${Directories.scriptPath}/hyprland/get_keybinds.py`) - property string defaultKeybindConfigPath: FileUtils.trimFileProtocol(`${Directories.config}/hypr/hyprland/keybinds.conf`) - property string userKeybindConfigPath: FileUtils.trimFileProtocol(`${Directories.config}/hypr/custom/keybinds.conf`) - property var defaultKeybinds: {"children": []} - property var userKeybinds: {"children": []} - property var keybinds: ({ - children: [ - ...(defaultKeybinds.children ?? []), - ...(userKeybinds.children ?? []), - ] - }) + property var keybinds: [] Connections { target: Hyprland function onRawEvent(event) { if (event.name == "configreloaded") { - getDefaultKeybinds.running = true - getUserKeybinds.running = true + getKeybinds.running = true } } } Process { - id: getDefaultKeybinds + id: getKeybinds running: true - command: [root.keybindParserPath, "--path", root.defaultKeybindConfigPath] + command: ["hyprctl", "binds", "-j"] - stdout: SplitParser { - onRead: data => { + stdout: StdioCollector { + onStreamFinished: { try { - root.defaultKeybinds = JSON.parse(data) - } catch (e) { - console.error("[CheatsheetKeybinds] Error parsing keybinds:", e) - } - } - } - } - - Process { - id: getUserKeybinds - running: true - command: [root.keybindParserPath, "--path", root.userKeybindConfigPath] - - stdout: SplitParser { - onRead: data => { - try { - root.userKeybinds = JSON.parse(data) + root.keybinds = JSON.parse(text) } catch (e) { console.error("[CheatsheetKeybinds] Error parsing keybinds:", e) } From 388783e992761ad24ff424b442fdb73078f9495b Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Tue, 12 May 2026 09:55:24 +0200 Subject: [PATCH 2/7] hyprland: exclude monitors and workspaces conf --- sdata/subcmd-install/3.files-exp.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdata/subcmd-install/3.files-exp.yaml b/sdata/subcmd-install/3.files-exp.yaml index ec4458357..81ce76016 100644 --- a/sdata/subcmd-install/3.files-exp.yaml +++ b/sdata/subcmd-install/3.files-exp.yaml @@ -46,7 +46,7 @@ patterns: - from: "dots/.config/hypr" to: "$XDG_CONFIG_HOME/hypr" mode: "sync" - excludes: ["custom", "hyprlock.conf", "hypridle.conf", "monitors.conf", "workspaces.conf"] + excludes: ["custom", "hyprlock.conf", "hypridle.conf"] # Hyprland special files - from: "dots/.config/hypr/hypridle.conf" to: "$XDG_CONFIG_HOME/hypr/hypridle.conf" From 281b3e562787cc65cda7d743261fa543530bd19e Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Tue, 12 May 2026 09:59:17 +0200 Subject: [PATCH 3/7] previous commit but in the "legacy" script --- sdata/subcmd-install/3.files-legacy.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdata/subcmd-install/3.files-legacy.sh b/sdata/subcmd-install/3.files-legacy.sh index 866089dc4..a2d4c9dfa 100644 --- a/sdata/subcmd-install/3.files-legacy.sh +++ b/sdata/subcmd-install/3.files-legacy.sh @@ -48,10 +48,10 @@ case "${SKIP_HYPRLAND}" in true) sleep 0;; *) install_dir__sync dots/.config/hypr/hyprland "$XDG_CONFIG_HOME"/hypr/hyprland - for i in hyprlock.conf {monitors,workspaces}.conf ; do + for i in hyprlock.conf ; do install_file__auto_backup "dots/.config/hypr/$i" "${XDG_CONFIG_HOME}/hypr/$i" done - for i in hyprland.conf ; do + for i in hyprland.lua ; do case "${SKIP_HYPRLAND_ENTRY}" in true) sleep 0;; *) install_file "dots/.config/hypr/$i" "${XDG_CONFIG_HOME}/hypr/$i" ;; From a9f87c06ca4b19506133f39e6bb0b19370dee16a Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Tue, 12 May 2026 10:06:10 +0200 Subject: [PATCH 4/7] install script: rename hyprland.conf to not use it --- sdata/subcmd-install/3.files-legacy.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/sdata/subcmd-install/3.files-legacy.sh b/sdata/subcmd-install/3.files-legacy.sh index a2d4c9dfa..4f84c13d2 100644 --- a/sdata/subcmd-install/3.files-legacy.sh +++ b/sdata/subcmd-install/3.files-legacy.sh @@ -48,6 +48,7 @@ case "${SKIP_HYPRLAND}" in true) sleep 0;; *) install_dir__sync dots/.config/hypr/hyprland "$XDG_CONFIG_HOME"/hypr/hyprland + mv "${XDG_CONFIG_HOME}/hypr/hyprland.conf" "${XDG_CONFIG_HOME}/hypr/hyprland.conf.old" # disable old config for i in hyprlock.conf ; do install_file__auto_backup "dots/.config/hypr/$i" "${XDG_CONFIG_HOME}/hypr/$i" done From 7aad60eb2c2d19e4f99a97af75559b4829989869 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Tue, 12 May 2026 10:31:40 +0200 Subject: [PATCH 5/7] install script: add check for hyprland.conf rename --- sdata/subcmd-install/3.files-legacy.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sdata/subcmd-install/3.files-legacy.sh b/sdata/subcmd-install/3.files-legacy.sh index 4f84c13d2..eb04b4a0f 100644 --- a/sdata/subcmd-install/3.files-legacy.sh +++ b/sdata/subcmd-install/3.files-legacy.sh @@ -48,7 +48,10 @@ case "${SKIP_HYPRLAND}" in true) sleep 0;; *) install_dir__sync dots/.config/hypr/hyprland "$XDG_CONFIG_HOME"/hypr/hyprland - mv "${XDG_CONFIG_HOME}/hypr/hyprland.conf" "${XDG_CONFIG_HOME}/hypr/hyprland.conf.old" # disable old config + if [ -f "${XDG_CONFIG_HOME}/hypr/hyprland.conf" ]; then + mv "${XDG_CONFIG_HOME}/hypr/hyprland.conf" "${XDG_CONFIG_HOME}/hypr/hyprland.conf.old" # disable old config + echo 'hyprland.conf has been renamed to hyprland.conf.old. This is to allow the new lua config to load.' + fi for i in hyprlock.conf ; do install_file__auto_backup "dots/.config/hypr/$i" "${XDG_CONFIG_HOME}/hypr/$i" done From 1c117e0880fc502b2bb06f978a99a873c3d4b562 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Tue, 12 May 2026 10:34:59 +0200 Subject: [PATCH 6/7] add example keybind for editing user keybinds --- dots/.config/hypr/custom/keybinds.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dots/.config/hypr/custom/keybinds.lua b/dots/.config/hypr/custom/keybinds.lua index 8b1378917..e853b96d6 100644 --- a/dots/.config/hypr/custom/keybinds.lua +++ b/dots/.config/hypr/custom/keybinds.lua @@ -1 +1 @@ - +hl.bind("CTRL+SUPER+ALT+Slash", hl.dsp.exec_cmd("xdg-open ~/.config/hypr/custom/keybinds.lua"), {description = "Edit user keybinds"} ) From ba0e76da1b6ebf0894bf202c9c788bdaa16773df Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Tue, 12 May 2026 10:47:44 +0200 Subject: [PATCH 7/7] fix hyprland theming --- dots/.config/matugen/config.toml | 4 +-- .../matugen/templates/hyprland/colors.conf | 32 ------------------- .../matugen/templates/hyprland/colors.lua | 16 ++++++++++ 3 files changed, 18 insertions(+), 34 deletions(-) delete mode 100644 dots/.config/matugen/templates/hyprland/colors.conf create mode 100644 dots/.config/matugen/templates/hyprland/colors.lua diff --git a/dots/.config/matugen/config.toml b/dots/.config/matugen/config.toml index 1f47d1565..4c4449a3b 100644 --- a/dots/.config/matugen/config.toml +++ b/dots/.config/matugen/config.toml @@ -6,8 +6,8 @@ input_path = '~/.config/matugen/templates/colors.json' output_path = '~/.local/state/quickshell/user/generated/colors.json' [templates.hyprland] -input_path = '~/.config/matugen/templates/hyprland/colors.conf' -output_path = '~/.config/hypr/hyprland/colors.conf' +input_path = '~/.config/matugen/templates/hyprland/colors.lua' +output_path = '~/.config/hypr/hyprland/colors.lua' [templates.hyprlock] input_path = '~/.config/matugen/templates/hyprland/hyprlock-colors.conf' diff --git a/dots/.config/matugen/templates/hyprland/colors.conf b/dots/.config/matugen/templates/hyprland/colors.conf deleted file mode 100644 index 6c11ce26a..000000000 --- a/dots/.config/matugen/templates/hyprland/colors.conf +++ /dev/null @@ -1,32 +0,0 @@ -general { - col.active_border = rgba({{colors.outline_variant.default.hex_stripped}}77) - col.inactive_border = rgba({{colors.surface_container_low.default.hex_stripped}}33) -} - -misc { - background_color = rgba({{colors.surface.dark.hex_stripped}}FF) -} - -plugin { - hyprbars { - # Honestly idk if it works like css, but well, why not - bar_text_font = Google Sans Flex Medium, Rubik, Geist, AR One Sans, Reddit Sans, Inter, Roboto, Ubuntu, Noto Sans, sans-serif - bar_height = 30 - bar_padding = 10 - bar_button_padding = 5 - bar_precedence_over_border = true - bar_part_of_window = true - - bar_color = rgba({{colors.background.default.hex_stripped}}FF) - col.text = rgba({{colors.on_background.default.hex_stripped}}FF) - - - # example buttons (R -> L) - # hyprbars-button = color, size, on-click - hyprbars-button = rgb({{colors.on_background.default.hex_stripped}}), 13, 󰖭, hyprctl dispatch killactive - hyprbars-button = rgb({{colors.on_background.default.hex_stripped}}), 13, 󰖯, hyprctl dispatch fullscreen 1 - hyprbars-button = rgb({{colors.on_background.default.hex_stripped}}), 13, 󰖰, hyprctl dispatch movetoworkspacesilent special - } -} - -windowrule = border_color rgba({{colors.primary.default.hex_stripped}}AA) rgba({{colors.primary.default.hex_stripped}}77), match:pin 1 diff --git a/dots/.config/matugen/templates/hyprland/colors.lua b/dots/.config/matugen/templates/hyprland/colors.lua new file mode 100644 index 000000000..0175f2d47 --- /dev/null +++ b/dots/.config/matugen/templates/hyprland/colors.lua @@ -0,0 +1,16 @@ +hl.config({ + general = { + col = { + active_border = "rgba({{colors.outline_variant.default.hex_stripped}}77)", + inactive_border = "rgba({{colors.surface_container_low.default.hex_stripped}}33)", + }, + }, + misc = { + background_color = "rgba({{colors.surface.dark.hex_stripped}}FF)", + }, +}) + +hl.window_rule({ + match = { pin = 1 }, + border_color = "rgba({{colors.primary.default.hex_stripped}}AA) rgba({{colors.primary.default.hex_stripped}}77)", +})