Compare commits

..
16 changed files with 244 additions and 25 deletions

View file

@ -31,7 +31,7 @@ Singleton {
watchChanges: true watchChanges: true
onAdapterUpdated: reload() onAdapterUpdated: reload()
onAdapterChanged: reload() onAdapterChanged: reload()
blockLoading: true // colors resolved before first paint, no flash of defaults blockLoading: true
property alias base00: palette.base00 property alias base00: palette.base00
property alias base01: palette.base01 property alias base01: palette.base01
property alias base02: palette.base02 property alias base02: palette.base02
@ -51,7 +51,6 @@ Singleton {
JsonAdapter { JsonAdapter {
id: palette id: palette
// strings, not colors — QML coerces "#rrggbb" -> color at the readonly props above
property string base00 property string base00
property string base01 property string base01
property string base02 property string base02

View file

@ -1,3 +1,4 @@
pragma ComponentBehavior: Bound
import Quickshell.Widgets import Quickshell.Widgets
import Quickshell.Hyprland import Quickshell.Hyprland
import QtQuick import QtQuick
@ -5,13 +6,24 @@ import QtQuick.Layouts
import qs import qs
import qs.widgets import qs.widgets
import qs.settings import qs.settings
import QtQuick.Effects
Rectangle { Rectangle {
id: root id: root
required property double moduleHeight required property double moduleHeight
layer.enabled: true
layer.effect: MultiEffect {
id: dropShadow
source: root
shadowEnabled: true
shadowHorizontalOffset: 4
shadowVerticalOffset: 2
shadowOpacity: 0.5
shadowColor: "#020202"
}
implicitHeight: moduleHeight implicitHeight: moduleHeight
implicitWidth: titleLayout.width + 32 implicitWidth: titleLayout.width + 32
color: Colors.base01 color: Colors.base02
radius: Config.rounding radius: Config.rounding
RowLayout { RowLayout {
id: titleLayout id: titleLayout

View file

@ -5,6 +5,7 @@ import Quickshell.Wayland
import qs import qs
import qs.settings import qs.settings
import qs.modules.wallpaper
Variants { Variants {
model: Quickshell.screens model: Quickshell.screens
@ -45,21 +46,25 @@ Variants {
moduleHeight: root.moduleHeight moduleHeight: root.moduleHeight
} }
} }
Item {
id: middleItem
anchors.centerIn: parent
implicitWidth: centerLayout.width
implicitHeight: centerLayout.height
RowLayout { RowLayout {
id: centerLayout id: centerLayout
anchors.centerIn: parent
spacing: 5 spacing: 5
Clock { Clock {
moduleHeight: root.moduleHeight moduleHeight: root.moduleHeight
} }
} }
}
RowLayout { RowLayout {
id: rightLayout id: rightLayout
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
spacing: 5 spacing: 15
anchors.rightMargin: Config.floating ? (Config.barHeight - root.moduleHeight) / 2 : Config.rounding anchors.rightMargin: Config.floating ? (Config.barHeight - root.moduleHeight) / 2 : Config.rounding
Mpris { Mpris {
moduleHeight: root.moduleHeight moduleHeight: root.moduleHeight
@ -73,6 +78,10 @@ Variants {
Tray { Tray {
moduleHeight: root.moduleHeight moduleHeight: root.moduleHeight
} }
WallpaperPicker {
moduleHeight: root.moduleHeight
screenHeight: root.modelData.height
}
} }
} }
} }

View file

@ -1,15 +1,25 @@
import Quickshell.Widgets
import Quickshell.Services.UPower import Quickshell.Services.UPower
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Effects
import qs import qs
import qs.widgets import qs.widgets
import qs.settings import qs.settings
Rectangle { Rectangle {
id: root 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 clip: true
color: Colors.base01 color: Colors.base02
visible: UPower.displayDevice.isLaptopBattery visible: UPower.displayDevice.isLaptopBattery
property double percent: UPower.displayDevice.percentage * 100 property double percent: UPower.displayDevice.percentage * 100
property bool hasBattery: UPower.displayDevice.isLaptopBattery property bool hasBattery: UPower.displayDevice.isLaptopBattery

View file

@ -1,16 +1,28 @@
pragma ComponentBehavior: Bound
import Quickshell import Quickshell
import QtQuick import QtQuick
import QtQuick.Effects
import qs import qs
import qs.widgets import qs.widgets
import qs.settings import qs.settings
Rectangle { Rectangle {
id: root 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 clip: true
required property double moduleHeight required property double moduleHeight
implicitHeight: moduleHeight implicitHeight: moduleHeight
implicitWidth: clockText.implicitWidth + 32 implicitWidth: clockText.implicitWidth + 32
color: Colors.base01 color: Colors.base02
radius: Config.rounding radius: Config.rounding
SystemClock { SystemClock {
id: clock id: clock
@ -19,6 +31,6 @@ Rectangle {
StyledText { StyledText {
id: clockText id: clockText
anchors.centerIn: root anchors.centerIn: root
text: Qt.formatDateTime(clock.date, "d.M.yy - hh:mm:s") text: Qt.formatDateTime(clock.date, "d.M.yy - hh:mm:ss")
} }
} }

View file

@ -1,13 +1,24 @@
pragma ComponentBehavior: Bound
import Quickshell.Services.Mpris import Quickshell.Services.Mpris
import Quickshell.Widgets
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Effects
import qs import qs
import qs.widgets import qs.widgets
import qs.settings import qs.settings
Rectangle { Rectangle {
id: root 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 required property double moduleHeight
implicitHeight: moduleHeight implicitHeight: moduleHeight
implicitWidth: songLayout.implicitWidth + 32 implicitWidth: songLayout.implicitWidth + 32
@ -20,7 +31,7 @@ Rectangle {
} }
visible: spotify !== null && spotify.playbackState === MprisPlaybackState.Playing visible: spotify !== null && spotify.playbackState === MprisPlaybackState.Playing
clip: true clip: true
color: Colors.base01 color: Colors.base02
radius: Config.rounding radius: Config.rounding
RowLayout { RowLayout {
id: songLayout id: songLayout

View file

@ -1,14 +1,26 @@
pragma ComponentBehavior: Bound
import Quickshell.Services.Pipewire import Quickshell.Services.Pipewire
import Quickshell.Io import Quickshell.Io
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Effects
import qs import qs
import qs.widgets import qs.widgets
import qs.settings import qs.settings
Rectangle { Rectangle {
id: root id: root
color: clickHandler.containsMouse ? Colors.base02 : Colors.base01 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.base03 : Colors.base02
property PwNode defaultAudio: Pipewire.ready ? Pipewire.defaultAudioSink : null property PwNode defaultAudio: Pipewire.ready ? Pipewire.defaultAudioSink : null
property bool mute: Pipewire.ready ? defaultAudio?.audio.muted : null property bool mute: Pipewire.ready ? defaultAudio?.audio.muted : null
radius: Config.rounding radius: Config.rounding

View file

@ -4,17 +4,28 @@ import Quickshell.Services.SystemTray
import Quickshell.Widgets import Quickshell.Widgets
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Effects
import qs import qs
import qs.settings import qs.settings
Rectangle { Rectangle {
id: root id: root
layer.enabled: true
layer.effect: MultiEffect {
id: dropShadow
source: root
shadowEnabled: true
shadowHorizontalOffset: 4
shadowVerticalOffset: 2
shadowOpacity: 0.5
shadowColor: "#020202"
}
visible: iconRepeater.count != 0 visible: iconRepeater.count != 0
Layout.fillHeight: true Layout.fillHeight: true
required property double moduleHeight required property double moduleHeight
implicitHeight: moduleHeight implicitHeight: moduleHeight
implicitWidth: iconlayout.width + 16 implicitWidth: iconlayout.width + 16
color: Colors.base01 color: Colors.base02
radius: Config.rounding radius: Config.rounding
RowLayout { RowLayout {

View file

@ -14,7 +14,7 @@ import qs.settings
*/ */
Variants { Variants {
model: Quickshell.screens model: Quickshell.screens
delegate: PanelWindow { delegate: WlrLayershell {
id: root id: root
required property ShellScreen modelData required property ShellScreen modelData
screen: modelData screen: modelData
@ -24,9 +24,11 @@ Variants {
left: true left: true
right: true right: true
} }
margins.top: Config.floating ? 0 : Config.barHeight margins {
top: Config.floating ? 0 : Config.barHeight
}
mask: Region { mask: Region {
item: root item: Item {}
} }
color: 'transparent' color: 'transparent'
exclusionMode: ExclusionMode.Ignore exclusionMode: ExclusionMode.Ignore

View file

@ -36,6 +36,9 @@ IpcHandler {
function floating(toggle: bool) { function floating(toggle: bool) {
Config.floating = toggle Config.floating = toggle
} }
function reload(hard: bool) {
Quickshell.reload(hard)
}
function setWall(newWall: string) { function setWall(newWall: string) {
if (newWall.startsWith("/")) { if (newWall.startsWith("/")) {

View file

@ -13,7 +13,6 @@ WlrLayershell {
for (let i = 0; i < Quickshell.screens.length; i++) { for (let i = 0; i < Quickshell.screens.length; i++) {
current = Quickshell.screens[i]; current = Quickshell.screens[i];
if (Hyprland.monitorFor(current) == Hyprland.focusedMonitor) { if (Hyprland.monitorFor(current) == Hyprland.focusedMonitor) {
console.log(current.name);
return current; return current;
} }
} }

View file

@ -0,0 +1,136 @@
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.base02
radius: Config.rounding
implicitWidth: moduleHeight
implicitHeight: moduleHeight
MaterialIcon {
anchors.centerIn: main
text: "\ue1bc"
font.pixelSize: 16
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();
}
ClippingRectangle {
id: container
focus: true
Keys.onEscapePressed: {
wallPicker.visible = false;
}
anchors.fill: parent
color: Colors.base01
radius: Config.rounding
border.width: 2
border.color: Colors.base0D
GridView {
id: wallpaperLayout
clip: true
snapMode: GridView.SnapOneRow
flow: GridView.FlowTopToBottom
cellHeight: container.height
cellWidth: container.width / 8
anchors.fill: parent
anchors.rightMargin: 10
model: wallpaperList
delegate: ClippingWrapperRectangle {
id: wallTile
margin: 10
required property var modelData
color: 'transparent'
implicitWidth: wallPicker.width / 8
implicitHeight: wallPicker.height
child: ClippingRectangle {
id: wpRounder
color: 'transparent'
radius: Config.rounding / 1.5
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"]
}
}
}
}

View file

@ -5,7 +5,7 @@ import Quickshell
Singleton { Singleton {
id: root id: root
property string font: "Adwaita Mono Nerd Font Propo" property string font: "Maple Mono"
property int fontSize: 12 property int fontSize: 12
property int iconSize: 14 property int iconSize: 14
property int barHeight: 30 property int barHeight: 30
@ -14,6 +14,7 @@ Singleton {
property bool floating: false property bool floating: false
property double opacity: 1.0 property double opacity: 1.0
property string primaryMon: "eDP-1" property string primaryMon: "eDP-1"
property string wallDir: "file://" + Quickshell.env("HOME") + "/.walls"
Settings { Settings {
location: Qt.resolvedUrl("file:///home/lucy/.config/quickshell/settings/settings.ini") location: Qt.resolvedUrl("file:///home/lucy/.config/quickshell/settings/settings.ini")
@ -25,5 +26,6 @@ Singleton {
property alias opacity: root.opacity property alias opacity: root.opacity
property alias primaryMon: root.primaryMon property alias primaryMon: root.primaryMon
property alias floating: root.floating property alias floating: root.floating
property alias wallDir: root.wallDir
} }
} }

View file

@ -12,4 +12,5 @@ ShellRoot {
Ipc {} Ipc {}
Wallpaper {} Wallpaper {}
NotiPopup {} NotiPopup {}
WallpaperPicker {}
} }

View file

@ -4,7 +4,7 @@ import QtQuick
Text { Text {
font.family: "Material Symbols Rounded" font.family: "Material Symbols Rounded"
color: Colors.base07 color: Colors.base05
font.pixelSize: Config.iconSize font.pixelSize: Config.iconSize
property bool fill: true property bool fill: true
renderType: Text.NativeRendering renderType: Text.NativeRendering

View file

@ -5,5 +5,5 @@ import qs.settings
Text { Text {
font.family: Config.font font.family: Config.font
font.pixelSize: Config.fontSize font.pixelSize: Config.fontSize
color: Colors.base07 color: Colors.base05
} }