From 0f8929c55a8fd525a9d7fe805064b8cfb7e8e4d0 Mon Sep 17 00:00:00 2001 From: lucy Date: Sun, 23 Aug 2026 21:25:55 +0200 Subject: [PATCH] move qs config to work on mango and do general improvements --- Colors.js | 18 +++++ Colors.qml | 31 +++++++ modules/bar/ActiveWindow.qml | 18 +++++ modules/bar/ActiveWindow.qml~ | 31 +++++++ modules/bar/Bar.qml | 48 +++++++++++ modules/bar/Bar.qml~ | 13 +++ modules/bar/Bat.qml | 44 ++++++++++ modules/bar/Bat.qml~ | 58 +++++++++++++ modules/bar/Date.qml | 19 +++++ modules/bar/Date.qml~ | 26 ++++++ modules/bar/Mpris.qml | 35 ++++++++ modules/bar/Mpris.qml~ | 49 +++++++++++ modules/bar/Pw.qml | 65 +++++++++++++++ modules/bar/Pw.qml~ | 77 ++++++++++++++++++ modules/bar/Ws.qml | 30 +++++++ modules/bar/Ws.qml~ | 27 +++++++ modules/wallpaper/WallPicker.qml | 110 +++++++++++++++++++++++++ modules/wallpaper/WallPicker.qml~ | 130 ++++++++++++++++++++++++++++++ modules/wallpaper/Wallpaper.qml | 27 +++++++ settings/Config.qml | 34 ++++++++ settings/settings.ini | 12 +++ settings/settings.ini~ | 12 +++ shell.qml | 9 +++ shell.qml~ | 6 ++ widgets/BarComponent.qml | 10 +++ widgets/BarComponent.qml~ | 11 +++ widgets/MaterialIcon.qml | 16 ++++ widgets/StyledText.qml | 9 +++ widgets/StyledText.qml~ | 10 +++ widgets/barComponent.qml~ | 9 +++ 30 files changed, 994 insertions(+) create mode 100644 Colors.js create mode 100644 Colors.qml create mode 100644 modules/bar/ActiveWindow.qml create mode 100644 modules/bar/ActiveWindow.qml~ create mode 100644 modules/bar/Bar.qml create mode 100644 modules/bar/Bar.qml~ create mode 100644 modules/bar/Bat.qml create mode 100644 modules/bar/Bat.qml~ create mode 100644 modules/bar/Date.qml create mode 100644 modules/bar/Date.qml~ create mode 100644 modules/bar/Mpris.qml create mode 100644 modules/bar/Mpris.qml~ create mode 100644 modules/bar/Pw.qml create mode 100644 modules/bar/Pw.qml~ create mode 100644 modules/bar/Ws.qml create mode 100644 modules/bar/Ws.qml~ create mode 100644 modules/wallpaper/WallPicker.qml create mode 100644 modules/wallpaper/WallPicker.qml~ create mode 100644 modules/wallpaper/Wallpaper.qml create mode 100644 settings/Config.qml create mode 100644 settings/settings.ini create mode 100644 settings/settings.ini~ create mode 100644 shell.qml create mode 100644 shell.qml~ create mode 100644 widgets/BarComponent.qml create mode 100644 widgets/BarComponent.qml~ create mode 100644 widgets/MaterialIcon.qml create mode 100644 widgets/StyledText.qml create mode 100644 widgets/StyledText.qml~ create mode 100644 widgets/barComponent.qml~ diff --git a/Colors.js b/Colors.js new file mode 100644 index 0000000..9774932 --- /dev/null +++ b/Colors.js @@ -0,0 +1,18 @@ +const colors = { + base00: "#1e1e2e", + base01: "#181825", + base02: "#313244", + base03: "#45475a", + base04: "#585b70", + base05: "#cdd6f4", + base06: "#f5e0dc", + base07: "#b4befe", + base08: "#f38ba8", + base09: "#fab387", + base0A: "#f9e2af", + base0B: "#a6e3a1", + base0C: "#94e2d5", + base0D: "#89b4fa", + base0E: "#cba6f7", + base0F: "#f2cdcd", +} diff --git a/Colors.qml b/Colors.qml new file mode 100644 index 0000000..b8ce299 --- /dev/null +++ b/Colors.qml @@ -0,0 +1,31 @@ +pragma ComponentBehavior: Bound +pragma Singleton +import QtQuick +import Quickshell +import "Colors.js" as Colors + +Singleton { + id: root + + readonly property color accent: base0D + readonly property color barBg: base01 + readonly property color moduleBg: Qt.hsla(base01.hslHue, base01.hslSaturation, base01.hslLightness + 0.05, 1.0) + readonly property color activeModuleBg: Qt.hsla(base01.hslHue, base01.hslSaturation, base01.hslLightness + 0.1, 1.0) + readonly property color text: base07 + readonly property color base00: Colors.colors.base00 + readonly property color base01: Colors.colors.base01 + readonly property color base02: Colors.colors.base02 + readonly property color base03: Colors.colors.base03 + readonly property color base04: Colors.colors.base04 + readonly property color base05: Colors.colors.base05 + readonly property color base06: Colors.colors.base06 + readonly property color base07: Colors.colors.base07 + readonly property color base08: Colors.colors.base08 + readonly property color base09: Colors.colors.base09 + readonly property color base0A: Colors.colors.base0A + readonly property color base0B: Colors.colors.base0B + readonly property color base0C: Colors.colors.base0C + readonly property color base0D: Colors.colors.base0D + readonly property color base0E: Colors.colors.base0E + readonly property color base0F: Colors.colors.base0F +} diff --git a/modules/bar/ActiveWindow.qml b/modules/bar/ActiveWindow.qml new file mode 100644 index 0000000..ab2b01f --- /dev/null +++ b/modules/bar/ActiveWindow.qml @@ -0,0 +1,18 @@ +pragma ComponentBehavior: Bound +import Quickshell.Widgets +import Quickshell.Wayland +import QtQuick +import QtQuick.Layouts +import qs +import qs.widgets +import qs.settings + +BarComponent { + id: root + implicitWidth: windowText.implicitWidth +16 + StyledText { + id: windowText + anchors.centerIn: parent + text: ToplevelManager.activeToplevel?.title ?? "Desktop" + } +} diff --git a/modules/bar/ActiveWindow.qml~ b/modules/bar/ActiveWindow.qml~ new file mode 100644 index 0000000..9020ca4 --- /dev/null +++ b/modules/bar/ActiveWindow.qml~ @@ -0,0 +1,31 @@ +pragma ComponentBehavior: Bound +import Quickshell.Widgets +import Quickshell.Hyprland +import QtQuick +import QtQuick.Layouts +import qs +import qs.widgets +import qs.settings +import QtQuick.Effects + +BarComponent { + id: root + implicitHeight: moduleHeight + implicitWidth: titleLayout.width + 32 + color: Colors.moduleBg + radius: Config.rounding + RowLayout { + id: titleLayout + anchors.centerIn: root + WrapperRectangle { + Layout.maximumWidth: 400 + color: 'transparent' + clip: true + StyledText { + property bool onWs: Hyprland.activeToplevel?.workspace == Hyprland.focusedWorkspace + text: onWs ? Hyprland.activeToplevel?.title ?? "Desktop" : "Desktop" + elide: Text.ElideRight + } + } + } +} diff --git a/modules/bar/Bar.qml b/modules/bar/Bar.qml new file mode 100644 index 0000000..e2d0279 --- /dev/null +++ b/modules/bar/Bar.qml @@ -0,0 +1,48 @@ +import Quickshell +import QtQuick +import QtQuick.Layouts +import qs.modules.wallpaper +import qs.settings +import qs.widgets +import qs + + +Variants { + model: Quickshell.screens + delegate: PanelWindow { + required property ShellScreen modelData + id: root + screen: modelData + anchors { + top: true + left: true + right: true + } + color: 'transparent' + implicitHeight: Config.barHeight + Rectangle { + anchors.fill: parent + color: Colors.barBg + RowLayout { + anchors.leftMargin: 10 + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + Ws { barScreen: root.modelData } + ActiveWindow {} + } + RowLayout { + anchors.centerIn: parent + Date {} + } + RowLayout { + anchors.rightMargin: 10 + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + Mpris {} + Bat {} + Pw {} + WallPicker {screenHeight: root.screen.height} + } + } + } +} diff --git a/modules/bar/Bar.qml~ b/modules/bar/Bar.qml~ new file mode 100644 index 0000000..d4d4aea --- /dev/null +++ b/modules/bar/Bar.qml~ @@ -0,0 +1,13 @@ +import Quickshell +import QtQuick + +Variants { + model: Quickshell.screens + delegate: PanelWindow { + anchors { + top: true + left: true + right: true + } + } +} diff --git a/modules/bar/Bat.qml b/modules/bar/Bat.qml new file mode 100644 index 0000000..0059503 --- /dev/null +++ b/modules/bar/Bat.qml @@ -0,0 +1,44 @@ +import Quickshell.Services.UPower +import QtQuick +import QtQuick.Layouts +import QtQuick.Effects +import qs +import qs.widgets +import qs.settings + +BarComponent { + id: root + visible: UPower.displayDevice.isLaptopBattery + property double percent: UPower.displayDevice.percentage * 100 + property bool hasBattery: UPower.displayDevice.isLaptopBattery + property bool charging: UPower.displayDevice.state === UPowerDeviceState.Charging + implicitHeight: Config.moduleHeight + implicitWidth: batLayout.implicitWidth + 16 + + function batteryIcon(percent) { + if (root.charging) + return "battery_android_frame_bolt"; + if (percent <= 15) + return "battery_android_alert"; + if (percent <= 30) + return "battery_android_frame_2"; + if (percent <= 50) + return "battery_android_frame_3"; + if (percent <= 70) + return "battery_android_frame_4"; + if (percent <= 85) + return "battery_android_frame_5"; + if (percent <= 100) + return "battery_android_frame_full"; + } + RowLayout { + id: batLayout + anchors.centerIn: root + MaterialIcon { + text: root.batteryIcon(root.percent) + } + StyledText { + text: Math.floor(root.percent) + "%" + } + } +} diff --git a/modules/bar/Bat.qml~ b/modules/bar/Bat.qml~ new file mode 100644 index 0000000..8a44028 --- /dev/null +++ b/modules/bar/Bat.qml~ @@ -0,0 +1,58 @@ +import Quickshell.Services.UPower +import QtQuick +import QtQuick.Layouts +import QtQuick.Effects +import qs +import qs.widgets +import qs.settings + +BarComponent { + id: root + layer.enabled: true + layer.effect: MultiEffect { + id: dropShadow + source: root + shadowEnabled: true + shadowHorizontalOffset: 4 + shadowVerticalOffset: 2 + shadowOpacity: 0.5 + shadowColor: "#020202" + } + clip: true + color: Colors.moduleBg + visible: UPower.displayDevice.isLaptopBattery + property double percent: UPower.displayDevice.percentage * 100 + property bool hasBattery: UPower.displayDevice.isLaptopBattery + property bool charging: UPower.displayDevice.state === UPowerDeviceState.Charging + required property double moduleHeight + implicitHeight: moduleHeight + implicitWidth: batLayout.implicitWidth + 16 + radius: Config.rounding + + function batteryIcon(percent) { + if (root.charging) + return "battery_android_frame_bolt"; + if (percent <= 15) + return "battery_android_alert"; + if (percent <= 30) + return "battery_android_frame_2"; + if (percent <= 50) + return "battery_android_frame_3"; + if (percent <= 70) + return "battery_android_frame_4"; + if (percent <= 85) + return "battery_android_frame_5"; + if (percent <= 100) + return "battery_android_frame_full"; + } + RowLayout { + id: batLayout + anchors.centerIn: root + MaterialIcon { + text: root.batteryIcon(root.percent) + } + StyledText { + text: Math.floor(root.percent) + "%" + } + } +} diff --git a/modules/bar/Date.qml b/modules/bar/Date.qml new file mode 100644 index 0000000..e6b3c29 --- /dev/null +++ b/modules/bar/Date.qml @@ -0,0 +1,19 @@ +import Quickshell +import QtQuick +import qs +import qs.widgets +import qs.settings + +BarComponent { + id: root + implicitWidth: clockText.width + 16 + SystemClock { + id: clock + precision: SystemClock.Seconds + } + StyledText { + anchors.centerIn: parent + id: clockText + text: Qt.formatDateTime(clock.date, "d.M.yy - hh:mm:ss") + } +} diff --git a/modules/bar/Date.qml~ b/modules/bar/Date.qml~ new file mode 100644 index 0000000..fa6ab8a --- /dev/null +++ b/modules/bar/Date.qml~ @@ -0,0 +1,26 @@ +pragma ComponentBehavior: Bound +import Quickshell +import QtQuick +import QtQuick.Effects +import qs +import qs.widgets +import qs.settings + +BarComponent { + id: root + clip: true + required property double moduleHeight + implicitHeight: moduleHeight + implicitWidth: clockText.implicitWidth + 32 + color: Colors.moduleBg + radius: Config.rounding + SystemClock { + id: clock + precision: SystemClock.Seconds + } + StyledText { + id: clockText + anchors.centerIn: root + text: Qt.formatDateTime(clock.date, "d.M.yy - hh:mm:ss") + } +} diff --git a/modules/bar/Mpris.qml b/modules/bar/Mpris.qml new file mode 100644 index 0000000..f0c4eb4 --- /dev/null +++ b/modules/bar/Mpris.qml @@ -0,0 +1,35 @@ +pragma ComponentBehavior: Bound +import Quickshell.Services.Mpris +import QtQuick +import QtQuick.Layouts +import QtQuick.Effects +import qs +import qs.widgets +import qs.settings + +BarComponent { + id: root + implicitHeight: Config.moduleHeight + implicitWidth: songLayout.implicitWidth + 16 + property MprisPlayer spotify: { + for (const player of Mpris.players.values) { + if (player.identity === "Spotify") + return player; + } + return null; + } + visible: spotify !== null && spotify.playbackState === MprisPlaybackState.Playing + RowLayout { + id: songLayout + anchors.centerIn: root + MaterialIcon { + text: "music_note_2" + } + StyledText { + Layout.maximumWidth: 400 + Layout.maximumHeight: Config.barHeight / 1.6 + text: root.spotify?.trackTitle + " - " + root.spotify?.trackArtists + elide: Text.ElideRight + } + } +} diff --git a/modules/bar/Mpris.qml~ b/modules/bar/Mpris.qml~ new file mode 100644 index 0000000..c60ebf1 --- /dev/null +++ b/modules/bar/Mpris.qml~ @@ -0,0 +1,49 @@ +pragma ComponentBehavior: Bound +import Quickshell.Services.Mpris +import QtQuick +import QtQuick.Layouts +import QtQuick.Effects +import qs +import qs.widgets +import qs.settings + +Rectangle { + id: root + layer.enabled: true + layer.effect: MultiEffect { + id: dropShadow + source: root + shadowEnabled: true + shadowHorizontalOffset: 4 + shadowVerticalOffset: 2 + shadowOpacity: 0.5 + shadowColor: "#020202" + } + required property double moduleHeight + implicitHeight: moduleHeight + implicitWidth: songLayout.implicitWidth + 32 + property MprisPlayer spotify: { + for (const player of Mpris.players.values) { + if (player.identity === "Spotify") + return player; + } + return null; + } + visible: spotify !== null && spotify.playbackState === MprisPlaybackState.Playing + clip: true + color: Colors.moduleBg + radius: Config.rounding + RowLayout { + id: songLayout + anchors.centerIn: root + MaterialIcon { + text: "music_note_2" + } + StyledText { + Layout.maximumWidth: 400 + Layout.maximumHeight: Config.barHeight / 1.6 + text: root.spotify?.trackTitle + " - " + root.spotify?.trackArtists + elide: Text.ElideRight + } + } +} diff --git a/modules/bar/Pw.qml b/modules/bar/Pw.qml new file mode 100644 index 0000000..5a6b78d --- /dev/null +++ b/modules/bar/Pw.qml @@ -0,0 +1,65 @@ +pragma ComponentBehavior: Bound +import Quickshell.Services.Pipewire +import Quickshell.Io +import QtQuick +import QtQuick.Layouts +import QtQuick.Effects +import qs +import qs.widgets +import qs.settings + +BarComponent { + id: root + color: clickHandler.containsMouse ? Colors.activeModuleBg : Colors.moduleBg + property PwNode defaultAudio: Pipewire.ready ? Pipewire.defaultAudioSink : null + property bool mute: Pipewire.ready ? defaultAudio?.audio.muted : null + implicitHeight: Config.moduleHeight + implicitWidth: pwLayout.implicitWidth + 16 + function getVolumeIcon() { + let volume = Pipewire.ready ? root.defaultAudio.audio.volume : null; + if (root.mute) { + return "\ue04f"; + } + if (volume <= 0.33) { + return "\ue04e"; + } + if (volume <= 0.66) { + return "\ue04d"; + } + if (volume >= 0.66) { + return "\ue050"; + } + } + + PwObjectTracker { + objects: [Pipewire.ready ? Pipewire.defaultAudioSink : null] + } + + Process { + id: pavuLauncher + command: ["pavucontrol"] + running: false + } + + RowLayout { + id: pwLayout + anchors.centerIn: root + spacing: 4 + MaterialIcon { + text: root.getVolumeIcon() + opacity: root.defaultAudio?.audio.muted ? 0.6 : 1.0 + } + StyledText { + text: Math.round(root.defaultAudio?.audio.volume * 100) + "%" + opacity: root.defaultAudio?.audio.muted ? 0.6 : 1.0 + } + } + MouseArea { + id: clickHandler + hoverEnabled: true + acceptedButtons: Qt.LeftButton + cursorShape: Qt.PointingHandCursor + anchors.fill: root + onClicked: pavuLauncher.running = true + } +} diff --git a/modules/bar/Pw.qml~ b/modules/bar/Pw.qml~ new file mode 100644 index 0000000..b26c8ca --- /dev/null +++ b/modules/bar/Pw.qml~ @@ -0,0 +1,77 @@ +pragma ComponentBehavior: Bound +import Quickshell.Services.Pipewire +import Quickshell.Io +import QtQuick +import QtQuick.Layouts +import QtQuick.Effects +import qs +import qs.widgets +import qs.settings + +BarComponent { + id: root + layer.enabled: true + layer.effect: MultiEffect { + id: dropShadow + source: root + shadowEnabled: true + shadowHorizontalOffset: 4 + shadowVerticalOffset: 2 + shadowOpacity: 0.5 + shadowColor: "#020202" + } + color: clickHandler.containsMouse ? Colors.activeModuleBg : Colors.moduleBg + property PwNode defaultAudio: Pipewire.ready ? Pipewire.defaultAudioSink : null + property bool mute: Pipewire.ready ? defaultAudio?.audio.muted : null + radius: Config.rounding + required property double moduleHeight + implicitHeight: moduleHeight + implicitWidth: pwLayout.implicitWidth + 16 + function getVolumeIcon() { + let volume = Pipewire.ready ? root.defaultAudio.audio.volume : null; + if (root.mute) { + return "\ue04f"; + } + if (volume <= 0.33) { + return "\ue04e"; + } + if (volume <= 0.66) { + return "\ue04d"; + } + if (volume >= 0.66) { + return "\ue050"; + } + } + + PwObjectTracker { + objects: [Pipewire.ready ? Pipewire.defaultAudioSink : null] + } + + Process { + id: pavuLauncher + command: ["pavucontrol"] + running: false + } + + RowLayout { + id: pwLayout + anchors.centerIn: root + spacing: 4 + MaterialIcon { + text: root.getVolumeIcon() + opacity: root.defaultAudio?.audio.muted ? 0.6 : 1.0 + } + StyledText { + text: Math.round(root.defaultAudio?.audio.volume * 100) + "%" + opacity: root.defaultAudio?.audio.muted ? 0.6 : 1.0 + } + } + MouseArea { + id: clickHandler + hoverEnabled: true + acceptedButtons: Qt.LeftButton + cursorShape: Qt.PointingHandCursor + anchors.fill: root + onClicked: pavuLauncher.running = true + } +} diff --git a/modules/bar/Ws.qml b/modules/bar/Ws.qml new file mode 100644 index 0000000..29a9d32 --- /dev/null +++ b/modules/bar/Ws.qml @@ -0,0 +1,30 @@ +import Quickshell +import Quickshell.WindowManager +import QtQuick +import QtQuick.Layouts +import qs +import qs.widgets + +BarComponent { + id: root + required property ShellScreen barScreen + implicitWidth: wsLayout.implicitWidth + wsLayout.spacing * 2 + RowLayout { + id: wsLayout + spacing: 15 + anchors.centerIn: parent + Repeater { + model: WindowManager.screenProjection(root.barScreen).windowsets + delegate: Rectangle { + required property var modelData + visible: modelData.shouldDisplay + StyledText { + id: wsText + anchors.centerIn: parent + text: parent.modelData.name + color: parent.modelData.active ? Colors.base0D: Colors.base03 + } + } + } + } +} diff --git a/modules/bar/Ws.qml~ b/modules/bar/Ws.qml~ new file mode 100644 index 0000000..4c18d5f --- /dev/null +++ b/modules/bar/Ws.qml~ @@ -0,0 +1,27 @@ +import Quickshell +import Quickshell.WindowManager +import QtQuick +import QtQuick.Layouts +import qs +import qs.widgets + +BarComponent { + id: root + required property ShellScreen barScreen + RowLayout { + spacing: 15 + anchors.fill: parent + Repeater { + model: WindowManager.screenProjection(root.barScreen).windowsets + delegate: Rectangle { + required property var modelData + visible: modelData.shouldDisplay + StyledText { + id: wsText + text: parent.modelData.name + color: parent.modelData.active ? Colors.base0D: Colors.base03 + } + } + } + } +} diff --git a/modules/wallpaper/WallPicker.qml b/modules/wallpaper/WallPicker.qml new file mode 100644 index 0000000..c84a449 --- /dev/null +++ b/modules/wallpaper/WallPicker.qml @@ -0,0 +1,110 @@ +pragma ComponentBehavior: Bound +import Quickshell +import Quickshell.Wayland +import Quickshell.Widgets +import Quickshell.Hyprland +import QtQuick +import Qt.labs.folderlistmodel 2.11 +import QtQuick.Effects + +import qs +import qs.settings +import qs.widgets + +BarComponent { + implicitHeight: Config.moduleHeight + implicitWidth: Config.moduleHeight + required property int screenHeight + id: main + MaterialIcon { + anchors.centerIn: main + text: "\ue1bc" + font.bold: true + } + MouseArea { + id: clickHandler + anchors.fill: main + acceptedButtons: Qt.LeftButton + cursorShape: Qt.PointingHandCursor + onClicked: { + wallPicker.visible = !wallPicker.visible; + } + } + WlrLayershell { + id: wallPicker + visible: false + exclusionMode: ExclusionMode.Ignore + keyboardFocus: WlrKeyboardFocus.OnDemand + implicitHeight: main.screenHeight / 8 + color: 'transparent' + anchors { + bottom: true + left: true + right: true + } + margins { + bottom: 20 + left: 20 + right: 20 + } + onVisibleChanged: { + if (wallPicker.visible) + container.forceActiveFocus(); + } + Rectangle { + id: container + focus: true + Keys.onEscapePressed: { + wallPicker.visible = false; + } + anchors.fill: parent + color: Colors.base00 + radius: Config.rounding + GridView { + id: wallpaperLayout + clip: true + snapMode: GridView.SnapOneRow + flow: GridView.FlowTopToBottom + cellHeight: container.height + cellWidth: container.width / 8 + anchors.fill: parent + anchors.centerIn: parent + anchors.margins: 10 + model: wallpaperList + delegate: ClippingRectangle { + id: wallTile + clip: true + required property var modelData + radius: Config.rounding / 1.5 + color: 'transparent' + implicitWidth: wallpaperLayout.cellWidth - 20 + implicitHeight: wallpaperLayout.cellHeight - 20 + Image { + id: wallpaper + anchors.fill: parent + source: wallTile.modelData.filePath + sourceSize.width: 16 * 30 + sourceSize.height: 9 * 30 + asynchronous: true + cache: true + } + MouseArea { + id: wpClickHandler + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + acceptedButtons: Qt.LeftButton + hoverEnabled: true + onClicked: { + Config.wallpaper = wallTile.modelData.filePath; + } + } + } + } + FolderListModel { + id: wallpaperList + folder: Config.wallDir + nameFilters: ["*.png"] + } + } + } +} diff --git a/modules/wallpaper/WallPicker.qml~ b/modules/wallpaper/WallPicker.qml~ new file mode 100644 index 0000000..feeb973 --- /dev/null +++ b/modules/wallpaper/WallPicker.qml~ @@ -0,0 +1,130 @@ +pragma ComponentBehavior: Bound +import Quickshell +import Quickshell.Wayland +import Quickshell.Widgets +import Quickshell.Hyprland +import QtQuick +import Qt.labs.folderlistmodel 2.11 +import QtQuick.Effects + +import qs +import qs.settings +import qs.widgets + +Rectangle { + id: main + + layer.enabled: true + layer.effect: MultiEffect { + id: dropShadow + source: main + shadowEnabled: true + shadowHorizontalOffset: 4 + shadowVerticalOffset: 2 + shadowOpacity: 0.5 + shadowColor: "#020202" + } + required property real moduleHeight + required property int screenHeight + color: Colors.moduleBg + radius: Config.rounding + implicitWidth: moduleHeight + implicitHeight: moduleHeight + MaterialIcon { + anchors.centerIn: main + text: "\ue1bc" + font.bold: true + } + MouseArea { + id: clickHandler + anchors.fill: main + acceptedButtons: Qt.LeftButton + cursorShape: Qt.PointingHandCursor + onClicked: { + wallPicker.visible = !wallPicker.visible; + } + } + WlrLayershell { + id: wallPicker + visible: false + exclusionMode: ExclusionMode.Ignore + keyboardFocus: WlrKeyboardFocus.OnDemand + implicitHeight: main.screenHeight / 8 + color: 'transparent' + anchors { + bottom: true + left: true + right: true + } + margins { + bottom: 20 + left: 20 + right: 20 + } + HyprlandFocusGrab { + id: grabber + active: wallPicker.visible + windows: [wallPicker] + onCleared: wallPicker.visible = false + } + onVisibleChanged: { + if (wallPicker.visible) + container.forceActiveFocus(); + } + Rectangle { + id: container + focus: true + Keys.onEscapePressed: { + wallPicker.visible = false; + } + anchors.fill: parent + color: Colors.base00 + radius: Config.rounding + GridView { + id: wallpaperLayout + clip: true + snapMode: GridView.SnapOneRow + flow: GridView.FlowTopToBottom + cellHeight: container.height + cellWidth: container.width / 8 + anchors.fill: parent + anchors.centerIn: parent + anchors.margins: 10 + model: wallpaperList + delegate: ClippingRectangle { + id: wallTile + clip: true + required property var modelData + radius: Config.rounding / 1.5 + color: 'transparent' + implicitWidth: wallpaperLayout.cellWidth - 20 + implicitHeight: wallpaperLayout.cellHeight - 20 + Image { + id: wallpaper + anchors.fill: parent + source: wallTile.modelData.filePath + sourceSize.width: 16 * 30 + sourceSize.height: 9 * 30 + asynchronous: true + cache: true + } + MouseArea { + id: wpClickHandler + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + acceptedButtons: Qt.LeftButton + hoverEnabled: true + onClicked: { + Config.wallpaper = wallTile.modelData.filePath; + } + } + } + } + FolderListModel { + id: wallpaperList + folder: Config.wallDir + nameFilters: ["*.png"] + } + } + } +} diff --git a/modules/wallpaper/Wallpaper.qml b/modules/wallpaper/Wallpaper.qml new file mode 100644 index 0000000..966c7ff --- /dev/null +++ b/modules/wallpaper/Wallpaper.qml @@ -0,0 +1,27 @@ +import Quickshell.Wayland +import Quickshell +import QtQuick +import qs.settings + +Variants { + model: Quickshell.screens + delegate: WlrLayershell { + id: root + layer: WlrLayer.Background + required property ShellScreen modelData + screen: modelData + exclusionMode: ExclusionMode.Ignore + + anchors { + top: true + bottom: true + left: true + right: true + } + Image { + cache: false + anchors.fill: parent + source: Config.wallpaper + } + } +} diff --git a/settings/Config.qml b/settings/Config.qml new file mode 100644 index 0000000..f492035 --- /dev/null +++ b/settings/Config.qml @@ -0,0 +1,34 @@ +pragma Singleton +import QtCore +import QtQuick +import Quickshell + +Singleton { + id: root + property string font: "Maple Mono" + property int fontSize: 12 + property int iconSize: 14 + property int barHeight: 30 + property int rounding: 16 + property url wallpaper: "file:///home/lucy/.walls/frierensuff.png" + property bool floating: false + property double opacity: 1.0 + property string primaryMon: "eDP-1" + property string wallDir: "file://" + Quickshell.env("HOME") + "/.walls" + property bool showCorners: true + property real moduleHeight: barHeight - 8 + Settings { + location: Qt.resolvedUrl("file:///home/lucy/.config/quickshell/settings/settings.ini") + property alias font: root.font + property alias fontSize: root.fontSize + property alias barHeight: root.barHeight + property alias rounding: root.rounding + property alias wallpaper: root.wallpaper + property alias opacity: root.opacity + property alias primaryMon: root.primaryMon + property alias floating: root.floating + property alias wallDir: root.wallDir + property alias showCorners: root.showCorners + property alias iconSize: root.iconSize + } +} diff --git a/settings/settings.ini b/settings/settings.ini new file mode 100644 index 0000000..c46fe67 --- /dev/null +++ b/settings/settings.ini @@ -0,0 +1,12 @@ +[General] +barHeight=30 +floating=false +font=Iosevka +fontSize=16 +iconSize=14 +opacity=1 +primaryMon=eDP-1 +rounding=16 +showCorners=true +wallDir=file:///home/lucy/.walls +wallpaper=@Variant(\0\0\0\x11\0\0\0\x1b/home/lucy/.walls/asuka.png) diff --git a/settings/settings.ini~ b/settings/settings.ini~ new file mode 100644 index 0000000..3bd7b0b --- /dev/null +++ b/settings/settings.ini~ @@ -0,0 +1,12 @@ +[General] +barHeight=30 +floating=false +font=Maple Mono +fontSize=12 +iconSize=14 +opacity=1 +primaryMon=eDP-1 +rounding=16 +showCorners=true +wallDir=file:///home/lucy/.walls +wallpaper=@Variant(\0\0\0\x11\0\0\0(file:///home/lucy/.walls/frierensuff.png) diff --git a/shell.qml b/shell.qml new file mode 100644 index 0000000..52a3fd4 --- /dev/null +++ b/shell.qml @@ -0,0 +1,9 @@ +import Quickshell +import qs.modules.bar +import qs.modules.wallpaper + + +ShellRoot { + Bar {} + Wallpaper {} +} diff --git a/shell.qml~ b/shell.qml~ new file mode 100644 index 0000000..c84cbb6 --- /dev/null +++ b/shell.qml~ @@ -0,0 +1,6 @@ +import Quickshell + + +ShellRoot { + +} diff --git a/widgets/BarComponent.qml b/widgets/BarComponent.qml new file mode 100644 index 0000000..5e7f1cf --- /dev/null +++ b/widgets/BarComponent.qml @@ -0,0 +1,10 @@ +import Quickshell +import QtQuick +import qs +import qs.settings + +Rectangle { + property bool active: false + color: active ? Colors.activeModuleBg : Colors.moduleBg + implicitHeight: Config.moduleHeight +} diff --git a/widgets/BarComponent.qml~ b/widgets/BarComponent.qml~ new file mode 100644 index 0000000..940d0fd --- /dev/null +++ b/widgets/BarComponent.qml~ @@ -0,0 +1,11 @@ +import Quickshell +import QtQuick + + + + +Rectangle { + property bool active: false + color: active ? Colors.activeModuleBg : Colors.moduleBg + implicitHeight: Config.moduleHeight +} diff --git a/widgets/MaterialIcon.qml b/widgets/MaterialIcon.qml new file mode 100644 index 0000000..0a4b33d --- /dev/null +++ b/widgets/MaterialIcon.qml @@ -0,0 +1,16 @@ +import qs +import qs.settings +import QtQuick + +Text { + font.family: "Material Symbols Outlined" + color: Colors.text + font.pointSize: Config.iconSize + property bool fill: false + renderType: Text.NativeRendering + font.variableAxes: { + "FILL": fill ? 1 : 0, + "opsz": 24, + "wght": 400 + } +} diff --git a/widgets/StyledText.qml b/widgets/StyledText.qml new file mode 100644 index 0000000..117d6ba --- /dev/null +++ b/widgets/StyledText.qml @@ -0,0 +1,9 @@ +import QtQuick +import qs +import qs.settings + +Text { + color: Colors.text + font.family: Config.font + font.pixelSize: Config.fontSize +} diff --git a/widgets/StyledText.qml~ b/widgets/StyledText.qml~ new file mode 100644 index 0000000..eee9fef --- /dev/null +++ b/widgets/StyledText.qml~ @@ -0,0 +1,10 @@ +import QtQuick +import qs +import qs.settings + +Text { + color: Colors.text + anchors.verticalCenter: parent.verticalCenter + font.family: Config.font + font.pixelSize: Config.fontSize +} diff --git a/widgets/barComponent.qml~ b/widgets/barComponent.qml~ new file mode 100644 index 0000000..df46f52 --- /dev/null +++ b/widgets/barComponent.qml~ @@ -0,0 +1,9 @@ +import Quickshell +import QtQuick + + + + +Rectangle { + color: Colors.moduleBg +}