diff --git a/Commons/Keybinds.qml b/Commons/Keybinds.qml new file mode 100644 index 000000000..cb464054d --- /dev/null +++ b/Commons/Keybinds.qml @@ -0,0 +1,179 @@ +pragma Singleton + +import QtQuick + +QtObject { + function getKeybindString(event) { + let keyStr = ""; + if (event.modifiers & Qt.ControlModifier) + keyStr += "Ctrl+"; + if (event.modifiers & Qt.AltModifier) + keyStr += "Alt+"; + if (event.modifiers & Qt.ShiftModifier) + keyStr += "Shift+"; + + let keyName = ""; + let rawText = event.text; + + if (event.key >= Qt.Key_A && event.key <= Qt.Key_Z || event.key >= Qt.Key_0 && event.key <= Qt.Key_9) { + keyName = String.fromCharCode(event.key); + } else if (event.key >= Qt.Key_F1 && event.key <= Qt.Key_F12) { + keyName = "F" + (event.key - Qt.Key_F1 + 1); + } else if (rawText && rawText.length > 0 && rawText.charCodeAt(0) > 31 && rawText.charCodeAt(0) !== 127) { + keyName = rawText.toUpperCase(); + + if (event.modifiers & Qt.ShiftModifier) { + const shiftMap = { + "!": "1", + "\"": "2", + "§": "3", + "$": "4", + "%": "5", + "&": "6", + "/": "7", + "(": "8", + ")": "9", + "=": "0", + "@": "2", + "#": "3", + "^": "6", + "*": "8" + }; + if (shiftMap[keyName]) { + keyName = shiftMap[keyName]; + } + } + } else { + switch (event.key) { + case Qt.Key_Escape: + keyName = "Esc"; + break; + case Qt.Key_Space: + keyName = "Space"; + break; + case Qt.Key_Return: + keyName = "Return"; + break; + case Qt.Key_Enter: + keyName = "Enter"; + break; + case Qt.Key_Tab: + keyName = "Tab"; + break; + case Qt.Key_Backspace: + keyName = "Backspace"; + break; + case Qt.Key_Delete: + keyName = "Del"; + break; + case Qt.Key_Insert: + keyName = "Ins"; + break; + case Qt.Key_Home: + keyName = "Home"; + break; + case Qt.Key_End: + keyName = "End"; + break; + case Qt.Key_PageUp: + keyName = "PgUp"; + break; + case Qt.Key_PageDown: + keyName = "PgDn"; + break; + case Qt.Key_Left: + keyName = "Left"; + break; + case Qt.Key_Right: + keyName = "Right"; + break; + case Qt.Key_Up: + keyName = "Up"; + break; + case Qt.Key_Down: + keyName = "Down"; + break; + } + } + + if (!keyName) + return ""; + return keyStr + keyName; + } + + function checkKey(event, settingName, settings) { + // Map simplified names to the actual setting property names + var propName = "key" + settingName.charAt(0).toUpperCase() + settingName.slice(1); + var boundKeys = settings.data.general.keybinds[propName]; + if (!boundKeys || boundKeys.length === 0) + return false; + var eventString = getKeybindString(event); + for (var i = 0; i < boundKeys.length; i++) { + if (boundKeys[i] === eventString) + return true; + } + return false; + } + + /** + * Check if a keybind string conflicts with any other existing keybinds. + * @param {string} keyStr - The keybind string to check (e.g., "Ctrl+A"). + * @param {string} currentPath - The settings path of the keybind being edited (to skip checking itself). + * @param {object} data - The settings data object (from Settings.data). + * @returns {string|null} - The name of the conflicting action, or null if no conflict. + */ + function getKeybindConflict(keyStr, currentPath, data) { + if (!keyStr || !data) + return null; + + const searchKey = String(keyStr).trim().toLowerCase(); + + // 1. Check navigation keybinds + const navKeybinds = data.general ? data.general.keybinds : null; + const navMap = { + "keyUp": "Navigation: Up", + "keyDown": "Navigation: Down", + "keyLeft": "Navigation: Left", + "keyRight": "Navigation: Right", + "keyEnter": "Navigation: Enter", + "keyEscape": "Navigation: Escape" + }; + + if (navKeybinds) { + for (const prop in navMap) { + const fullPath = "general.keybinds." + prop; + if (fullPath === currentPath) + continue; + + const boundKeys = navKeybinds[prop]; + if (boundKeys && boundKeys.length !== undefined) { + for (let i = 0; i < boundKeys.length; i++) { + if (String(boundKeys[i]).trim().toLowerCase() === searchKey) { + return navMap[prop]; + } + } + } + } + } + + // 2. Check session menu power options + const sessionMenu = data.sessionMenu; + if (sessionMenu && sessionMenu.powerOptions) { + const powerOptions = sessionMenu.powerOptions; + for (let i = 0; i < powerOptions.length; i++) { + const entry = powerOptions[i]; + const fullPath = "sessionMenu.powerOptions[" + i + "].keybind"; + if (fullPath === currentPath) + continue; + + if (entry.keybind && String(entry.keybind).trim().toLowerCase() === searchKey) { + // Capitalize action name + const actionName = entry.action ? entry.action.charAt(0).toUpperCase() + entry.action.slice(1) : "Unknown"; + return "Session Menu: " + actionName; + } + } + } + + return null; + } +} diff --git a/Helpers/Keybinds.js b/Helpers/Keybinds.js deleted file mode 100644 index 20c0cd751..000000000 --- a/Helpers/Keybinds.js +++ /dev/null @@ -1,170 +0,0 @@ -function getKeybindString(event) { - let keyStr = ""; - if (event.modifiers & Qt.ControlModifier) - keyStr += "Ctrl+"; - if (event.modifiers & Qt.AltModifier) - keyStr += "Alt+"; - if (event.modifiers & Qt.ShiftModifier) - keyStr += "Shift+"; - - let keyName = ""; - let rawText = event.text; - - if (event.key >= Qt.Key_A && event.key <= Qt.Key_Z || event.key >= Qt.Key_0 && event.key <= Qt.Key_9) { - keyName = String.fromCharCode(event.key); - } else if (event.key >= Qt.Key_F1 && event.key <= Qt.Key_F12) { - keyName = "F" + (event.key - Qt.Key_F1 + 1); - } else if (rawText && rawText.length > 0 && rawText.charCodeAt(0) > 31 && rawText.charCodeAt(0) !== 127) { - keyName = rawText.toUpperCase(); - - if (event.modifiers & Qt.ShiftModifier) { - const shiftMap = { - "!": "1", - "\"": "2", - "§": "3", - "$": "4", - "%": "5", - "&": "6", - "/": "7", - "(": "8", - ")": "9", - "=": "0", - "@": "2", - "#": "3", - "^": "6", - "*": "8" - }; - if (shiftMap[keyName]) { - keyName = shiftMap[keyName]; - } - } - } else { - switch (event.key) { - case Qt.Key_Escape: - keyName = "Esc"; - break; - case Qt.Key_Space: - keyName = "Space"; - break; - case Qt.Key_Return: - keyName = "Return"; - break; - case Qt.Key_Enter: - keyName = "Enter"; - break; - case Qt.Key_Tab: - keyName = "Tab"; - break; - case Qt.Key_Backspace: - keyName = "Backspace"; - break; - case Qt.Key_Delete: - keyName = "Del"; - break; - case Qt.Key_Insert: - keyName = "Ins"; - break; - case Qt.Key_Home: - keyName = "Home"; - break; - case Qt.Key_End: - keyName = "End"; - break; - case Qt.Key_PageUp: - keyName = "PgUp"; - break; - case Qt.Key_PageDown: - keyName = "PgDn"; - break; - case Qt.Key_Left: - keyName = "Left"; - break; - case Qt.Key_Right: - keyName = "Right"; - break; - case Qt.Key_Up: - keyName = "Up"; - break; - case Qt.Key_Down: - keyName = "Down"; - break; - } - } - - if (!keyName) - return ""; - return keyStr + keyName; -} - -function checkKey(event, settingName, settings) { - // Map simplified names to the actual setting property names - var propName = "key" + settingName.charAt(0).toUpperCase() + settingName.slice(1); - var boundKeys = settings.data.general.keybinds[propName]; - if (!boundKeys || boundKeys.length === 0) - return false; - var eventString = getKeybindString(event); - for (var i = 0; i < boundKeys.length; i++) { - if (boundKeys[i] === eventString) - return true; - } - return false; -} - -/** - * Check if a keybind string conflicts with any other existing keybinds. - * @param {string} keyStr - The keybind string to check (e.g., "Ctrl+A"). - * @param {string} currentPath - The settings path of the keybind being edited (to skip checking itself). - * @param {object} data - The settings data object (from Settings.data). - * @returns {string|null} - The name of the conflicting action, or null if no conflict. - */ -function getKeybindConflict(keyStr, currentPath, data) { - if (!keyStr || !data) return null; - - const searchKey = String(keyStr).trim().toLowerCase(); - - // 1. Check navigation keybinds - const navKeybinds = data.general ? data.general.keybinds : null; - const navMap = { - "keyUp": "Navigation: Up", - "keyDown": "Navigation: Down", - "keyLeft": "Navigation: Left", - "keyRight": "Navigation: Right", - "keyEnter": "Navigation: Enter", - "keyEscape": "Navigation: Escape" - }; - - if (navKeybinds) { - for (const prop in navMap) { - const fullPath = "general.keybinds." + prop; - if (fullPath === currentPath) continue; - - const boundKeys = navKeybinds[prop]; - if (boundKeys && boundKeys.length !== undefined) { - for (let i = 0; i < boundKeys.length; i++) { - if (String(boundKeys[i]).trim().toLowerCase() === searchKey) { - return navMap[prop]; - } - } - } - } - } - - // 2. Check session menu power options - const sessionMenu = data.sessionMenu; - if (sessionMenu && sessionMenu.powerOptions) { - const powerOptions = sessionMenu.powerOptions; - for (let i = 0; i < powerOptions.length; i++) { - const entry = powerOptions[i]; - const fullPath = "sessionMenu.powerOptions[" + i + "].keybind"; - if (fullPath === currentPath) continue; - - if (entry.keybind && String(entry.keybind).trim().toLowerCase() === searchKey) { - // Capitalize action name - const actionName = entry.action ? entry.action.charAt(0).toUpperCase() + entry.action.slice(1) : "Unknown"; - return "Session Menu: " + actionName; - } - } - } - - return null; -} diff --git a/Modules/LockScreen/LockScreen.qml b/Modules/LockScreen/LockScreen.qml index e9c571605..ad08e4f73 100644 --- a/Modules/LockScreen/LockScreen.qml +++ b/Modules/LockScreen/LockScreen.qml @@ -4,7 +4,6 @@ import QtQuick.Layouts import Quickshell import Quickshell.Services.Pam import Quickshell.Wayland -import "../../Helpers/Keybinds.js" as Keybinds import qs.Commons import qs.Services.Compositor import qs.Services.Hardware diff --git a/Modules/Panels/Launcher/LauncherCore.qml b/Modules/Panels/Launcher/LauncherCore.qml index 49bf8e3e7..6c92f4907 100644 --- a/Modules/Panels/Launcher/LauncherCore.qml +++ b/Modules/Panels/Launcher/LauncherCore.qml @@ -3,7 +3,6 @@ import QtQuick.Controls import QtQuick.Layouts import Quickshell import Quickshell.Widgets -import "../../../Helpers/Keybinds.js" as Keybinds import "Providers" import qs.Commons diff --git a/Modules/Panels/NotificationHistory/NotificationHistoryPanel.qml b/Modules/Panels/NotificationHistory/NotificationHistoryPanel.qml index 80b43dd51..b14117afc 100644 --- a/Modules/Panels/NotificationHistory/NotificationHistoryPanel.qml +++ b/Modules/Panels/NotificationHistory/NotificationHistoryPanel.qml @@ -4,7 +4,6 @@ import QtQuick.Layouts import Quickshell import Quickshell.Services.Notifications import Quickshell.Wayland -import "../../../Helpers/Keybinds.js" as Keybinds import qs.Commons import qs.Modules.MainScreen import qs.Services.System diff --git a/Modules/Panels/SessionMenu/SessionMenu.qml b/Modules/Panels/SessionMenu/SessionMenu.qml index 42fa2b552..0e30c8071 100644 --- a/Modules/Panels/SessionMenu/SessionMenu.qml +++ b/Modules/Panels/SessionMenu/SessionMenu.qml @@ -6,7 +6,6 @@ import Quickshell import Quickshell.Io import Quickshell.Wayland import Quickshell.Widgets -import "../../../Helpers/Keybinds.js" as Keybinds import qs.Commons import qs.Modules.MainScreen import qs.Services.Compositor diff --git a/Modules/Panels/Wallpaper/WallpaperPanel.qml b/Modules/Panels/Wallpaper/WallpaperPanel.qml index f005a0711..1ed33d65c 100644 --- a/Modules/Panels/Wallpaper/WallpaperPanel.qml +++ b/Modules/Panels/Wallpaper/WallpaperPanel.qml @@ -2,7 +2,6 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import Quickshell -import "../../../Helpers/Keybinds.js" as Keybinds import qs.Commons import qs.Modules.MainScreen import qs.Modules.Panels.Settings diff --git a/Widgets/NKeybindRecorder.qml b/Widgets/NKeybindRecorder.qml index 6e3a3f4ce..31c0f7d89 100644 --- a/Widgets/NKeybindRecorder.qml +++ b/Widgets/NKeybindRecorder.qml @@ -1,7 +1,6 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts -import "../Helpers/Keybinds.js" as Keybinds import qs.Commons import qs.Services.UI import qs.Widgets