diff --git a/.config/quickshell/modules/bar/UtilButtons.qml b/.config/quickshell/modules/bar/UtilButtons.qml index 9d9832a0a..25ae0ca3f 100644 --- a/.config/quickshell/modules/bar/UtilButtons.qml +++ b/.config/quickshell/modules/bar/UtilButtons.qml @@ -11,6 +11,7 @@ Item { id: root property bool borderless: ConfigOptions.bar.borderless implicitWidth: rowLayout.implicitWidth + rowLayout.spacing * 2 + implicitHeight: rowLayout.implicitHeight RowLayout { id: rowLayout @@ -34,21 +35,21 @@ Item { } } - Loader { - active: ConfigOptions.bar.utilButtons.showColorPicker - visible: ConfigOptions.bar.utilButtons.showColorPicker - sourceComponent: CircleUtilButton { - Layout.alignment: Qt.AlignVCenter - onClicked: Hyprland.dispatch("exec hyprpicker -a") - MaterialSymbol { - horizontalAlignment: Qt.AlignHCenter - fill: 1 - text: "colorize" - iconSize: Appearance.font.pixelSize.large - color: Appearance.colors.colOnLayer2 - } - } - } + Loader { + active: ConfigOptions.bar.utilButtons.showColorPicker + visible: ConfigOptions.bar.utilButtons.showColorPicker + sourceComponent: CircleUtilButton { + Layout.alignment: Qt.AlignVCenter + onClicked: Hyprland.dispatch("exec hyprpicker -a") + MaterialSymbol { + horizontalAlignment: Qt.AlignHCenter + fill: 1 + text: "colorize" + iconSize: Appearance.font.pixelSize.large + color: Appearance.colors.colOnLayer2 + } + } + } Loader { active: ConfigOptions.bar.utilButtons.showKeyboardToggle @@ -81,5 +82,27 @@ Item { } } } + + Loader { + active: ConfigOptions.bar.utilButtons.showDarkModeToggle + visible: ConfigOptions.bar.utilButtons.showDarkModeToggle + sourceComponent: CircleUtilButton { + Layout.alignment: Qt.AlignVCenter + onClicked: event => { + if (Appearance.m3colors.darkmode) { + Hyprland.dispatch(`exec ${Directories.wallpaperSwitchScriptPath} --mode light --noswitch`); + } else { + Hyprland.dispatch(`exec ${Directories.wallpaperSwitchScriptPath} --mode dark --noswitch`); + } + } + MaterialSymbol { + horizontalAlignment: Qt.AlignHCenter + fill: 0 + text: Appearance.m3colors.darkmode ? "light_mode" : "dark_mode" + iconSize: Appearance.font.pixelSize.large + color: Appearance.colors.colOnLayer2 + } + } + } } } diff --git a/.config/quickshell/modules/common/ConfigOptions.qml b/.config/quickshell/modules/common/ConfigOptions.qml index 1c2484f3e..5807d684b 100644 --- a/.config/quickshell/modules/common/ConfigOptions.qml +++ b/.config/quickshell/modules/common/ConfigOptions.qml @@ -1,7 +1,7 @@ -import QtQuick -import Quickshell pragma Singleton pragma ComponentBehavior: Bound +import QtQuick +import Quickshell Singleton { property QtObject policies: QtObject { @@ -21,8 +21,10 @@ Singleton { } } - property QtObject audio: QtObject { // Values in % - property QtObject protection: QtObject { // Prevent sudden bangs + property QtObject audio: QtObject { + // Values in % + property QtObject protection: QtObject { + // Prevent sudden bangs property bool enable: true property real maxAllowedIncrease: 10 property real maxAllowed: 90 // Realistically should already provide some protection when it's 99... @@ -59,6 +61,7 @@ Singleton { property bool showColorPicker: false property bool showMicToggle: false property bool showKeyboardToggle: true + property bool showDarkModeToggle: true } property QtObject tray: QtObject { property bool monochromeIcons: true @@ -74,7 +77,8 @@ Singleton { property QtObject battery: QtObject { property int low: 20 property int critical: 5 - property int suspend: 2 + property bool automaticSuspend: true + property int suspend: 3 } property QtObject dock: QtObject { @@ -83,9 +87,7 @@ Singleton { property bool pinnedOnStartup: false property bool hoverToReveal: false // When false, only reveals on empty workspace property list pinnedApps: [ // IDs of pinned entries - "org.kde.dolphin", - "kitty", - ] + "org.kde.dolphin", "kitty",] } property QtObject language: QtObject { @@ -112,9 +114,8 @@ Singleton { property QtObject overview: QtObject { property real scale: 0.18 // Relative to screen size - property real numOfRows: 2 - property real numOfCols: 5 - property bool showXwaylandIndicator: true + property real rows: 2 + property real columns: 5 } property QtObject resources: QtObject { @@ -124,7 +125,7 @@ Singleton { property QtObject search: QtObject { property int nonAppResultDelay: 30 // This prevents lagging when typing property string engineBaseUrl: "https://www.google.com/search?q=" - property list excludedSites: [ "quora.com" ] + property list excludedSites: ["quora.com"] property bool sloppy: false // Uses levenshtein distance based scoring instead of fuzzy sort. Very weird. property QtObject prefix: QtObject { property string action: "/" @@ -161,5 +162,4 @@ Singleton { property QtObject hacks: QtObject { property int arbitraryRaceConditionDelay: 20 // milliseconds } - } diff --git a/.config/quickshell/modules/common/widgets/ConfigSpinBox.qml b/.config/quickshell/modules/common/widgets/ConfigSpinBox.qml new file mode 100644 index 000000000..972c221df --- /dev/null +++ b/.config/quickshell/modules/common/widgets/ConfigSpinBox.qml @@ -0,0 +1,31 @@ +import "root:/modules/common/widgets/" +import "root:/modules/common/" +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +RowLayout { + id: root + property string text: "" + property alias value: spinBoxWidget.value + property alias stepSize: spinBoxWidget.stepSize + property alias from: spinBoxWidget.from + property alias to: spinBoxWidget.to + spacing: 10 + Layout.leftMargin: 8 + Layout.rightMargin: 8 + + StyledText { + id: labelWidget + Layout.fillWidth: true + text: root.text + font.pixelSize: Appearance.font.pixelSize.small + color: Appearance.colors.colOnSecondaryContainer + } + + StyledSpinBox { + id: spinBoxWidget + Layout.fillWidth: false + value: root.value + } +} diff --git a/.config/quickshell/modules/common/widgets/ContentPage.qml b/.config/quickshell/modules/common/widgets/ContentPage.qml index 07d889492..d23922c71 100644 --- a/.config/quickshell/modules/common/widgets/ContentPage.qml +++ b/.config/quickshell/modules/common/widgets/ContentPage.qml @@ -6,7 +6,7 @@ import "root:/modules/common/widgets/" Flickable { id: root - property real baseWidth: 500 + property real baseWidth: 550 property bool forceWidth: false property real bottomContentPadding: 100 diff --git a/.config/quickshell/modules/common/widgets/ContentSection.qml b/.config/quickshell/modules/common/widgets/ContentSection.qml index ee2410c40..01eab5cbf 100644 --- a/.config/quickshell/modules/common/widgets/ContentSection.qml +++ b/.config/quickshell/modules/common/widgets/ContentSection.qml @@ -14,6 +14,7 @@ ColumnLayout { StyledText { text: root.title font.pixelSize: Appearance.font.pixelSize.larger + font.weight: Font.Medium } ColumnLayout { id: sectionContent diff --git a/.config/quickshell/modules/common/widgets/ContentSubsection.qml b/.config/quickshell/modules/common/widgets/ContentSubsection.qml index 6df0c8fa9..0eb3b3b50 100644 --- a/.config/quickshell/modules/common/widgets/ContentSubsection.qml +++ b/.config/quickshell/modules/common/widgets/ContentSubsection.qml @@ -7,16 +7,37 @@ import "root:/modules/common/widgets/" ColumnLayout { id: root property string title: "" + property string tooltip: "" default property alias data: sectionContent.data Layout.fillWidth: true Layout.topMargin: 4 spacing: 2 - ContentSubsectionLabel { - Layout.fillWidth: true - visible: root.title && root.title.length > 0 - text: root.title + RowLayout { + ContentSubsectionLabel { + visible: root.title && root.title.length > 0 + text: root.title + } + MaterialSymbol { + visible: root.tooltip && root.tooltip.length > 0 + text: "info" + iconSize: Appearance.font.pixelSize.large + + color: Appearance.colors.colSubtext + MouseArea { + id: infoMouseArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.WhatsThisCursor + StyledToolTip { + extraVisibleCondition: false + alternativeVisibleCondition: infoMouseArea.containsMouse + content: root.tooltip + } + } + } + Item { Layout.fillWidth: true } } ColumnLayout { id: sectionContent diff --git a/.config/quickshell/modules/common/widgets/StyledProgressBar.qml b/.config/quickshell/modules/common/widgets/StyledProgressBar.qml index 1ea8a93ae..c36f31e2b 100644 --- a/.config/quickshell/modules/common/widgets/StyledProgressBar.qml +++ b/.config/quickshell/modules/common/widgets/StyledProgressBar.qml @@ -32,10 +32,8 @@ ProgressBar { animation: Appearance?.animation.elementMoveEnter.numberAnimation.createObject(this) } - background: Rectangle { + background: Item { anchors.fill: parent - color: "transparent" - radius: Appearance?.rounding.full ?? 9999 implicitHeight: valueBarHeight implicitWidth: valueBarWidth } diff --git a/.config/quickshell/modules/common/widgets/StyledSpinBox.qml b/.config/quickshell/modules/common/widgets/StyledSpinBox.qml new file mode 100644 index 000000000..9dac2544d --- /dev/null +++ b/.config/quickshell/modules/common/widgets/StyledSpinBox.qml @@ -0,0 +1,92 @@ +import "root:/modules/common" +import "root:/modules/common/functions/color_utils.js" as ColorUtils +import QtQuick +import QtQuick.Controls + +/** + * Material 3 styled SpinBox component. + */ +SpinBox { + id: root + + property real baseHeight: 35 + property real radius: Appearance.rounding.small + property real innerButtonRadius: Appearance.rounding.unsharpen + editable: true + + background: Rectangle { + color: Appearance.colors.colLayer2 + radius: root.radius + } + + contentItem: Item { + implicitHeight: root.baseHeight + implicitWidth: Math.max(labelText.implicitWidth, 40) + + StyledTextInput { + id: labelText + anchors.centerIn: parent + text: root.value // displayText would make the numbers weird like 1,000 instead of 1000 + color: Appearance.colors.colOnLayer2 + font.pixelSize: Appearance.font.pixelSize.small + validator: root.validator + onTextChanged: { + root.value = parseFloat(text); + } + } + } + + down.indicator: Rectangle { + anchors { + verticalCenter: parent.verticalCenter + left: parent.left + } + implicitHeight: root.baseHeight + implicitWidth: root.baseHeight + topLeftRadius: root.radius + bottomLeftRadius: root.radius + topRightRadius: root.innerButtonRadius + bottomRightRadius: root.innerButtonRadius + + color: root.down.pressed ? Appearance.colors.colLayer2Active : + root.down.hovered ? Appearance.colors.colLayer2Hover : + ColorUtils.transparentize(Appearance.colors.colLayer2) + Behavior on color { + animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) + } + + MaterialSymbol { + anchors.centerIn: parent + text: "remove" + iconSize: 20 + color: Appearance.colors.colOnLayer2 + } + } + + up.indicator: Rectangle { + anchors { + verticalCenter: parent.verticalCenter + right: parent.right + } + implicitHeight: root.baseHeight + implicitWidth: root.baseHeight + topRightRadius: root.radius + bottomRightRadius: root.radius + topLeftRadius: root.innerButtonRadius + bottomLeftRadius: root.innerButtonRadius + + color: root.up.pressed ? Appearance.colors.colLayer2Active : + root.up.hovered ? Appearance.colors.colLayer2Hover : + ColorUtils.transparentize(Appearance.colors.colLayer2) + Behavior on color { + animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) + } + + MaterialSymbol { + anchors.centerIn: parent + text: "add" + iconSize: 20 + color: Appearance.colors.colOnLayer2 + } + } +} diff --git a/.config/quickshell/modules/common/widgets/StyledTextInput.qml b/.config/quickshell/modules/common/widgets/StyledTextInput.qml new file mode 100644 index 000000000..9ca242f19 --- /dev/null +++ b/.config/quickshell/modules/common/widgets/StyledTextInput.qml @@ -0,0 +1,17 @@ +import "root:/modules/common" +import QtQuick +import QtQuick.Controls + +/** + * Does not include visual layout, but includes the easily neglected colors. + */ +TextInput { + renderType: Text.NativeRendering + selectedTextColor: Appearance.m3colors.m3onSecondaryContainer + selectionColor: Appearance.colors.colSecondaryContainer + font { + family: Appearance?.font.family.main ?? "sans-serif" + pixelSize: Appearance?.font.pixelSize.small ?? 15 + hintingPreference: Font.PreferFullHinting + } +} diff --git a/.config/quickshell/modules/overview/OverviewWidget.qml b/.config/quickshell/modules/overview/OverviewWidget.qml index 5faa8699d..813ee5ce9 100644 --- a/.config/quickshell/modules/overview/OverviewWidget.qml +++ b/.config/quickshell/modules/overview/OverviewWidget.qml @@ -17,7 +17,7 @@ Item { required property var panelWindow readonly property HyprlandMonitor monitor: Hyprland.monitorFor(panelWindow.screen) readonly property var toplevels: ToplevelManager.toplevels - readonly property int workspacesShown: ConfigOptions.overview.numOfRows * ConfigOptions.overview.numOfCols + readonly property int workspacesShown: ConfigOptions.overview.rows * ConfigOptions.overview.columns readonly property int workspaceGroup: Math.floor((monitor.activeWorkspace?.id - 1) / workspacesShown) property bool monitorIsFocused: (Hyprland.focusedMonitor?.id == monitor.id) property var windows: HyprlandData.windowList @@ -71,18 +71,18 @@ Item { anchors.centerIn: parent spacing: workspaceSpacing Repeater { - model: ConfigOptions.overview.numOfRows + model: ConfigOptions.overview.rows delegate: RowLayout { id: row property int rowIndex: index spacing: workspaceSpacing Repeater { // Workspace repeater - model: ConfigOptions.overview.numOfCols + model: ConfigOptions.overview.columns Rectangle { // Workspace id: workspace property int colIndex: index - property int workspaceValue: root.workspaceGroup * workspacesShown + rowIndex * ConfigOptions.overview.numOfCols + colIndex + 1 + property int workspaceValue: root.workspaceGroup * workspacesShown + rowIndex * ConfigOptions.overview.columns + colIndex + 1 property color defaultWorkspaceColor: Appearance.colors.colLayer1 // TODO: reconsider this color for a cleaner look property color hoveredWorkspaceColor: ColorUtils.mix(defaultWorkspaceColor, Appearance.colors.colLayer1Hover, 0.1) property color hoveredBorderColor: Appearance.colors.colLayer2Hover @@ -171,8 +171,8 @@ Item { property bool atInitPosition: (initX == x && initY == y) restrictToWorkspace: Drag.active || atInitPosition - property int workspaceColIndex: (windowData?.workspace.id - 1) % ConfigOptions.overview.numOfCols - property int workspaceRowIndex: Math.floor((windowData?.workspace.id - 1) % root.workspacesShown / ConfigOptions.overview.numOfCols) + property int workspaceColIndex: (windowData?.workspace.id - 1) % ConfigOptions.overview.columns + property int workspaceRowIndex: Math.floor((windowData?.workspace.id - 1) % root.workspacesShown / ConfigOptions.overview.columns) xOffset: (root.workspaceImplicitWidth + workspaceSpacing) * workspaceColIndex - (monitor?.x * root.scale) yOffset: (root.workspaceImplicitHeight + workspaceSpacing) * workspaceRowIndex - (monitor?.y * root.scale) @@ -245,8 +245,8 @@ Item { Rectangle { // Focused workspace indicator id: focusedWorkspaceIndicator property int activeWorkspaceInGroup: monitor.activeWorkspace?.id - (root.workspaceGroup * root.workspacesShown) - property int activeWorkspaceRowIndex: Math.floor((activeWorkspaceInGroup - 1) / ConfigOptions.overview.numOfCols) - property int activeWorkspaceColIndex: (activeWorkspaceInGroup - 1) % ConfigOptions.overview.numOfCols + property int activeWorkspaceRowIndex: Math.floor((activeWorkspaceInGroup - 1) / ConfigOptions.overview.columns) + property int activeWorkspaceColIndex: (activeWorkspaceInGroup - 1) % ConfigOptions.overview.columns x: (root.workspaceImplicitWidth + workspaceSpacing) * activeWorkspaceColIndex y: (root.workspaceImplicitHeight + workspaceSpacing) * activeWorkspaceRowIndex z: root.windowZ diff --git a/.config/quickshell/modules/overview/OverviewWindow.qml b/.config/quickshell/modules/overview/OverviewWindow.qml index 3b376988b..b749ab160 100644 --- a/.config/quickshell/modules/overview/OverviewWindow.qml +++ b/.config/quickshell/modules/overview/OverviewWindow.qml @@ -38,7 +38,7 @@ Item { // Window property var iconPath: Quickshell.iconPath(AppSearch.guessIcon(windowData?.class), "image-missing") property bool compactMode: Appearance.font.pixelSize.smaller * 4 > targetWindowHeight || Appearance.font.pixelSize.smaller * 4 > targetWindowWidth - property bool indicateXWayland: (ConfigOptions.overview.showXwaylandIndicator && windowData?.xwayland) ?? false + property bool indicateXWayland: windowData?.xwayland ?? false x: initX y: initY diff --git a/.config/quickshell/modules/overview/SearchWidget.qml b/.config/quickshell/modules/overview/SearchWidget.qml index f52710c5b..02ef98361 100644 --- a/.config/quickshell/modules/overview/SearchWidget.qml +++ b/.config/quickshell/modules/overview/SearchWidget.qml @@ -90,7 +90,7 @@ Item { // Wrapper id: mathProcess property list baseCommand: ["qalc", "-t"] function calculateExpression(expression) { - // mathProcess.running = false + mathProcess.running = false mathProcess.command = baseCommand.concat(expression) mathProcess.running = true } diff --git a/.config/quickshell/modules/settings/GeneralConfig.qml b/.config/quickshell/modules/settings/GeneralConfig.qml deleted file mode 100644 index ae051836e..000000000 --- a/.config/quickshell/modules/settings/GeneralConfig.qml +++ /dev/null @@ -1,144 +0,0 @@ -import QtQuick -import QtQuick.Controls -import QtQuick.Layouts -import "root:/services/" -import "root:/modules/common/" -import "root:/modules/common/widgets/" - -ContentPage { - forceWidth: true - ContentSection { - title: "Policies" - - ConfigRow { - ColumnLayout { // Weeb policy - ContentSubsectionLabel { - text: "Weeb" - } - ConfigSelectionArray { - currentValue: ConfigOptions.policies.weeb - configOptionName: "policies.weeb" - onSelected: (newValue) => { - ConfigLoader.setConfigValueAndSave("policies.weeb", newValue); - } - options: [ - { displayName: "No", value: 0 }, - { displayName: "Yes", value: 1 }, - { displayName: "Closet", value: 2 } - ] - } - } - - ColumnLayout { // AI policy - ContentSubsectionLabel { - text: "AI" - } - ConfigSelectionArray { - currentValue: ConfigOptions.policies.ai - configOptionName: "policies.ai" - onSelected: (newValue) => { - ConfigLoader.setConfigValueAndSave("policies.ai", newValue); - } - options: [ - { displayName: "No", value: 0 }, - { displayName: "Yes", value: 1 }, - { displayName: "Local only", value: 2 } - ] - } - } - } - } - ContentSection { - title: "Audio" - ConfigSwitch { - text: "Earbang protection" - checked: ConfigOptions.audio.protection.enable - onCheckedChanged: { - ConfigLoader.setConfigValueAndSave("audio.protection.enable", checked); - } - StyledToolTip { - content: "Prevents abrupt increments and restricts volume limit" - } - } - } - ContentSection { - title: "AI" - MaterialTextField { - id: systemPromptField - Layout.fillWidth: true - placeholderText: "System prompt" - text: ConfigOptions.ai.systemPrompt - wrapMode: TextEdit.Wrap - onTextChanged: { - ConfigLoader.setConfigValueAndSave("ai.systemPrompt", text); - } - } - } - - ContentSection { - title: "Bar" - - ContentSubsection { - title: "Appearance" - ConfigRow { - uniform: true - ConfigSwitch { - text: 'Borderless' - checked: ConfigOptions.bar.borderless - onCheckedChanged: { - ConfigLoader.setConfigValueAndSave("bar.borderless", checked); - } - } - ConfigSwitch { - text: 'Show background' - checked: ConfigOptions.bar.showBackground - onCheckedChanged: { - ConfigLoader.setConfigValueAndSave("bar.showBackground", checked); - } - StyledToolTip { - content: "Note: turning off can hurt readability" - } - } - } - } - - ContentSubsection { - title: "Buttons" - ConfigRow { - uniform: true - ConfigSwitch { - text: "Screen snip" - checked: ConfigOptions.bar.utilButtons.showScreenSnip - onCheckedChanged: { - ConfigLoader.setConfigValueAndSave("bar.utilButtons.showScreenSnip", checked); - } - } - ConfigSwitch { - text: "Color picker" - checked: ConfigOptions.bar.utilButtons.showColorPicker - onCheckedChanged: { - ConfigLoader.setConfigValueAndSave("bar.utilButtons.showColorPicker", checked); - } - } - } - ConfigRow { - uniform: true - ConfigSwitch { - text: "Mic toggle" - checked: ConfigOptions.bar.utilButtons.showMicToggle - onCheckedChanged: { - ConfigLoader.setConfigValueAndSave("bar.utilButtons.showMicToggle", checked); - } - } - ConfigSwitch { - text: "Keyboard toggle" - checked: ConfigOptions.bar.utilButtons.showKeyboardToggle - onCheckedChanged: { - ConfigLoader.setConfigValueAndSave("bar.utilButtons.showKeyboardToggle", checked); - } - } - } - } - - } -} \ No newline at end of file diff --git a/.config/quickshell/modules/settings/InterfaceConfig.qml b/.config/quickshell/modules/settings/InterfaceConfig.qml new file mode 100644 index 000000000..7d3799d23 --- /dev/null +++ b/.config/quickshell/modules/settings/InterfaceConfig.qml @@ -0,0 +1,263 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import "root:/services/" +import "root:/modules/common/" +import "root:/modules/common/widgets/" + +ContentPage { + forceWidth: true + ContentSection { + title: "Policies" + + ConfigRow { + ColumnLayout { // Weeb policy + ContentSubsectionLabel { + text: "Weeb" + } + ConfigSelectionArray { + currentValue: ConfigOptions.policies.weeb + configOptionName: "policies.weeb" + onSelected: (newValue) => { + ConfigLoader.setConfigValueAndSave("policies.weeb", newValue); + } + options: [ + { displayName: "No", value: 0 }, + { displayName: "Yes", value: 1 }, + { displayName: "Closet", value: 2 } + ] + } + } + + ColumnLayout { // AI policy + ContentSubsectionLabel { + text: "AI" + } + ConfigSelectionArray { + currentValue: ConfigOptions.policies.ai + configOptionName: "policies.ai" + onSelected: (newValue) => { + ConfigLoader.setConfigValueAndSave("policies.ai", newValue); + } + options: [ + { displayName: "No", value: 0 }, + { displayName: "Yes", value: 1 }, + { displayName: "Local only", value: 2 } + ] + } + } + } + } + + ContentSection { + title: "Bar" + + ContentSubsection { + title: "Appearance" + ConfigRow { + uniform: true + ConfigSwitch { + text: 'Borderless' + checked: ConfigOptions.bar.borderless + onCheckedChanged: { + ConfigLoader.setConfigValueAndSave("bar.borderless", checked); + } + } + ConfigSwitch { + text: 'Show background' + checked: ConfigOptions.bar.showBackground + onCheckedChanged: { + ConfigLoader.setConfigValueAndSave("bar.showBackground", checked); + } + StyledToolTip { + content: "Note: turning off can hurt readability" + } + } + } + } + + ContentSubsection { + title: "Buttons" + ConfigRow { + uniform: true + ConfigSwitch { + text: "Screen snip" + checked: ConfigOptions.bar.utilButtons.showScreenSnip + onCheckedChanged: { + ConfigLoader.setConfigValueAndSave("bar.utilButtons.showScreenSnip", checked); + } + } + ConfigSwitch { + text: "Color picker" + checked: ConfigOptions.bar.utilButtons.showColorPicker + onCheckedChanged: { + ConfigLoader.setConfigValueAndSave("bar.utilButtons.showColorPicker", checked); + } + } + } + ConfigRow { + uniform: true + ConfigSwitch { + text: "Mic toggle" + checked: ConfigOptions.bar.utilButtons.showMicToggle + onCheckedChanged: { + ConfigLoader.setConfigValueAndSave("bar.utilButtons.showMicToggle", checked); + } + } + ConfigSwitch { + text: "Keyboard toggle" + checked: ConfigOptions.bar.utilButtons.showKeyboardToggle + onCheckedChanged: { + ConfigLoader.setConfigValueAndSave("bar.utilButtons.showKeyboardToggle", checked); + } + } + } + ConfigRow { + uniform: true + ConfigSwitch { + text: "Dark/Light toggle" + checked: ConfigOptions.bar.utilButtons.showDarkModeToggle + onCheckedChanged: { + ConfigLoader.setConfigValueAndSave("bar.utilButtons.showDarkModeToggle", checked); + } + } + ConfigSwitch { + opacity: 0 + enabled: false + } + } + } + + ContentSubsection { + title: "Workspaces" + tooltip: "Tip: Hide icons and always show numbers for\nthe classic illogical-impulse experience" + + ConfigRow { + uniform: true + ConfigSwitch { + text: 'Show app icons' + checked: ConfigOptions.bar.workspaces.showAppIcons + onCheckedChanged: { + ConfigLoader.setConfigValueAndSave("bar.workspaces.showAppIcons", checked); + } + } + ConfigSwitch { + text: 'Always show numbers' + checked: ConfigOptions.bar.workspaces.alwaysShowNumbers + onCheckedChanged: { + ConfigLoader.setConfigValueAndSave("bar.workspaces.alwaysShowNumbers", checked); + } + } + } + ConfigSpinBox { + text: "Workspaces shown" + value: ConfigOptions.bar.workspaces.shown + from: 1 + to: 30 + stepSize: 1 + onValueChanged: { + ConfigLoader.setConfigValueAndSave("bar.workspaces.shown", value); + } + } + ConfigSpinBox { + text: "Number show delay when pressing Super (ms)" + value: ConfigOptions.bar.workspaces.showNumberDelay + from: 0 + to: 1000 + stepSize: 50 + onValueChanged: { + ConfigLoader.setConfigValueAndSave("bar.workspaces.showNumberDelay", value); + } + } + } + } + + ContentSection { + title: "Battery" + + ConfigRow { + uniform: true + ConfigSpinBox { + text: "Low warning" + value: ConfigOptions.battery.low + from: 0 + to: 100 + stepSize: 5 + onValueChanged: { + ConfigLoader.setConfigValueAndSave("battery.low", value); + } + } + ConfigSpinBox { + text: "Critical warning" + value: ConfigOptions.battery.critical + from: 0 + to: 100 + stepSize: 5 + onValueChanged: { + ConfigLoader.setConfigValueAndSave("battery.critical", value); + } + } + } + ConfigRow { + uniform: true + ConfigSwitch { + text: "Automatic suspend" + checked: ConfigOptions.battery.automaticSuspend + onCheckedChanged: { + ConfigLoader.setConfigValueAndSave("battery.automaticSuspend", checked); + } + StyledToolTip { + content: "Automatically suspends the system when battery is low" + } + } + ConfigSpinBox { + text: "Suspend at" + value: ConfigOptions.battery.suspend + from: 0 + to: 100 + stepSize: 5 + onValueChanged: { + ConfigLoader.setConfigValueAndSave("battery.suspend", value); + } + } + } + } + + ContentSection { + title: "Overview" + ConfigSpinBox { + text: "Scale (%)" + value: ConfigOptions.overview.scale * 100 + from: 1 + to: 100 + stepSize: 1 + onValueChanged: { + ConfigLoader.setConfigValueAndSave("overview.scale", value / 100); + } + } + ConfigRow { + uniform: true + ConfigSpinBox { + text: "Rows" + value: ConfigOptions.overview.rows + from: 1 + to: 20 + stepSize: 1 + onValueChanged: { + ConfigLoader.setConfigValueAndSave("overview.rows", value); + } + } + ConfigSpinBox { + text: "Columns" + value: ConfigOptions.overview.columns + from: 1 + to: 20 + stepSize: 1 + onValueChanged: { + ConfigLoader.setConfigValueAndSave("overview.columns", value); + } + } + } + + } +} \ No newline at end of file diff --git a/.config/quickshell/modules/settings/ServicesConfig.qml b/.config/quickshell/modules/settings/ServicesConfig.qml new file mode 100644 index 000000000..1be540363 --- /dev/null +++ b/.config/quickshell/modules/settings/ServicesConfig.qml @@ -0,0 +1,139 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import "root:/services/" +import "root:/modules/common/" +import "root:/modules/common/widgets/" + +ContentPage { + forceWidth: true + + ContentSection { + title: "Audio" + + ConfigSwitch { + text: "Earbang protection" + checked: ConfigOptions.audio.protection.enable + onCheckedChanged: { + ConfigLoader.setConfigValueAndSave("audio.protection.enable", checked); + } + StyledToolTip { + content: "Prevents abrupt increments and restricts volume limit" + } + } + ConfigRow { + // uniform: true + ConfigSpinBox { + text: "Max allowed increase" + value: ConfigOptions.audio.protection.maxAllowedIncrease + from: 0 + to: 100 + stepSize: 2 + onValueChanged: { + ConfigLoader.setConfigValueAndSave("audio.protection.maxAllowedIncrease", value); + } + } + ConfigSpinBox { + text: "Volume limit" + value: ConfigOptions.audio.protection.maxAllowed + from: 0 + to: 100 + stepSize: 2 + onValueChanged: { + ConfigLoader.setConfigValueAndSave("audio.protection.maxAllowed", value); + } + } + } + } + ContentSection { + title: "AI" + MaterialTextField { + Layout.fillWidth: true + placeholderText: "System prompt" + text: ConfigOptions.ai.systemPrompt + wrapMode: TextEdit.Wrap + onTextChanged: { + ConfigLoader.setConfigValueAndSave("ai.systemPrompt", text); + } + } + } + + ContentSection { + title: "Battery" + + ConfigRow { + uniform: true + ConfigSpinBox { + text: "Low warning" + value: ConfigOptions.battery.low + from: 0 + to: 100 + stepSize: 5 + onValueChanged: { + ConfigLoader.setConfigValueAndSave("battery.low", value); + } + } + ConfigSpinBox { + text: "Critical warning" + value: ConfigOptions.battery.critical + from: 0 + to: 100 + stepSize: 5 + onValueChanged: { + ConfigLoader.setConfigValueAndSave("battery.critical", value); + } + } + } + ConfigRow { + uniform: true + ConfigSwitch { + text: "Automatic suspend" + checked: ConfigOptions.battery.automaticSuspend + onCheckedChanged: { + ConfigLoader.setConfigValueAndSave("battery.automaticSuspend", checked); + } + StyledToolTip { + content: "Automatically suspends the system when battery is low" + } + } + ConfigSpinBox { + text: "Suspend at" + value: ConfigOptions.battery.suspend + from: 0 + to: 100 + stepSize: 5 + onValueChanged: { + ConfigLoader.setConfigValueAndSave("battery.suspend", value); + } + } + } + } + + ContentSection { + title: "Networking" + MaterialTextField { + Layout.fillWidth: true + placeholderText: "User agent (for services that require it)" + text: ConfigOptions.networking.userAgent + wrapMode: TextEdit.Wrap + onTextChanged: { + ConfigLoader.setConfigValueAndSave("networking.userAgent", text); + } + } + } + + ContentSection { + title: "Resources" + ConfigSpinBox { + text: "Polling interval (ms)" + value: ConfigOptions.resources.updateInterval + from: 100 + to: 10000 + stepSize: 100 + onValueChanged: { + ConfigLoader.setConfigValueAndSave("resources.updateInterval", value); + } + } + } + +} \ No newline at end of file diff --git a/.config/quickshell/modules/sidebarLeft/aiChat/AiMessage.qml b/.config/quickshell/modules/sidebarLeft/aiChat/AiMessage.qml index 0105ad5a9..4317f2265 100644 --- a/.config/quickshell/modules/sidebarLeft/aiChat/AiMessage.qml +++ b/.config/quickshell/modules/sidebarLeft/aiChat/AiMessage.qml @@ -247,9 +247,7 @@ Rectangle { spacing: 0 Repeater { - model: ScriptModel { - values: root.messageBlocks.map((block, index) => index) - } + model: root.messageBlocks.length delegate: Loader { required property int index property var thisBlock: root.messageBlocks[index] diff --git a/.config/quickshell/services/AppSearch.qml b/.config/quickshell/services/AppSearch.qml index 876df1838..1e383e672 100644 --- a/.config/quickshell/services/AppSearch.qml +++ b/.config/quickshell/services/AppSearch.qml @@ -23,6 +23,7 @@ Singleton { "wpsoffice": "wps-office2019-kprometheus", "footclient": "foot", "zen": "zen-browser", + "brave-browser": "brave-desktop" }) property var regexSubstitutions: [ { diff --git a/.config/quickshell/services/Battery.qml b/.config/quickshell/services/Battery.qml index b19910d85..e952dab97 100644 --- a/.config/quickshell/services/Battery.qml +++ b/.config/quickshell/services/Battery.qml @@ -12,6 +12,7 @@ Singleton { property bool isCharging: chargeState == UPowerDeviceState.Charging property bool isPluggedIn: isCharging || chargeState == UPowerDeviceState.PendingCharge property real percentage: UPower.displayDevice.percentage + readonly property bool allowAutomaticSuspend: ConfigOptions.battery.automaticSuspend property bool isLow: percentage <= ConfigOptions.battery.low / 100 property bool isCritical: percentage <= ConfigOptions.battery.critical / 100 @@ -19,6 +20,7 @@ Singleton { property bool isLowAndNotCharging: isLow && !isCharging property bool isCriticalAndNotCharging: isCritical && !isCharging + property bool isSuspendingAndNotCharging: allowAutomaticSuspend && isSuspending && !isCharging onIsLowAndNotChargingChanged: { if (available && isLowAndNotCharging) @@ -29,4 +31,10 @@ Singleton { if (available && isCriticalAndNotCharging) Quickshell.execDetached(["bash", "-c", `notify-send "Critically low battery" "🙏 I beg for pleas charg\nAutomatic suspend triggers at ${ConfigOptions.battery.suspend}%" -u critical -a "Shell"`]); } + + onIsSuspendingAndNotChargingChanged: { + if (available && isSuspendingAndNotCharging) { + Quickshell.execDetached(["bash", "-c", `systemctl suspend || loginctl suspend`]); + } + } } diff --git a/.config/quickshell/settings.qml b/.config/quickshell/settings.qml index 00f07e2ff..c68665658 100644 --- a/.config/quickshell/settings.qml +++ b/.config/quickshell/settings.qml @@ -33,9 +33,14 @@ ApplicationWindow { component: "modules/settings/StyleConfig.qml" }, { - name: "General", + name: "Interface", + icon: "cards", + component: "modules/settings/InterfaceConfig.qml" + }, + { + name: "Services", icon: "settings", - component: "modules/settings/GeneralConfig.qml" + component: "modules/settings/ServicesConfig.qml" }, { name: "About", @@ -56,8 +61,8 @@ ApplicationWindow { minimumWidth: 600 minimumHeight: 400 - width: 900 - height: 650 + width: 1100 + height: 750 color: Appearance.m3colors.m3background ColumnLayout { @@ -67,7 +72,6 @@ ApplicationWindow { } Keys.onPressed: (event) => { - console.log(`Key pressed: ${event.key}, Modifiers: ${event.modifiers}`); if (event.modifiers === Qt.ControlModifier) { if (event.key === Qt.Key_PageDown) { root.currentPage = Math.min(root.currentPage + 1, root.pages.length - 1) @@ -218,7 +222,7 @@ ApplicationWindow { properties: "opacity" from: 1 to: 0 - duration: 0 + duration: 100 easing.type: Appearance.animation.elementMoveExit.type easing.bezierCurve: Appearance.animationCurves.emphasizedFirstHalf } @@ -232,7 +236,7 @@ ApplicationWindow { properties: "opacity" from: 0 to: 1 - duration: 0 + duration: 200 easing.type: Appearance.animation.elementMoveEnter.type easing.bezierCurve: Appearance.animationCurves.emphasizedLastHalf } diff --git a/arch-packages/illogical-impulse-kde/PKGBUILD b/arch-packages/illogical-impulse-kde/PKGBUILD index b8b91c3f9..99eec5651 100644 --- a/arch-packages/illogical-impulse-kde/PKGBUILD +++ b/arch-packages/illogical-impulse-kde/PKGBUILD @@ -10,5 +10,6 @@ depends=( networkmanager plasma-nm polkit-kde-agent + dolphin systemsettings ) diff --git a/arch-packages/illogical-impulse-toolkit/PKGBUILD b/arch-packages/illogical-impulse-toolkit/PKGBUILD index 6f12584a2..636709f29 100644 --- a/arch-packages/illogical-impulse-toolkit/PKGBUILD +++ b/arch-packages/illogical-impulse-toolkit/PKGBUILD @@ -7,6 +7,7 @@ license=(None) depends=( kdialog qt6-5compat + qt6-avif-image-plugin qt6-base qt6-declarative qt6-imageformats