From daa671c6a528e037539d5b2ac689db8605ea61bc Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Sat, 25 Oct 2025 00:42:28 +0200 Subject: [PATCH 01/52] feat: add custom super key icon, mac symbol for mods keys and icon for function keys --- .../modules/cheatsheet/CheatsheetKeybinds.qml | 46 +++++-- .../quickshell/ii/modules/common/Config.qml | 10 ++ .../ii/modules/settings/AdvancedConfig.qml | 115 ++++++++++++++++++ 3 files changed, 163 insertions(+), 8 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml index 0cf6d40c8..521522530 100644 --- a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml +++ b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml @@ -14,18 +14,48 @@ Item { property real padding: 4 implicitWidth: row.implicitWidth + padding * 2 implicitHeight: row.implicitHeight + padding * 2 - + property list superMap: [ + "󰖳", "󰌽", "󰘳", "", "󰨡", "", "", + "󰣇", "", "", "", "", " ", "", "󱄛" + ] property var keyBlacklist: ["Super_L"] property var keySubstitutions: ({ - "Super": "󰖳", - "mouse_up": "Scroll ↓", // ikr, weird - "mouse_down": "Scroll ↑", // trust me bro - "mouse:272": "LMB", - "mouse:273": "RMB", + "Super": superMap[Config.options.appearance.keybinds.superKey], + "Ctrl": Config.options.appearance.keybinds.useMacSymbol ? "󰘴" : "Ctrl", + "Alt": Config.options.appearance.keybinds.useMacSymbol ? "󰘵" : "Alt", + "Shift": Config.options.appearance.keybinds.useMacSymbol ? "󰘶" : "Shift", + "Space": Config.options.appearance.keybinds.useMacSymbol ? "󱁐" : "Space", + "Tab": Config.options.appearance.keybinds.useMacSymbol ? "" : "Tab", + "Equal": Config.options.appearance.keybinds.useMacSymbol ? "󰇼" : "Equal", + "Minus": Config.options.appearance.keybinds.useMacSymbol ? "" : "Minus", + "Print": Config.options.appearance.keybinds.useMacSymbol ? "" : "Print", + "Delete": Config.options.appearance.keybinds.useMacSymbol ? "󰭜" : "Delete", + "Return": Config.options.appearance.keybinds.useMacSymbol ? "󰌑" : "Enter", + "Period": Config.options.appearance.keybinds.useMacSymbol ? "." : "Period", + + // Function keys + "Escape": Config.options.appearance.keybinds.useFnSymbol ? "󱊷" : "Escape", + "F1": Config.options.appearance.keybinds.useFnSymbol ? "󱊫" : "F1", + "F2": Config.options.appearance.keybinds.useFnSymbol ? "󱊬" : "F2", + "F3": Config.options.appearance.keybinds.useFnSymbol ? "󱊭" : "F3", + "F4": Config.options.appearance.keybinds.useFnSymbol ? "󱊮" : "F4", + "F5": Config.options.appearance.keybinds.useFnSymbol ? "󱊯" : "F5", + "F6": Config.options.appearance.keybinds.useFnSymbol ? "󱊰" : "F6", + "F7": Config.options.appearance.keybinds.useFnSymbol ? "󱊱" : "F7", + "F8": Config.options.appearance.keybinds.useFnSymbol ? "󱊲" : "F8", + "F9": Config.options.appearance.keybinds.useFnSymbol ? "󱊳" : "F9", + "F10": Config.options.appearance.keybinds.useFnSymbol ? "󱊴" : "F10", + "F11": Config.options.appearance.keybinds.useFnSymbol ? "󱊵" : "F11", + "F12": Config.options.appearance.keybinds.useFnSymbol ? "󱊶" : "F12", + + // Mouse keys + "mouse_up": Config.options.appearance.keybinds.useMouseSymbol ? "󱕐" : "Scroll ↓", // ikr, weird + "mouse_down": Config.options.appearance.keybinds.useMouseSymbol ? "󱕑" : "Scroll ↑", // trust me bro + "mouse:272": Config.options.appearance.keybinds.useMouseSymbol ? "L󰍽" : "LMB", + "mouse:273": Config.options.appearance.keybinds.useMouseSymbol ? "R󰍽" : "RMB", "mouse:275": "MouseBack", "Slash": "/", "Hash": "#", - "Return": "Enter", // "Shift": "", }) @@ -149,4 +179,4 @@ Item { } } -} \ No newline at end of file +} diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index 39c0ef131..dd4e1bc74 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -123,6 +123,16 @@ Singleton { property JsonObject palette: JsonObject { property string type: "auto" // Allowed: auto, scheme-content, scheme-expressive, scheme-fidelity, scheme-fruit-salad, scheme-monochrome, scheme-neutral, scheme-rainbow, scheme-tonal-spot } + property JsonObject keybinds: JsonObject { + // Use a nerdfont to see the icons + // 0: 󰖳 | 1: 󰌽 | 2: 󰘳 | 3:  | 4: 󰨡 + // 5:  | 6:  | 7: 󰣇 | 8:  | 9:  + // 10:  | 11:  | 12:  | 13:  | 14: 󱄛 + property int superKey: 0 + property bool useMacSymbol: false + property bool useMouseSymbol: false + property bool useFnSymbol: false + } } property JsonObject audio: JsonObject { diff --git a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml index 811cf7ca6..4dc71faa2 100644 --- a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml @@ -90,4 +90,119 @@ ContentPage { } } + ContentSection { + icon: "keyboard" + title: Translation.tr("Keybinds Cheatsheet") + + ContentSubsection { + title: Translation.tr("Super Key Symbol") + ConfigSelectionArray { + currentValue: Config.options.appearance.keybinds.superKey + onSelected: newValue => { + Config.options.appearance.keybinds.superKey = newValue; + } + // Use a nerdfont to see the icons + // 0: 󰖳 | 1: 󰌽 | 2: 󰘳 | 3:  | 4: 󰨡 + // 5:  | 6:  | 7: 󰣇 | 8:  | 9:  + // 10:  | 11:  | 12:  | 13:  | 14: 󱄛 + options: [ + { + displayName: "󰖳", + icon: "", + value: 0 + }, + { + displayName: "", + icon: "", + value: 3 + }, + { + displayName: "󰨡", + icon: "", + value: 4 + }, + { + displayName: "", + icon: "", + value: 5 + }, + { + displayName: "󰣇", + icon: "", + value: 7 + }, + { + displayName: "", + icon: "", + value: 12 + }, + { + displayName: "", + icon: "", + value: 13 + }, + { + displayName: "", + icon: "", + value: 11 + }, + { + displayName: "", + icon: "", + value: 10 + }, + { + displayName: "", + icon: "", + value: 8 + }, + { + displayName: "󱄛", + icon: "", + value: 14 + }, + { + displayName: "", + icon: "", + value: 9 + }, + { + displayName: "", + icon: "", + value: 6 + }, + { + displayName: "󰘳", + icon: "", + value: 2 + }, + ] + } + } + + ConfigSwitch { + buttonIcon: "󰘵" + text: Translation.tr("Use macOS-like symbols for mods keys") + checked: Config.options.appearance.keybinds.useMacSymbol + onCheckedChanged: { + Config.options.appearance.keybinds.useMacSymbol = checked; + } + } + ConfigSwitch { + buttonIcon: "󱊶" + text: Translation.tr("Use symbols for function keys") + checked: Config.options.appearance.keybinds.useFnSymbol + onCheckedChanged: { + Config.options.appearance.keybinds.useFnSymbol = checked; + } + } + ConfigSwitch { + buttonIcon: "󰍽" + text: Translation.tr("Use symbols for mouse") + checked: Config.options.appearance.keybinds.s + onCheckedChanged: { + Config.options.appearance.keybinds.useMouseSymbol = checked; + } + } + } } From 3da64f6bc51f227870e9a20d9f8460f4c23e814e Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Sat, 25 Oct 2025 00:59:42 +0200 Subject: [PATCH 02/52] fix useMouseSymbol boolean typo --- dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml index 4dc71faa2..f126cc0d8 100644 --- a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml @@ -199,7 +199,7 @@ ContentPage { ConfigSwitch { buttonIcon: "󰍽" text: Translation.tr("Use symbols for mouse") - checked: Config.options.appearance.keybinds.s + checked: Config.options.appearance.keybinds.useMouseSymbol onCheckedChanged: { Config.options.appearance.keybinds.useMouseSymbol = checked; } From 8c125cccb1036ea523e8f843c4ae0dbc5cb9f6df Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Sat, 25 Oct 2025 01:45:42 +0200 Subject: [PATCH 03/52] add other symbols --- .../quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml index 521522530..8d2d058ea 100644 --- a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml +++ b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml @@ -53,6 +53,8 @@ Item { "mouse_down": Config.options.appearance.keybinds.useMouseSymbol ? "󱕑" : "Scroll ↑", // trust me bro "mouse:272": Config.options.appearance.keybinds.useMouseSymbol ? "L󰍽" : "LMB", "mouse:273": Config.options.appearance.keybinds.useMouseSymbol ? "R󰍽" : "RMB", + "Scroll ↑/↓": Config.options.appearance.keybinds.useMouseSymbol ? "󱕒" : "Scroll ↑/↓", + "Page_↑/↓": Config.options.appearance.keybinds.useMouseSymbol ? "Page " : "Page_↑/↓", "mouse:275": "MouseBack", "Slash": "/", "Hash": "#", From 533156e0d0d31ebe703490449fd2f66c7753142d Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Sat, 25 Oct 2025 04:22:01 +0200 Subject: [PATCH 04/52] cheatsheet add font size setting and macos like shortcut --- .../modules/cheatsheet/CheatsheetKeybinds.qml | 20 +++++- .../quickshell/ii/modules/common/Config.qml | 5 ++ .../ii/modules/common/widgets/KeyboardKey.qml | 3 +- .../ii/modules/settings/AdvancedConfig.qml | 66 ++++++++++++++----- 4 files changed, 75 insertions(+), 19 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml index 8d2d058ea..64d695547 100644 --- a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml +++ b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml @@ -106,6 +106,17 @@ Item { var result = []; for (var i = 0; i < keybindSection.modelData.keybinds.length; i++) { const keybind = keybindSection.modelData.keybinds[i]; + + if (Config.options.appearance.keybinds.useMacLikeShortcut) { + + 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, @@ -137,17 +148,19 @@ Item { delegate: KeyboardKey { required property var modelData key: keySubstitutions[modelData] || modelData + pixelSize: Config.options.appearance.keybinds.pixelSize.key } } StyledText { id: keybindPlus - visible: !keyBlacklist.includes(modelData.key) && modelData.mods.length > 0 + visible: !Config.options.appearance.keybinds.useMacLikeShortcut && !keyBlacklist.includes(modelData.key) && modelData.mods.length > 0 text: "+" } KeyboardKey { id: keybindKey - visible: !keyBlacklist.includes(modelData.key) + visible: !Config.options.appearance.keybinds.useMacLikeShortcut && !keyBlacklist.includes(modelData.key) key: keySubstitutions[modelData.key] || modelData.key + pixelSize: Config.options.appearance.keybinds.pixelSize.key color: Appearance.colors.colOnLayer0 } } @@ -163,7 +176,8 @@ Item { StyledText { id: commentText anchors.centerIn: parent - font.pixelSize: Appearance.font.pixelSize.smaller + // font.pixelSize: Appearance.font.pixelSize.smaller + font.pixelSize: Config.options.appearance.keybinds.pixelSize.comment text: modelData.comment } } diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index dd4e1bc74..11526c81b 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -130,8 +130,13 @@ Singleton { // 10:  | 11:  | 12:  | 13:  | 14: 󱄛 property int superKey: 0 property bool useMacSymbol: false + property bool useMacLikeShortcut: false property bool useMouseSymbol: false property bool useFnSymbol: false + property JsonObject pixelSize: JsonObject { + property int key: Appearance.font.pixelSize.smaller + property int comment: Appareance.font.pixelSize.smaller + } } } diff --git a/dots/.config/quickshell/ii/modules/common/widgets/KeyboardKey.qml b/dots/.config/quickshell/ii/modules/common/widgets/KeyboardKey.qml index 14c75c62d..c769554ec 100644 --- a/dots/.config/quickshell/ii/modules/common/widgets/KeyboardKey.qml +++ b/dots/.config/quickshell/ii/modules/common/widgets/KeyboardKey.qml @@ -11,6 +11,7 @@ Rectangle { property real extraBottomBorderWidth: 2 property color borderColor: Appearance.colors.colOnLayer0 property real borderRadius: 5 + property int pixelSize: Appearance.font.pixelSize.smallie property color keyColor: Appearance.m3colors.m3surfaceContainerLow implicitWidth: keyFace.implicitWidth + borderWidth * 2 implicitHeight: keyFace.implicitHeight + borderWidth * 2 + extraBottomBorderWidth @@ -35,7 +36,7 @@ Rectangle { id: keyText anchors.centerIn: parent font.family: Appearance.font.family.monospace - font.pixelSize: Appearance.font.pixelSize.smaller + font.pixelSize: pixelSize text: key } } diff --git a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml index f126cc0d8..103d5b8f2 100644 --- a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml @@ -1,6 +1,10 @@ import QtQuick +import Quickshell +import Quickshell.Io +import QtQuick.Layouts import qs.services import qs.modules.common +import qs.modules.common.functions import qs.modules.common.widgets ContentPage { @@ -90,6 +94,8 @@ ContentPage { } } + + ContentSection { icon: "keyboard" title: Translation.tr("Keybinds Cheatsheet") @@ -108,72 +114,58 @@ ContentPage { options: [ { displayName: "󰖳", - icon: "", value: 0 }, { displayName: "", - icon: "", value: 3 }, { displayName: "󰨡", - icon: "", value: 4 }, { displayName: "", - icon: "", value: 5 }, { displayName: "󰣇", - icon: "", value: 7 }, { displayName: "", - icon: "", value: 12 }, { displayName: "", - icon: "", value: 13 }, { displayName: "", - icon: "", value: 11 }, { displayName: "", - icon: "", value: 10 }, { displayName: "", - icon: "", value: 8 }, { displayName: "󱄛", - icon: "", value: 14 }, { - displayName: "", - icon: "", + displayName: "", value: 9 }, { displayName: "", - icon: "", value: 6 }, { displayName: "󰘳", - icon: "", value: 2 }, ] @@ -187,7 +179,11 @@ ContentPage { onCheckedChanged: { Config.options.appearance.keybinds.useMacSymbol = checked; } + StyledToolTip { + text: Translation.tr("macOS-style symbols, e.g. 󰘴 for Ctrl, 󰘵 for Alt, 󰘶 for Shift, etc") + } } + ConfigSwitch { buttonIcon: "󱊶" text: Translation.tr("Use symbols for function keys") @@ -195,6 +191,9 @@ ContentPage { onCheckedChanged: { Config.options.appearance.keybinds.useFnSymbol = checked; } + StyledToolTip { + text: Translation.tr("Show 󱊷 instead of Escape, 󱊫 for F1, etc to 󱊶 for F12") + } } ConfigSwitch { buttonIcon: "󰍽" @@ -203,6 +202,43 @@ ContentPage { onCheckedChanged: { Config.options.appearance.keybinds.useMouseSymbol = checked; } + StyledToolTip { + text: Translation.tr("Replace 󱕐 for \"Scroll ↓\", 󱕑 \"Scroll ↑\", L󰍽 \"LMB\", R󰍽 \"RMB\", 󱕒 \"Scroll ↑/↓\" and Page  for \"Page_↑/↓\"") + } + } + ConfigSwitch { + buttonIcon: "" + text: Translation.tr("Use macOS shortcut layout") + checked: Config.options.appearance.keybinds.useMacLikeShortcut + onCheckedChanged: { + Config.options.appearance.keybinds.useMacLikeShortcut = checked; + } + StyledToolTip { + text: Translation.tr("Show mods and key in the same keycap, look better with symbols") + } + + } + + ConfigSpinBox { + // text: Translation.tr("Keycap") + text: Translation.tr("Key font size") + value: Config.options.appearance.keybinds.pixelSize.key + from: Appearance.font.pixelSize.smallest + to: Appearance.font.pixelSize.large + stepSize: 1 + onValueChanged: { + Config.options.appearance.keybinds.pixelSize.key = value; + } + } + ConfigSpinBox { + text: Translation.tr("Comment font size") + value: Config.options.appearance.commentbinds.pixelSize.comment + from: Appearance.font.pixelSize.smallest + to: Appearance.font.pixelSize.large + stepSize: 1 + onValueChanged: { + Config.options.appearance.commentbinds.pixelSize.comment = value; + } } } } From 69fc9d9b3516ea44143ea7674c5235a68109dd04 Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Sat, 25 Oct 2025 17:00:01 +0200 Subject: [PATCH 05/52] fix comment pixelSize key --- .../.config/quickshell/ii/modules/settings/AdvancedConfig.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml index 103d5b8f2..912bb13f4 100644 --- a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml @@ -232,12 +232,12 @@ ContentPage { } ConfigSpinBox { text: Translation.tr("Comment font size") - value: Config.options.appearance.commentbinds.pixelSize.comment + value: Config.options.appearance.keybinds.pixelSize.comment from: Appearance.font.pixelSize.smallest to: Appearance.font.pixelSize.large stepSize: 1 onValueChanged: { - Config.options.appearance.commentbinds.pixelSize.comment = value; + Config.options.appearance.keybinds.pixelSize.comment = value; } } } From fc17f23533e952194b8a9d504f1ce4a07aa0a740 Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Sat, 25 Oct 2025 17:06:08 +0200 Subject: [PATCH 06/52] fix typo --- dots/.config/quickshell/ii/modules/common/Config.qml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index 11526c81b..38e47dd6b 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -135,8 +135,7 @@ Singleton { property bool useFnSymbol: false property JsonObject pixelSize: JsonObject { property int key: Appearance.font.pixelSize.smaller - property int comment: Appareance.font.pixelSize.smaller - } + property int comment: Appearance.font.pixelSize.smaller } } } From 90cc63e57aedafa7d9740afb35b072a9fd74830b Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Sun, 26 Oct 2025 14:58:28 +0100 Subject: [PATCH 07/52] checkbox on tooltip --- .../quickshell/ii/modules/settings/AdvancedConfig.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml index 912bb13f4..966e832aa 100644 --- a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml @@ -214,14 +214,14 @@ ContentPage { Config.options.appearance.keybinds.useMacLikeShortcut = checked; } StyledToolTip { - text: Translation.tr("Show mods and key in the same keycap, look better with symbols") + text: Translation.tr("Display modifiers and keys in a single keycap (e.g., \"Ctrl A\" instead of \"Ctrl + A\" or \"󰘴 A\" instead of \"󰘴 + A\")") } } ConfigSpinBox { // text: Translation.tr("Keycap") - text: Translation.tr("Key font size") + text: Translation.tr("Keybind font size") value: Config.options.appearance.keybinds.pixelSize.key from: Appearance.font.pixelSize.smallest to: Appearance.font.pixelSize.large @@ -231,7 +231,7 @@ ContentPage { } } ConfigSpinBox { - text: Translation.tr("Comment font size") + text: Translation.tr("Description font size") value: Config.options.appearance.keybinds.pixelSize.comment from: Appearance.font.pixelSize.smallest to: Appearance.font.pixelSize.large From c61da40f703304e934f65a608f70462d58b28c7e Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Tue, 28 Oct 2025 10:28:15 +0100 Subject: [PATCH 08/52] new symbol map --- .../modules/cheatsheet/CheatsheetKeybinds.qml | 84 +++++++++++-------- .../ii/modules/settings/AdvancedConfig.qml | 4 +- 2 files changed, 51 insertions(+), 37 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml index 64d695547..d7b7b056b 100644 --- a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml +++ b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml @@ -15,51 +15,65 @@ Item { implicitWidth: row.implicitWidth + padding * 2 implicitHeight: row.implicitHeight + padding * 2 property list superMap: [ - "󰖳", "󰌽", "󰘳", "", "󰨡", "", "", + "󰖳", "󰌽", "⌘", "", "󰨡", "", "", "󰣇", "", "", "", "", " ", "", "󱄛" ] + property var macSymbolMap: ({ + "Ctrl": "󰘴" , + "Alt": "󰘵" , + "Shift": "󰘶" , + "Space": "󱁐" , + "Tab": "↹" , + "Equal": "󰇼" , + "Minus": "" , + "Print": "" , + "BackSpace": "󰭜" , + "Delete": "⌦" , + "Return": "󰌑" , + "Period": "." , + "Escape": "⎋" + }) + property var functionSymbolMap: ({ + "F1": "󱊫", + "F2": "󱊬", + "F3": "󱊭", + "F4": "󱊮", + "F5": "󱊯", + "F6": "󱊰", + "F7": "󱊱", + "F8": "󱊲", + "F9": "󱊳", + "F10": "󱊴", + "F11": "󱊵", + "F12": "󱊶", + }) + + property var mouseSymbolMap: ({ + "mouse_up": "󱕐" , + "mouse_down": "󱕑", + "mouse:272": "L󰍽", + "mouse:273": "R󰍽", + "Scroll ↑/↓": "󱕒", + "Page_↑/↓": "⇞/⇟", + }) + property var keyBlacklist: ["Super_L"] property var keySubstitutions: ({ "Super": superMap[Config.options.appearance.keybinds.superKey], - "Ctrl": Config.options.appearance.keybinds.useMacSymbol ? "󰘴" : "Ctrl", - "Alt": Config.options.appearance.keybinds.useMacSymbol ? "󰘵" : "Alt", - "Shift": Config.options.appearance.keybinds.useMacSymbol ? "󰘶" : "Shift", - "Space": Config.options.appearance.keybinds.useMacSymbol ? "󱁐" : "Space", - "Tab": Config.options.appearance.keybinds.useMacSymbol ? "" : "Tab", - "Equal": Config.options.appearance.keybinds.useMacSymbol ? "󰇼" : "Equal", - "Minus": Config.options.appearance.keybinds.useMacSymbol ? "" : "Minus", - "Print": Config.options.appearance.keybinds.useMacSymbol ? "" : "Print", - "Delete": Config.options.appearance.keybinds.useMacSymbol ? "󰭜" : "Delete", - "Return": Config.options.appearance.keybinds.useMacSymbol ? "󰌑" : "Enter", - "Period": Config.options.appearance.keybinds.useMacSymbol ? "." : "Period", - - // Function keys - "Escape": Config.options.appearance.keybinds.useFnSymbol ? "󱊷" : "Escape", - "F1": Config.options.appearance.keybinds.useFnSymbol ? "󱊫" : "F1", - "F2": Config.options.appearance.keybinds.useFnSymbol ? "󱊬" : "F2", - "F3": Config.options.appearance.keybinds.useFnSymbol ? "󱊭" : "F3", - "F4": Config.options.appearance.keybinds.useFnSymbol ? "󱊮" : "F4", - "F5": Config.options.appearance.keybinds.useFnSymbol ? "󱊯" : "F5", - "F6": Config.options.appearance.keybinds.useFnSymbol ? "󱊰" : "F6", - "F7": Config.options.appearance.keybinds.useFnSymbol ? "󱊱" : "F7", - "F8": Config.options.appearance.keybinds.useFnSymbol ? "󱊲" : "F8", - "F9": Config.options.appearance.keybinds.useFnSymbol ? "󱊳" : "F9", - "F10": Config.options.appearance.keybinds.useFnSymbol ? "󱊴" : "F10", - "F11": Config.options.appearance.keybinds.useFnSymbol ? "󱊵" : "F11", - "F12": Config.options.appearance.keybinds.useFnSymbol ? "󱊶" : "F12", - // Mouse keys - "mouse_up": Config.options.appearance.keybinds.useMouseSymbol ? "󱕐" : "Scroll ↓", // ikr, weird - "mouse_down": Config.options.appearance.keybinds.useMouseSymbol ? "󱕑" : "Scroll ↑", // trust me bro - "mouse:272": Config.options.appearance.keybinds.useMouseSymbol ? "L󰍽" : "LMB", - "mouse:273": Config.options.appearance.keybinds.useMouseSymbol ? "R󰍽" : "RMB", - "Scroll ↑/↓": Config.options.appearance.keybinds.useMouseSymbol ? "󱕒" : "Scroll ↑/↓", - "Page_↑/↓": Config.options.appearance.keybinds.useMouseSymbol ? "Page " : "Page_↑/↓", + "mouse_up": "Scroll ↓", // ikr, weird + "mouse_down": "Scroll ↑", // trust me bro + "mouse:272": "LMB", + "mouse:273": "RMB", "mouse:275": "MouseBack", "Slash": "/", "Hash": "#", // "Shift": "", - }) + }, + Config.options.appearance.keybinds.useMacSymbol ? macSymbolMap : {}, + Config.options.appearance.keybinds.useFnSymbol ? functionSymbolMap : {}, + Config.options.appearance.keybinds.useMouseSymbol ? mouseSymbolMap : {}, + ) Row { // Keybind columns id: row diff --git a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml index 966e832aa..bc05cf3fe 100644 --- a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml @@ -192,7 +192,7 @@ ContentPage { Config.options.appearance.keybinds.useFnSymbol = checked; } StyledToolTip { - text: Translation.tr("Show 󱊷 instead of Escape, 󱊫 for F1, etc to 󱊶 for F12") + text: Translation.tr("Show functions keys as symbols, e.g. 󱊫 for F1, 󱊶 for F12") } } ConfigSwitch { @@ -203,7 +203,7 @@ ContentPage { Config.options.appearance.keybinds.useMouseSymbol = checked; } StyledToolTip { - text: Translation.tr("Replace 󱕐 for \"Scroll ↓\", 󱕑 \"Scroll ↑\", L󰍽 \"LMB\", R󰍽 \"RMB\", 󱕒 \"Scroll ↑/↓\" and Page  for \"Page_↑/↓\"") + text: Translation.tr("Replace 󱕐 for \"Scroll ↓\", 󱕑 \"Scroll ↑\", L󰍽 \"LMB\", R󰍽 \"RMB\", 󱕒 \"Scroll ↑/↓\" and ⇞/⇟ for \"Page_↑/↓\"") } } ConfigSwitch { From 367b1b9499e2f5e6081cf52ff7e18882fd259fcd Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Tue, 28 Oct 2025 10:30:37 +0100 Subject: [PATCH 09/52] fix keySubstitutions --- .../quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml index d7b7b056b..9b7444156 100644 --- a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml +++ b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml @@ -58,7 +58,7 @@ Item { }) property var keyBlacklist: ["Super_L"] - property var keySubstitutions: ({ + property var keySubstitutions: Object.assign({ "Super": superMap[Config.options.appearance.keybinds.superKey], // Mouse keys "mouse_up": "Scroll ↓", // ikr, weird From 886e16a1cff624536442692500d55c9677ac4d93 Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Tue, 28 Oct 2025 10:37:32 +0100 Subject: [PATCH 10/52] add comment and bring back some value --- .../quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml index 9b7444156..d2eb9d922 100644 --- a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml +++ b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml @@ -14,6 +14,8 @@ Item { property real padding: 4 implicitWidth: row.implicitWidth + padding * 2 implicitHeight: row.implicitHeight + padding * 2 + // Excellent symbol explaination and source : + // http://xahlee.info/comp/unicode_computing_symbols.html property list superMap: [ "󰖳", "󰌽", "⌘", "", "󰨡", "", "", "󰣇", "", "", "", "", " ", "", "󱄛" @@ -68,6 +70,7 @@ Item { "mouse:275": "MouseBack", "Slash": "/", "Hash": "#", + "Return": "Enter", // "Shift": "", }, Config.options.appearance.keybinds.useMacSymbol ? macSymbolMap : {}, From fc479c358268864e55c9f80e424a85b75ec00049 Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Tue, 28 Oct 2025 10:41:43 +0100 Subject: [PATCH 11/52] clean some values --- .../quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml | 3 +-- .../quickshell/ii/modules/common/widgets/KeyboardKey.qml | 2 +- .../quickshell/ii/modules/settings/AdvancedConfig.qml | 5 ----- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml index d2eb9d922..8f26aa2c7 100644 --- a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml +++ b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml @@ -193,8 +193,7 @@ Item { StyledText { id: commentText anchors.centerIn: parent - // font.pixelSize: Appearance.font.pixelSize.smaller - font.pixelSize: Config.options.appearance.keybinds.pixelSize.comment + font.pixelSize: Config.options.appearance.keybinds.pixelSize.comment || Appearance.font.pixelSize.smaller text: modelData.comment } } diff --git a/dots/.config/quickshell/ii/modules/common/widgets/KeyboardKey.qml b/dots/.config/quickshell/ii/modules/common/widgets/KeyboardKey.qml index c769554ec..f620a3e3f 100644 --- a/dots/.config/quickshell/ii/modules/common/widgets/KeyboardKey.qml +++ b/dots/.config/quickshell/ii/modules/common/widgets/KeyboardKey.qml @@ -11,7 +11,7 @@ Rectangle { property real extraBottomBorderWidth: 2 property color borderColor: Appearance.colors.colOnLayer0 property real borderRadius: 5 - property int pixelSize: Appearance.font.pixelSize.smallie + property int pixelSize: Appearance.font.pixelSize.smaller property color keyColor: Appearance.m3colors.m3surfaceContainerLow implicitWidth: keyFace.implicitWidth + borderWidth * 2 implicitHeight: keyFace.implicitHeight + borderWidth * 2 + extraBottomBorderWidth diff --git a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml index bc05cf3fe..e118358b9 100644 --- a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml @@ -1,10 +1,6 @@ import QtQuick -import Quickshell -import Quickshell.Io -import QtQuick.Layouts import qs.services import qs.modules.common -import qs.modules.common.functions import qs.modules.common.widgets ContentPage { @@ -220,7 +216,6 @@ ContentPage { } ConfigSpinBox { - // text: Translation.tr("Keycap") text: Translation.tr("Keybind font size") value: Config.options.appearance.keybinds.pixelSize.key from: Appearance.font.pixelSize.smallest From af64052e33b2e591434841d1e16f7e7853968cb8 Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Wed, 29 Oct 2025 10:29:34 +0100 Subject: [PATCH 12/52] remove super directly override --- .../quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml index 8f26aa2c7..127fbbbbc 100644 --- a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml +++ b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml @@ -61,8 +61,7 @@ Item { property var keyBlacklist: ["Super_L"] property var keySubstitutions: Object.assign({ - "Super": superMap[Config.options.appearance.keybinds.superKey], - // Mouse keys + "Super": "󰖳", "mouse_up": "Scroll ↓", // ikr, weird "mouse_down": "Scroll ↑", // trust me bro "mouse:272": "LMB", @@ -73,6 +72,9 @@ Item { "Return": "Enter", // "Shift": "", }, + Config.options.appearance.keybinds.superKey > 0 ? { + "Super": superMap[Config.options.appearance.keybinds.superKey], + }: {}, Config.options.appearance.keybinds.useMacSymbol ? macSymbolMap : {}, Config.options.appearance.keybinds.useFnSymbol ? functionSymbolMap : {}, Config.options.appearance.keybinds.useMouseSymbol ? mouseSymbolMap : {}, From 79df7bbeefa417829384d1b643c3d0f39e6c7031 Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Thu, 30 Oct 2025 17:00:31 +0100 Subject: [PATCH 13/52] add google (assistant, chrome, android) keys --- .../ii/modules/cheatsheet/CheatsheetKeybinds.qml | 3 ++- .../ii/modules/settings/AdvancedConfig.qml | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml index 127fbbbbc..4740b4975 100644 --- a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml +++ b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml @@ -18,7 +18,8 @@ Item { // http://xahlee.info/comp/unicode_computing_symbols.html property list superMap: [ "󰖳", "󰌽", "⌘", "", "󰨡", "", "", - "󰣇", "", "", "", "", " ", "", "󱄛" + "󰣇", "", "", "", "", " ", "", + "󱄛", "󰀲", "󰟍", "" ] property var macSymbolMap: ({ "Ctrl": "󰘴" , diff --git a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml index e118358b9..4c9218edc 100644 --- a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml @@ -107,6 +107,7 @@ ContentPage { // 0: 󰖳 | 1: 󰌽 | 2: 󰘳 | 3:  | 4: 󰨡 // 5:  | 6:  | 7: 󰣇 | 8:  | 9:  // 10:  | 11:  | 12:  | 13:  | 14: 󱄛 + // 15: 󰀲 | 16: 󰟍 | 17:  | options: [ { displayName: "󰖳", @@ -164,6 +165,19 @@ ContentPage { displayName: "󰘳", value: 2 }, + { + displayName: "󰀲", + value: 15 + }, + { + displayName: "󰟍", + value: 16 + }, + { + displayName: "", + value: 17 + }, + ] } } From a0332cb0df936370d55b5f0c4f32845354b08c4b Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Thu, 30 Oct 2025 17:26:30 +0100 Subject: [PATCH 14/52] add reference to nerdfonts symbol cheat sheet --- .../quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml index 4740b4975..57a16ec0b 100644 --- a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml +++ b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml @@ -16,6 +16,7 @@ Item { implicitHeight: row.implicitHeight + padding * 2 // Excellent symbol explaination and source : // http://xahlee.info/comp/unicode_computing_symbols.html + // https://www.nerdfonts.com/cheat-sheet property list superMap: [ "󰖳", "󰌽", "⌘", "", "󰨡", "", "", "󰣇", "", "", "", "", " ", "", From aeb1955947dfe64a0731ff91d652435f3f479e2e Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Thu, 30 Oct 2025 22:12:25 +0100 Subject: [PATCH 15/52] end-4 feedback --- .../modules/cheatsheet/CheatsheetKeybinds.qml | 6 +- .../quickshell/ii/modules/common/Config.qml | 5 +- .../ii/modules/settings/AdvancedConfig.qml | 158 ----------------- .../ii/modules/settings/InterfaceConfig.qml | 159 ++++++++++++++++++ 4 files changed, 165 insertions(+), 163 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml index 57a16ec0b..80208df5e 100644 --- a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml +++ b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml @@ -169,7 +169,7 @@ Item { delegate: KeyboardKey { required property var modelData key: keySubstitutions[modelData] || modelData - pixelSize: Config.options.appearance.keybinds.pixelSize.key + pixelSize: Config.options.appearance.keybinds.fontSize.key } } StyledText { @@ -181,7 +181,7 @@ Item { id: keybindKey visible: !Config.options.appearance.keybinds.useMacLikeShortcut && !keyBlacklist.includes(modelData.key) key: keySubstitutions[modelData.key] || modelData.key - pixelSize: Config.options.appearance.keybinds.pixelSize.key + pixelSize: Config.options.appearance.keybinds.fontSize.key color: Appearance.colors.colOnLayer0 } } @@ -197,7 +197,7 @@ Item { StyledText { id: commentText anchors.centerIn: parent - font.pixelSize: Config.options.appearance.keybinds.pixelSize.comment || Appearance.font.pixelSize.smaller + font.pixelSize: Config.options.appearance.keybinds.fontSize.comment || Appearance.font.pixelSize.smaller text: modelData.comment } } diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index 38e47dd6b..6ae8d25f8 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -133,9 +133,10 @@ Singleton { property bool useMacLikeShortcut: false property bool useMouseSymbol: false property bool useFnSymbol: false - property JsonObject pixelSize: JsonObject { + property JsonObject fontSize: JsonObject { property int key: Appearance.font.pixelSize.smaller - property int comment: Appearance.font.pixelSize.smaller } + property int comment: Appearance.font.pixelSize.smaller + } } } diff --git a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml index 4c9218edc..7d51dbe12 100644 --- a/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/AdvancedConfig.qml @@ -92,162 +92,4 @@ ContentPage { - ContentSection { - icon: "keyboard" - title: Translation.tr("Keybinds Cheatsheet") - - ContentSubsection { - title: Translation.tr("Super Key Symbol") - ConfigSelectionArray { - currentValue: Config.options.appearance.keybinds.superKey - onSelected: newValue => { - Config.options.appearance.keybinds.superKey = newValue; - } - // Use a nerdfont to see the icons - // 0: 󰖳 | 1: 󰌽 | 2: 󰘳 | 3:  | 4: 󰨡 - // 5:  | 6:  | 7: 󰣇 | 8:  | 9:  - // 10:  | 11:  | 12:  | 13:  | 14: 󱄛 - // 15: 󰀲 | 16: 󰟍 | 17:  | - options: [ - { - displayName: "󰖳", - value: 0 - }, - { - displayName: "", - value: 3 - }, - { - displayName: "󰨡", - value: 4 - }, - { - displayName: "", - value: 5 - }, - { - displayName: "󰣇", - value: 7 - }, - { - displayName: "", - value: 12 - }, - { - displayName: "", - value: 13 - }, - { - displayName: "", - value: 11 - }, - { - displayName: "", - value: 10 - }, - { - displayName: "", - value: 8 - }, - { - displayName: "󱄛", - value: 14 - }, - { - displayName: "", - value: 9 - }, - { - displayName: "", - value: 6 - }, - { - displayName: "󰘳", - value: 2 - }, - { - displayName: "󰀲", - value: 15 - }, - { - displayName: "󰟍", - value: 16 - }, - { - displayName: "", - value: 17 - }, - - ] - } - } - - ConfigSwitch { - buttonIcon: "󰘵" - text: Translation.tr("Use macOS-like symbols for mods keys") - checked: Config.options.appearance.keybinds.useMacSymbol - onCheckedChanged: { - Config.options.appearance.keybinds.useMacSymbol = checked; - } - StyledToolTip { - text: Translation.tr("macOS-style symbols, e.g. 󰘴 for Ctrl, 󰘵 for Alt, 󰘶 for Shift, etc") - } - } - - ConfigSwitch { - buttonIcon: "󱊶" - text: Translation.tr("Use symbols for function keys") - checked: Config.options.appearance.keybinds.useFnSymbol - onCheckedChanged: { - Config.options.appearance.keybinds.useFnSymbol = checked; - } - StyledToolTip { - text: Translation.tr("Show functions keys as symbols, e.g. 󱊫 for F1, 󱊶 for F12") - } - } - ConfigSwitch { - buttonIcon: "󰍽" - text: Translation.tr("Use symbols for mouse") - checked: Config.options.appearance.keybinds.useMouseSymbol - onCheckedChanged: { - Config.options.appearance.keybinds.useMouseSymbol = checked; - } - StyledToolTip { - text: Translation.tr("Replace 󱕐 for \"Scroll ↓\", 󱕑 \"Scroll ↑\", L󰍽 \"LMB\", R󰍽 \"RMB\", 󱕒 \"Scroll ↑/↓\" and ⇞/⇟ for \"Page_↑/↓\"") - } - } - ConfigSwitch { - buttonIcon: "" - text: Translation.tr("Use macOS shortcut layout") - checked: Config.options.appearance.keybinds.useMacLikeShortcut - onCheckedChanged: { - Config.options.appearance.keybinds.useMacLikeShortcut = checked; - } - StyledToolTip { - text: Translation.tr("Display modifiers and keys in a single keycap (e.g., \"Ctrl A\" instead of \"Ctrl + A\" or \"󰘴 A\" instead of \"󰘴 + A\")") - } - - } - - ConfigSpinBox { - text: Translation.tr("Keybind font size") - value: Config.options.appearance.keybinds.pixelSize.key - from: Appearance.font.pixelSize.smallest - to: Appearance.font.pixelSize.large - stepSize: 1 - onValueChanged: { - Config.options.appearance.keybinds.pixelSize.key = value; - } - } - ConfigSpinBox { - text: Translation.tr("Description font size") - value: Config.options.appearance.keybinds.pixelSize.comment - from: Appearance.font.pixelSize.smallest - to: Appearance.font.pixelSize.large - stepSize: 1 - onValueChanged: { - Config.options.appearance.keybinds.pixelSize.comment = value; - } - } - } } diff --git a/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml b/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml index 13a909cbb..79b01bf95 100644 --- a/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml @@ -1012,4 +1012,163 @@ ContentPage { } } } + + ContentSection { + icon: "keyboard" + title: Translation.tr("Cheatsheet") + + ContentSubsection { + title: Translation.tr("Super Key Symbol") + ConfigSelectionArray { + currentValue: Config.options.appearance.keybinds.superKey + onSelected: newValue => { + Config.options.appearance.keybinds.superKey = newValue; + } + // Use a nerdfont to see the icons + // 0: 󰖳 | 1: 󰌽 | 2: 󰘳 | 3:  | 4: 󰨡 + // 5:  | 6:  | 7: 󰣇 | 8:  | 9:  + // 10:  | 11:  | 12:  | 13:  | 14: 󱄛 + // 15: 󰀲 | 16: 󰟍 | 17:  | + options: [ + { + displayName: "󰖳", + value: 0 + }, + { + displayName: "", + value: 3 + }, + { + displayName: "󰨡", + value: 4 + }, + { + displayName: "", + value: 5 + }, + { + displayName: "󰣇", + value: 7 + }, + { + displayName: "", + value: 12 + }, + { + displayName: "", + value: 13 + }, + { + displayName: "", + value: 11 + }, + { + displayName: "", + value: 10 + }, + { + displayName: "", + value: 8 + }, + { + displayName: "󱄛", + value: 14 + }, + { + displayName: "", + value: 9 + }, + { + displayName: "", + value: 6 + }, + { + displayName: "󰘳", + value: 2 + }, + { + displayName: "󰀲", + value: 15 + }, + { + displayName: "󰟍", + value: 16 + }, + { + displayName: "", + value: 17 + }, + + ] + } + } + + ConfigSwitch { + buttonIcon: "󰘵" + text: Translation.tr("Use macOS-like symbols for mods keys") + checked: Config.options.appearance.keybinds.useMacSymbol + onCheckedChanged: { + Config.options.appearance.keybinds.useMacSymbol = checked; + } + StyledToolTip { + text: Translation.tr("macOS-style symbols, e.g. 󰘴 for Ctrl, 󰘵 for Alt, 󰘶 for Shift, etc") + } + } + + ConfigSwitch { + buttonIcon: "󱊶" + text: Translation.tr("Use symbols for function keys") + checked: Config.options.appearance.keybinds.useFnSymbol + onCheckedChanged: { + Config.options.appearance.keybinds.useFnSymbol = checked; + } + StyledToolTip { + text: Translation.tr("Show functions keys as symbols, e.g. 󱊫 for F1, 󱊶 for F12") + } + } + ConfigSwitch { + buttonIcon: "󰍽" + text: Translation.tr("Use symbols for mouse") + checked: Config.options.appearance.keybinds.useMouseSymbol + onCheckedChanged: { + Config.options.appearance.keybinds.useMouseSymbol = checked; + } + StyledToolTip { + text: Translation.tr("Replace 󱕐 for \"Scroll ↓\", 󱕑 \"Scroll ↑\", L󰍽 \"LMB\", R󰍽 \"RMB\", 󱕒 \"Scroll ↑/↓\" and ⇞/⇟ for \"Page_↑/↓\"") + } + } + ConfigSwitch { + buttonIcon: "" + text: Translation.tr("Use macOS shortcut layout") + checked: Config.options.appearance.keybinds.useMacLikeShortcut + onCheckedChanged: { + Config.options.appearance.keybinds.useMacLikeShortcut = checked; + } + StyledToolTip { + text: Translation.tr("Display modifiers and keys in a single keycap (e.g., \"Ctrl A\" instead of \"Ctrl + A\" or \"󰘴 A\" instead of \"󰘴 + A\")") + } + + } + + ConfigSpinBox { + text: Translation.tr("Keybind font size") + value: Config.options.appearance.keybinds.fontSize.key + from: Appearance.font.pixelSize.smallest + to: Appearance.font.pixelSize.large + stepSize: 1 + onValueChanged: { + Config.options.appearance.keybinds.fontSize.key = value; + } + } + ConfigSpinBox { + text: Translation.tr("Description font size") + value: Config.options.appearance.keybinds.fontSize.comment + from: Appearance.font.pixelSize.smallest + to: Appearance.font.pixelSize.large + stepSize: 1 + onValueChanged: { + Config.options.appearance.keybinds.fontSize.comment = value; + } + } + } } From e567f06cefbadc3f2313669c4bba809033cba350 Mon Sep 17 00:00:00 2001 From: vaguesyntax Date: Sat, 1 Nov 2025 14:38:16 +0300 Subject: [PATCH 16/52] initial commit of record-location --- .../quickshell/ii/modules/common/Config.qml | 4 + .../ii/modules/settings/ServicesConfig.qml | 19 +++ .../quickshell/ii/scripts/videos/record.sh | 110 ++++++++++-------- 3 files changed, 85 insertions(+), 48 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index 39c0ef131..042d10639 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -460,6 +460,10 @@ Singleton { } } + property JsonObject screenRecord: JsonObject { + property string savePath: Directories.videos + } + property JsonObject sounds: JsonObject { property bool battery: false property bool pomodoro: false diff --git a/dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml b/dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml index c9ff0c16b..778ff2b84 100644 --- a/dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml @@ -85,6 +85,25 @@ ContentPage { } + ContentSection { + icon: "screen_record" + title: Translation.tr("Screen Recording") + + ContentSubsection { + title: Translation.tr("Save path") + " (example: /home/user/Videos)" + MaterialTextArea { + Layout.fillWidth: true + placeholderText: Translation.tr("Path") + text: Config.options.screenRecord.savePath + wrapMode: TextEdit.Wrap + onTextChanged: { + Config.options.screenRecord.savePath = text; + } + } + } + + } + ContentSection { icon: "search" title: Translation.tr("Search") diff --git a/dots/.config/quickshell/ii/scripts/videos/record.sh b/dots/.config/quickshell/ii/scripts/videos/record.sh index 794bcf1ba..f6410838c 100755 --- a/dots/.config/quickshell/ii/scripts/videos/record.sh +++ b/dots/.config/quickshell/ii/scripts/videos/record.sh @@ -1,21 +1,35 @@ #!/usr/bin/env bash +CONFIG_FILE="$HOME/.config/illogical-impulse/config.json" +JSON_PATH=".screenRecord.savePath" + +CUSTOM_PATH=$(jq -r "$JSON_PATH" "$CONFIG_FILE" 2>/dev/null) + +RECORDING_DIR="" + +if [[ -n "$CUSTOM_PATH" ]]; then + RECORDING_DIR="$CUSTOM_PATH" +else + RECORDING_DIR="$HOME/Videos" +fi + getdate() { - date '+%Y-%m-%d_%H.%M.%S' + date '+%Y-%m-%d_%H.%M.%S' } getaudiooutput() { - pactl list sources | grep 'Name' | grep 'monitor' | cut -d ' ' -f2 + pactl list sources | grep 'Name' | grep 'monitor' | cut -d ' ' -f2 } getactivemonitor() { - hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .name' + hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .name' } -xdgvideo="$(xdg-user-dir VIDEOS)" -if [[ $xdgvideo = "$HOME" ]]; then - unset xdgvideo -fi -mkdir -p "${xdgvideo:-$HOME/Videos}" -cd "${xdgvideo:-$HOME/Videos}" || exit +# ORİJİNAL XDG MANTIĞI SİLİNDİ, YERİNE SADECE YENİ DEĞİŞKEN KULLANILDI +# xdgvideo="$(xdg-user-dir VIDEOS)" +# if $xdgvideo = "$HOME" ]]; then +# unset xdgvideo +# fi +mkdir -p "$RECORDING_DIR" +cd "$RECORDING_DIR" || exit # parse --region without modifying $@ so other flags like --fullscreen still work ARGS=("$@") @@ -23,47 +37,47 @@ MANUAL_REGION="" SOUND_FLAG=0 FULLSCREEN_FLAG=0 for ((i=0;i<${#ARGS[@]};i++)); do - if [[ "${ARGS[i]}" == "--region" ]]; then - if (( i+1 < ${#ARGS[@]} )); then - MANUAL_REGION="${ARGS[i+1]}" - else - notify-send "Recording cancelled" "No region specified for --region" -a 'Recorder' & disown - exit 1 - fi - elif [[ "${ARGS[i]}" == "--sound" ]]; then - SOUND_FLAG=1 - elif [[ "${ARGS[i]}" == "--fullscreen" ]]; then - FULLSCREEN_FLAG=1 - fi + if [[ "${ARGS[i]}" == "--region" ]]; then + if (( i+1 < ${#ARGS[@]} )); then + MANUAL_REGION="${ARGS[i+1]}" + else + notify-send "Recording cancelled" "No region specified for --region" -a 'Recorder' & disown + exit 1 + fi + elif [[ "${ARGS[i]}" == "--sound" ]]; then + SOUND_FLAG=1 + elif [[ "${ARGS[i]}" == "--fullscreen" ]]; then + FULLSCREEN_FLAG=1 + fi done if pgrep wf-recorder > /dev/null; then - notify-send "Recording Stopped" "Stopped" -a 'Recorder' & - pkill wf-recorder & + notify-send "Recording Stopped" "Stopped" -a 'Recorder' & + pkill wf-recorder & else - if [[ $FULLSCREEN_FLAG -eq 1 ]]; then - notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'Recorder' & disown - if [[ $SOUND_FLAG -eq 1 ]]; then - wf-recorder -o "$(getactivemonitor)" --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --audio="$(getaudiooutput)" - else - wf-recorder -o "$(getactivemonitor)" --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t - fi - else - # If a manual region was provided via --region, use it; otherwise run slurp as before. - if [[ -n "$MANUAL_REGION" ]]; then - region="$MANUAL_REGION" - else - if ! region="$(slurp 2>&1)"; then - notify-send "Recording cancelled" "Selection was cancelled" -a 'Recorder' & disown - exit 1 - fi - fi + if [[ $FULLSCREEN_FLAG -eq 1 ]]; then + notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'Recorder' & disown + if [[ $SOUND_FLAG -eq 1 ]]; then + wf-recorder -o "$(getactivemonitor)" --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --audio="$(getaudiooutput)" + else + wf-recorder -o "$(getactivemonitor)" --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t + fi + else + # If a manual region was provided via --region, use it; otherwise run slurp as before. + if [[ -n "$MANUAL_REGION" ]]; then + region="$MANUAL_REGION" + else + if ! region="$(slurp 2>&1)"; then + notify-send "Recording cancelled" "Selection was cancelled" -a 'Recorder' & disown + exit 1 + fi + fi - notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'Recorder' & disown - if [[ $SOUND_FLAG -eq 1 ]]; then - wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$region" --audio="$(getaudiooutput)" - else - wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$region" - fi - fi -fi + notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'Recorder' & disown + if [[ $SOUND_FLAG -eq 1 ]]; then + wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$region" --audio="$(getaudiooutput)" + else + wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$region" + fi + fi +fi \ No newline at end of file From 0fabedb0c4a445bcab33fe4f693f4d6f9c954f94 Mon Sep 17 00:00:00 2001 From: vaguesyntax Date: Sat, 1 Nov 2025 14:41:29 +0300 Subject: [PATCH 17/52] tweaks in script --- .../quickshell/ii/scripts/videos/record.sh | 91 +++++++++---------- 1 file changed, 43 insertions(+), 48 deletions(-) diff --git a/dots/.config/quickshell/ii/scripts/videos/record.sh b/dots/.config/quickshell/ii/scripts/videos/record.sh index f6410838c..bf0ab504d 100755 --- a/dots/.config/quickshell/ii/scripts/videos/record.sh +++ b/dots/.config/quickshell/ii/scripts/videos/record.sh @@ -8,26 +8,21 @@ CUSTOM_PATH=$(jq -r "$JSON_PATH" "$CONFIG_FILE" 2>/dev/null) RECORDING_DIR="" if [[ -n "$CUSTOM_PATH" ]]; then - RECORDING_DIR="$CUSTOM_PATH" + RECORDING_DIR="$CUSTOM_PATH" else - RECORDING_DIR="$HOME/Videos" + RECORDING_DIR="$HOME/Videos" # Use default path fi getdate() { - date '+%Y-%m-%d_%H.%M.%S' + date '+%Y-%m-%d_%H.%M.%S' } getaudiooutput() { - pactl list sources | grep 'Name' | grep 'monitor' | cut -d ' ' -f2 + pactl list sources | grep 'Name' | grep 'monitor' | cut -d ' ' -f2 } getactivemonitor() { - hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .name' + hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .name' } -# ORİJİNAL XDG MANTIĞI SİLİNDİ, YERİNE SADECE YENİ DEĞİŞKEN KULLANILDI -# xdgvideo="$(xdg-user-dir VIDEOS)" -# if $xdgvideo = "$HOME" ]]; then -# unset xdgvideo -# fi mkdir -p "$RECORDING_DIR" cd "$RECORDING_DIR" || exit @@ -37,47 +32,47 @@ MANUAL_REGION="" SOUND_FLAG=0 FULLSCREEN_FLAG=0 for ((i=0;i<${#ARGS[@]};i++)); do - if [[ "${ARGS[i]}" == "--region" ]]; then - if (( i+1 < ${#ARGS[@]} )); then - MANUAL_REGION="${ARGS[i+1]}" - else - notify-send "Recording cancelled" "No region specified for --region" -a 'Recorder' & disown - exit 1 - fi - elif [[ "${ARGS[i]}" == "--sound" ]]; then - SOUND_FLAG=1 - elif [[ "${ARGS[i]}" == "--fullscreen" ]]; then - FULLSCREEN_FLAG=1 - fi + if [[ "${ARGS[i]}" == "--region" ]]; then + if (( i+1 < ${#ARGS[@]} )); then + MANUAL_REGION="${ARGS[i+1]}" + else + notify-send "Recording cancelled" "No region specified for --region" -a 'Recorder' & disown + exit 1 + fi + elif [[ "${ARGS[i]}" == "--sound" ]]; then + SOUND_FLAG=1 + elif [[ "${ARGS[i]}" == "--fullscreen" ]]; then + FULLSCREEN_FLAG=1 + fi done if pgrep wf-recorder > /dev/null; then - notify-send "Recording Stopped" "Stopped" -a 'Recorder' & - pkill wf-recorder & + notify-send "Recording Stopped" "Stopped" -a 'Recorder' & + pkill wf-recorder & else - if [[ $FULLSCREEN_FLAG -eq 1 ]]; then - notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'Recorder' & disown - if [[ $SOUND_FLAG -eq 1 ]]; then - wf-recorder -o "$(getactivemonitor)" --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --audio="$(getaudiooutput)" - else - wf-recorder -o "$(getactivemonitor)" --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t - fi - else - # If a manual region was provided via --region, use it; otherwise run slurp as before. - if [[ -n "$MANUAL_REGION" ]]; then - region="$MANUAL_REGION" - else - if ! region="$(slurp 2>&1)"; then - notify-send "Recording cancelled" "Selection was cancelled" -a 'Recorder' & disown - exit 1 - fi - fi + if [[ $FULLSCREEN_FLAG -eq 1 ]]; then + notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'Recorder' & disown + if [[ $SOUND_FLAG -eq 1 ]]; then + wf-recorder -o "$(getactivemonitor)" --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --audio="$(getaudiooutput)" + else + wf-recorder -o "$(getactivemonitor)" --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t + fi + else + # If a manual region was provided via --region, use it; otherwise run slurp as before. + if [[ -n "$MANUAL_REGION" ]]; then + region="$MANUAL_REGION" + else + if ! region="$(slurp 2>&1)"; then + notify-send "Recording cancelled" "Selection was cancelled" -a 'Recorder' & disown + exit 1 + fi + fi - notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'Recorder' & disown - if [[ $SOUND_FLAG -eq 1 ]]; then - wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$region" --audio="$(getaudiooutput)" - else - wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$region" - fi - fi + notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'Recorder' & disown + if [[ $SOUND_FLAG -eq 1 ]]; then + wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$region" --audio="$(getaudiooutput)" + else + wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$region" + fi + fi fi \ No newline at end of file From ace8802480227850ab528d7e171288328e7786a9 Mon Sep 17 00:00:00 2001 From: vaguesyntax Date: Sat, 1 Nov 2025 15:55:46 +0300 Subject: [PATCH 18/52] add screenshot location --- .../quickshell/ii/modules/common/Config.qml | 4 ++++ .../regionSelector/RegionSelection.qml | 22 ++++++++++++++++++- .../ii/modules/settings/ServicesConfig.qml | 19 +++++++++++++--- .../quickshell/ii/services/DateTime.qml | 1 + 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index 042d10639..db8171b45 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -464,6 +464,10 @@ Singleton { property string savePath: Directories.videos } + property JsonObject screenSnip: JsonObject { + property string savePath: "/home/vaguesyntax/Pictures" + } + property JsonObject sounds: JsonObject { property bool battery: false property bool pomodoro: false diff --git a/dots/.config/quickshell/ii/modules/regionSelector/RegionSelection.qml b/dots/.config/quickshell/ii/modules/regionSelector/RegionSelection.qml index 5ecce47ba..53ccfaf34 100644 --- a/dots/.config/quickshell/ii/modules/regionSelector/RegionSelection.qml +++ b/dots/.config/quickshell/ii/modules/regionSelector/RegionSelection.qml @@ -33,6 +33,10 @@ PanelWindow { property var selectionMode: RegionSelection.SelectionMode.RectCorners signal dismiss() + property string permanentScreenshotDir: Config.options.screenSnip.savePath && Config.options.screenSnip.savePath !== "" + ? Config.options.screenSnip.savePath + : "" + property string screenshotDir: Directories.screenshotTemp property string imageSearchEngineBaseUrl: Config.options.search.imageSearch.imageSearchEngineBaseUrl property string fileUploadApiEndpoint: "https://uguu.se/upload" @@ -258,8 +262,24 @@ PanelWindow { } switch (root.action) { case RegionSelection.SnipAction.Copy: - snipProc.command = ["bash", "-c", `${cropToStdout} | wl-copy && ${cleanup}`] + if (permanentScreenshotDir === "") { + // no permanent dir, just copy to clipboard + snipProc.command = ["bash", "-c", `${cropToStdout} | wl-copy && ${cleanup}`] + break; + } + const saveFileName = 'screenshot-' + DateTime.fileDateTime + '.png' + const savePath = `${root.permanentScreenshotDir}/${saveFileName}` + + snipProc.command = [ + "bash", "-c", + `mkdir -p '${StringUtils.shellSingleQuoteEscape(root.permanentScreenshotDir)}' ` + + `&& ${cropToStdout} | tee >(wl-copy) > '${StringUtils.shellSingleQuoteEscape(savePath)}' ` + + `&& ${cleanup}` + ] break; + + //snipProc.command = ["bash", "-c", `${cropToStdout} | wl-copy && ${cleanup}`] + //break; case RegionSelection.SnipAction.Edit: snipProc.command = ["bash", "-c", `${cropToStdout} | swappy -f - && ${cleanup}`] break; diff --git a/dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml b/dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml index 778ff2b84..5511a6bad 100644 --- a/dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml @@ -86,11 +86,11 @@ ContentPage { } ContentSection { - icon: "screen_record" - title: Translation.tr("Screen Recording") + icon: "file_open" + title: Translation.tr("Save paths") ContentSubsection { - title: Translation.tr("Save path") + " (example: /home/user/Videos)" + title: Translation.tr("Video save path") MaterialTextArea { Layout.fillWidth: true placeholderText: Translation.tr("Path") @@ -101,6 +101,19 @@ ContentPage { } } } + + ContentSubsection { + title: Translation.tr("Screenshot save path") + " (leave empty to just copy)" + MaterialTextArea { + Layout.fillWidth: true + placeholderText: Translation.tr("Path") + text: Config.options.screenSnip.savePath + wrapMode: TextEdit.Wrap + onTextChanged: { + Config.options.screenSnip.savePath = text; + } + } + } } diff --git a/dots/.config/quickshell/ii/services/DateTime.qml b/dots/.config/quickshell/ii/services/DateTime.qml index 62d296dbc..c6998f056 100644 --- a/dots/.config/quickshell/ii/services/DateTime.qml +++ b/dots/.config/quickshell/ii/services/DateTime.qml @@ -22,6 +22,7 @@ Singleton { property string shortDate: Qt.locale().toString(clock.date, Config.options?.time.shortDateFormat ?? "dd/MM") property string date: Qt.locale().toString(clock.date, Config.options?.time.dateFormat ?? "dddd, dd/MM") property string collapsedCalendarFormat: Qt.locale().toString(clock.date, "dd MMMM yyyy") + property string fileDateTime: Qt.locale().toString(clock.date, "dd-MM-yyyy_HH.mm") property string uptime: "0h, 0m" Timer { From 0c587415eadd3081c968d061fd1b6f921d2ee888 Mon Sep 17 00:00:00 2001 From: vaguesyntax Date: Sat, 1 Nov 2025 16:00:32 +0300 Subject: [PATCH 19/52] tweaks in settings/config --- .../quickshell/ii/modules/common/Config.qml | 2 +- .../ii/modules/settings/ServicesConfig.qml | 39 ++++++++----------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index db8171b45..8a3b51c73 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -465,7 +465,7 @@ Singleton { } property JsonObject screenSnip: JsonObject { - property string savePath: "/home/vaguesyntax/Pictures" + property string savePath: "" // only copy to clipboard when empty } property JsonObject sounds: JsonObject { diff --git a/dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml b/dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml index 5511a6bad..3f5f25f45 100644 --- a/dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml @@ -89,32 +89,25 @@ ContentPage { icon: "file_open" title: Translation.tr("Save paths") - ContentSubsection { - title: Translation.tr("Video save path") - MaterialTextArea { - Layout.fillWidth: true - placeholderText: Translation.tr("Path") - text: Config.options.screenRecord.savePath - wrapMode: TextEdit.Wrap - onTextChanged: { - Config.options.screenRecord.savePath = text; - } - } - } - - ContentSubsection { - title: Translation.tr("Screenshot save path") + " (leave empty to just copy)" - MaterialTextArea { - Layout.fillWidth: true - placeholderText: Translation.tr("Path") - text: Config.options.screenSnip.savePath - wrapMode: TextEdit.Wrap - onTextChanged: { - Config.options.screenSnip.savePath = text; - } + MaterialTextArea { + Layout.fillWidth: true + placeholderText: Translation.tr("Video Recording Path") + text: Config.options.screenRecord.savePath + wrapMode: TextEdit.Wrap + onTextChanged: { + Config.options.screenRecord.savePath = text; } } + MaterialTextArea { + Layout.fillWidth: true + placeholderText: Translation.tr("Screenshot Path (leave empyt to just copy)") + text: Config.options.screenSnip.savePath + wrapMode: TextEdit.Wrap + onTextChanged: { + Config.options.screenSnip.savePath = text; + } + } } ContentSection { From 6afa6d2142acc019ea921f0340bffbf0548165b0 Mon Sep 17 00:00:00 2001 From: vaguesyntax Date: Sat, 1 Nov 2025 16:04:04 +0300 Subject: [PATCH 20/52] remove reduntant code --- .../quickshell/ii/modules/regionSelector/RegionSelection.qml | 3 --- 1 file changed, 3 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/regionSelector/RegionSelection.qml b/dots/.config/quickshell/ii/modules/regionSelector/RegionSelection.qml index 53ccfaf34..9d984d5ec 100644 --- a/dots/.config/quickshell/ii/modules/regionSelector/RegionSelection.qml +++ b/dots/.config/quickshell/ii/modules/regionSelector/RegionSelection.qml @@ -277,9 +277,6 @@ PanelWindow { `&& ${cleanup}` ] break; - - //snipProc.command = ["bash", "-c", `${cropToStdout} | wl-copy && ${cleanup}`] - //break; case RegionSelection.SnipAction.Edit: snipProc.command = ["bash", "-c", `${cropToStdout} | swappy -f - && ${cleanup}`] break; From a240329f22822a927a8ee757b19d9395bec7a4ca Mon Sep 17 00:00:00 2001 From: vaguesyntax Date: Sat, 1 Nov 2025 16:18:02 +0300 Subject: [PATCH 21/52] fix: initialize recording path setting properly --- dots/.config/quickshell/ii/modules/common/Config.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index 8a3b51c73..10eaa0126 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -461,7 +461,7 @@ Singleton { } property JsonObject screenRecord: JsonObject { - property string savePath: Directories.videos + property string savePath: Directories.videos.replace("file://","") // strip "file://" } property JsonObject screenSnip: JsonObject { From 8e1a3d26b1de458ecee8d5040ffec0ca21baf9a7 Mon Sep 17 00:00:00 2001 From: Vague Syntax Date: Sat, 1 Nov 2025 17:56:38 +0300 Subject: [PATCH 22/52] Update dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml Co-authored-by: Madjid Taha <1833954+madjidtaha@users.noreply.github.com> --- dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml b/dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml index 3f5f25f45..f5931bb1b 100644 --- a/dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/ServicesConfig.qml @@ -101,7 +101,7 @@ ContentPage { MaterialTextArea { Layout.fillWidth: true - placeholderText: Translation.tr("Screenshot Path (leave empyt to just copy)") + placeholderText: Translation.tr("Screenshot Path (leave empty to just copy)") text: Config.options.screenSnip.savePath wrapMode: TextEdit.Wrap onTextChanged: { From b267b74e8be45ae6a3737cc0b9c04be5280a227f Mon Sep 17 00:00:00 2001 From: EinBowser <146022965+EinBowser@users.noreply.github.com> Date: Sat, 1 Nov 2025 20:50:39 +0100 Subject: [PATCH 23/52] Added battery health and made it configurable --- .../ii/modules/bar/BatteryPopup.qml | 23 +++++++++++++++++++ .../quickshell/ii/modules/common/Config.qml | 1 + .../ii/scripts/battery/calculate_health.sh | 11 +++++++++ .../quickshell/ii/services/Battery.qml | 23 +++++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100644 dots/.config/quickshell/ii/scripts/battery/calculate_health.sh diff --git a/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml b/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml index 5bc07d18c..72523393d 100644 --- a/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml +++ b/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml @@ -63,6 +63,29 @@ StyledPopup { text: Battery.isCharging ? Translation.tr("Time to full:") : Translation.tr("Time to empty:") color: Appearance.colors.colOnSurfaceVariant } + RowLayout { + spacing: 5 + visible: Config.options.battery.showHealth + Layout.fillWidth: true + + MaterialSymbol { + text: "healing" + color: Appearance.colors.colOnSurfaceVariant + iconSize: Appearance.font.pixelSize.large + } + + StyledText { + text: Translation.tr("Health:") + color: Appearance.colors.colOnSurfaceVariant + } + + StyledText { + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + color: Appearance.colors.colOnSurfaceVariant + text: `${(Battery.health).toFixed(1)}%` + } + } StyledText { Layout.fillWidth: true horizontalAlignment: Text.AlignRight diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index 39c0ef131..854a059ab 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -257,6 +257,7 @@ Singleton { property int full: 101 property bool automaticSuspend: true property int suspend: 3 + property bool showHealth: true } property JsonObject conflictKiller: JsonObject { diff --git a/dots/.config/quickshell/ii/scripts/battery/calculate_health.sh b/dots/.config/quickshell/ii/scripts/battery/calculate_health.sh new file mode 100644 index 000000000..58a4b1d4d --- /dev/null +++ b/dots/.config/quickshell/ii/scripts/battery/calculate_health.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +# This just guesses that the BAT0 is the actuall battery +full=$(cat /sys/class/power_supply/BAT0/charge_full) +design=$(cat /sys/class/power_supply/BAT0/charge_full_design) + +if [ "$design" -gt 0 ]; then # basically if design > 0 + awk "BEGIN { printf \"%.1f\n\", ($full/$design)*100 }" +else + echo "Error" +fi \ No newline at end of file diff --git a/dots/.config/quickshell/ii/services/Battery.qml b/dots/.config/quickshell/ii/services/Battery.qml index b07bd5305..8ff75da10 100644 --- a/dots/.config/quickshell/ii/services/Battery.qml +++ b/dots/.config/quickshell/ii/services/Battery.qml @@ -31,6 +31,29 @@ Singleton { property real timeToEmpty: UPower.displayDevice.timeToEmpty property real timeToFull: UPower.displayDevice.timeToFull + property real health: 0 + Process { + id: batteryProcess + running: Config.options.battery.showHealth + command: [ + "bash", + `${FileUtils.trimFileProtocol(Directories.scriptPath)}/battery/calculate-health.sh` + ] + + stdout: StdioCollector { + onStreamFinished: { + const output = text.trim() + const value = Number(output) + if (!isNaN(value)) { + root.health = value + console.log("Battery health:", value) + } else { + console.warn("Battery script output invalid:", output) + } + } + } + } + onIsLowAndNotChargingChanged: { if (!root.available || !isLowAndNotCharging) return; Quickshell.execDetached([ From ca7d6c8ae0ded1b5678c0baeb55f5503bcc69ef2 Mon Sep 17 00:00:00 2001 From: EinBowser <146022965+EinBowser@users.noreply.github.com> Date: Sat, 1 Nov 2025 22:11:39 +0100 Subject: [PATCH 24/52] Added config toggle to settings --- .../quickshell/ii/modules/settings/GeneralConfig.qml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dots/.config/quickshell/ii/modules/settings/GeneralConfig.qml b/dots/.config/quickshell/ii/modules/settings/GeneralConfig.qml index c2ea1f930..3be552b9c 100644 --- a/dots/.config/quickshell/ii/modules/settings/GeneralConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/GeneralConfig.qml @@ -127,6 +127,14 @@ ContentPage { } } } + ConfigSwitch { + buttonIcon: "healing" + text: Translation.tr('Show battery health in popup') + checked: Config.options.battery.showHealth + onCheckedChanged: { + Config.options.battery.showHealth = checked; + } + } } ContentSection { From 6676d5844bd5db542e491c1027ccebce30efc293 Mon Sep 17 00:00:00 2001 From: EinBowser <146022965+EinBowser@users.noreply.github.com> Date: Sat, 1 Nov 2025 22:22:58 +0100 Subject: [PATCH 25/52] changed the script to the right name, added some info and removed unnecesary debug --- .../battery/{calculate_health.sh => calculate-health.sh} | 7 ++++++- dots/.config/quickshell/ii/services/Battery.qml | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) rename dots/.config/quickshell/ii/scripts/battery/{calculate_health.sh => calculate-health.sh} (53%) diff --git a/dots/.config/quickshell/ii/scripts/battery/calculate_health.sh b/dots/.config/quickshell/ii/scripts/battery/calculate-health.sh similarity index 53% rename from dots/.config/quickshell/ii/scripts/battery/calculate_health.sh rename to dots/.config/quickshell/ii/scripts/battery/calculate-health.sh index 58a4b1d4d..83b52a5a0 100644 --- a/dots/.config/quickshell/ii/scripts/battery/calculate_health.sh +++ b/dots/.config/quickshell/ii/scripts/battery/calculate-health.sh @@ -1,6 +1,7 @@ #!/bin/bash # This just guesses that the BAT0 is the actuall battery +# because BAT0 is the default for modern systems full=$(cat /sys/class/power_supply/BAT0/charge_full) design=$(cat /sys/class/power_supply/BAT0/charge_full_design) @@ -8,4 +9,8 @@ if [ "$design" -gt 0 ]; then # basically if design > 0 awk "BEGIN { printf \"%.1f\n\", ($full/$design)*100 }" else echo "Error" -fi \ No newline at end of file +fi + +# If you have any issues try to find your "real" battery. +# Run 'ls /sys/class/power_supply'. You may see BATM or BAT1 and no BAT0 +# You can check what is what my running 'cat /sys/class/power_supply/{whatever_you_got}/model_name' diff --git a/dots/.config/quickshell/ii/services/Battery.qml b/dots/.config/quickshell/ii/services/Battery.qml index 8ff75da10..caa0ab9fe 100644 --- a/dots/.config/quickshell/ii/services/Battery.qml +++ b/dots/.config/quickshell/ii/services/Battery.qml @@ -46,7 +46,6 @@ Singleton { const value = Number(output) if (!isNaN(value)) { root.health = value - console.log("Battery health:", value) } else { console.warn("Battery script output invalid:", output) } From 0e63e698f26a3c8afc22a8f0708a6c3895a46944 Mon Sep 17 00:00:00 2001 From: EinBowser <146022965+EinBowser@users.noreply.github.com> Date: Sat, 1 Nov 2025 23:26:36 +0100 Subject: [PATCH 26/52] Wrong position and forgot an import --- .../ii/modules/bar/BatteryPopup.qml | 43 ++++++++++--------- .../quickshell/ii/services/Battery.qml | 1 + 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml b/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml index 72523393d..bba4c422c 100644 --- a/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml +++ b/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml @@ -63,7 +63,28 @@ StyledPopup { text: Battery.isCharging ? Translation.tr("Time to full:") : Translation.tr("Time to empty:") color: Appearance.colors.colOnSurfaceVariant } - RowLayout { + StyledText { + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + color: Appearance.colors.colOnSurfaceVariant + text: { + function formatTime(seconds) { + var h = Math.floor(seconds / 3600); + var m = Math.floor((seconds % 3600) / 60); + if (h > 0) + return `${h}h, ${m}m`; + else + return `${m}m`; + } + if (Battery.isCharging) + return formatTime(Battery.timeToFull); + else + return formatTime(Battery.timeToEmpty); + } + } + } + + RowLayout { spacing: 5 visible: Config.options.battery.showHealth Layout.fillWidth: true @@ -86,26 +107,6 @@ StyledPopup { text: `${(Battery.health).toFixed(1)}%` } } - StyledText { - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - color: Appearance.colors.colOnSurfaceVariant - text: { - function formatTime(seconds) { - var h = Math.floor(seconds / 3600); - var m = Math.floor((seconds % 3600) / 60); - if (h > 0) - return `${h}h, ${m}m`; - else - return `${m}m`; - } - if (Battery.isCharging) - return formatTime(Battery.timeToFull); - else - return formatTime(Battery.timeToEmpty); - } - } - } RowLayout { spacing: 5 diff --git a/dots/.config/quickshell/ii/services/Battery.qml b/dots/.config/quickshell/ii/services/Battery.qml index caa0ab9fe..a3f45ac77 100644 --- a/dots/.config/quickshell/ii/services/Battery.qml +++ b/dots/.config/quickshell/ii/services/Battery.qml @@ -6,6 +6,7 @@ import Quickshell import Quickshell.Services.UPower import QtQuick import Quickshell.Io +import qs.modules.common.functions Singleton { id: root From 8a208242663868464e696ecfce0e0520adf7b86a Mon Sep 17 00:00:00 2001 From: EinBowser <146022965+EinBowser@users.noreply.github.com> Date: Sat, 1 Nov 2025 23:32:08 +0100 Subject: [PATCH 27/52] Disabled by default --- dots/.config/quickshell/ii/modules/common/Config.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index 854a059ab..7e82e87d0 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -257,7 +257,7 @@ Singleton { property int full: 101 property bool automaticSuspend: true property int suspend: 3 - property bool showHealth: true + property bool showHealth: false } property JsonObject conflictKiller: JsonObject { From 0c2916705753605d2b935832b0fcad49afe93dd5 Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Sun, 2 Nov 2025 17:23:31 +0100 Subject: [PATCH 28/52] try something for the nyx-4 feedback --- .../modules/cheatsheet/CheatsheetKeybinds.qml | 37 ++++---- .../quickshell/ii/modules/common/Config.qml | 2 +- .../ii/modules/settings/InterfaceConfig.qml | 84 ++----------------- 3 files changed, 26 insertions(+), 97 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml index 80208df5e..d47acc9a0 100644 --- a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml +++ b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml @@ -17,25 +17,20 @@ Item { // Excellent symbol explaination and source : // http://xahlee.info/comp/unicode_computing_symbols.html // https://www.nerdfonts.com/cheat-sheet - property list superMap: [ - "󰖳", "󰌽", "⌘", "", "󰨡", "", "", - "󰣇", "", "", "", "", " ", "", - "󱄛", "󰀲", "󰟍", "" - ] property var macSymbolMap: ({ - "Ctrl": "󰘴" , - "Alt": "󰘵" , - "Shift": "󰘶" , - "Space": "󱁐" , - "Tab": "↹" , - "Equal": "󰇼" , - "Minus": "" , - "Print": "" , - "BackSpace": "󰭜" , - "Delete": "⌦" , - "Return": "󰌑" , - "Period": "." , - "Escape": "⎋" + "Ctrl": "󰘴", + "Alt": "󰘵", + "Shift": "󰘶", + "Space": "󱁐", + "Tab": "↹", + "Equal": "󰇼", + "Minus": "", + "Print": "", + "BackSpace": "󰭜", + "Delete": "⌦", + "Return": "󰌑", + "Period": ".", + "Escape": "⎋" }) property var functionSymbolMap: ({ "F1": "󱊫", @@ -53,7 +48,7 @@ Item { }) property var mouseSymbolMap: ({ - "mouse_up": "󱕐" , + "mouse_up": "󱕐", "mouse_down": "󱕑", "mouse:272": "L󰍽", "mouse:273": "R󰍽", @@ -74,8 +69,8 @@ Item { "Return": "Enter", // "Shift": "", }, - Config.options.appearance.keybinds.superKey > 0 ? { - "Super": superMap[Config.options.appearance.keybinds.superKey], + !!Config.options.appearance.keybinds.superKey ? { + "Super": Config.options.appearance.keybinds.superKey, }: {}, Config.options.appearance.keybinds.useMacSymbol ? macSymbolMap : {}, Config.options.appearance.keybinds.useFnSymbol ? functionSymbolMap : {}, diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index 6ae8d25f8..c4af0a850 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -128,7 +128,7 @@ Singleton { // 0: 󰖳 | 1: 󰌽 | 2: 󰘳 | 3:  | 4: 󰨡 // 5:  | 6:  | 7: 󰣇 | 8:  | 9:  // 10:  | 11:  | 12:  | 13:  | 14: 󱄛 - property int superKey: 0 + property string superKey: "󰖳" property bool useMacSymbol: false property bool useMacLikeShortcut: false property bool useMouseSymbol: false diff --git a/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml b/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml index 79b01bf95..b1d51063b 100644 --- a/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml @@ -1019,87 +1019,21 @@ ContentPage { ContentSubsection { title: Translation.tr("Super Key Symbol") + tooltip: Translation.tr("Choose a symbol from this list or edit config.json and add your own nerd symbol in appearance.keybinds.superKey.") ConfigSelectionArray { currentValue: Config.options.appearance.keybinds.superKey onSelected: newValue => { Config.options.appearance.keybinds.superKey = newValue; } // Use a nerdfont to see the icons - // 0: 󰖳 | 1: 󰌽 | 2: 󰘳 | 3:  | 4: 󰨡 - // 5:  | 6:  | 7: 󰣇 | 8:  | 9:  - // 10:  | 11:  | 12:  | 13:  | 14: 󱄛 - // 15: 󰀲 | 16: 󰟍 | 17:  | - options: [ - { - displayName: "󰖳", - value: 0 - }, - { - displayName: "", - value: 3 - }, - { - displayName: "󰨡", - value: 4 - }, - { - displayName: "", - value: 5 - }, - { - displayName: "󰣇", - value: 7 - }, - { - displayName: "", - value: 12 - }, - { - displayName: "", - value: 13 - }, - { - displayName: "", - value: 11 - }, - { - displayName: "", - value: 10 - }, - { - displayName: "", - value: 8 - }, - { - displayName: "󱄛", - value: 14 - }, - { - displayName: "", - value: 9 - }, - { - displayName: "", - value: 6 - }, - { - displayName: "󰘳", - value: 2 - }, - { - displayName: "󰀲", - value: 15 - }, - { - displayName: "󰟍", - value: 16 - }, - { - displayName: "", - value: 17 - }, - - ] + options: ([ + "󰖳", "", "󰨡", "", "󰌽", "󰣇", "", "", "", + "", "", "󱄛", "", "", "⌘", "󰀲", "󰟍", "" + ]).map(icon => { return { + displayName: icon, + value: icon + } + }) } } From a323e32a4290b2e861f1d1a65dc581f03c5a5ef0 Mon Sep 17 00:00:00 2001 From: EinBowser <146022965+EinBowser@users.noreply.github.com> Date: Mon, 3 Nov 2025 20:53:40 +0100 Subject: [PATCH 29/52] Removed helper script and made workaround in qml --- .../ii/scripts/battery/calculate-health.sh | 16 --------- .../quickshell/ii/services/Battery.qml | 34 ++++++++++--------- 2 files changed, 18 insertions(+), 32 deletions(-) delete mode 100644 dots/.config/quickshell/ii/scripts/battery/calculate-health.sh diff --git a/dots/.config/quickshell/ii/scripts/battery/calculate-health.sh b/dots/.config/quickshell/ii/scripts/battery/calculate-health.sh deleted file mode 100644 index 83b52a5a0..000000000 --- a/dots/.config/quickshell/ii/scripts/battery/calculate-health.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -# This just guesses that the BAT0 is the actuall battery -# because BAT0 is the default for modern systems -full=$(cat /sys/class/power_supply/BAT0/charge_full) -design=$(cat /sys/class/power_supply/BAT0/charge_full_design) - -if [ "$design" -gt 0 ]; then # basically if design > 0 - awk "BEGIN { printf \"%.1f\n\", ($full/$design)*100 }" -else - echo "Error" -fi - -# If you have any issues try to find your "real" battery. -# Run 'ls /sys/class/power_supply'. You may see BATM or BAT1 and no BAT0 -# You can check what is what my running 'cat /sys/class/power_supply/{whatever_you_got}/model_name' diff --git a/dots/.config/quickshell/ii/services/Battery.qml b/dots/.config/quickshell/ii/services/Battery.qml index a3f45ac77..0875bbe70 100644 --- a/dots/.config/quickshell/ii/services/Battery.qml +++ b/dots/.config/quickshell/ii/services/Battery.qml @@ -32,27 +32,29 @@ Singleton { property real timeToEmpty: UPower.displayDevice.timeToEmpty property real timeToFull: UPower.displayDevice.timeToFull - property real health: 0 - Process { - id: batteryProcess - running: Config.options.battery.showHealth - command: [ - "bash", - `${FileUtils.trimFileProtocol(Directories.scriptPath)}/battery/calculate-health.sh` - ] + property real health: (function() { + if (!Config.options.battery.showHealth) { + return 0; + } - stdout: StdioCollector { - onStreamFinished: { - const output = text.trim() - const value = Number(output) - if (!isNaN(value)) { - root.health = value + const devList = UPower.devices.values; + for (let i = 0; i < devList.length; ++i) { + const dev = devList[i]; + if (dev.isLaptopBattery && dev.healthSupported) { + const health = dev.healthPercentage; + if (health === 0) { + return 0; + } else if (health < 1) { + return health * 100; } else { - console.warn("Battery script output invalid:", output) + return health; } } } - } + return 0; + })() + + onIsLowAndNotChargingChanged: { if (!root.available || !isLowAndNotCharging) return; From c0d64c463037f59cbc95b06a4c5e8c38cc15534c Mon Sep 17 00:00:00 2001 From: EinBowser <146022965+EinBowser@users.noreply.github.com> Date: Mon, 3 Nov 2025 20:55:17 +0100 Subject: [PATCH 30/52] Forgot to delete unnecessary import --- dots/.config/quickshell/ii/services/Battery.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/dots/.config/quickshell/ii/services/Battery.qml b/dots/.config/quickshell/ii/services/Battery.qml index 0875bbe70..39aa720ab 100644 --- a/dots/.config/quickshell/ii/services/Battery.qml +++ b/dots/.config/quickshell/ii/services/Battery.qml @@ -6,7 +6,6 @@ import Quickshell import Quickshell.Services.UPower import QtQuick import Quickshell.Io -import qs.modules.common.functions Singleton { id: root From c1ff57c3d043d995a1f9a4b85451b9d7ee09e42f Mon Sep 17 00:00:00 2001 From: EinBowser <146022965+EinBowser@users.noreply.github.com> Date: Tue, 4 Nov 2025 14:20:23 +0100 Subject: [PATCH 31/52] Don't display when unsupported --- dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml | 2 +- dots/.config/quickshell/ii/services/Battery.qml | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml b/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml index bba4c422c..6e4bf1c9e 100644 --- a/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml +++ b/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml @@ -86,7 +86,7 @@ StyledPopup { RowLayout { spacing: 5 - visible: Config.options.battery.showHealth + visible: Config.options.battery.showHealth && Battery.health > 0 Layout.fillWidth: true MaterialSymbol { diff --git a/dots/.config/quickshell/ii/services/Battery.qml b/dots/.config/quickshell/ii/services/Battery.qml index 39aa720ab..849870cd2 100644 --- a/dots/.config/quickshell/ii/services/Battery.qml +++ b/dots/.config/quickshell/ii/services/Battery.qml @@ -35,14 +35,13 @@ Singleton { if (!Config.options.battery.showHealth) { return 0; } - const devList = UPower.devices.values; for (let i = 0; i < devList.length; ++i) { const dev = devList[i]; if (dev.isLaptopBattery && dev.healthSupported) { const health = dev.healthPercentage; if (health === 0) { - return 0; + return 0.01; } else if (health < 1) { return health * 100; } else { @@ -54,7 +53,6 @@ Singleton { })() - onIsLowAndNotChargingChanged: { if (!root.available || !isLowAndNotCharging) return; Quickshell.execDetached([ From 31f2184dc67984fd127041c02e0d32acb472ae86 Mon Sep 17 00:00:00 2001 From: EinBowser <146022965+EinBowser@users.noreply.github.com> Date: Tue, 4 Nov 2025 15:58:01 +0100 Subject: [PATCH 32/52] Removed settings and configs for battery health --- dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml | 2 +- dots/.config/quickshell/ii/modules/common/Config.qml | 1 - .../quickshell/ii/modules/settings/GeneralConfig.qml | 8 -------- dots/.config/quickshell/ii/services/Battery.qml | 3 --- 4 files changed, 1 insertion(+), 13 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml b/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml index 6e4bf1c9e..47345ee1f 100644 --- a/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml +++ b/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml @@ -86,7 +86,7 @@ StyledPopup { RowLayout { spacing: 5 - visible: Config.options.battery.showHealth && Battery.health > 0 + visible: Battery.health > 0 Layout.fillWidth: true MaterialSymbol { diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index 7e82e87d0..39c0ef131 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -257,7 +257,6 @@ Singleton { property int full: 101 property bool automaticSuspend: true property int suspend: 3 - property bool showHealth: false } property JsonObject conflictKiller: JsonObject { diff --git a/dots/.config/quickshell/ii/modules/settings/GeneralConfig.qml b/dots/.config/quickshell/ii/modules/settings/GeneralConfig.qml index 3be552b9c..c2ea1f930 100644 --- a/dots/.config/quickshell/ii/modules/settings/GeneralConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/GeneralConfig.qml @@ -127,14 +127,6 @@ ContentPage { } } } - ConfigSwitch { - buttonIcon: "healing" - text: Translation.tr('Show battery health in popup') - checked: Config.options.battery.showHealth - onCheckedChanged: { - Config.options.battery.showHealth = checked; - } - } } ContentSection { diff --git a/dots/.config/quickshell/ii/services/Battery.qml b/dots/.config/quickshell/ii/services/Battery.qml index 849870cd2..f368b8203 100644 --- a/dots/.config/quickshell/ii/services/Battery.qml +++ b/dots/.config/quickshell/ii/services/Battery.qml @@ -32,9 +32,6 @@ Singleton { property real timeToFull: UPower.displayDevice.timeToFull property real health: (function() { - if (!Config.options.battery.showHealth) { - return 0; - } const devList = UPower.devices.values; for (let i = 0; i < devList.length; ++i) { const dev = devList[i]; From a28945f3eceff58a7eca4b3d298561789fc13540 Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Tue, 4 Nov 2025 17:51:16 +0100 Subject: [PATCH 33/52] fix: remove warning unqualified access --- .../quickshell/ii/modules/common/widgets/KeyboardKey.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/common/widgets/KeyboardKey.qml b/dots/.config/quickshell/ii/modules/common/widgets/KeyboardKey.qml index f620a3e3f..cdb287aca 100644 --- a/dots/.config/quickshell/ii/modules/common/widgets/KeyboardKey.qml +++ b/dots/.config/quickshell/ii/modules/common/widgets/KeyboardKey.qml @@ -11,7 +11,7 @@ Rectangle { property real extraBottomBorderWidth: 2 property color borderColor: Appearance.colors.colOnLayer0 property real borderRadius: 5 - property int pixelSize: Appearance.font.pixelSize.smaller + property real pixelSize: Appearance.font.pixelSize.smaller property color keyColor: Appearance.m3colors.m3surfaceContainerLow implicitWidth: keyFace.implicitWidth + borderWidth * 2 implicitHeight: keyFace.implicitHeight + borderWidth * 2 + extraBottomBorderWidth @@ -36,7 +36,7 @@ Rectangle { id: keyText anchors.centerIn: parent font.family: Appearance.font.family.monospace - font.pixelSize: pixelSize + font.pixelSize: root.pixelSize text: key } } From ede86dc7a73a1fc91c8487aff4f18eaca99b7cdf Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Tue, 4 Nov 2025 20:55:34 +0100 Subject: [PATCH 34/52] fix(cheatsheet): change config keys --- .../modules/cheatsheet/CheatsheetKeybinds.qml | 22 +-- .../quickshell/ii/modules/common/Config.qml | 31 +-- .../ii/modules/settings/InterfaceConfig.qml | 184 +++++++++--------- 3 files changed, 119 insertions(+), 118 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml index a7c32fa13..3a78e86ce 100644 --- a/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml +++ b/dots/.config/quickshell/ii/modules/cheatsheet/CheatsheetKeybinds.qml @@ -69,12 +69,12 @@ Item { "Return": "Enter", // "Shift": "", }, - !!Config.options.appearance.keybinds.superKey ? { - "Super": Config.options.appearance.keybinds.superKey, + !!Config.options.cheatsheet.superKey ? { + "Super": Config.options.cheatsheet.superKey, }: {}, - Config.options.appearance.keybinds.useMacSymbol ? macSymbolMap : {}, - Config.options.appearance.keybinds.useFnSymbol ? functionSymbolMap : {}, - Config.options.appearance.keybinds.useMouseSymbol ? mouseSymbolMap : {}, + Config.options.cheatsheet.useMacSymbol ? macSymbolMap : {}, + Config.options.cheatsheet.useFnSymbol ? functionSymbolMap : {}, + Config.options.cheatsheet.useMouseSymbol ? mouseSymbolMap : {}, ) Row { // Keybind columns @@ -126,7 +126,7 @@ Item { for (var i = 0; i < keybindSection.modelData.keybinds.length; i++) { const keybind = keybindSection.modelData.keybinds[i]; - if (Config.options.appearance.keybinds.useMacLikeShortcut) { + if (!Config.options.cheatsheet.splitButtons) { for (var j = 0; j < keybind.mods.length; j++) { keybind.mods[j] = keySubstitutions[keybind.mods[j]] || keybind.mods[j]; @@ -167,19 +167,19 @@ Item { delegate: KeyboardKey { required property var modelData key: keySubstitutions[modelData] || modelData - pixelSize: Config.options.appearance.keybinds.fontSize.key + pixelSize: Config.options.cheatsheet.fontSize.key } } StyledText { id: keybindPlus - visible: !Config.options.appearance.keybinds.useMacLikeShortcut && !keyBlacklist.includes(modelData.key) && modelData.mods.length > 0 + visible: Config.options.cheatsheet.splitButtons && !keyBlacklist.includes(modelData.key) && modelData.mods.length > 0 text: "+" } KeyboardKey { id: keybindKey - visible: !Config.options.appearance.keybinds.useMacLikeShortcut && !keyBlacklist.includes(modelData.key) + visible: Config.options.cheatsheet.splitButtons && !keyBlacklist.includes(modelData.key) key: keySubstitutions[modelData.key] || modelData.key - pixelSize: Config.options.appearance.keybinds.fontSize.key + pixelSize: Config.options.cheatsheet.fontSize.key color: Appearance.colors.colOnLayer0 } } @@ -195,7 +195,7 @@ Item { StyledText { id: commentText anchors.centerIn: parent - font.pixelSize: Config.options.appearance.keybinds.fontSize.comment || Appearance.font.pixelSize.smaller + font.pixelSize: Config.options.cheatsheet.fontSize.comment || Appearance.font.pixelSize.smaller text: modelData.comment } } diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index 766033e47..15b143c8c 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -123,21 +123,6 @@ Singleton { property JsonObject palette: JsonObject { property string type: "auto" // Allowed: auto, scheme-content, scheme-expressive, scheme-fidelity, scheme-fruit-salad, scheme-monochrome, scheme-neutral, scheme-rainbow, scheme-tonal-spot } - property JsonObject keybinds: JsonObject { - // Use a nerdfont to see the icons - // 0: 󰖳 | 1: 󰌽 | 2: 󰘳 | 3:  | 4: 󰨡 - // 5:  | 6:  | 7: 󰣇 | 8:  | 9:  - // 10:  | 11:  | 12:  | 13:  | 14: 󱄛 - property string superKey: "󰖳" - property bool useMacSymbol: false - property bool useMacLikeShortcut: false - property bool useMouseSymbol: false - property bool useFnSymbol: false - property JsonObject fontSize: JsonObject { - property int key: Appearance.font.pixelSize.smaller - property int comment: Appearance.font.pixelSize.smaller - } - } } property JsonObject audio: JsonObject { @@ -274,6 +259,22 @@ Singleton { property int suspend: 3 } + property JsonObject cheatsheet: JsonObject { + // Use a nerdfont to see the icons + // 0: 󰖳 | 1: 󰌽 | 2: 󰘳 | 3:  | 4: 󰨡 + // 5:  | 6:  | 7: 󰣇 | 8:  | 9:  + // 10:  | 11:  | 12:  | 13:  | 14: 󱄛 + property string superKey: "󰖳" + property bool useMacSymbol: false + property bool splitButtons: true + property bool useMouseSymbol: false + property bool useFnSymbol: false + property JsonObject fontSize: JsonObject { + property int key: Appearance.font.pixelSize.smaller + property int comment: Appearance.font.pixelSize.smaller + } + } + property JsonObject conflictKiller: JsonObject { property bool autoKillNotificationDaemons: false property bool autoKillTrays: false diff --git a/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml b/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml index 90aa11030..431b8f2ea 100644 --- a/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml @@ -402,6 +402,98 @@ ContentPage { } } + ContentSection { + icon: "keyboard" + title: Translation.tr("Cheat sheet") + + ContentSubsection { + title: Translation.tr("Super key symbol") + tooltip: Translation.tr("Choose a symbol from this list or edit config.json and add your own nerd symbol in cheatsheet.superKey.") + ConfigSelectionArray { + currentValue: Config.options.cheatsheet.superKey + onSelected: newValue => { + Config.options.cheatsheet.superKey = newValue; + } + // Use a nerdfont to see the icons + options: ([ + "󰖳", "", "󰨡", "", "󰌽", "󰣇", "", "", "", + "", "", "󱄛", "", "", "⌘", "󰀲", "󰟍", "" + ]).map(icon => { return { + displayName: icon, + value: icon + } + }) + } + } + + ConfigSwitch { + buttonIcon: "󰘵" + text: Translation.tr("Use macOS-like symbols for mods keys") + checked: Config.options.cheatsheet.useMacSymbol + onCheckedChanged: { + Config.options.cheatsheet.useMacSymbol = checked; + } + StyledToolTip { + text: Translation.tr("e.g. 󰘴 for Ctrl, 󰘵 for Alt, 󰘶 for Shift, etc") + } + } + + ConfigSwitch { + buttonIcon: "󱊶" + text: Translation.tr("Use symbols for function keys") + checked: Config.options.cheatsheet.useFnSymbol + onCheckedChanged: { + Config.options.cheatsheet.useFnSymbol = checked; + } + StyledToolTip { + text: Translation.tr("e.g. 󱊫 for F1, 󱊶 for F12") + } + } + ConfigSwitch { + buttonIcon: "󰍽" + text: Translation.tr("Use symbols for mouse") + checked: Config.options.cheatsheet.useMouseSymbol + onCheckedChanged: { + Config.options.cheatsheet.useMouseSymbol = checked; + } + StyledToolTip { + text: Translation.tr("Replace 󱕐 for \"Scroll ↓\", 󱕑 \"Scroll ↑\", L󰍽 \"LMB\", R󰍽 \"RMB\", 󱕒 \"Scroll ↑/↓\" and ⇞/⇟ for \"Page_↑/↓\"") + } + } + ConfigSwitch { + buttonIcon: "highlight_keyboard_focus" + text: Translation.tr("Split Buttons") + checked: Config.options.cheatsheet.splitButtons + onCheckedChanged: { + Config.options.cheatsheet.splitButtons = checked; + } + StyledToolTip { + text: Translation.tr("Display modifiers and keys in multiple keycap (e.g., \"Ctrl + A\" instead of \"Ctrl A\" or \"󰘴 + A\" instead of \"󰘴 A\")") + } + + } + + ConfigSpinBox { + text: Translation.tr("Keybind font size") + value: Config.options.cheatsheet.fontSize.key + from: 8 + to: 30 + stepSize: 1 + onValueChanged: { + Config.options.cheatsheet.fontSize.key = value; + } + } + ConfigSpinBox { + text: Translation.tr("Description font size") + value: Config.options.cheatsheet.fontSize.comment + from: 8 + to: 30 + stepSize: 1 + onValueChanged: { + Config.options.cheatsheet.fontSize.comment = value; + } + } + } ContentSection { icon: "point_scan" title: Translation.tr("Crosshair overlay") @@ -1021,96 +1113,4 @@ ContentPage { } } - ContentSection { - icon: "keyboard" - title: Translation.tr("Cheatsheet") - - ContentSubsection { - title: Translation.tr("Super Key Symbol") - tooltip: Translation.tr("Choose a symbol from this list or edit config.json and add your own nerd symbol in appearance.keybinds.superKey.") - ConfigSelectionArray { - currentValue: Config.options.appearance.keybinds.superKey - onSelected: newValue => { - Config.options.appearance.keybinds.superKey = newValue; - } - // Use a nerdfont to see the icons - options: ([ - "󰖳", "", "󰨡", "", "󰌽", "󰣇", "", "", "", - "", "", "󱄛", "", "", "⌘", "󰀲", "󰟍", "" - ]).map(icon => { return { - displayName: icon, - value: icon - } - }) - } - } - - ConfigSwitch { - buttonIcon: "󰘵" - text: Translation.tr("Use macOS-like symbols for mods keys") - checked: Config.options.appearance.keybinds.useMacSymbol - onCheckedChanged: { - Config.options.appearance.keybinds.useMacSymbol = checked; - } - StyledToolTip { - text: Translation.tr("macOS-style symbols, e.g. 󰘴 for Ctrl, 󰘵 for Alt, 󰘶 for Shift, etc") - } - } - - ConfigSwitch { - buttonIcon: "󱊶" - text: Translation.tr("Use symbols for function keys") - checked: Config.options.appearance.keybinds.useFnSymbol - onCheckedChanged: { - Config.options.appearance.keybinds.useFnSymbol = checked; - } - StyledToolTip { - text: Translation.tr("Show functions keys as symbols, e.g. 󱊫 for F1, 󱊶 for F12") - } - } - ConfigSwitch { - buttonIcon: "󰍽" - text: Translation.tr("Use symbols for mouse") - checked: Config.options.appearance.keybinds.useMouseSymbol - onCheckedChanged: { - Config.options.appearance.keybinds.useMouseSymbol = checked; - } - StyledToolTip { - text: Translation.tr("Replace 󱕐 for \"Scroll ↓\", 󱕑 \"Scroll ↑\", L󰍽 \"LMB\", R󰍽 \"RMB\", 󱕒 \"Scroll ↑/↓\" and ⇞/⇟ for \"Page_↑/↓\"") - } - } - ConfigSwitch { - buttonIcon: "" - text: Translation.tr("Use macOS shortcut layout") - checked: Config.options.appearance.keybinds.useMacLikeShortcut - onCheckedChanged: { - Config.options.appearance.keybinds.useMacLikeShortcut = checked; - } - StyledToolTip { - text: Translation.tr("Display modifiers and keys in a single keycap (e.g., \"Ctrl A\" instead of \"Ctrl + A\" or \"󰘴 A\" instead of \"󰘴 + A\")") - } - - } - - ConfigSpinBox { - text: Translation.tr("Keybind font size") - value: Config.options.appearance.keybinds.fontSize.key - from: Appearance.font.pixelSize.smallest - to: Appearance.font.pixelSize.large - stepSize: 1 - onValueChanged: { - Config.options.appearance.keybinds.fontSize.key = value; - } - } - ConfigSpinBox { - text: Translation.tr("Description font size") - value: Config.options.appearance.keybinds.fontSize.comment - from: Appearance.font.pixelSize.smallest - to: Appearance.font.pixelSize.large - stepSize: 1 - onValueChanged: { - Config.options.appearance.keybinds.fontSize.comment = value; - } - } - } } From a0131e5bf83cc4533f54afcde62f81800ba2e3bf Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Thu, 6 Nov 2025 12:33:29 +0100 Subject: [PATCH 35/52] fix: use end-4 copy in InterfaceConfig --- .../quickshell/ii/modules/settings/InterfaceConfig.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml b/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml index 22a67f6fd..8e4aab5ab 100644 --- a/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml @@ -408,7 +408,7 @@ ContentPage { ContentSubsection { title: Translation.tr("Super key symbol") - tooltip: Translation.tr("Choose a symbol from this list or edit config.json and add your own nerd symbol in cheatsheet.superKey.") + tooltip: Translation.tr("You can also manually edit cheatsheet.superKey") ConfigSelectionArray { currentValue: Config.options.cheatsheet.superKey onSelected: newValue => { @@ -462,7 +462,7 @@ ContentPage { } ConfigSwitch { buttonIcon: "highlight_keyboard_focus" - text: Translation.tr("Split Buttons") + text: Translation.tr("Split buttons") checked: Config.options.cheatsheet.splitButtons onCheckedChanged: { Config.options.cheatsheet.splitButtons = checked; From 2f1c66570f5ed0135b368cba5bf9b6e81f8e70f4 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Thu, 6 Nov 2025 21:14:51 +0100 Subject: [PATCH 36/52] Change battery health icon from 'healing' to 'heart_check' --- dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml b/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml index 47345ee1f..037313e3f 100644 --- a/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml +++ b/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml @@ -90,7 +90,7 @@ StyledPopup { Layout.fillWidth: true MaterialSymbol { - text: "healing" + text: "heart_check" color: Appearance.colors.colOnSurfaceVariant iconSize: Appearance.font.pixelSize.large } From 06c51553ba5636edce9a67fe1d817763b6c3dde8 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Thu, 6 Nov 2025 21:35:31 +0100 Subject: [PATCH 37/52] refractor bar tooltips --- .../ii/modules/bar/BatteryPopup.qml | 161 +++++------------- .../quickshell/ii/modules/bar/ClockWidget.qml | 2 +- .../ii/modules/bar/ClockWidgetPopup.qml | 70 ++++++++ .../ii/modules/bar/ClockWidgetTooltip.qml | 110 ------------ .../ii/modules/bar/ResourcesPopup.qml | 73 ++------ .../ii/modules/bar/StyledPopupHeaderRow.qml | 30 ++++ .../ii/modules/bar/StyledPopupValueRow.qml | 29 ++++ .../verticalBar/VerticalClockWidget.qml | 2 +- .../ii/modules/verticalBar/VerticalMedia.qml | 25 +-- 9 files changed, 184 insertions(+), 318 deletions(-) create mode 100644 dots/.config/quickshell/ii/modules/bar/ClockWidgetPopup.qml delete mode 100644 dots/.config/quickshell/ii/modules/bar/ClockWidgetTooltip.qml create mode 100644 dots/.config/quickshell/ii/modules/bar/StyledPopupHeaderRow.qml create mode 100644 dots/.config/quickshell/ii/modules/bar/StyledPopupValueRow.qml diff --git a/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml b/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml index 037313e3f..9e3dc49bd 100644 --- a/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml +++ b/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml @@ -13,143 +13,58 @@ StyledPopup { spacing: 4 // Header - Row { - id: header - spacing: 5 - - MaterialSymbol { - anchors.verticalCenter: parent.verticalCenter - fill: 0 - font.weight: Font.Medium - text: "battery_android_full" - iconSize: Appearance.font.pixelSize.large - color: Appearance.colors.colOnSurfaceVariant - } - - StyledText { - anchors.verticalCenter: parent.verticalCenter - text: "Battery" - font { - weight: Font.Medium - pixelSize: Appearance.font.pixelSize.normal - } - color: Appearance.colors.colOnSurfaceVariant - } + StyledPopupHeaderRow { + icon: "battery_android_full" + label: Translation.tr("Battery") } - // This row is hidden when the battery is full. - RowLayout { - spacing: 5 - Layout.fillWidth: true - property bool rowVisible: { + StyledPopupValueRow { + visible: { let timeValue = Battery.isCharging ? Battery.timeToFull : Battery.timeToEmpty; let power = Battery.energyRate; return !(Battery.chargeState == 4 || timeValue <= 0 || power <= 0.01); } - visible: rowVisible - opacity: rowVisible ? 1 : 0 - Behavior on opacity { - NumberAnimation { - duration: 500 - } - } - - MaterialSymbol { - text: "schedule" - color: Appearance.colors.colOnSurfaceVariant - iconSize: Appearance.font.pixelSize.large - } - StyledText { - text: Battery.isCharging ? Translation.tr("Time to full:") : Translation.tr("Time to empty:") - color: Appearance.colors.colOnSurfaceVariant - } - StyledText { - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - color: Appearance.colors.colOnSurfaceVariant - text: { - function formatTime(seconds) { - var h = Math.floor(seconds / 3600); - var m = Math.floor((seconds % 3600) / 60); - if (h > 0) - return `${h}h, ${m}m`; - else - return `${m}m`; - } - if (Battery.isCharging) - return formatTime(Battery.timeToFull); + icon: "schedule" + label: Battery.isCharging ? Translation.tr("Time to full:") : Translation.tr("Time to empty:") + value: { + function formatTime(seconds) { + var h = Math.floor(seconds / 3600); + var m = Math.floor((seconds % 3600) / 60); + if (h > 0) + return `${h}h, ${m}m`; else - return formatTime(Battery.timeToEmpty); + return `${m}m`; } + if (Battery.isCharging) + return formatTime(Battery.timeToFull); + else + return formatTime(Battery.timeToEmpty); } } - RowLayout { - spacing: 5 - visible: Battery.health > 0 - Layout.fillWidth: true + StyledPopupValueRow { + icon: "heart_check" + label: Translation.tr("Health:") + value: `${(Battery.health).toFixed(1)}%` + } - MaterialSymbol { - text: "heart_check" - color: Appearance.colors.colOnSurfaceVariant - iconSize: Appearance.font.pixelSize.large - } - - StyledText { - text: Translation.tr("Health:") - color: Appearance.colors.colOnSurfaceVariant - } - - StyledText { - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - color: Appearance.colors.colOnSurfaceVariant - text: `${(Battery.health).toFixed(1)}%` + StyledPopupValueRow { + visible: !(Battery.chargeState != 4 && Battery.energyRate == 0) + icon: "bolt" + label: { + if (Battery.chargeState == 4) { + return Translation.tr("Fully charged"); + } else if (Battery.chargeState == 1) { + return Translation.tr("Charging:"); + } else { + return Translation.tr("Discharging:"); } } - - RowLayout { - spacing: 5 - Layout.fillWidth: true - - property bool rowVisible: !(Battery.chargeState != 4 && Battery.energyRate == 0) - visible: rowVisible - opacity: rowVisible ? 1 : 0 - Behavior on opacity { - NumberAnimation { - duration: 500 - } - } - - MaterialSymbol { - text: "bolt" - color: Appearance.colors.colOnSurfaceVariant - iconSize: Appearance.font.pixelSize.large - } - - StyledText { - text: { - if (Battery.chargeState == 4) { - return Translation.tr("Fully charged"); - } else if (Battery.chargeState == 1) { - return Translation.tr("Charging:"); - } else { - return Translation.tr("Discharging:"); - } - } - color: Appearance.colors.colOnSurfaceVariant - } - - StyledText { - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - color: Appearance.colors.colOnSurfaceVariant - text: { - if (Battery.chargeState == 4) { - return ""; - } else { - return `${Battery.energyRate.toFixed(2)}W`; - } + value: { + if (Battery.chargeState == 4) { + return ""; + } else { + return `${Battery.energyRate.toFixed(2)}W`; } } } diff --git a/dots/.config/quickshell/ii/modules/bar/ClockWidget.qml b/dots/.config/quickshell/ii/modules/bar/ClockWidget.qml index 4d6fb61f2..895ad9be0 100644 --- a/dots/.config/quickshell/ii/modules/bar/ClockWidget.qml +++ b/dots/.config/quickshell/ii/modules/bar/ClockWidget.qml @@ -43,7 +43,7 @@ Item { hoverEnabled: true acceptedButtons: Qt.NoButton - ClockWidgetTooltip { + ClockWidgetPopup { hoverTarget: mouseArea } } diff --git a/dots/.config/quickshell/ii/modules/bar/ClockWidgetPopup.qml b/dots/.config/quickshell/ii/modules/bar/ClockWidgetPopup.qml new file mode 100644 index 000000000..c23edb7b4 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/bar/ClockWidgetPopup.qml @@ -0,0 +1,70 @@ +import qs.modules.common +import qs.modules.common.widgets +import qs.services +import QtQuick +import QtQuick.Layouts + +StyledPopup { + id: root + property string formattedDate: Qt.locale().toString(DateTime.clock.date, "dddd, MMMM dd, yyyy") + property string formattedTime: DateTime.time + property string formattedUptime: DateTime.uptime + property string todosSection: getUpcomingTodos() + + function getUpcomingTodos() { + const unfinishedTodos = Todo.list.filter(function (item) { + return !item.done; + }); + if (unfinishedTodos.length === 0) { + return Translation.tr("No pending tasks"); + } + + // Limit to first 5 todos to keep popup manageable + const limitedTodos = unfinishedTodos.slice(0, 5); + let todoText = limitedTodos.map(function (item, index) { + return ` ${index + 1}. ${item.content}`; + }).join('\n'); + + if (unfinishedTodos.length > 5) { + todoText += `\n ${Translation.tr("... and %1 more").arg(unfinishedTodos.length - 5)}`; + } + + return todoText; + } + + ColumnLayout { + id: columnLayout + anchors.centerIn: parent + spacing: 4 + + StyledPopupHeaderRow { + icon: "calendar_month" + label: root.formattedDate + } + + StyledPopupValueRow { + icon: "timelapse" + label: Translation.tr("System uptime:") + value: root.formattedUptime + } + + // Tasks + Column { + spacing: 0 + Layout.fillWidth: true + + StyledPopupValueRow { + icon: "checklist" + label: Translation.tr("To Do:") + value: "" + } + + StyledText { + horizontalAlignment: Text.AlignLeft + wrapMode: Text.Wrap + color: Appearance.colors.colOnSurfaceVariant + text: root.todosSection + } + } + } +} diff --git a/dots/.config/quickshell/ii/modules/bar/ClockWidgetTooltip.qml b/dots/.config/quickshell/ii/modules/bar/ClockWidgetTooltip.qml deleted file mode 100644 index 734d89b22..000000000 --- a/dots/.config/quickshell/ii/modules/bar/ClockWidgetTooltip.qml +++ /dev/null @@ -1,110 +0,0 @@ -import qs.modules.common -import qs.modules.common.widgets -import qs.services -import QtQuick -import QtQuick.Layouts - -StyledPopup { - id: root - property string formattedDate: Qt.locale().toString(DateTime.clock.date, "dddd, MMMM dd, yyyy") - property string formattedTime: DateTime.time - property string formattedUptime: DateTime.uptime - property string todosSection: getUpcomingTodos() - - function getUpcomingTodos() { - const unfinishedTodos = Todo.list.filter(function (item) { - return !item.done; - }); - if (unfinishedTodos.length === 0) { - return Translation.tr("No pending tasks"); - } - - // Limit to first 5 todos to keep popup manageable - const limitedTodos = unfinishedTodos.slice(0, 5); - let todoText = limitedTodos.map(function (item, index) { - return `${index + 1}. ${item.content}`; - }).join('\n'); - - if (unfinishedTodos.length > 5) { - todoText += `\n${Translation.tr("... and %1 more").arg(unfinishedTodos.length - 5)}`; - } - - return todoText; - } - - ColumnLayout { - id: columnLayout - anchors.centerIn: parent - spacing: 4 - - // Date + Time row - Row { - spacing: 5 - - MaterialSymbol { - anchors.verticalCenter: parent.verticalCenter - fill: 0 - font.weight: Font.Medium - text: "calendar_month" - iconSize: Appearance.font.pixelSize.large - color: Appearance.colors.colOnSurfaceVariant - } - StyledText { - anchors.verticalCenter: parent.verticalCenter - horizontalAlignment: Text.AlignLeft - color: Appearance.colors.colOnSurfaceVariant - text: `${root.formattedDate}` - font.weight: Font.Medium - } - } - - // Uptime row - RowLayout { - spacing: 5 - Layout.fillWidth: true - MaterialSymbol { - text: "timelapse" - color: Appearance.colors.colOnSurfaceVariant - font.pixelSize: Appearance.font.pixelSize.large - } - StyledText { - text: Translation.tr("System uptime:") - color: Appearance.colors.colOnSurfaceVariant - } - StyledText { - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - color: Appearance.colors.colOnSurfaceVariant - text: root.formattedUptime - } - } - - // Tasks - Column { - spacing: 0 - Layout.fillWidth: true - - Row { - spacing: 4 - MaterialSymbol { - anchors.verticalCenter: parent.verticalCenter - text: "checklist" - color: Appearance.colors.colOnSurfaceVariant - font.pixelSize: Appearance.font.pixelSize.large - } - StyledText { - anchors.verticalCenter: parent.verticalCenter - text: Translation.tr("To Do:") - color: Appearance.colors.colOnSurfaceVariant - } - } - - StyledText { - horizontalAlignment: Text.AlignLeft - wrapMode: Text.Wrap - color: Appearance.colors.colOnSurfaceVariant - text: root.todosSection - } - } - } -} diff --git a/dots/.config/quickshell/ii/modules/bar/ResourcesPopup.qml b/dots/.config/quickshell/ii/modules/bar/ResourcesPopup.qml index 1cac240d8..40ed72756 100644 --- a/dots/.config/quickshell/ii/modules/bar/ResourcesPopup.qml +++ b/dots/.config/quickshell/ii/modules/bar/ResourcesPopup.qml @@ -12,57 +12,6 @@ StyledPopup { return (kb / (1024 * 1024)).toFixed(1) + " GB"; } - component ResourceItem: RowLayout { - id: resourceItem - required property string icon - required property string label - required property string value - spacing: 4 - - MaterialSymbol { - text: resourceItem.icon - color: Appearance.colors.colOnSurfaceVariant - iconSize: Appearance.font.pixelSize.large - } - StyledText { - text: resourceItem.label - color: Appearance.colors.colOnSurfaceVariant - } - StyledText { - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - visible: resourceItem.value !== "" - color: Appearance.colors.colOnSurfaceVariant - text: resourceItem.value - } - } - - component ResourceHeaderItem: Row { - id: headerItem - required property var icon - required property var label - spacing: 5 - - MaterialSymbol { - anchors.verticalCenter: parent.verticalCenter - fill: 0 - font.weight: Font.Medium - text: headerItem.icon - iconSize: Appearance.font.pixelSize.large - color: Appearance.colors.colOnSurfaceVariant - } - - StyledText { - anchors.verticalCenter: parent.verticalCenter - text: headerItem.label - font { - weight: Font.Medium - pixelSize: Appearance.font.pixelSize.normal - } - color: Appearance.colors.colOnSurfaceVariant - } - } - Row { anchors.centerIn: parent spacing: 12 @@ -71,23 +20,23 @@ StyledPopup { anchors.top: parent.top spacing: 8 - ResourceHeaderItem { + StyledPopupHeaderRow { icon: "memory" label: "RAM" } Column { spacing: 4 - ResourceItem { + StyledPopupValueRow { icon: "clock_loader_60" label: Translation.tr("Used:") value: root.formatKB(ResourceUsage.memoryUsed) } - ResourceItem { + StyledPopupValueRow { icon: "check_circle" label: Translation.tr("Free:") value: root.formatKB(ResourceUsage.memoryFree) } - ResourceItem { + StyledPopupValueRow { icon: "empty_dashboard" label: Translation.tr("Total:") value: root.formatKB(ResourceUsage.memoryTotal) @@ -100,23 +49,23 @@ StyledPopup { anchors.top: parent.top spacing: 8 - ResourceHeaderItem { + StyledPopupHeaderRow { icon: "swap_horiz" label: "Swap" } Column { spacing: 4 - ResourceItem { + StyledPopupValueRow { icon: "clock_loader_60" label: Translation.tr("Used:") value: root.formatKB(ResourceUsage.swapUsed) } - ResourceItem { + StyledPopupValueRow { icon: "check_circle" label: Translation.tr("Free:") value: root.formatKB(ResourceUsage.swapFree) } - ResourceItem { + StyledPopupValueRow { icon: "empty_dashboard" label: Translation.tr("Total:") value: root.formatKB(ResourceUsage.swapTotal) @@ -128,16 +77,16 @@ StyledPopup { anchors.top: parent.top spacing: 8 - ResourceHeaderItem { + StyledPopupHeaderRow { icon: "planner_review" label: "CPU" } Column { spacing: 4 - ResourceItem { + StyledPopupValueRow { icon: "bolt" label: Translation.tr("Load:") - value: (ResourceUsage.cpuUsage > 0.8 ? Translation.tr("High") : ResourceUsage.cpuUsage > 0.4 ? Translation.tr("Medium") : Translation.tr("Low")) + ` (${Math.round(ResourceUsage.cpuUsage * 100)}%)` + value: `${Math.round(ResourceUsage.cpuUsage * 100)}%` } } } diff --git a/dots/.config/quickshell/ii/modules/bar/StyledPopupHeaderRow.qml b/dots/.config/quickshell/ii/modules/bar/StyledPopupHeaderRow.qml new file mode 100644 index 000000000..f5c7ba445 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/bar/StyledPopupHeaderRow.qml @@ -0,0 +1,30 @@ +import QtQuick +import QtQuick.Layouts +import qs.modules.common +import qs.modules.common.widgets + +Row { + id: root + required property var icon + required property var label + spacing: 5 + + MaterialSymbol { + anchors.verticalCenter: parent.verticalCenter + fill: 0 + font.weight: Font.DemiBold + text: root.icon + iconSize: Appearance.font.pixelSize.large + color: Appearance.colors.colOnSurfaceVariant + } + + StyledText { + anchors.verticalCenter: parent.verticalCenter + text: root.label + font { + weight: Font.DemiBold + pixelSize: Appearance.font.pixelSize.normal + } + color: Appearance.colors.colOnSurfaceVariant + } +} \ No newline at end of file diff --git a/dots/.config/quickshell/ii/modules/bar/StyledPopupValueRow.qml b/dots/.config/quickshell/ii/modules/bar/StyledPopupValueRow.qml new file mode 100644 index 000000000..de8ac579e --- /dev/null +++ b/dots/.config/quickshell/ii/modules/bar/StyledPopupValueRow.qml @@ -0,0 +1,29 @@ +import QtQuick +import QtQuick.Layouts +import qs.modules.common +import qs.modules.common.widgets + +RowLayout { + id: root + required property string icon + required property string label + required property string value + spacing: 4 + + MaterialSymbol { + text: root.icon + color: Appearance.colors.colOnSurfaceVariant + iconSize: Appearance.font.pixelSize.large + } + StyledText { + text: root.label + color: Appearance.colors.colOnSurfaceVariant + } + StyledText { + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + visible: root.value !== "" + color: Appearance.colors.colOnSurfaceVariant + text: root.value + } +} diff --git a/dots/.config/quickshell/ii/modules/verticalBar/VerticalClockWidget.qml b/dots/.config/quickshell/ii/modules/verticalBar/VerticalClockWidget.qml index 391d2e78c..921f63603 100644 --- a/dots/.config/quickshell/ii/modules/verticalBar/VerticalClockWidget.qml +++ b/dots/.config/quickshell/ii/modules/verticalBar/VerticalClockWidget.qml @@ -36,7 +36,7 @@ Item { hoverEnabled: true acceptedButtons: Qt.NoButton - Bar.ClockWidgetTooltip { + Bar.ClockWidgetPopup { hoverTarget: mouseArea } } diff --git a/dots/.config/quickshell/ii/modules/verticalBar/VerticalMedia.qml b/dots/.config/quickshell/ii/modules/verticalBar/VerticalMedia.qml index 7a512564a..677941d64 100644 --- a/dots/.config/quickshell/ii/modules/verticalBar/VerticalMedia.qml +++ b/dots/.config/quickshell/ii/modules/verticalBar/VerticalMedia.qml @@ -74,30 +74,13 @@ MouseArea { anchors.centerIn: parent spacing: 4 - Row { - spacing: 4 - - MaterialSymbol { - anchors.verticalCenter: parent.verticalCenter - fill: 0 - font.weight: Font.Medium - text: "music_note" - iconSize: Appearance.font.pixelSize.large - color: Appearance.colors.colOnSurfaceVariant - } - - StyledText { - anchors.verticalCenter: parent.verticalCenter - text: "Media" - font { - weight: Font.Medium - pixelSize: Appearance.font.pixelSize.normal - } - color: Appearance.colors.colOnSurfaceVariant - } + Bar.StyledPopupHeaderRow { + icon: "music_note" + label: Translation.tr("Media") } StyledText { + color: Appearance.colors.colOnSurfaceVariant text: `${cleanedTitle}${activePlayer?.trackArtist ? '\n' + activePlayer.trackArtist : ''}` } } From 47aa8232f7e583b0b9e9ac5a8462be8dafb97b81 Mon Sep 17 00:00:00 2001 From: vaguesyntax Date: Thu, 6 Nov 2025 23:39:32 +0300 Subject: [PATCH 38/52] fixes --- .../regionSelector/RegionSelection.qml | 25 +++++++++++-------- .../quickshell/ii/services/DateTime.qml | 1 - 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/regionSelector/RegionSelection.qml b/dots/.config/quickshell/ii/modules/regionSelector/RegionSelection.qml index 9d984d5ec..2af55f014 100644 --- a/dots/.config/quickshell/ii/modules/regionSelector/RegionSelection.qml +++ b/dots/.config/quickshell/ii/modules/regionSelector/RegionSelection.qml @@ -33,9 +33,9 @@ PanelWindow { property var selectionMode: RegionSelection.SelectionMode.RectCorners signal dismiss() - property string permanentScreenshotDir: Config.options.screenSnip.savePath && Config.options.screenSnip.savePath !== "" - ? Config.options.screenSnip.savePath - : "" + property string saveScreenshotDir: Config.options.screenSnip.savePath !== "" + ? Config.options.screenSnip.savePath + : "" property string screenshotDir: Directories.screenshotTemp property string imageSearchEngineBaseUrl: Config.options.search.imageSearch.imageSearchEngineBaseUrl @@ -262,20 +262,23 @@ PanelWindow { } switch (root.action) { case RegionSelection.SnipAction.Copy: - if (permanentScreenshotDir === "") { - // no permanent dir, just copy to clipboard + if (saveScreenshotDir === "") { + // not saving the screenshot, just copy to clipboard snipProc.command = ["bash", "-c", `${cropToStdout} | wl-copy && ${cleanup}`] break; } - const saveFileName = 'screenshot-' + DateTime.fileDateTime + '.png' - const savePath = `${root.permanentScreenshotDir}/${saveFileName}` + + const savePathBase = root.saveScreenshotDir snipProc.command = [ - "bash", "-c", - `mkdir -p '${StringUtils.shellSingleQuoteEscape(root.permanentScreenshotDir)}' ` + - `&& ${cropToStdout} | tee >(wl-copy) > '${StringUtils.shellSingleQuoteEscape(savePath)}' ` + - `&& ${cleanup}` + "bash", "-c", + `mkdir -p '${StringUtils.shellSingleQuoteEscape(savePathBase)}' && \ + saveFileName="screenshot-$(date '+%Y-%m-%d_%H.%M.%S').png" && \ + savePath="${savePathBase}/$saveFileName" && \ + ${cropToStdout} | tee >(wl-copy) > "$savePath" && \ + ${cleanup}` ] + break; case RegionSelection.SnipAction.Edit: snipProc.command = ["bash", "-c", `${cropToStdout} | swappy -f - && ${cleanup}`] diff --git a/dots/.config/quickshell/ii/services/DateTime.qml b/dots/.config/quickshell/ii/services/DateTime.qml index c6998f056..62d296dbc 100644 --- a/dots/.config/quickshell/ii/services/DateTime.qml +++ b/dots/.config/quickshell/ii/services/DateTime.qml @@ -22,7 +22,6 @@ Singleton { property string shortDate: Qt.locale().toString(clock.date, Config.options?.time.shortDateFormat ?? "dd/MM") property string date: Qt.locale().toString(clock.date, Config.options?.time.dateFormat ?? "dddd, dd/MM") property string collapsedCalendarFormat: Qt.locale().toString(clock.date, "dd MMMM yyyy") - property string fileDateTime: Qt.locale().toString(clock.date, "dd-MM-yyyy_HH.mm") property string uptime: "0h, 0m" Timer { From e5e598853fb387f86b26ef7cde2eee07ded088d3 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Thu, 6 Nov 2025 21:49:03 +0100 Subject: [PATCH 39/52] japanese borrows chinese chars... --- dots/.config/quickshell/ii/modules/settings/BarConfig.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dots/.config/quickshell/ii/modules/settings/BarConfig.qml b/dots/.config/quickshell/ii/modules/settings/BarConfig.qml index 9738bf49c..c00ef30cd 100644 --- a/dots/.config/quickshell/ii/modules/settings/BarConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/BarConfig.qml @@ -321,7 +321,7 @@ ContentPage { value: '[]' }, { - displayName: Translation.tr("Japanese"), + displayName: Translation.tr("Chenis/Japenis"), icon: "square_dot", value: '["一","二","三","四","五","六","七","八","九","十","十一","十二","十三","十四","十五","十六","十七","十八","十九","二十"]' }, From 1a4b4b8befd43b78a11f8f11a46e18bc4aca3dfc Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Thu, 6 Nov 2025 22:59:09 +0100 Subject: [PATCH 40/52] use ipc calls more for compatibility --- .../quickshell/ii/modules/bar/UtilButtons.qml | 2 +- .../quickshell/ii/modules/lock/Lock.qml | 18 +++++++++++------- .../ii/modules/overview/SearchBar.qml | 2 +- .../androidStyle/AndroidScreenSnipToggle.qml | 2 +- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/bar/UtilButtons.qml b/dots/.config/quickshell/ii/modules/bar/UtilButtons.qml index cc3eb64a2..2f7197b58 100644 --- a/dots/.config/quickshell/ii/modules/bar/UtilButtons.qml +++ b/dots/.config/quickshell/ii/modules/bar/UtilButtons.qml @@ -25,7 +25,7 @@ Item { visible: Config.options.bar.utilButtons.showScreenSnip sourceComponent: CircleUtilButton { Layout.alignment: Qt.AlignVCenter - onClicked: Hyprland.dispatch("global quickshell:regionScreenshot") + onClicked: Quickshell.execDetached(["qs", "-p", Quickshell.shellPath(""), "ipc", "call", "region", "screenshot"]); MaterialSymbol { horizontalAlignment: Qt.AlignHCenter fill: 1 diff --git a/dots/.config/quickshell/ii/modules/lock/Lock.qml b/dots/.config/quickshell/ii/modules/lock/Lock.qml index e5557425b..4266d03f7 100644 --- a/dots/.config/quickshell/ii/modules/lock/Lock.qml +++ b/dots/.config/quickshell/ii/modules/lock/Lock.qml @@ -128,11 +128,19 @@ Scope { } } + function lock() { + if (Config.options.lock.useHyprlock) { + Quickshell.execDetached(["bash", "-c", "pidof hyprlock || hyprlock"]); + return; + } + GlobalStates.screenLocked = true; + } + IpcHandler { target: "lock" function activate(): void { - GlobalStates.screenLocked = true; + root.lock(); } function focus(): void { lockContext.shouldReFocus(); @@ -144,11 +152,7 @@ Scope { description: "Locks the screen" onPressed: { - if (Config.options.lock.useHyprlock) { - Quickshell.execDetached(["bash", "-c", "pidof hyprlock || hyprlock"]); - return; - } - GlobalStates.screenLocked = true; + root.lock() } } @@ -165,7 +169,7 @@ Scope { function initIfReady() { if (!Config.ready || !Persistent.ready) return; if (Config.options.lock.launchOnStartup && Persistent.isNewHyprlandInstance) { - Hyprland.dispatch("global quickshell:lock") + root.lock(); } else { KeyringStorage.fetchKeyringData(); } diff --git a/dots/.config/quickshell/ii/modules/overview/SearchBar.qml b/dots/.config/quickshell/ii/modules/overview/SearchBar.qml index a0abd54c8..5cd7b9ac5 100644 --- a/dots/.config/quickshell/ii/modules/overview/SearchBar.qml +++ b/dots/.config/quickshell/ii/modules/overview/SearchBar.qml @@ -99,7 +99,7 @@ RowLayout { Layout.bottomMargin: 4 onClicked: { GlobalStates.overviewOpen = false; - Hyprland.dispatch("global quickshell:regionSearch") + Quickshell.execDetached(["qs", "-p", Quickshell.shellPath(""), "ipc", "call", "region", "search"]); } text: "image_search" StyledToolTip { diff --git a/dots/.config/quickshell/ii/modules/sidebarRight/quickToggles/androidStyle/AndroidScreenSnipToggle.qml b/dots/.config/quickshell/ii/modules/sidebarRight/quickToggles/androidStyle/AndroidScreenSnipToggle.qml index c4b4a5479..875022249 100644 --- a/dots/.config/quickshell/ii/modules/sidebarRight/quickToggles/androidStyle/AndroidScreenSnipToggle.qml +++ b/dots/.config/quickshell/ii/modules/sidebarRight/quickToggles/androidStyle/AndroidScreenSnipToggle.qml @@ -23,7 +23,7 @@ AndroidQuickToggleButton { interval: 300 repeat: false onTriggered: { - Hyprland.dispatch("global quickshell:regionScreenshot") + Quickshell.execDetached(["qs", "-p", Quickshell.shellPath(""), "ipc", "call", "region", "screenshot"]); } } From bf70be7f4a20efad2b4895dbb4bcae062dd04ec5 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Thu, 6 Nov 2025 23:02:21 +0100 Subject: [PATCH 41/52] overlay: add recorder widget --- .../ii/modules/common/Persistent.qml | 12 +- .../ii/modules/overlay/OverlayContext.qml | 3 +- .../overlay/OverlayWidgetDelegateChooser.qml | 2 + .../ii/modules/overlay/recorder/Recorder.qml | 122 ++++++++++++++++++ .../overlay/volumeMixer/VolumeMixer.qml | 4 +- 5 files changed, 137 insertions(+), 6 deletions(-) create mode 100644 dots/.config/quickshell/ii/modules/overlay/recorder/Recorder.qml diff --git a/dots/.config/quickshell/ii/modules/common/Persistent.qml b/dots/.config/quickshell/ii/modules/common/Persistent.qml index 814938452..5335deb9d 100644 --- a/dots/.config/quickshell/ii/modules/common/Persistent.qml +++ b/dots/.config/quickshell/ii/modules/common/Persistent.qml @@ -84,14 +84,20 @@ Singleton { property JsonObject crosshair: JsonObject { property bool pinned: false property bool clickthrough: true + property real x: 835 + property real y: 490 + } + property JsonObject recorder: JsonObject { + property bool pinned: false + property bool clickthrough: false property real x: 100 - property real y: 100 + property real y: 130 } property JsonObject volumeMixer: JsonObject { property bool pinned: false property bool clickthrough: false - property real x: 55 - property real y: 188 + property real x: 100 + property real y: 320 } } diff --git a/dots/.config/quickshell/ii/modules/overlay/OverlayContext.qml b/dots/.config/quickshell/ii/modules/overlay/OverlayContext.qml index 1417c8467..22746c4de 100644 --- a/dots/.config/quickshell/ii/modules/overlay/OverlayContext.qml +++ b/dots/.config/quickshell/ii/modules/overlay/OverlayContext.qml @@ -7,7 +7,8 @@ Singleton { readonly property list availableWidgets: [ { identifier: "crosshair", materialSymbol: "point_scan" }, - { identifier: "volumeMixer", materialSymbol: "volume_up" } + { identifier: "volumeMixer", materialSymbol: "volume_up" }, + { identifier: "recorder", materialSymbol: "screen_record" }, ] readonly property bool hasPinnedWidgets: root.pinnedWidgetIdentifiers.length > 0 diff --git a/dots/.config/quickshell/ii/modules/overlay/OverlayWidgetDelegateChooser.qml b/dots/.config/quickshell/ii/modules/overlay/OverlayWidgetDelegateChooser.qml index e7420f625..39df62ac3 100644 --- a/dots/.config/quickshell/ii/modules/overlay/OverlayWidgetDelegateChooser.qml +++ b/dots/.config/quickshell/ii/modules/overlay/OverlayWidgetDelegateChooser.qml @@ -8,6 +8,7 @@ import Quickshell import Quickshell.Bluetooth import qs.modules.overlay.crosshair import qs.modules.overlay.volumeMixer +import qs.modules.overlay.recorder DelegateChooser { id: root @@ -15,4 +16,5 @@ DelegateChooser { DelegateChoice { roleValue: "crosshair"; Crosshair {} } DelegateChoice { roleValue: "volumeMixer"; VolumeMixer {} } + DelegateChoice { roleValue: "recorder"; Recorder {} } } diff --git a/dots/.config/quickshell/ii/modules/overlay/recorder/Recorder.qml b/dots/.config/quickshell/ii/modules/overlay/recorder/Recorder.qml new file mode 100644 index 000000000..d32adedea --- /dev/null +++ b/dots/.config/quickshell/ii/modules/overlay/recorder/Recorder.qml @@ -0,0 +1,122 @@ +pragma ComponentBehavior: Bound +import QtQuick +import QtQuick.Layouts +import Quickshell +import Quickshell.Hyprland +import qs +import qs.modules.common +import qs.modules.common.widgets +import qs.modules.overlay + +StyledOverlayWidget { + id: root + + contentItem: Rectangle { + id: contentItem + anchors.centerIn: parent + color: Appearance.m3colors.m3surfaceContainer + property real padding: 8 + implicitHeight: contentColumn.implicitHeight + padding * 2 + implicitWidth: 350 + ColumnLayout { + id: contentColumn + anchors { + fill: parent + margins: parent.padding + } + spacing: 10 + + Row { + Layout.alignment: Qt.AlignHCenter + spacing: 10 + + BigRecorderButton { + materialSymbol: "screenshot_region" + name: "Screenshot region" + onClicked: { + GlobalStates.overlayOpen = false; + Quickshell.execDetached(["qs", "-p", Quickshell.shellPath(""), "ipc", "call", "region", "screenshot"]); + } + } + + BigRecorderButton { + materialSymbol: "photo_camera" + name: "Screenshot" + onClicked: { + GlobalStates.overlayOpen = false; + Quickshell.execDetached(["bash", "-c", "grim - | wl-copy"]); + } + } + + BigRecorderButton { + materialSymbol: "screen_record" + name: "Record region" + onClicked: { + GlobalStates.overlayOpen = false; + Quickshell.execDetached(["qs", "-p", Quickshell.shellPath(""), "ipc", "call", "region", "recordWithSound"]); + } + } + + BigRecorderButton { + materialSymbol: "capture" + name: "Record screen" + onClicked: { + GlobalStates.overlayOpen = false; + Quickshell.execDetached([Directories.recordScriptPath, "--fullscreen", "--sound"]); + } + } + } + + RippleButton { + Layout.alignment: Qt.AlignHCenter + Layout.fillWidth: false + buttonRadius: height / 2 + colBackground: Appearance.colors.colLayer3 + colBackgroundHover: Appearance.colors.colLayer3Hover + colRipple: Appearance.colors.colLayer3Active + onClicked: { + GlobalStates.overlayOpen = false; + Qt.openUrlExternally(Directories.videos); + } + contentItem: Row { + anchors.centerIn: parent + spacing: 6 + MaterialSymbol { + anchors.verticalCenter: parent.verticalCenter + text: "animated_images" + iconSize: 20 + } + StyledText { + anchors.verticalCenter: parent.verticalCenter + text: qsTr("Open recordings folder") + } + } + } + } + } + + component BigRecorderButton: RippleButton { + id: bigButton + required property string materialSymbol + required property string name + implicitHeight: 66 + implicitWidth: 66 + buttonRadius: height / 2 + + colBackground: Appearance.colors.colLayer3 + colBackgroundHover: Appearance.colors.colLayer3Hover + colRipple: Appearance.colors.colLayer3Active + + contentItem: MaterialSymbol { + anchors.centerIn: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + text: bigButton.materialSymbol + iconSize: 28 + } + + StyledToolTip { + text: bigButton.name + } + } +} diff --git a/dots/.config/quickshell/ii/modules/overlay/volumeMixer/VolumeMixer.qml b/dots/.config/quickshell/ii/modules/overlay/volumeMixer/VolumeMixer.qml index 433a2e11f..14aa53006 100644 --- a/dots/.config/quickshell/ii/modules/overlay/volumeMixer/VolumeMixer.qml +++ b/dots/.config/quickshell/ii/modules/overlay/volumeMixer/VolumeMixer.qml @@ -11,8 +11,8 @@ StyledOverlayWidget { anchors.centerIn: parent color: Appearance.m3colors.m3surfaceContainer property real padding: 16 - implicitHeight: 700 - implicitWidth: 400 + implicitHeight: 600 + implicitWidth: 350 VolumeDialogContent { anchors.fill: parent From 6afe810d69ab63264169bf315ddf0fdb28ce7c6f Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Thu, 6 Nov 2025 23:04:42 +0100 Subject: [PATCH 42/52] batterypopup: move health to below energy rate --- .../quickshell/ii/modules/bar/BatteryPopup.qml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml b/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml index 9e3dc49bd..26eda569e 100644 --- a/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml +++ b/dots/.config/quickshell/ii/modules/bar/BatteryPopup.qml @@ -42,12 +42,6 @@ StyledPopup { } } - StyledPopupValueRow { - icon: "heart_check" - label: Translation.tr("Health:") - value: `${(Battery.health).toFixed(1)}%` - } - StyledPopupValueRow { visible: !(Battery.chargeState != 4 && Battery.energyRate == 0) icon: "bolt" @@ -68,5 +62,11 @@ StyledPopup { } } } + + StyledPopupValueRow { + icon: "heart_check" + label: Translation.tr("Health:") + value: `${(Battery.health).toFixed(1)}%` + } } } From 3365719a4953ed9e9d49ef756ae43f5f2516b0df Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Thu, 6 Nov 2025 23:07:50 +0100 Subject: [PATCH 43/52] tray menu: fix weird popin anim origin point --- dots/.config/quickshell/ii/modules/bar/SysTray.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/dots/.config/quickshell/ii/modules/bar/SysTray.qml b/dots/.config/quickshell/ii/modules/bar/SysTray.qml index 5489eb2f3..0233b2405 100644 --- a/dots/.config/quickshell/ii/modules/bar/SysTray.qml +++ b/dots/.config/quickshell/ii/modules/bar/SysTray.qml @@ -104,7 +104,6 @@ Item { id: overflowPopup hoverTarget: trayOverflowButton active: root.trayOverflowOpen && root.unpinnedItems.length > 0 - popupBackgroundMargin: 300 // This should be plenty... makes sure tooltips don't get cutoff (easily) GridLayout { id: trayOverflowLayout From a0c5940a94c06314da5c07c54f928382caebe6c3 Mon Sep 17 00:00:00 2001 From: clsty Date: Fri, 7 Nov 2025 06:08:46 +0800 Subject: [PATCH 44/52] Use "Han chars" --- dots/.config/quickshell/ii/modules/settings/BarConfig.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dots/.config/quickshell/ii/modules/settings/BarConfig.qml b/dots/.config/quickshell/ii/modules/settings/BarConfig.qml index c00ef30cd..a53d30644 100644 --- a/dots/.config/quickshell/ii/modules/settings/BarConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/BarConfig.qml @@ -321,7 +321,7 @@ ContentPage { value: '[]' }, { - displayName: Translation.tr("Chenis/Japenis"), + displayName: Translation.tr("Han chars"), icon: "square_dot", value: '["一","二","三","四","五","六","七","八","九","十","十一","十二","十三","十四","十五","十六","十七","十八","十九","二十"]' }, From b06a7ce58e44228e1178f0bf28ff35a478aa587a Mon Sep 17 00:00:00 2001 From: Madjid Taha Date: Fri, 7 Nov 2025 02:42:51 +0100 Subject: [PATCH 45/52] fix merge --- .../ii/modules/settings/InterfaceConfig.qml | 434 ------------------ 1 file changed, 434 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml b/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml index 8e4aab5ab..c57406a7f 100644 --- a/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/InterfaceConfig.qml @@ -7,401 +7,6 @@ import qs.modules.common.widgets ContentPage { forceWidth: true - ContentSection { - icon: "wallpaper" - title: Translation.tr("Background") - - ConfigSwitch { - buttonIcon: "nest_clock_farsight_analog" - text: Translation.tr("Show clock") - checked: Config.options.background.clock.show - onCheckedChanged: { - Config.options.background.clock.show = checked; - } - } - - - ConfigSpinBox { - icon: "loupe" - text: Translation.tr("Scale (%)") - value: Config.options.background.clock.scale * 100 - from: 1 - to: 200 - stepSize: 2 - onValueChanged: { - Config.options.background.clock.scale = value / 100; - } - } - - ContentSubsection { - title: Translation.tr("Clock style") - ConfigSelectionArray { - currentValue: Config.options.background.clock.style - onSelected: newValue => { - Config.options.background.clock.style = newValue; - } - options: [ - { - displayName: Translation.tr("Simple digital"), - icon: "timer_10", - value: "digital" - }, - { - displayName: Translation.tr("Material cookie"), - icon: "cookie", - value: "cookie" - } - ] - } - } - - ContentSubsection { - visible: Config.options.background.clock.style === "digital" - title: Translation.tr("Digital clock settings") - - ConfigSwitch { - buttonIcon: "animation" - text: Translation.tr("Animate time change") - checked: Config.options.background.clock.digital.animateChange - onCheckedChanged: { - Config.options.background.clock.digital.animateChange = checked; - } - } - } - - ContentSubsection { - visible: Config.options.background.clock.style === "cookie" - title: Translation.tr("Cookie clock settings") - - ConfigSwitch { - buttonIcon: "wand_stars" - text: Translation.tr("Auto styling with Gemini") - checked: Config.options.background.clock.cookie.aiStyling - onCheckedChanged: { - Config.options.background.clock.cookie.aiStyling = checked; - } - StyledToolTip { - text: Translation.tr("Uses Gemini to categorize the wallpaper then picks a preset based on it.\nYou'll need to set Gemini API key on the left sidebar first.\nImages are downscaled for performance, but just to be safe,\ndo not select wallpapers with sensitive information.") - } - } - - ConfigSwitch { - buttonIcon: "airwave" - text: Translation.tr("Use old sine wave cookie implementation") - checked: Config.options.background.clock.cookie.useSineCookie - onCheckedChanged: { - Config.options.background.clock.cookie.useSineCookie = checked; - } - StyledToolTip { - text: "Looks a bit softer and more consistent with different number of sides,\nbut has less impressive morphing" - } - } - - ConfigSpinBox { - icon: "add_triangle" - text: Translation.tr("Sides") - value: Config.options.background.clock.cookie.sides - from: 0 - to: 40 - stepSize: 1 - onValueChanged: { - Config.options.background.clock.cookie.sides = value; - } - } - - ConfigSwitch { - buttonIcon: "autoplay" - text: Translation.tr("Constantly rotate") - checked: Config.options.background.clock.cookie.constantlyRotate - onCheckedChanged: { - Config.options.background.clock.cookie.constantlyRotate = checked; - } - StyledToolTip { - text: "Makes the clock always rotate. This is extremely expensive\n(expect 50% usage on Intel UHD Graphics) and thus impractical." - } - } - - ConfigRow { - - ConfigSwitch { - enabled: Config.options.background.clock.style === "cookie" && Config.options.background.clock.cookie.dialNumberStyle === "dots" || Config.options.background.clock.cookie.dialNumberStyle === "full" - buttonIcon: "brightness_7" - text: Translation.tr("Hour marks") - checked: Config.options.background.clock.cookie.hourMarks - onEnabledChanged: { - checked = Config.options.background.clock.cookie.hourMarks; - } - onCheckedChanged: { - Config.options.background.clock.cookie.hourMarks = checked; - } - StyledToolTip { - text: "Can only be turned on using the 'Dots' or 'Full' dial style for aesthetic reasons" - } - } - - ConfigSwitch { - enabled: Config.options.background.clock.style === "cookie" && Config.options.background.clock.cookie.dialNumberStyle !== "numbers" - buttonIcon: "timer_10" - text: Translation.tr("Digits in the middle") - checked: Config.options.background.clock.cookie.timeIndicators - onEnabledChanged: { - checked = Config.options.background.clock.cookie.timeIndicators; - } - onCheckedChanged: { - Config.options.background.clock.cookie.timeIndicators = checked; - } - StyledToolTip { - text: "Can't be turned on when using 'Numbers' dial style for aesthetic reasons" - } - } - } - } - - ContentSubsection { - visible: Config.options.background.clock.style === "cookie" - title: Translation.tr("Dial style") - ConfigSelectionArray { - currentValue: Config.options.background.clock.cookie.dialNumberStyle - onSelected: newValue => { - Config.options.background.clock.cookie.dialNumberStyle = newValue; - if (newValue !== "dots" && newValue !== "full") { - Config.options.background.clock.cookie.hourMarks = false; - } - if (newValue === "numbers") { - Config.options.background.clock.cookie.timeIndicators = false; - } - } - options: [ - { - displayName: "", - icon: "block", - value: "none" - }, - { - displayName: Translation.tr("Dots"), - icon: "graph_6", - value: "dots" - }, - { - displayName: Translation.tr("Full"), - icon: "history_toggle_off", - value: "full" - }, - { - displayName: Translation.tr("Numbers"), - icon: "counter_1", - value: "numbers" - } - ] - } - } - - ContentSubsection { - visible: Config.options.background.clock.style === "cookie" - title: Translation.tr("Hour hand") - ConfigSelectionArray { - currentValue: Config.options.background.clock.cookie.hourHandStyle - onSelected: newValue => { - Config.options.background.clock.cookie.hourHandStyle = newValue; - } - options: [ - { - displayName: "", - icon: "block", - value: "hide" - }, - { - displayName: Translation.tr("Classic"), - icon: "radio", - value: "classic" - }, - { - displayName: Translation.tr("Hollow"), - icon: "circle", - value: "hollow" - }, - { - displayName: Translation.tr("Fill"), - icon: "eraser_size_5", - value: "fill" - }, - ] - } - } - - ContentSubsection { - visible: Config.options.background.clock.style === "cookie" - title: Translation.tr("Minute hand") - - ConfigSelectionArray { - currentValue: Config.options.background.clock.cookie.minuteHandStyle - onSelected: newValue => { - Config.options.background.clock.cookie.minuteHandStyle = newValue; - } - options: [ - { - displayName: "", - icon: "block", - value: "hide" - }, - { - displayName: Translation.tr("Classic"), - icon: "radio", - value: "classic" - }, - { - displayName: Translation.tr("Thin"), - icon: "line_end", - value: "thin" - }, - { - displayName: Translation.tr("Medium"), - icon: "eraser_size_2", - value: "medium" - }, - { - displayName: Translation.tr("Bold"), - icon: "eraser_size_4", - value: "bold" - }, - ] - } - } - - ContentSubsection { - visible: Config.options.background.clock.style === "cookie" - title: Translation.tr("Second hand") - - ConfigSelectionArray { - currentValue: Config.options.background.clock.cookie.secondHandStyle - onSelected: newValue => { - Config.options.background.clock.cookie.secondHandStyle = newValue; - } - options: [ - { - displayName: "", - icon: "block", - value: "hide" - }, - { - displayName: Translation.tr("Classic"), - icon: "radio", - value: "classic" - }, - { - displayName: Translation.tr("Line"), - icon: "line_end", - value: "line" - }, - { - displayName: Translation.tr("Dot"), - icon: "adjust", - value: "dot" - }, - ] - } - } - - ContentSubsection { - visible: Config.options.background.clock.style === "cookie" - title: Translation.tr("Date style") - - ConfigSelectionArray { - currentValue: Config.options.background.clock.cookie.dateStyle - onSelected: newValue => { - Config.options.background.clock.cookie.dateStyle = newValue; - } - options: [ - { - displayName: "", - icon: "block", - value: "hide" - }, - { - displayName: Translation.tr("Bubble"), - icon: "bubble_chart", - value: "bubble" - }, - { - displayName: Translation.tr("Border"), - icon: "rotate_right", - value: "border" - }, - { - displayName: Translation.tr("Rect"), - icon: "rectangle", - value: "rect" - } - ] - } - } - - ContentSubsection { - title: Translation.tr("Quote settings") - ConfigSwitch { - buttonIcon: "format_quote" - text: Translation.tr("Show quote") - checked: Config.options.background.showQuote - onCheckedChanged: { - Config.options.background.showQuote = checked; - } - } - MaterialTextArea { - Layout.fillWidth: true - placeholderText: Translation.tr("Quote") - text: Config.options.background.quote - wrapMode: TextEdit.Wrap - onTextChanged: { - Config.options.background.quote = text; - } - } - } - - ContentSubsection { - title: Translation.tr("Wallpaper parallax") - - ConfigSwitch { - buttonIcon: "unfold_more_double" - text: Translation.tr("Vertical") - checked: Config.options.background.parallax.vertical - onCheckedChanged: { - Config.options.background.parallax.vertical = checked; - } - } - - ConfigRow { - uniform: true - ConfigSwitch { - buttonIcon: "counter_1" - text: Translation.tr("Depends on workspace") - checked: Config.options.background.parallax.enableWorkspace - onCheckedChanged: { - Config.options.background.parallax.enableWorkspace = checked; - } - } - ConfigSwitch { - buttonIcon: "side_navigation" - text: Translation.tr("Depends on sidebars") - checked: Config.options.background.parallax.enableSidebar - onCheckedChanged: { - Config.options.background.parallax.enableSidebar = checked; - } - } - } - ConfigSpinBox { - icon: "loupe" - text: Translation.tr("Preferred wallpaper zoom (%)") - value: Config.options.background.parallax.workspaceZoom * 100 - from: 100 - to: 150 - stepSize: 1 - onValueChanged: { - Config.options.background.parallax.workspaceZoom = value / 100; - } - } - } - } - ContentSection { icon: "keyboard" title: Translation.tr("Cheat sheet") @@ -494,45 +99,6 @@ ContentPage { } } } - ContentSection { - icon: "point_scan" - title: Translation.tr("Crosshair overlay") - - MaterialTextArea { - Layout.fillWidth: true - placeholderText: Translation.tr("Crosshair code (in Valorant's format)") - text: Config.options.crosshair.code - wrapMode: TextEdit.Wrap - onTextChanged: { - Config.options.crosshair.code = text; - } - } - - RowLayout { - StyledText { - Layout.leftMargin: 10 - color: Appearance.colors.colSubtext - font.pixelSize: Appearance.font.pixelSize.smallie - text: Translation.tr("Press Super+G to toggle appearance") - } - Item { - Layout.fillWidth: true - } - RippleButtonWithIcon { - id: editorButton - buttonRadius: Appearance.rounding.full - materialIcon: "open_in_new" - mainText: Translation.tr("Open editor") - onClicked: { - Qt.openUrlExternally(`https://www.vcrdb.net/builder?c=${Config.options.crosshair.code}`); - } - StyledToolTip { - text: "www.vcrdb.net" - } - } - } - } - ContentSection { icon: "call_to_action" title: Translation.tr("Dock") From e5e85db75d69ff6cf6a8e87065d75efb68610cb0 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Fri, 7 Nov 2025 12:56:08 +0100 Subject: [PATCH 46/52] refractor secondary tab bar --- .../common/widgets/SecondaryTabBar.qml | 53 ++++++++++++ .../common/widgets/SecondaryTabButton.qml | 22 ++--- .../sidebarRight/pomodoro/PomodoroWidget.qml | 82 ++----------------- .../modules/sidebarRight/todo/TodoWidget.qml | 80 ++---------------- 4 files changed, 78 insertions(+), 159 deletions(-) create mode 100644 dots/.config/quickshell/ii/modules/common/widgets/SecondaryTabBar.qml diff --git a/dots/.config/quickshell/ii/modules/common/widgets/SecondaryTabBar.qml b/dots/.config/quickshell/ii/modules/common/widgets/SecondaryTabBar.qml new file mode 100644 index 000000000..dcb490048 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/common/widgets/SecondaryTabBar.qml @@ -0,0 +1,53 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import qs.modules.common +import qs.modules.common.models + +TabBar { + id: root + property real indicatorPadding: 8 + Layout.fillWidth: true + + background: Item { + WheelHandler { + onWheel: (event) => { + if (event.angleDelta.y < 0) root.incrementCurrentIndex(); + else if (event.angleDelta.y > 0) root.decrementCurrentIndex(); + } + acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad + } + + Rectangle { + id: activeIndicator + z: 9999 + anchors.bottom: parent.bottom + topLeftRadius: height + topRightRadius: height + bottomLeftRadius: 0 + bottomRightRadius: 0 + color: Appearance.colors.colPrimary + // Animation + property real baseWidth: root.width / root.count + AnimatedTabIndexPair { + id: idxPair + index: root.currentIndex + } + height: 3 + x: Math.min(idxPair.idx1, idxPair.idx2) * baseWidth + root.indicatorPadding + width: ((Math.max(idxPair.idx1, idxPair.idx2) + 1) * baseWidth - root.indicatorPadding) - x + } + + Rectangle { // Tabbar bottom border + id: tabBarBottomBorder + z: 9998 + anchors.bottom: parent.bottom + height: 1 + anchors { + left: parent.left + right: parent.right + } + color: Appearance.colors.colOutlineVariant + } + } +} diff --git a/dots/.config/quickshell/ii/modules/common/widgets/SecondaryTabButton.qml b/dots/.config/quickshell/ii/modules/common/widgets/SecondaryTabButton.qml index b1036c777..b0bc9b4de 100644 --- a/dots/.config/quickshell/ii/modules/common/widgets/SecondaryTabButton.qml +++ b/dots/.config/quickshell/ii/modules/common/widgets/SecondaryTabButton.qml @@ -1,6 +1,6 @@ import qs.modules.common -import qs.modules.common.widgets import qs.modules.common.functions +import qs.modules.common.widgets import Qt5Compat.GraphicalEffects import QtQuick import QtQuick.Controls @@ -10,14 +10,12 @@ TabButton { id: root property string buttonText property string buttonIcon - property bool selected: false property int rippleDuration: 1200 - height: buttonBackground.height property int tabContentWidth: buttonBackground.width - buttonBackground.radius*2 - property color colBackground: ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1) - property color colBackgroundHover: Appearance.colors.colLayer1Hover - property color colRipple: Appearance.colors.colLayer1Active + property color colBackground: ColorUtils.transparentize(Appearance.colors.colSurfaceContainer) + property color colBackgroundHover: ColorUtils.transparentize(Appearance.colors.colOnSurface, root.checked ? 1 : 0.95) + property color colRipple: ColorUtils.transparentize(Appearance.colors.colOnSurface, 0.95) PointingHandInteraction {} @@ -91,8 +89,12 @@ TabButton { background: Rectangle { id: buttonBackground + anchors { + fill: parent + margins: 3 + } radius: Appearance?.rounding.normal - implicitHeight: 37 + implicitHeight: 42 color: (root.hovered ? root.colBackgroundHover : root.colBackground) layer.enabled: true layer.effect: OpacityMask { @@ -156,8 +158,8 @@ TabButton { verticalAlignment: Text.AlignVCenter text: buttonIcon iconSize: Appearance.font.pixelSize.huge - fill: selected ? 1 : 0 - color: selected ? Appearance.colors.colPrimary : Appearance.colors.colOnLayer1 + fill: root.checked ? 1 : 0 + color: root.checked ? Appearance.colors.colPrimary : Appearance.colors.colOnLayer1 Behavior on color { animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) } @@ -167,7 +169,7 @@ TabButton { id: buttonTextWidget verticalAlignment: Text.AlignVCenter font.pixelSize: Appearance.font.pixelSize.small - color: selected ? Appearance.colors.colPrimary : Appearance.colors.colOnLayer1 + color: root.checked ? Appearance.colors.colPrimary : Appearance.colors.colOnLayer1 text: buttonText Behavior on color { animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) diff --git a/dots/.config/quickshell/ii/modules/sidebarRight/pomodoro/PomodoroWidget.qml b/dots/.config/quickshell/ii/modules/sidebarRight/pomodoro/PomodoroWidget.qml index ca7723db3..a62a9616c 100644 --- a/dots/.config/quickshell/ii/modules/sidebarRight/pomodoro/PomodoroWidget.qml +++ b/dots/.config/quickshell/ii/modules/sidebarRight/pomodoro/PomodoroWidget.qml @@ -7,7 +7,6 @@ import QtQuick.Layouts Item { id: root - property int currentTab: 0 property var tabButtonList: [ {"name": Translation.tr("Pomodoro"), "icon": "search_activity"}, {"name": Translation.tr("Stopwatch"), "icon": "timer"} @@ -17,20 +16,20 @@ Item { Keys.onPressed: (event) => { if ((event.key === Qt.Key_PageDown || event.key === Qt.Key_PageUp) && event.modifiers === Qt.NoModifier) { // Switch tabs if (event.key === Qt.Key_PageDown) { - currentTab = Math.min(currentTab + 1, root.tabButtonList.length - 1) + tabBar.incrementCurrentIndex(); } else if (event.key === Qt.Key_PageUp) { - currentTab = Math.max(currentTab - 1, 0) + tabBar.decrementCurrentIndex(); } event.accepted = true } else if (event.key === Qt.Key_Space || event.key === Qt.Key_S) { // Pause/resume with Space or S - if (currentTab === 0) { + if (tabBar.currentIndex === 0) { TimerService.togglePomodoro() } else { TimerService.toggleStopwatch() } event.accepted = true } else if (event.key === Qt.Key_R) { // Reset with R - if (currentTab === 0) { + if (tabBar.currentIndex === 0) { TimerService.resetPomodoro() } else { TimerService.stopwatchReset() @@ -46,82 +45,19 @@ Item { anchors.fill: parent spacing: 0 - TabBar { + SecondaryTabBar { id: tabBar - Layout.fillWidth: true - currentIndex: currentTab - onCurrentIndexChanged: currentTab = currentIndex - - background: Item { - WheelHandler { - onWheel: (event) => { - if (event.angleDelta.y < 0) - tabBar.currentIndex = Math.min(tabBar.currentIndex + 1, root.tabButtonList.length - 1) - else if (event.angleDelta.y > 0) - tabBar.currentIndex = Math.max(tabBar.currentIndex - 1, 0) - } - acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad - } - } + currentIndex: swipeView.currentIndex Repeater { model: root.tabButtonList delegate: SecondaryTabButton { - selected: (index == currentTab) buttonText: modelData.name buttonIcon: modelData.icon } } } - Item { // Tab indicator - id: tabIndicator - Layout.fillWidth: true - height: 3 - property bool enableIndicatorAnimation: false - Connections { - target: root - function onCurrentTabChanged() { - tabIndicator.enableIndicatorAnimation = true - } - } - - Rectangle { - id: indicator - property int tabCount: root.tabButtonList.length - property real fullTabSize: root.width / tabCount; - property real targetWidth: tabBar.contentItem.children[0].children[tabBar.currentIndex].tabContentWidth - - implicitWidth: targetWidth - anchors { - top: parent.top - bottom: parent.bottom - } - - x: tabBar.currentIndex * fullTabSize + (fullTabSize - targetWidth) / 2 - - color: Appearance.colors.colPrimary - radius: Appearance.rounding.full - - Behavior on x { - enabled: tabIndicator.enableIndicatorAnimation - animation: Appearance.animation.elementMove.numberAnimation.createObject(this) - } - - Behavior on implicitWidth { - enabled: tabIndicator.enableIndicatorAnimation - animation: Appearance.animation.elementMove.numberAnimation.createObject(this) - } - } - } - - Rectangle { // Tabbar bottom border - id: tabBarBottomBorder - Layout.fillWidth: true - height: 1 - color: Appearance.colors.colOutlineVariant - } - SwipeView { id: swipeView Layout.topMargin: 10 @@ -129,11 +65,7 @@ Item { Layout.fillHeight: true spacing: 10 clip: true - currentIndex: currentTab - onCurrentIndexChanged: { - tabIndicator.enableIndicatorAnimation = true - currentTab = currentIndex - } + currentIndex: tabBar.currentIndex // Tabs PomodoroTimer {} diff --git a/dots/.config/quickshell/ii/modules/sidebarRight/todo/TodoWidget.qml b/dots/.config/quickshell/ii/modules/sidebarRight/todo/TodoWidget.qml index 99b0100f5..36c885523 100644 --- a/dots/.config/quickshell/ii/modules/sidebarRight/todo/TodoWidget.qml +++ b/dots/.config/quickshell/ii/modules/sidebarRight/todo/TodoWidget.qml @@ -7,7 +7,6 @@ import QtQuick.Layouts Item { id: root - property int currentTab: 0 property var tabButtonList: [{"icon": "checklist", "name": Translation.tr("Unfinished")}, {"name": Translation.tr("Done"), "icon": "check_circle"}] property bool showAddDialog: false property int dialogMargins: 20 @@ -17,9 +16,9 @@ Item { Keys.onPressed: (event) => { if ((event.key === Qt.Key_PageDown || event.key === Qt.Key_PageUp) && event.modifiers === Qt.NoModifier) { if (event.key === Qt.Key_PageDown) { - currentTab = Math.min(currentTab + 1, root.tabButtonList.length - 1) + tabBar.incrementCurrentIndex(); } else if (event.key === Qt.Key_PageUp) { - currentTab = Math.max(currentTab - 1, 0) + tabBar.decrementCurrentIndex(); } event.accepted = true; } @@ -39,82 +38,19 @@ Item { anchors.fill: parent spacing: 0 - TabBar { + SecondaryTabBar { id: tabBar - Layout.fillWidth: true - currentIndex: currentTab - onCurrentIndexChanged: currentTab = currentIndex - - background: Item { - WheelHandler { - onWheel: (event) => { - if (event.angleDelta.y < 0) - tabBar.currentIndex = Math.min(tabBar.currentIndex + 1, root.tabButtonList.length - 1) - else if (event.angleDelta.y > 0) - tabBar.currentIndex = Math.max(tabBar.currentIndex - 1, 0) - } - acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad - } - } + currentIndex: swipeView.currentIndex Repeater { model: root.tabButtonList delegate: SecondaryTabButton { - selected: (index == currentTab) buttonText: modelData.name buttonIcon: modelData.icon } } } - Item { // Tab indicator - id: tabIndicator - Layout.fillWidth: true - height: 3 - property bool enableIndicatorAnimation: false - Connections { - target: root - function onCurrentTabChanged() { - tabIndicator.enableIndicatorAnimation = true - } - } - - Rectangle { - id: indicator - property int tabCount: root.tabButtonList.length - property real fullTabSize: root.width / tabCount; - property real targetWidth: tabBar?.contentItem?.children[0]?.children[tabBar.currentIndex]?.tabContentWidth ?? 0 - - implicitWidth: targetWidth - anchors { - top: parent.top - bottom: parent.bottom - } - - x: tabBar.currentIndex * fullTabSize + (fullTabSize - targetWidth) / 2 - - color: Appearance.colors.colPrimary - radius: Appearance.rounding.full - - Behavior on x { - enabled: tabIndicator.enableIndicatorAnimation - animation: Appearance.animation.elementMove.numberAnimation.createObject(this) - } - - Behavior on implicitWidth { - enabled: tabIndicator.enableIndicatorAnimation - animation: Appearance.animation.elementMove.numberAnimation.createObject(this) - } - } - } - - Rectangle { // Tabbar bottom border - id: tabBarBottomBorder - Layout.fillWidth: true - height: 1 - color: Appearance.colors.colOutlineVariant - } - SwipeView { id: swipeView Layout.topMargin: 10 @@ -122,11 +58,7 @@ Item { Layout.fillHeight: true spacing: 10 clip: true - currentIndex: currentTab - onCurrentIndexChanged: { - tabIndicator.enableIndicatorAnimation = true - currentTab = currentIndex - } + currentIndex: tabBar.currentIndex // To Do tab TaskList { @@ -215,7 +147,7 @@ Item { Todo.addTask(todoInput.text) todoInput.text = "" root.showAddDialog = false - root.currentTab = 0 // Show unfinished tasks + tabBar.setCurrentIndex(0) // Show unfinished tasks } } From a27a6deddfc9c770d1aa2556835d019c6388d7ff Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Fri, 7 Nov 2025 12:56:44 +0100 Subject: [PATCH 47/52] overlay: add resource monitor widget --- .../quickshell/ii/modules/common/Config.qml | 1 + .../ii/modules/common/Persistent.qml | 7 + .../ii/modules/common/widgets/Graph.qml | 51 +++++++ .../ii/modules/overlay/OverlayContext.qml | 5 +- .../overlay/OverlayWidgetDelegateChooser.qml | 2 + .../ii/modules/overlay/recorder/Recorder.qml | 1 - .../modules/overlay/resources/Resources.qml | 134 ++++++++++++++++++ .../quickshell/ii/services/ResourceUsage.qml | 83 +++++++++-- 8 files changed, 272 insertions(+), 12 deletions(-) create mode 100644 dots/.config/quickshell/ii/modules/common/widgets/Graph.qml create mode 100644 dots/.config/quickshell/ii/modules/overlay/resources/Resources.qml diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index 55c9c94a8..d064d2533 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -411,6 +411,7 @@ Singleton { property JsonObject resources: JsonObject { property int updateInterval: 3000 + property int historyLength: 60 } property JsonObject musicRecognition: JsonObject { diff --git a/dots/.config/quickshell/ii/modules/common/Persistent.qml b/dots/.config/quickshell/ii/modules/common/Persistent.qml index 5335deb9d..f40fdf6cb 100644 --- a/dots/.config/quickshell/ii/modules/common/Persistent.qml +++ b/dots/.config/quickshell/ii/modules/common/Persistent.qml @@ -93,6 +93,13 @@ Singleton { property real x: 100 property real y: 130 } + property JsonObject resources: JsonObject { + property bool pinned: false + property bool clickthrough: true + property real x: 1000 + property real y: 320 + property int tabIndex: 0 + } property JsonObject volumeMixer: JsonObject { property bool pinned: false property bool clickthrough: false diff --git a/dots/.config/quickshell/ii/modules/common/widgets/Graph.qml b/dots/.config/quickshell/ii/modules/common/widgets/Graph.qml new file mode 100644 index 000000000..4747e5665 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/common/widgets/Graph.qml @@ -0,0 +1,51 @@ +import QtQuick +import qs.modules.common +import qs.modules.common.functions + +/* + * Simple one value line graph + */ +Canvas { + id: root + + enum Alignment { Left, Right } + + required property list values + property int points: values.length + property color color: Appearance.colors.colPrimary + property real fillOpacity: 0.5 + property var alignment: Graph.Alignment.Left + + onValuesChanged: root.requestPaint() + onPaint: { + var ctx = getContext("2d") + ctx.clearRect(0, 0, width, height) + if (!root.values || root.values.length < 2) + return + + var n = root.points + var dx = width / (n - 1) + ctx.strokeStyle = root.color + ctx.fillStyle = ColorUtils.transparentize(root.color, 1 - root.fillOpacity) + ctx.lineWidth = 2 + ctx.beginPath() + for (var i = 0; i < n; ++i) { + var valueIndex = (root.alignment === Graph.Alignment.Right) ? root.values.length - n + i : i + if (valueIndex < 0 || valueIndex >= root.values.length) { + continue; // No data for this point + } + var x = i * dx + var norm = root.values[valueIndex] // already in 0-1 range + var y = height - norm * height + if (valueIndex === 0) { + ctx.moveTo(x, height) + ctx.lineTo(x, y) + } else { + ctx.lineTo(x, y) + } + } + ctx.stroke() + ctx.lineTo(width, height) + ctx.fill() + } +} diff --git a/dots/.config/quickshell/ii/modules/overlay/OverlayContext.qml b/dots/.config/quickshell/ii/modules/overlay/OverlayContext.qml index 22746c4de..c13b1933c 100644 --- a/dots/.config/quickshell/ii/modules/overlay/OverlayContext.qml +++ b/dots/.config/quickshell/ii/modules/overlay/OverlayContext.qml @@ -6,9 +6,10 @@ Singleton { id: root readonly property list availableWidgets: [ - { identifier: "crosshair", materialSymbol: "point_scan" }, - { identifier: "volumeMixer", materialSymbol: "volume_up" }, { identifier: "recorder", materialSymbol: "screen_record" }, + { identifier: "volumeMixer", materialSymbol: "volume_up" }, + { identifier: "crosshair", materialSymbol: "point_scan" }, + { identifier: "resources", materialSymbol: "browse_activity" } ] readonly property bool hasPinnedWidgets: root.pinnedWidgetIdentifiers.length > 0 diff --git a/dots/.config/quickshell/ii/modules/overlay/OverlayWidgetDelegateChooser.qml b/dots/.config/quickshell/ii/modules/overlay/OverlayWidgetDelegateChooser.qml index 39df62ac3..90f85a7fd 100644 --- a/dots/.config/quickshell/ii/modules/overlay/OverlayWidgetDelegateChooser.qml +++ b/dots/.config/quickshell/ii/modules/overlay/OverlayWidgetDelegateChooser.qml @@ -9,6 +9,7 @@ import Quickshell.Bluetooth import qs.modules.overlay.crosshair import qs.modules.overlay.volumeMixer import qs.modules.overlay.recorder +import qs.modules.overlay.resources DelegateChooser { id: root @@ -17,4 +18,5 @@ DelegateChooser { DelegateChoice { roleValue: "crosshair"; Crosshair {} } DelegateChoice { roleValue: "volumeMixer"; VolumeMixer {} } DelegateChoice { roleValue: "recorder"; Recorder {} } + DelegateChoice { roleValue: "resources"; Resources {} } } diff --git a/dots/.config/quickshell/ii/modules/overlay/recorder/Recorder.qml b/dots/.config/quickshell/ii/modules/overlay/recorder/Recorder.qml index d32adedea..78d747ed6 100644 --- a/dots/.config/quickshell/ii/modules/overlay/recorder/Recorder.qml +++ b/dots/.config/quickshell/ii/modules/overlay/recorder/Recorder.qml @@ -2,7 +2,6 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import Quickshell -import Quickshell.Hyprland import qs import qs.modules.common import qs.modules.common.widgets diff --git a/dots/.config/quickshell/ii/modules/overlay/resources/Resources.qml b/dots/.config/quickshell/ii/modules/overlay/resources/Resources.qml new file mode 100644 index 000000000..f5f5ff286 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/overlay/resources/Resources.qml @@ -0,0 +1,134 @@ +pragma ComponentBehavior: Bound +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell +import Quickshell.Hyprland +import Qt5Compat.GraphicalEffects +import Qt.labs.synchronizer +import qs +import qs.services +import qs.modules.common +import qs.modules.common.widgets +import qs.modules.overlay + +StyledOverlayWidget { + id: root + property list resources: [ + { + "icon": "planner_review", + "name": Translation.tr("CPU"), + "history": ResourceUsage.cpuUsageHistory, + "maxAvailableString": ResourceUsage.maxAvailableCpuString + }, + { + "icon": "memory", + "name": Translation.tr("RAM"), + "history": ResourceUsage.memoryUsageHistory, + "maxAvailableString": ResourceUsage.maxAvailableMemoryString + }, + { + "icon": "swap_horiz", + "name": Translation.tr("Swap"), + "history": ResourceUsage.swapUsageHistory, + "maxAvailableString": ResourceUsage.maxAvailableSwapString + }, + ] + + contentItem: Rectangle { + id: contentItem + anchors.centerIn: parent + color: Appearance.m3colors.m3surfaceContainer + property real padding: 4 + implicitWidth: 350 + implicitHeight: 200 + // implicitHeight: contentColumn.implicitHeight + padding * 2 + ColumnLayout { + id: contentColumn + anchors { + fill: parent + margins: parent.padding + } + spacing: 10 + + SecondaryTabBar { + id: tabBar + + currentIndex: Persistent.states.overlay.resources.tabIndex + onCurrentIndexChanged: { + Persistent.states.overlay.resources.tabIndex = tabBar.currentIndex; + } + + Repeater { + model: root.resources.length + delegate: SecondaryTabButton { + required property int index + property var modelData: root.resources[index] + buttonIcon: modelData.icon + buttonText: modelData.name + } + } + } + + ResourceSummary { + Layout.margins: 8 + history: root.resources[tabBar.currentIndex]?.history ?? [] + maxAvailableString: root.resources[tabBar.currentIndex]?.maxAvailableString ?? "--" + } + } + } + + component ResourceSummary: RowLayout { + id: resourceSummary + required property list history + required property string maxAvailableString + Layout.fillWidth: true + Layout.fillHeight: true + spacing: 12 + + ColumnLayout { + spacing: 2 + StyledText { + text: (resourceSummary.history[resourceSummary.history.length - 1] * 100).toFixed(1) + "%" + font { + family: Appearance.font.family.numbers + variableAxes: Appearance.font.variableAxes.numbers + pixelSize: Appearance.font.pixelSize.huge + } + } + StyledText { + text: Translation.tr("of %1").arg(resourceSummary.maxAvailableString) + font { + // family: Appearance.font.family.numbers + // variableAxes: Appearance.font.variableAxes.numbers + pixelSize: Appearance.font.pixelSize.smallie + } + color: Appearance.colors.colSubtext + } + Item { + Layout.fillHeight: true + } + } + Rectangle { + id: graphBg + Layout.fillWidth: true + Layout.fillHeight: true + radius: Appearance.rounding.small + color: Appearance.colors.colSecondaryContainer + layer.enabled: true + layer.effect: OpacityMask { + maskSource: Rectangle { + width: graphBg.width + height: graphBg.height + radius: graphBg.radius + } + } + Graph { + anchors.fill: parent + values: root.resources[tabBar.currentIndex]?.history ?? [] + points: ResourceUsage.historyLength + alignment: Graph.Alignment.Right + } + } + } +} diff --git a/dots/.config/quickshell/ii/services/ResourceUsage.qml b/dots/.config/quickshell/ii/services/ResourceUsage.qml index 650528408..e42022cb5 100644 --- a/dots/.config/quickshell/ii/services/ResourceUsage.qml +++ b/dots/.config/quickshell/ii/services/ResourceUsage.qml @@ -10,17 +10,55 @@ import Quickshell.Io * Simple polled resource usage service with RAM, Swap, and CPU usage. */ Singleton { - property double memoryTotal: 1 - property double memoryFree: 1 - property double memoryUsed: memoryTotal - memoryFree - property double memoryUsedPercentage: memoryUsed / memoryTotal - property double swapTotal: 1 - property double swapFree: 1 - property double swapUsed: swapTotal - swapFree - property double swapUsedPercentage: swapTotal > 0 ? (swapUsed / swapTotal) : 0 - property double cpuUsage: 0 + id: root + property real memoryTotal: 1 + property real memoryFree: 0 + property real memoryUsed: memoryTotal - memoryFree + property real memoryUsedPercentage: memoryUsed / memoryTotal + property real swapTotal: 1 + property real swapFree: 0 + property real swapUsed: swapTotal - swapFree + property real swapUsedPercentage: swapTotal > 0 ? (swapUsed / swapTotal) : 0 + property real cpuUsage: 0 property var previousCpuStats + property string maxAvailableMemoryString: kbToGbString(ResourceUsage.memoryTotal) + property string maxAvailableSwapString: kbToGbString(ResourceUsage.swapTotal) + property string maxAvailableCpuString: "--" + + readonly property int historyLength: Config?.options.resources.historyLength ?? 60 + property list cpuUsageHistory: [] + property list memoryUsageHistory: [] + property list swapUsageHistory: [] + + function kbToGbString(kb) { + return (kb / (1024 * 1024)).toFixed(1) + " GB"; + } + + function updateMemoryUsageHistory() { + memoryUsageHistory = [...memoryUsageHistory, memoryUsedPercentage] + if (memoryUsageHistory.length > historyLength) { + memoryUsageHistory.shift() + } + } + function updateSwapUsageHistory() { + swapUsageHistory = [...swapUsageHistory, swapUsedPercentage] + if (swapUsageHistory.length > historyLength) { + swapUsageHistory.shift() + } + } + function updateCpuUsageHistory() { + cpuUsageHistory = [...cpuUsageHistory, cpuUsage] + if (cpuUsageHistory.length > historyLength) { + cpuUsageHistory.shift() + } + } + function updateHistories() { + updateMemoryUsageHistory() + updateSwapUsageHistory() + updateCpuUsageHistory() + } + Timer { interval: 1 running: true @@ -29,6 +67,7 @@ Singleton { // Reload files fileMeminfo.reload() fileStat.reload() + fileCpuinfo.reload() // Parse memory and swap usage const textMeminfo = fileMeminfo.text() @@ -53,10 +92,36 @@ Singleton { previousCpuStats = { total, idle } } + + // Parse max CPU frequency + const textCpuinfo = fileCpuinfo.text() + // Try to find 'cpu max MHz', fallback to highest 'cpu MHz' + let maxMHz = 0 + let match + // Try cpu max MHz (modern kernels) + match = textCpuinfo.match(/cpu max MHz\s*:\s*([\d.]+)/) + if (match) { + maxMHz = Number(match[1]) + } else { + // Fallback: find all cpu MHz lines and take the max + let mhzRegex = /cpu MHz\s*:\s*([\d.]+)/g + let mhzMatch + let mhzList = [] + while ((mhzMatch = mhzRegex.exec(textCpuinfo)) !== null) { + mhzList.push(Number(mhzMatch[1])) + } + if (mhzList.length > 0) { + maxMHz = Math.max.apply(null, mhzList) + } + } + root.maxAvailableCpuString = maxMHz > 0 ? (maxMHz / 1000).toFixed(1) + "GHz" : "--" + + root.updateHistories() interval = Config.options?.resources?.updateInterval ?? 3000 } } FileView { id: fileMeminfo; path: "/proc/meminfo" } FileView { id: fileStat; path: "/proc/stat" } + FileView { id: fileCpuinfo; path: "/proc/cpuinfo" } } From 0f867df271ee7f6fa169f25a1bc73c6d8c7db923 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Fri, 7 Nov 2025 13:02:34 +0100 Subject: [PATCH 48/52] overlay: better default positions --- .../quickshell/ii/modules/common/Persistent.qml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/common/Persistent.qml b/dots/.config/quickshell/ii/modules/common/Persistent.qml index f40fdf6cb..f2de212c9 100644 --- a/dots/.config/quickshell/ii/modules/common/Persistent.qml +++ b/dots/.config/quickshell/ii/modules/common/Persistent.qml @@ -80,7 +80,7 @@ Singleton { } property JsonObject overlay: JsonObject { - property list open: ["crosshair"] + property list open: ["crosshair", "recorder", "volumeMixer", "resources"] property JsonObject crosshair: JsonObject { property bool pinned: false property bool clickthrough: true @@ -90,21 +90,21 @@ Singleton { property JsonObject recorder: JsonObject { property bool pinned: false property bool clickthrough: false - property real x: 100 - property real y: 130 + property real x: 80 + property real y: 80 } property JsonObject resources: JsonObject { property bool pinned: false property bool clickthrough: true - property real x: 1000 - property real y: 320 + property real x: 1500 + property real y: 770 property int tabIndex: 0 } property JsonObject volumeMixer: JsonObject { property bool pinned: false property bool clickthrough: false - property real x: 100 - property real y: 320 + property real x: 80 + property real y: 250 } } From 1766375348bae573ae2061c877456db73dfb9211 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Fri, 7 Nov 2025 14:00:17 +0100 Subject: [PATCH 49/52] fix weird max cpu freq --- .../quickshell/ii/services/ResourceUsage.qml | 37 ++++++------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/dots/.config/quickshell/ii/services/ResourceUsage.qml b/dots/.config/quickshell/ii/services/ResourceUsage.qml index e42022cb5..df823adf7 100644 --- a/dots/.config/quickshell/ii/services/ResourceUsage.qml +++ b/dots/.config/quickshell/ii/services/ResourceUsage.qml @@ -67,7 +67,6 @@ Singleton { // Reload files fileMeminfo.reload() fileStat.reload() - fileCpuinfo.reload() // Parse memory and swap usage const textMeminfo = fileMeminfo.text() @@ -93,29 +92,6 @@ Singleton { previousCpuStats = { total, idle } } - // Parse max CPU frequency - const textCpuinfo = fileCpuinfo.text() - // Try to find 'cpu max MHz', fallback to highest 'cpu MHz' - let maxMHz = 0 - let match - // Try cpu max MHz (modern kernels) - match = textCpuinfo.match(/cpu max MHz\s*:\s*([\d.]+)/) - if (match) { - maxMHz = Number(match[1]) - } else { - // Fallback: find all cpu MHz lines and take the max - let mhzRegex = /cpu MHz\s*:\s*([\d.]+)/g - let mhzMatch - let mhzList = [] - while ((mhzMatch = mhzRegex.exec(textCpuinfo)) !== null) { - mhzList.push(Number(mhzMatch[1])) - } - if (mhzList.length > 0) { - maxMHz = Math.max.apply(null, mhzList) - } - } - root.maxAvailableCpuString = maxMHz > 0 ? (maxMHz / 1000).toFixed(1) + "GHz" : "--" - root.updateHistories() interval = Config.options?.resources?.updateInterval ?? 3000 } @@ -123,5 +99,16 @@ Singleton { FileView { id: fileMeminfo; path: "/proc/meminfo" } FileView { id: fileStat; path: "/proc/stat" } - FileView { id: fileCpuinfo; path: "/proc/cpuinfo" } + + Process { + id: findCpuMaxFreqProc + command: ["bash", "-c", "lscpu | grep 'CPU max MHz' | awk '{print $4}'"] + running: true + stdout: StdioCollector { + id: outputCollector + onStreamFinished: { + root.maxAvailableCpuString = (parseFloat(outputCollector.text) / 1000).toFixed(0) + " GHz" + } + } + } } From fd8f569477776c34302747a7f4db26e49b75b8cc Mon Sep 17 00:00:00 2001 From: "Celestial.y" Date: Fri, 7 Nov 2025 22:27:44 +0800 Subject: [PATCH 50/52] Add comment (#2220) --- dots/.config/hypr/hyprland/execs.conf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dots/.config/hypr/hyprland/execs.conf b/dots/.config/hypr/hyprland/execs.conf index 252e3afa8..c273da531 100644 --- a/dots/.config/hypr/hyprland/execs.conf +++ b/dots/.config/hypr/hyprland/execs.conf @@ -23,3 +23,5 @@ exec-once = wl-paste --type image --watch bash -c 'cliphist store && qs -c $qsCo # Cursor exec-once = hyprctl setcursor Bibata-Modern-Classic 24 +# Fix dock pinned apps not launching properly (https://github.com/end-4/dots-hyprland/issues/2200) +# exec-once = sleep 3.5 && hyprctl reload && sleep 0.5 && touch ~/.config/quickshell/ii/shell.qml From 082f12084d2a79354e3c768105532a9cdbe2c598 Mon Sep 17 00:00:00 2001 From: "Celestial.y" Date: Fri, 7 Nov 2025 23:59:20 +0800 Subject: [PATCH 51/52] Fix #2200 --- dots/.config/hypr/hyprland/execs.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dots/.config/hypr/hyprland/execs.conf b/dots/.config/hypr/hyprland/execs.conf index c273da531..e4f33f6aa 100644 --- a/dots/.config/hypr/hyprland/execs.conf +++ b/dots/.config/hypr/hyprland/execs.conf @@ -24,4 +24,4 @@ exec-once = wl-paste --type image --watch bash -c 'cliphist store && qs -c $qsCo exec-once = hyprctl setcursor Bibata-Modern-Classic 24 # Fix dock pinned apps not launching properly (https://github.com/end-4/dots-hyprland/issues/2200) -# exec-once = sleep 3.5 && hyprctl reload && sleep 0.5 && touch ~/.config/quickshell/ii/shell.qml +exec-once = sleep 3.5 && hyprctl reload && sleep 0.5 && touch ~/.config/quickshell/ii/shell.qml From 2c88a71eedee8e8c0292c721d9a8b240d70b2712 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Fri, 7 Nov 2025 18:21:59 +0100 Subject: [PATCH 52/52] overlay: make widgets have proper round corners when pinned --- .../ii/modules/common/Persistent.qml | 2 +- .../modules/overlay/StyledOverlayWidget.qml | 32 ++++++++++++------- .../modules/overlay/crosshair/Crosshair.qml | 6 +++- .../ii/modules/overlay/recorder/Recorder.qml | 1 + .../modules/overlay/resources/Resources.qml | 1 + .../overlay/volumeMixer/VolumeMixer.qml | 1 + 6 files changed, 29 insertions(+), 14 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/common/Persistent.qml b/dots/.config/quickshell/ii/modules/common/Persistent.qml index f2de212c9..43da3467e 100644 --- a/dots/.config/quickshell/ii/modules/common/Persistent.qml +++ b/dots/.config/quickshell/ii/modules/common/Persistent.qml @@ -104,7 +104,7 @@ Singleton { property bool pinned: false property bool clickthrough: false property real x: 80 - property real y: 250 + property real y: 280 } } diff --git a/dots/.config/quickshell/ii/modules/overlay/StyledOverlayWidget.qml b/dots/.config/quickshell/ii/modules/overlay/StyledOverlayWidget.qml index 5e6a0ce3f..42d61c3bd 100644 --- a/dots/.config/quickshell/ii/modules/overlay/StyledOverlayWidget.qml +++ b/dots/.config/quickshell/ii/modules/overlay/StyledOverlayWidget.qml @@ -21,6 +21,7 @@ AbstractOverlayWidget { id: root required property Item contentItem + property bool fancyBorders: true required property var modelData readonly property string identifier: modelData.identifier @@ -29,6 +30,8 @@ AbstractOverlayWidget { property var persistentStateEntry: Persistent.states.overlay[identifier] property real radius: Appearance.rounding.windowRounding property real minWidth: 250 + property real padding: 6 + property real contentRadius: radius - padding draggable: GlobalStates.overlayOpen x: Math.round(persistentStateEntry.x) // Round or it'll be blurry @@ -96,11 +99,15 @@ AbstractOverlayWidget { Rectangle { id: border anchors.fill: parent - color: "transparent" + color: (root.fancyBorders && GlobalStates.overlayOpen) ? Appearance.colors.colLayer1 : "transparent" radius: root.radius border.color: ColorUtils.transparentize(Appearance.colors.colOutlineVariant, GlobalStates.overlayOpen ? 0 : 1) border.width: 1 + Behavior on color { + animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) + } + layer.enabled: GlobalStates.overlayOpen layer.effect: OpacityMask { maskSource: Rectangle { @@ -110,25 +117,23 @@ AbstractOverlayWidget { } } - Column { + ColumnLayout { id: contentColumn - z: -1 + z: root.fancyBorders ? 0 : -1 anchors.fill: parent + spacing: 0 // Title bar Rectangle { id: titleBar opacity: GlobalStates.overlayOpen ? 1 : 0 - anchors { - left: parent.left - right: parent.right - } - property real padding: 2 + Layout.fillWidth: true + property real padding: 6 implicitWidth: titleBarRow.implicitWidth + padding * 2 implicitHeight: titleBarRow.implicitHeight + padding * 2 - color: Appearance.m3colors.m3surfaceContainer - border.color: Appearance.colors.colOutlineVariant - border.width: 1 + color: root.fancyBorders ? "transparent" : Appearance.colors.colLayer1 + // border.color: Appearance.colors.colOutlineVariant + // border.width: 1 RowLayout { id: titleBarRow @@ -191,7 +196,10 @@ AbstractOverlayWidget { // Content Item { id: contentContainer - anchors.horizontalCenter: parent.horizontalCenter + Layout.fillWidth: true + Layout.fillHeight: true + Layout.margins: root.fancyBorders ? root.padding : 0 + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter implicitWidth: root.contentItem.implicitWidth implicitHeight: root.contentItem.implicitHeight children: [root.contentItem] diff --git a/dots/.config/quickshell/ii/modules/overlay/crosshair/Crosshair.qml b/dots/.config/quickshell/ii/modules/overlay/crosshair/Crosshair.qml index abb1cbf26..bb60bd1fd 100644 --- a/dots/.config/quickshell/ii/modules/overlay/crosshair/Crosshair.qml +++ b/dots/.config/quickshell/ii/modules/overlay/crosshair/Crosshair.qml @@ -1,9 +1,13 @@ import QtQuick +import QtQuick.Layouts import Quickshell import qs.modules.common import qs.modules.overlay StyledOverlayWidget { id: root - contentItem: CrosshairContent {} + fancyBorders: false // Crosshair should be see-through + contentItem: CrosshairContent { + anchors.centerIn: parent + } } diff --git a/dots/.config/quickshell/ii/modules/overlay/recorder/Recorder.qml b/dots/.config/quickshell/ii/modules/overlay/recorder/Recorder.qml index 78d747ed6..e853819b4 100644 --- a/dots/.config/quickshell/ii/modules/overlay/recorder/Recorder.qml +++ b/dots/.config/quickshell/ii/modules/overlay/recorder/Recorder.qml @@ -13,6 +13,7 @@ StyledOverlayWidget { contentItem: Rectangle { id: contentItem anchors.centerIn: parent + radius: root.contentRadius color: Appearance.m3colors.m3surfaceContainer property real padding: 8 implicitHeight: contentColumn.implicitHeight + padding * 2 diff --git a/dots/.config/quickshell/ii/modules/overlay/resources/Resources.qml b/dots/.config/quickshell/ii/modules/overlay/resources/Resources.qml index f5f5ff286..1b78b867e 100644 --- a/dots/.config/quickshell/ii/modules/overlay/resources/Resources.qml +++ b/dots/.config/quickshell/ii/modules/overlay/resources/Resources.qml @@ -39,6 +39,7 @@ StyledOverlayWidget { id: contentItem anchors.centerIn: parent color: Appearance.m3colors.m3surfaceContainer + radius: root.contentRadius property real padding: 4 implicitWidth: 350 implicitHeight: 200 diff --git a/dots/.config/quickshell/ii/modules/overlay/volumeMixer/VolumeMixer.qml b/dots/.config/quickshell/ii/modules/overlay/volumeMixer/VolumeMixer.qml index 14aa53006..487f470b5 100644 --- a/dots/.config/quickshell/ii/modules/overlay/volumeMixer/VolumeMixer.qml +++ b/dots/.config/quickshell/ii/modules/overlay/volumeMixer/VolumeMixer.qml @@ -10,6 +10,7 @@ StyledOverlayWidget { contentItem: Rectangle { anchors.centerIn: parent color: Appearance.m3colors.m3surfaceContainer + radius: root.contentRadius property real padding: 16 implicitHeight: 600 implicitWidth: 350