Merge pull request #4 from Zacharias-Brohn/wallpaperPicker

Wallpaper picker
This commit was merged in pull request #4.
This commit is contained in:
Zach
2025-11-12 20:29:57 +01:00
committed by GitHub
13 changed files with 456 additions and 220 deletions
+2
View File
@@ -8,6 +8,7 @@ Singleton {
property alias appCount: adapter.appCount
property alias baseBgColor: adapter.baseBgColor
property alias accentColor: adapter.accentColor
property alias wallpaperPath: adapter.wallpaperPath
FileView {
id: root
@@ -23,6 +24,7 @@ Singleton {
JsonAdapter {
id: adapter
property int appCount: 20
property string wallpaperPath: Quickshell.env("HOME") + "/Pictures/Wallpapers"
property string baseBgColor: "#801a1a1a"
property AccentColor accentColor: AccentColor {}
}
+22
View File
@@ -0,0 +1,22 @@
pragma Singleton
import Quickshell.Io
import Quickshell
Singleton {
function getInitialTitle(callback) {
initialTitleProc.running = true
initialTitleProc.stdout.streamFinished.connect( function() {
let cleaned = initialTitleProc.stdout.text.trim().replace(/\"/g, "")
callback(cleaned === "null" ? "" : cleaned)
})
}
Process {
id: initialTitleProc
command: ["./scripts/initialTitle.sh"]
running: false
stdout: StdioCollector {
}
}
}
+35
View File
@@ -0,0 +1,35 @@
pragma Singleton
import Quickshell
import Quickshell.Io
import qs.Config
import qs.Modules
import Caelestia.Models
Searcher {
id: root
list: wallpapers.entries
key: "relativePath"
useFuzzy: true
extraOpts: useFuzzy ? ({}) : ({
forward: false
})
// FileView {
// path: root.currentNamePath
// watchChanges: true
// onFileChanged: reload()
// onLoaded: {
// root.actualCurrent = text().trim();
// }
// }
FileSystemModel {
id: wallpapers
recursive: true
path: Config.wallpaperPath
filter: FileSystemModel.Images
}
}
+23
View File
@@ -0,0 +1,23 @@
pragma Singleton
import Quickshell
import Quickshell.Io
Singleton {
id: root
property alias currentWallpaperPath: adapter.currentWallpaperPath
FileView {
id: fileView
path: Quickshell.env("HOME") + "/.local/state/z-bar/wallpaper_path.json"
watchChanges: true
onFileChanged: reload()
onAdapterUpdated: writeAdapter()
JsonAdapter {
id: adapter
property string currentWallpaperPath: ""
}
}
}
+15 -4
View File
@@ -1,6 +1,7 @@
import Quickshell
import QtQuick
import QtQuick.Controls
import qs.Helpers
TextField {
id: root
@@ -63,15 +64,25 @@ TextField {
Keys.onPressed: {
if ( event.key === Qt.Key_Down ) {
appListView.decrementCurrentIndex();
if ( appListLoader.active ) {
appListLoader.item.decrementCurrentIndex();
} else {
wallpaperPickerLoader.item.decrementCurrentIndex();
}
event.accepted = true;
} else if ( event.key === Qt.Key_Up ) {
appListView.incrementCurrentIndex();
if ( appListLoader.active ) {
appListLoader.item.incrementCurrentIndex();
} else {
wallpaperPickerLoader.item.incrementCurrentIndex();
}
event.accepted = true;
} else if ( event.key === Qt.Key_Return || event.key === Qt.Key_Enter ) {
if ( appListView.currentItem ) {
Search.launch(appListView.currentItem.modelData);
if ( appListLoader.active ) {
Search.launch(appListLoader.item.currentItem.modelData);
launcherWindow.visible = false;
} else if ( wallpaperPickerLoader.active ) {
WallpaperPath.currentWallpaperPath = wallpaperPickerLoader.item.currentItem.modelData.path;
}
event.accepted = true;
} else if ( event.key === Qt.Key_Escape ) {
+115 -11
View File
@@ -6,6 +6,7 @@ import QtQuick.Controls
import QtQuick.Effects
import QtQuick.Layouts
import qs.Config
import qs.Helpers
Scope {
id: root
@@ -54,7 +55,7 @@ Scope {
Rectangle {
id: shadowRect
anchors {
top: appListView.count > 0 ? appListRect.top : backgroundRect.top
top: appListRect.top
bottom: backgroundRect.bottom
left: appListRect.left
right: appListRect.right
@@ -84,7 +85,7 @@ Scope {
anchors.bottom: parent.bottom
anchors.bottomMargin: -1
implicitHeight: mainLayout.childrenRect.height + 20
implicitWidth: 600
implicitWidth: appListRect.implicitWidth
x: Math.round(( parent.width - width ) / 2 )
color: "#d01a1a1a"
opacity: 1
@@ -99,7 +100,7 @@ Scope {
easing.bezierCurve: MaterialEasing.expressiveDefaultSpatial
property: "implicitHeight"
from: 40
to: appListView.implicitHeight + 20
to: appListContainer.implicitHeight + 20
}
Anim {
target: appListRect
@@ -134,7 +135,7 @@ Scope {
duration: MaterialEasing.expressiveFastSpatialTime
easing.bezierCurve: MaterialEasing.expressiveDefaultSpatial
property: "implicitHeight"
from: appListView.implicitHeight
from: appListContainer.implicitHeight
to: 40
}
SequentialAnimation {
@@ -187,14 +188,15 @@ Scope {
Rectangle {
id: appListRect
x: Math.round(( parent.width - width ) / 2 )
implicitWidth: backgroundRect.implicitWidth
implicitHeight: appListView.implicitHeight + 20
implicitWidth: appListContainer.implicitWidth + 20
implicitHeight: appListContainer.implicitHeight + 20
anchors.bottom: backgroundRect.top
anchors.bottomMargin: -1
color: backgroundRect.color
topRightRadius: 8
topLeftRadius: 8
border.color: backgroundRect.border.color
clip: true
Behavior on implicitHeight {
Anim {
@@ -203,12 +205,93 @@ Scope {
}
}
Behavior on implicitWidth {
Anim {
duration: MaterialEasing.expressiveFastSpatialTime
easing.bezierCurve: MaterialEasing.expressiveDefaultSpatial
}
}
Item {
anchors.fill: parent
visible: appListView.count > 0
anchors.margins: 10
anchors.centerIn: parent
id: appListContainer
visible: true
clip: true
ListView {
property var showWallpapers: searchInput.text.startsWith(">")
state: showWallpapers ? "wallpaperpicker" : "apps"
states: [
State {
name: "apps"
PropertyChanges {
appListLoader.active: true
appListContainer.implicitHeight: appListLoader.implicitHeight
appListContainer.implicitWidth: 600
}
},
State {
name: "wallpaperpicker"
PropertyChanges {
wallpaperPickerLoader.active: true
appListContainer.implicitHeight: wallpaperPickerLoader.implicitHeight
appListContainer.implicitWidth: wallpaperPickerLoader.implicitWidth
}
}
]
Loader {
id: wallpaperPickerLoader
active: false
anchors.fill: parent
sourceComponent: PathView {
id: wallpaperPickerView
anchors.fill: parent
model: ScriptModel {
id: wallpaperModel
readonly property string search: searchInput.text.split(" ").slice(1).join(" ")
values: SearchWallpapers.query( search )
}
cacheItemCount: 5
snapMode: PathView.SnapToItem
preferredHighlightBegin: 0.5
preferredHighlightEnd: 0.5
highlightRangeMode: PathView.StrictlyEnforceRange
pathItemCount: 7
implicitHeight: 212
implicitWidth: Math.min( wallpaperModel.values.length, 7 ) * 192 + Math.max(0, wallpaperModel.values.length -1) * 10
path: Path {
startY: wallpaperPickerView.height / 2
PathAttribute {
name: "z"
value: 0
}
PathLine {
x: wallpaperPickerView.width / 2
relativeY: 0
}
PathAttribute {
name: "z"
value: 1
}
PathLine {
x: wallpaperPickerView.width
relativeY: 0
}
}
focus: true
delegate: WallpaperItem { }
}
}
Loader {
id: appListLoader
active: false
anchors.fill: parent
sourceComponent: ListView {
id: appListView
anchors.fill: parent
model: ScriptModel {
@@ -246,7 +329,14 @@ Scope {
property list<var> search: Search.search( searchInput.text )
state: search.length === 0 ? "noresults" : "apps"
state: {
const text = searchInput.text
if ( search.length === 0 ) {
return "noresults"
} else {
return "apps"
}
}
states: [
State {
@@ -263,6 +353,14 @@ Scope {
appListView.delegate: noResultsItem
}
}
// State {
// name: "wallpaperpicker"
// PropertyChanges {
// appModel.values: SearchWallpapers.query( searchInput.text.split(" ").slice(1).join(" ") )
// appListView.delegate: wallpaperItem
// appListView.orientation: ListView.Horizontal
// }
// }
]
Component {
@@ -307,6 +405,11 @@ Scope {
}
}
Component {
id: wallpaperItem
WallpaperItem { }
}
transitions: Transition {
SequentialAnimation {
ParallelAnimation {
@@ -422,3 +525,4 @@ Scope {
}
}
}
}
+2
View File
@@ -143,6 +143,8 @@ PanelWindow {
Layout.fillWidth: true
text: "Do Not Disturb"
focus: false
activeFocusOnTab: false
focusPolicy: Qt.NoFocus
}
RowLayout {
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
+3 -1
View File
@@ -59,8 +59,10 @@ MouseArea {
if ( mouse.button === Qt.LeftButton ) {
root.item.activate();
} else if ( mouse.button === Qt.RightButton ) {
trayMenu.visible = !trayMenu.visible;
if ( root.item?.menu !== trayMenu.trayMenu ) {
trayMenu.trayMenu = root.item?.menu;
}
trayMenu.visible = !trayMenu.visible;
trayMenu.focusGrab = true;
}
}
+4 -4
View File
@@ -163,15 +163,15 @@ PanelWindow {
Behavior on implicitWidth {
NumberAnimation {
duration: MaterialEasing.standardTime
easing.bezierCurve: MaterialEasing.standard
duration: MaterialEasing.expressiveEffectsTime
easing.bezierCurve: MaterialEasing.expressiveEffects
}
}
Behavior on implicitHeight {
NumberAnimation {
duration: MaterialEasing.standardTime
easing.bezierCurve: MaterialEasing.standard
duration: MaterialEasing.expressiveEffectsTime
easing.bezierCurve: MaterialEasing.expressiveEffects
}
}
+44
View File
@@ -0,0 +1,44 @@
import Quickshell
import Quickshell.Widgets
import QtQuick
import Caelestia.Models
Item {
id: root
required property FileSystemEntry modelData
implicitWidth: 288
implicitHeight: 162
scale: 0.5
opacity: 0
z: PathView.z ?? 0
Component.onCompleted: {
scale = Qt.binding(() => PathView.isCurrentItem ? 1 : PathView.onPath ? 0.8 : 0);
opacity = Qt.binding(() => PathView.onPath ? 1 : 0);
}
ClippingRectangle {
anchors.fill: parent
radius: 8
color: "#10FFFFFF"
Image {
id: thumbnailImage
asynchronous: true
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
source: root.modelData.path
sourceSize.width: 960
sourceSize.height: 540
}
}
Behavior on scale {
Anim {}
}
Behavior on opacity {
Anim {}
}
}
+4 -14
View File
@@ -1,7 +1,7 @@
import QtQuick
import QtQuick.Layouts
import Quickshell.Io
import Quickshell.Hyprland
import qs.Helpers
Item {
id: root
@@ -12,22 +12,12 @@ Item {
property bool showFirst: true
Process {
id: initialTitleProc
command: ["./scripts/initialTitle.sh"]
running: false
stdout: StdioCollector {
onStreamFinished: {
let cleaned = this.text.trim().replace(/\"/g, "")
root.currentTitle = ( cleaned === "null" ) ? "" : cleaned
}
}
}
Component.onCompleted: {
Hyprland.rawEvent.connect(( event ) => {
if (event.name === "activewindow") {
initialTitleProc.running = true
InitialTitle.getInitialTitle( function( initialTitle ) {
root.currentTitle = initialTitle
})
}
})
}
+3 -2
View File
@@ -1,6 +1,7 @@
import Quickshell
import QtQuick
import Quickshell.Wayland
import qs.Helpers
Scope {
Variants {
@@ -21,8 +22,8 @@ Scope {
Image {
id: wallpaperImage
anchors.fill: parent
source: "/mnt/IronWolf/SDImages/SWWW_Wals/ComfyUI_00037_.png"
fillMode: Image.PreserveAspectFit
source: WallpaperPath.currentWallpaperPath
fillMode: Image.PreserveAspectCrop
}
}
}
+1 -1
View File
@@ -5,7 +5,7 @@ import qs.Modules
Scope {
Bar {}
// Wallpaper {}
Wallpaper {}
NotifServer {}
Launcher {}
}