fix wallpaper management and several other issues to have errorless startup

This commit is contained in:
lucy 2025-12-28 01:45:57 +01:00
parent b63dc47f22
commit 60b95f221b
12 changed files with 73 additions and 85 deletions

View File

@ -5,25 +5,25 @@ import Quickshell
Singleton { Singleton {
id: customColors id: customColors
// Core Backgrounds // Core Backgrounds
readonly property color background: "#24283B" readonly property color background: "#272E33"
readonly property color foreground: "#C0CAF5" readonly property color foreground: "#D3C6AA"
readonly property color cursor: "#C0CAF5" readonly property color cursor: "#D3C6AA"
// The 16 Colors of the Apocalypse // The 16 Colors of the Apocalypse
readonly property color color0: "#414868" readonly property color color0: "#2E383C"
readonly property color color1: "#F7768E" readonly property color color1: "#E67E80"
readonly property color color2: "#9ECE6A" readonly property color color2: "#A7C080"
readonly property color color3: "#E0AF68" readonly property color color3: "#DBBC7F"
readonly property color color4: "#7AA2F7" readonly property color color4: "#7FBBB3"
readonly property color color5: "#BB9AF7" readonly property color color5: "#D699B6"
readonly property color color6: "#7DCFFF" readonly property color color6: "#83C092"
readonly property color color7: "#C0CAF5" readonly property color color7: "#D3C6AA"
readonly property color color8: "#414868" readonly property color color8: "#5C6A72"
readonly property color color9: "#F7768E" readonly property color color9: "#F85552"
readonly property color color10: "#9ECE6A" readonly property color color10: "#8DA101"
readonly property color color11: "#E0AF68" readonly property color color11: "#DFA000"
readonly property color color12: "#7AA2F7" readonly property color color12: "#3A94C5"
readonly property color color13: "#BB9AF7" readonly property color color13: "#DF69BA"
readonly property color color14: "#7DCFFF" readonly property color color14: "#35A77C"
readonly property color color15: "#C0CAF5" readonly property color color15: "#DFDDC8"
} }

View File

