diff --git a/quickshell/DMSShellIPC.qml b/quickshell/DMSShellIPC.qml index f0d00e27..541dd843 100644 --- a/quickshell/DMSShellIPC.qml +++ b/quickshell/DMSShellIPC.qml @@ -332,18 +332,16 @@ Item { if (!provider) return "ERROR: No provider specified"; - KeybindsService.currentProvider = provider; - KeybindsService.loadBinds(); + KeybindsService.loadCheatsheet(provider); root.hyprKeybindsModalLoader.active = true; if (!root.hyprKeybindsModalLoader.item) return `KEYBINDS_TOGGLE_FAILED: ${provider}`; - if (root.hyprKeybindsModalLoader.item.shouldBeVisible) { + if (root.hyprKeybindsModalLoader.item.shouldBeVisible) root.hyprKeybindsModalLoader.item.close(); - } else { + else root.hyprKeybindsModalLoader.item.open(); - } return `KEYBINDS_TOGGLE_SUCCESS: ${provider}`; } @@ -351,18 +349,16 @@ Item { if (!provider) return "ERROR: No provider specified"; - KeybindsService.currentProvider = provider; - KeybindsService.loadBinds(); + KeybindsService.loadCheatsheet(provider); root.hyprKeybindsModalLoader.active = true; if (!root.hyprKeybindsModalLoader.item) return `KEYBINDS_TOGGLE_FAILED: ${provider}`; - if (root.hyprKeybindsModalLoader.item.shouldBeVisible) { + if (root.hyprKeybindsModalLoader.item.shouldBeVisible) root.hyprKeybindsModalLoader.item.close(); - } else { + else root.hyprKeybindsModalLoader.item.open(); - } return `KEYBINDS_TOGGLE_SUCCESS: ${provider} (${path})`; } @@ -370,8 +366,7 @@ Item { if (!provider) return "ERROR: No provider specified"; - KeybindsService.currentProvider = provider; - KeybindsService.loadBinds(); + KeybindsService.loadCheatsheet(provider); root.hyprKeybindsModalLoader.active = true; if (!root.hyprKeybindsModalLoader.item) @@ -385,8 +380,7 @@ Item { if (!provider) return "ERROR: No provider specified"; - KeybindsService.currentProvider = provider; - KeybindsService.loadBinds(); + KeybindsService.loadCheatsheet(provider); root.hyprKeybindsModalLoader.active = true; if (!root.hyprKeybindsModalLoader.item) diff --git a/quickshell/Modals/KeybindsModal.qml b/quickshell/Modals/KeybindsModal.qml index a723931f..f506fd03 100644 --- a/quickshell/Modals/KeybindsModal.qml +++ b/quickshell/Modals/KeybindsModal.qml @@ -19,7 +19,7 @@ DankModal { onBackgroundClicked: close() onOpened: { Qt.callLater(() => modalFocusScope.forceActiveFocus()); - if (KeybindsService.cheatsheetAvailable) + if (!Object.keys(KeybindsService.cheatsheet).length && KeybindsService.cheatsheetAvailable) KeybindsService.loadCheatsheet(); } @@ -118,12 +118,36 @@ DankModal { } property var categoryKeys: Object.keys(categories) + function estimateCategoryHeight(catName) { + const catData = categories[catName]; + if (!catData) + return 0; + let bindCount = 0; + for (const key of catData.subcatKeys) { + bindCount += catData.subcats[key]?.length || 0; + if (key !== "_root") + bindCount += 1; + } + return 40 + bindCount * 28; + } + function distributeCategories(cols) { const columns = []; - for (let i = 0; i < cols; i++) + const heights = []; + for (let i = 0; i < cols; i++) { columns.push([]); - for (let i = 0; i < categoryKeys.length; i++) - columns[i % cols].push(categoryKeys[i]); + heights.push(0); + } + const sorted = [...categoryKeys].sort((a, b) => estimateCategoryHeight(b) - estimateCategoryHeight(a)); + for (const cat of sorted) { + let minIdx = 0; + for (let i = 1; i < cols; i++) { + if (heights[i] < heights[minIdx]) + minIdx = i; + } + columns[minIdx].push(cat); + heights[minIdx] += estimateCategoryHeight(cat); + } return columns; } @@ -141,7 +165,7 @@ DankModal { Column { id: masonryColumn width: (rowLayout.width - rowLayout.spacing * (rowLayout.numColumns - 1)) / rowLayout.numColumns - spacing: Theme.spacingM + spacing: Theme.spacingXL Repeater { model: rowLayout.columnCategories[index] || [] @@ -203,37 +227,37 @@ DankModal { Repeater { model: parent.parent.subcatBinds - Row { + Item { width: parent.width - spacing: Theme.spacingS + height: 24 StyledRect { - width: Math.min(140, parent.width * 0.42) + id: keyBadge + width: Math.min(keyText.implicitWidth + 12, 160) height: 22 radius: 4 - opacity: 0.9 + anchors.verticalCenter: parent.verticalCenter StyledText { + id: keyText anchors.centerIn: parent - anchors.margins: 2 - width: parent.width - 4 color: Theme.secondary text: modelData.key || "" font.pixelSize: Theme.fontSizeSmall font.weight: Font.Medium isMonospace: true - elide: Text.ElideRight - horizontalAlignment: Text.AlignHCenter } } StyledText { - width: parent.width - 150 + anchors.left: parent.left + anchors.leftMargin: 170 + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter text: modelData.desc || modelData.action || "" font.pixelSize: Theme.fontSizeSmall opacity: 0.9 elide: Text.ElideRight - anchors.verticalCenter: parent.verticalCenter } } } diff --git a/quickshell/Services/KeybindsService.qml b/quickshell/Services/KeybindsService.qml index b21a0744..0d0be6a3 100644 --- a/quickshell/Services/KeybindsService.qml +++ b/quickshell/Services/KeybindsService.qml @@ -233,11 +233,14 @@ Singleton { loadBinds(true); } - function loadCheatsheet() { - if (cheatsheetProcess.running || !cheatsheetAvailable) + function loadCheatsheet(provider) { + if (cheatsheetProcess.running) + return; + const target = provider || cheatsheetProvider; + if (!target) return; cheatsheetLoading = true; - cheatsheetProcess.command = ["dms", "keybinds", "show", cheatsheetProvider]; + cheatsheetProcess.command = ["dms", "keybinds", "show", target]; cheatsheetProcess.running = true; }