diff options
Diffstat (limited to 'raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/KeybindsService.qml')
| -rw-r--r-- | raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/KeybindsService.qml | 528 |
1 files changed, 0 insertions, 528 deletions
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/KeybindsService.qml b/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/KeybindsService.qml deleted file mode 100644 index 470831b..0000000 --- a/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Services/KeybindsService.qml +++ /dev/null @@ -1,528 +0,0 @@ -pragma Singleton -pragma ComponentBehavior: Bound - -import QtCore -import QtQuick -import Quickshell -import Quickshell.Io -import Quickshell.Wayland -// ! Even though qmlls says this is unused, it is wrong -import qs.Common -import "../Common/KeybindActions.js" as Actions - -Singleton { - id: root - - Component.onCompleted: { - if (!shortcutInhibitorAvailable) { - console.warn("[KeybindsService] ShortcutInhibitor is not available in this environment, keybinds editor disabled."); - } - } - - readonly property bool shortcutInhibitorAvailable: { - try { - return typeof ShortcutInhibitor !== "undefined"; - } catch (e) { - return false; - } - } - - property bool available: (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl) && shortcutInhibitorAvailable - property string currentProvider: { - if (CompositorService.isNiri) - return "niri"; - if (CompositorService.isHyprland) - return "hyprland"; - if (CompositorService.isDwl) - return "mangowc"; - return ""; - } - - readonly property string cheatsheetProvider: { - if (CompositorService.isNiri) - return "niri"; - if (CompositorService.isHyprland) - return "hyprland"; - if (CompositorService.isDwl) - return "mangowc"; - return ""; - } - property bool cheatsheetAvailable: cheatsheetProvider !== "" - property bool cheatsheetLoading: false - property var cheatsheet: ({}) - - property bool loading: false - property bool saving: false - property bool fixing: false - property string lastError: "" - property bool dmsBindsIncluded: true - - property var dmsStatus: ({ - "exists": true, - "included": true, - "includePosition": -1, - "totalIncludes": 0, - "bindsAfterDms": 0, - "effective": true, - "overriddenBy": 0, - "statusMessage": "" - }) - - property var _rawData: null - property var keybinds: ({}) - property var _allBinds: ({}) - property var _categories: [] - property var _flatCache: [] - property var displayList: [] - property int _dataVersion: 0 - property string _pendingSavedKey: "" - - readonly property var categoryOrder: Actions.getCategoryOrder() - readonly property string configDir: Paths.strip(StandardPaths.writableLocation(StandardPaths.ConfigLocation)) - readonly property string compositorConfigDir: { - switch (currentProvider) { - case "niri": - return configDir + "/niri"; - case "hyprland": - return configDir + "/hypr"; - case "mangowc": - return configDir + "/mango"; - default: - return ""; - } - } - readonly property string dmsBindsPath: { - switch (currentProvider) { - case "niri": - return compositorConfigDir + "/dms/binds.kdl"; - case "hyprland": - case "mangowc": - return compositorConfigDir + "/dms/binds.conf"; - default: - return ""; - } - } - readonly property string mainConfigPath: { - switch (currentProvider) { - case "niri": - return compositorConfigDir + "/config.kdl"; - case "hyprland": - return compositorConfigDir + "/hyprland.conf"; - case "mangowc": - return compositorConfigDir + "/config.conf"; - default: - return ""; - } - } - readonly property var actionTypes: Actions.getActionTypes() - readonly property var dmsActions: getDmsActions() - - signal bindsLoaded - signal bindSaved(string key) - signal bindSaveCompleted(bool success) - signal bindRemoved(string key) - signal dmsBindsFixed - signal cheatsheetLoaded - - Connections { - target: CompositorService - function onCompositorChanged() { - if (!CompositorService.isNiri) - return; - Qt.callLater(root.loadBinds); - } - } - - Connections { - target: NiriService - enabled: CompositorService.isNiri - function onConfigReloaded() { - Qt.callLater(root.loadBinds, false); - } - } - - Process { - id: cheatsheetProcess - running: false - - stdout: StdioCollector { - onStreamFinished: { - try { - root.cheatsheet = JSON.parse(text); - } catch (e) { - console.error("[KeybindsService] Failed to parse cheatsheet:", e); - root.cheatsheet = {}; - } - root.cheatsheetLoading = false; - root.cheatsheetLoaded(); - } - } - - onExited: exitCode => { - if (exitCode === 0) - return; - console.warn("[KeybindsService] Cheatsheet load failed with code:", exitCode); - root.cheatsheetLoading = false; - } - } - - Process { - id: loadProcess - running: false - - stdout: StdioCollector { - onStreamFinished: { - try { - root._rawData = JSON.parse(text); - root._processData(); - } catch (e) { - console.error("[KeybindsService] Failed to parse binds:", e); - } - root.loading = false; - } - } - - onExited: exitCode => { - if (exitCode !== 0) { - console.warn("[KeybindsService] Load process failed with code:", exitCode); - root.loading = false; - } - } - } - - Process { - id: saveProcess - running: false - - stderr: StdioCollector { - onStreamFinished: { - if (!text.trim()) - return; - root.lastError = text.trim(); - ToastService.showError(I18n.tr("Failed to save keybind"), "", root.lastError, "keybinds"); - } - } - - onExited: exitCode => { - root.saving = false; - if (exitCode !== 0) { - console.error("[KeybindsService] Save failed with code:", exitCode); - root.bindSaveCompleted(false); - return; - } - root.lastError = ""; - root.bindSaveCompleted(true); - root.loadBinds(false); - } - } - - Process { - id: removeProcess - running: false - - stderr: StdioCollector { - onStreamFinished: { - if (!text.trim()) - return; - root.lastError = text.trim(); - ToastService.showError(I18n.tr("Failed to remove keybind"), "", root.lastError, "keybinds"); - } - } - - onExited: exitCode => { - if (exitCode !== 0) { - console.error("[KeybindsService] Remove failed with code:", exitCode); - return; - } - root.lastError = ""; - root.loadBinds(false); - } - } - - Process { - id: fixProcess - running: false - - stderr: StdioCollector { - onStreamFinished: { - if (!text.trim()) - return; - root.lastError = text.trim(); - ToastService.showError(I18n.tr("Failed to add binds include"), "", root.lastError, "keybinds"); - } - } - - onExited: exitCode => { - root.fixing = false; - if (exitCode !== 0) { - console.error("[KeybindsService] Fix failed with code:", exitCode); - return; - } - root.lastError = ""; - root.dmsBindsIncluded = true; - root.dmsBindsFixed(); - const bindsFile = root.currentProvider === "niri" ? "dms/binds.kdl" : "dms/binds.conf"; - ToastService.showInfo(I18n.tr("Binds include added"), I18n.tr("%1 is now included in config").arg(bindsFile), "", "keybinds"); - Qt.callLater(root.forceReload); - } - } - - function fixDmsBindsInclude() { - if (fixing || dmsBindsIncluded || !compositorConfigDir) - return; - fixing = true; - const timestamp = Math.floor(Date.now() / 1000); - const backupPath = `${mainConfigPath}.dmsbackup${timestamp}`; - let script; - switch (currentProvider) { - case "niri": - script = `mkdir -p "${compositorConfigDir}/dms" && touch "${compositorConfigDir}/dms/binds.kdl" && cp "${mainConfigPath}" "${backupPath}" && echo 'include "dms/binds.kdl"' >> "${mainConfigPath}"`; - break; - case "hyprland": - script = `mkdir -p "${compositorConfigDir}/dms" && touch "${compositorConfigDir}/dms/binds.conf" && cp "${mainConfigPath}" "${backupPath}" && echo 'source = ./dms/binds.conf' >> "${mainConfigPath}"`; - break; - case "mangowc": - script = `mkdir -p "${compositorConfigDir}/dms" && touch "${compositorConfigDir}/dms/binds.conf" && cp "${mainConfigPath}" "${backupPath}" && echo 'source = ./dms/binds.conf' >> "${mainConfigPath}"`; - break; - default: - fixing = false; - return; - } - fixProcess.command = ["sh", "-c", script]; - fixProcess.running = true; - } - - function forceReload() { - _allBinds = {}; - _flatCache = []; - _categories = []; - loadBinds(true); - } - - function loadCheatsheet(provider) { - if (cheatsheetProcess.running) - return; - const target = provider || cheatsheetProvider; - if (!target) - return; - cheatsheetLoading = true; - cheatsheetProcess.command = ["dms", "keybinds", "show", target]; - cheatsheetProcess.running = true; - } - - function loadBinds(showLoading) { - if (loadProcess.running || !available) - return; - const hasData = Object.keys(_allBinds).length > 0; - loading = showLoading !== false && !hasData; - loadProcess.command = ["dms", "keybinds", "show", currentProvider]; - loadProcess.running = true; - } - - function _processData() { - keybinds = _rawData || {}; - dmsBindsIncluded = _rawData?.dmsBindsIncluded ?? true; - const status = _rawData?.dmsStatus; - if (status) { - dmsStatus = { - "exists": status.exists ?? true, - "included": status.included ?? true, - "includePosition": status.includePosition ?? -1, - "totalIncludes": status.totalIncludes ?? 0, - "bindsAfterDms": status.bindsAfterDms ?? 0, - "effective": status.effective ?? true, - "overriddenBy": status.overriddenBy ?? 0, - "statusMessage": status.statusMessage ?? "" - }; - } - - if (!_rawData?.binds) { - _allBinds = {}; - _categories = []; - _flatCache = []; - displayList = []; - _dataVersion++; - bindsLoaded(); - if (_pendingSavedKey) { - bindSaved(_pendingSavedKey); - _pendingSavedKey = ""; - } - return; - } - - const processed = {}; - const bindsData = _rawData.binds; - for (const cat in bindsData) { - const binds = bindsData[cat]; - for (var i = 0; i < binds.length; i++) { - const bind = binds[i]; - const targetCat = Actions.isDmsAction(bind.action) ? "DMS" : cat; - if (!processed[targetCat]) - processed[targetCat] = []; - processed[targetCat].push(bind); - } - } - - const sortedCats = Object.keys(processed).sort((a, b) => { - const ai = categoryOrder.indexOf(a); - const bi = categoryOrder.indexOf(b); - return (ai === -1 ? 999 : ai) - (bi === -1 ? 999 : bi); - }); - - const grouped = []; - const actionMap = {}; - for (var ci = 0; ci < sortedCats.length; ci++) { - const category = sortedCats[ci]; - const binds = processed[category]; - if (!binds) - continue; - for (var i = 0; i < binds.length; i++) { - const bind = binds[i]; - const action = bind.action || ""; - const keyData = { - "key": bind.key || "", - "source": bind.source || "config", - "isOverride": bind.source === "dms", - "cooldownMs": bind.cooldownMs || 0, - "flags": bind.flags || "", - "allowWhenLocked": bind.allowWhenLocked || false, - "allowInhibiting": bind.allowInhibiting, - "repeat": bind.repeat - }; - if (actionMap[action]) { - actionMap[action].keys.push(keyData); - if (!actionMap[action].desc && bind.desc) - actionMap[action].desc = bind.desc; - if (!actionMap[action].conflict && bind.conflict) - actionMap[action].conflict = bind.conflict; - } else { - const entry = { - "category": category, - "action": action, - "desc": bind.desc || "", - "keys": [keyData], - "conflict": bind.conflict || null - }; - actionMap[action] = entry; - grouped.push(entry); - } - } - } - - const list = []; - for (const cat of sortedCats) { - list.push({ - "id": "cat:" + cat, - "type": "category", - "name": cat - }); - const binds = processed[cat]; - if (!binds) - continue; - for (const bind of binds) - list.push({ - "id": "bind:" + bind.key, - "type": "bind", - "key": bind.key, - "desc": bind.desc - }); - } - - _allBinds = processed; - _categories = sortedCats; - _flatCache = grouped; - displayList = list; - _dataVersion++; - bindsLoaded(); - if (_pendingSavedKey) { - bindSaved(_pendingSavedKey); - _pendingSavedKey = ""; - } - } - - function getCategories() { - return _categories; - } - - function getFlatBinds() { - return _flatCache; - } - - function saveBind(originalKey, bindData) { - if (!bindData.key || !Actions.isValidAction(bindData.action)) - return; - saving = true; - const cmd = ["dms", "keybinds", "set", currentProvider, bindData.key, bindData.action, "--desc", bindData.desc || ""]; - if (originalKey && originalKey !== bindData.key) - cmd.push("--replace-key", originalKey); - if (bindData.cooldownMs > 0) - cmd.push("--cooldown-ms", String(bindData.cooldownMs)); - if (bindData.allowWhenLocked) - cmd.push("--allow-when-locked"); - if (bindData.repeat === false) - cmd.push("--no-repeat"); - if (bindData.allowInhibiting === false) - cmd.push("--no-inhibiting"); - if (bindData.flags) - cmd.push("--flags", bindData.flags); - saveProcess.command = cmd; - saveProcess.running = true; - _pendingSavedKey = bindData.key; - } - - function removeBind(key) { - if (!key) - return; - removeProcess.command = ["dms", "keybinds", "remove", currentProvider, key]; - removeProcess.running = true; - bindRemoved(key); - } - - function isDmsAction(action) { - return Actions.isDmsAction(action); - } - - function isValidAction(action) { - return Actions.isValidAction(action); - } - - function getActionType(action) { - return Actions.getActionType(action); - } - - function getActionLabel(action) { - return Actions.getActionLabel(action, currentProvider); - } - - function getCompositorCategories() { - return Actions.getCompositorCategories(currentProvider); - } - - function getCompositorActions(category) { - return Actions.getCompositorActions(currentProvider, category); - } - - function getDmsActions() { - return Actions.getDmsActions(CompositorService.isNiri, CompositorService.isHyprland); - } - - function buildSpawnAction(command, args) { - return Actions.buildSpawnAction(command, args); - } - - function buildShellAction(shellCmd, shell) { - return Actions.buildShellAction(currentProvider, shellCmd, shell); - } - - function getShellFromAction(action) { - return Actions.getShellFromAction(action); - } - - function parseSpawnCommand(action) { - return Actions.parseSpawnCommand(action); - } - - function parseShellCommand(action) { - return Actions.parseShellCommand(action); - } -} |