@ -14,8 +14,8 @@ Item {
font.pixelSize: Appearance.fontSize font.pixelSize: Appearance.fontSize
anchors.centerIn: parent anchors.centerIn: parent
MouseArea { MouseArea {
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton acceptedButtons: Qt.LeftButton | Qt.RightButton
cursorShape: Qt.OpenHandCursor
anchors.fill: parent anchors.fill: parent
onClicked: mouse => { onClicked: mouse => {
const modes = [PowerProfile.PowerSaver, PowerProfile.Balanced, PowerProfile.Performance]; const modes = [PowerProfile.PowerSaver, PowerProfile.Balanced, PowerProfile.Performance];

View File

@ -2,7 +2,7 @@ import QtQuick
import Quickshell.Services.Pipewire import Quickshell.Services.Pipewire
import Quickshell.Widgets import Quickshell.Widgets
import Quickshell.Io import Quickshell.Io
import qs import "../../"
Item { Item {
id: root id: root
@ -16,11 +16,9 @@ Item {
} }
MouseArea { MouseArea {
cursorShape: Qt.OpenHandCursor cursorShape: Qt.PointingHandCursor
onClicked: mouse => { onClicked: mouse => {
if (mouse.button === Qt.LeftButton) { if (mouse.button === Qt.LeftButton) {
// Left Click: Summon the Mixer!
console.log("Summoning Pavucontrol... Nya!");
pavu.startDetached(); pavu.startDetached();
} }
} }
@ -61,27 +59,19 @@ Item {
width: 12 width: 12
height: 12 height: 12
// The magic: 'image://theme/' pulls from your system icon theme (Papirus, Adwaita, etc.)
source: "root:/icons/" + root.getVolumeIcon() + "-symbolic.svg" source: "root:/icons/" + root.getVolumeIcon() + "-symbolic.svg"
// Optional: Tint the icon if your theme needs it
// sourceSize: Qt.size(24, 24)
} }
Text { Text {
PwObjectTracker { PwObjectTracker {
objects: Pipewire.ready ? Pipewire.defaultAudioSink : []
objects: Pipewire.defaultAudioSink
} }
anchors.verticalCenter: parent.verticalCenter
width: 20 width: 20
font.weight: 900 font.weight: 900
color: Colors.foreground color: Colors.foreground
font.family: Appearance.font font.family: Appearance.font
font.pixelSize: Appearance.fontSize font.pixelSize: Appearance.fontSize
text: Math.round(Pipewire.defaultAudioSink.audio.volume * 100) + "%" text: Pipewire.ready ? Math.round(Pipewire.defaultAudioSink.audio.volume * 100) + "%" : "0%"
} }
// Click to toggle mute! (Bonus feature)
} }
} }

View File

@ -1,11 +1,10 @@
pragma ComponentBehavior: Bound
import Quickshell.Hyprland import Quickshell.Hyprland
import QtQuick import QtQuick
import QtQuick.Layouts import "../../"
import qs
Item { Item {
id: root id: root
property var modelData
implicitWidth: workspaceRow.implicitWidth implicitWidth: workspaceRow.implicitWidth
height: 30 height: 30
Row { Row {
@ -14,9 +13,12 @@ Item {
spacing: 10 // Slightly increase spacing between workspace buttons spacing: 10 // Slightly increase spacing between workspace buttons
Repeater { Repeater {
id: wsRepeater
model: Hyprland.workspaces
anchors.centerIn: parent anchors.centerIn: parent
Rectangle { Rectangle {
id: workspaceNumber id: workspaceNumber
required property var modelData
width: 16 width: 16
height: 16 height: 16
radius: 20 radius: 20
@ -27,11 +29,18 @@ Item {
font.family: Appearance.font font.family: Appearance.font
font.pixelSize: Appearance.fontSize font.pixelSize: Appearance.fontSize
anchors.centerIn: workspaceNumber anchors.centerIn: workspaceNumber
text: modelData.id text: parent.modelData.id
color: modelData.active ? Colors.background : Colors.foreground // Set contrasting color for workspace number color: parent.modelData.active ? Colors.background : Colors.foreground // Set contrasting color for workspace number
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton
cursorShape: Qt.PointingHandCursor
onClicked: {
parent.modelData.activate();
}
}
} }
}
model: Hyprland.workspaces
} }
} }
} }

View File

@ -3,8 +3,8 @@ import QtQuick
import Quickshell import Quickshell
import Quickshell.Wayland import Quickshell.Wayland
import Quickshell.Hyprland import Quickshell.Hyprland
import qs
import "." import "."
import "../../"
import QtQuick.Layouts import QtQuick.Layouts
WlrLayershell { WlrLayershell {
@ -34,7 +34,7 @@ WlrLayershell {
} }
implicitWidth: 300 implicitWidth: 300
implicitHeight: notifList.contentHeight + 10 implicitHeight: notifList.contentHeight + 20
// 2. Layer: Put it ABOVE normal windows // 2. Layer: Put it ABOVE normal windows
layer: WlrLayer.Overlay layer: WlrLayer.Overlay
@ -68,12 +68,12 @@ WlrLayershell {
delegate: Item { delegate: Item {
id: notifyItem id: notifyItem
implicitWidth: ListView.view.width implicitWidth: ListView.view.width
implicitHeight: 60 // Fixed height is usually better for icon layouts implicitHeight: 80 // Fixed height is usually better for icon layouts
required property var modelData required property var modelData
Timer { Timer {
id: timout id: timout
interval: 30000 interval: 3000000
running: true running: true
onRunningChanged: notifyItem.modelData.dismiss() onRunningChanged: notifyItem.modelData.dismiss()
} }
@ -86,6 +86,7 @@ WlrLayershell {
// 2. Use RowLayout to put Image | Text side-by-side // 2. Use RowLayout to put Image | Text side-by-side
RowLayout { RowLayout {
id: fullLayout
anchors.margins: 10 anchors.margins: 10
anchors.fill: parent anchors.fill: parent
spacing: 15 spacing: 15
@ -115,6 +116,7 @@ WlrLayershell {
// 📝 THE TEXT ON THE RIGHT // 📝 THE TEXT ON THE RIGHT
ColumnLayout { ColumnLayout {
id: textLayout
// Take up all remaining width // Take up all remaining width
Layout.fillWidth: true Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter | Qt.AlignTop // Center vertically Layout.alignment: Qt.AlignVCenter | Qt.AlignTop // Center vertically
@ -134,7 +136,7 @@ WlrLayershell {
// Limit to 2 lines // Limit to 2 lines
maximumLineCount: 2 maximumLineCount: 2
wrapMode: Text.WrapAnywhere wrapMode: Text.WordWrap
elide: Text.ElideRight elide: Text.ElideRight
Layout.fillWidth: true Layout.fillWidth: true
} }

View File

@ -2,7 +2,6 @@ pragma ComponentBehavior: Bound
pragma Singleton pragma Singleton
import Quickshell.Services.Notifications import Quickshell.Services.Notifications
import QtQuick import QtQuick
import Quickshell
NotificationServer { NotificationServer {
bodyMarkupSupported: true bodyMarkupSupported: true
@ -10,6 +9,5 @@ NotificationServer {
imageSupported: true imageSupported: true
onNotification: notification => { onNotification: notification => {
notification.tracked = true; notification.tracked = true;
console.log("got notification!!! arf woof");
} }
} }

View File

@ -5,8 +5,8 @@ import "../../"
import "." import "."
WlrLayershell { WlrLayershell {
required property var modelData
id: overlayRoot id: overlayRoot
required property var modelData
// 1. Fill the entire screen // 1. Fill the entire screen
anchors { anchors {

View File

@ -1,3 +1,4 @@
pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Shapes import QtQuick.Shapes
@ -49,7 +50,7 @@ Item {
readonly property real screenHeight: cornersShape.height readonly property real screenHeight: cornersShape.height
strokeWidth: -1 // No outline strokeWidth: -1 // No outline
fillColor: cornerColor fillColor: root.cornerColor
// Smooth fade if you toggle it // Smooth fade if you toggle it

View File

@ -1,16 +1,15 @@
pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import Qt.labs.folderlistmodel 2.15 // <--- The magic file scanner! import Qt.labs.folderlistmodel 2.15 // <--- The magic file scanner!
import Quickshell import Quickshell
import Quickshell.Hyprland import Quickshell.Hyprland
import Quickshell.Io import Quickshell.Io
import "." import "../../"
import qs.modules.bar
import qs
FloatingWindow { FloatingWindow {
id: root id: root
title: "quickshell-WallSwitcher" title: "quickshell-WallSwitcher"
visible: true visible: false
implicitWidth: 840 implicitWidth: 840
implicitHeight: 640 implicitHeight: 640
@ -21,8 +20,6 @@ FloatingWindow {
onPressed: { onPressed: {
// Toggle visibility! // Toggle visibility!
root.visible = !root.visible; root.visible = !root.visible;
console.log("Shortcut pressed! Switcher is now: " + (root.visible ? "Visible" : "Hidden"));
} }
} }
@ -63,19 +60,20 @@ FloatingWindow {
model: folderModel model: folderModel
delegate: Item { delegate: Item {
required property var modelData
width: 200 width: 200
height: 100 height: 100
Image { Image {
id: wallImage
width: 180 width: 180
height: 90 height: 90
anchors.centerIn: parent anchors.centerIn: parent
// "fileUrl" is provided by FolderListModel // "fileUrl" is provided by FolderListModel
source: fileUrl source: parent.modelData.fileUrl
// IMPORTANT: Downscale the image for the thumbnail! // IMPORTANT: Downscale the image for the thumbnail!
// If you don't do this, loading 50 4K images will eat your RAM // If you don't do this, loading 50 4K images will eat your RAM
// faster than Chrome eats memory! 🙀
sourceSize.width: 140 sourceSize.width: 140
sourceSize.height: 90 sourceSize.height: 90
@ -83,18 +81,11 @@ FloatingWindow {
} }
MouseArea { MouseArea {
Process {
id: generateScheme
property string cleanPath: fileUrl.toString().replace("file://", "")
command: ["wallust", "run", cleanPath]
}
anchors.fill: parent anchors.fill: parent
onClicked: { onClicked: {
let cleanPath = fileUrl.toString().replace("file://", ""); let cleanPath = parent.modelData.fileUrl.toString().replace("file://", "");
// Update the Singleton! // Update the Singleton!
WallpaperStore.currentWall = fileUrl.toString(); WallpaperStore.currentWall = parent.modelData.fileUrl.toString();
//generateScheme.startDetached();
console.log(generateScheme.stdout);
} }
} }
} }

View File

@ -1,3 +1,4 @@
pragma ComponentBehavior: Bound
import QtQuick import QtQuick
import QtQuick.Controls // <--- Needed for StackView import QtQuick.Controls // <--- Needed for StackView
import Quickshell import Quickshell
@ -28,17 +29,12 @@ WlrLayershell {
id: wallComponent id: wallComponent
Image { Image {
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
width: root.width width: wallStack.width
height: root.height height: wallStack.height
asynchronous: true // VERY IMPORTANT: Prevents lag while loading! asynchronous: true // VERY IMPORTANT: Prevents lag while loading!
} }
} }
// 3. Load the initial wallpaper immediately (No animation on boot)
initialItem: wallComponent.createObject(wallStack, {
"source": WallpaperStore.currentWall
})
// 4. THE ANIMATIONS 🎬 // 4. THE ANIMATIONS 🎬
// When a new wall replaces the old one: // When a new wall replaces the old one:

2
qmldir Normal file
View File

@ -0,0 +1,2 @@
singleton Colors 1.0 Colors.qml
singleton Appearance 1.0 Appearance.qml

View File

@ -22,12 +22,11 @@ ShellRoot {
} }
} }
Variants { Variants {
model: Quickshell.screens
id: wallVariants id: wallVariants
model: Quickshell.screens
delegate: Wallpaper { delegate: Wallpaper {
screen: modelData screen: modelData
} }
} }
NotiPopup {} NotiPopup {}
} }