brightess and volume control

This commit is contained in:
2026-03-26 13:15:54 -07:00
parent 80efc104ed
commit 5b8d82a934
20 changed files with 588 additions and 37 deletions

View File

@@ -15,7 +15,6 @@ WlSessionLock {
id: surface id: surface
color: "transparent" color: "transparent"
Component.onCompleted: console.log("done")
Rectangle { Rectangle {
id: content id: content
anchors.fill: parent anchors.fill: parent

View File

@@ -10,14 +10,13 @@ Column {
width: Math.max(childrenRect.width, 300) width: Math.max(childrenRect.width, 300)
height: childrenRect.height height: childrenRect.height
anchors.topMargin: 6 anchors.topMargin: 6
TapHandler {onTapped: console.log(width)}
Rectangle { Rectangle {
radius: 12 radius: 12
height: 40 height: 40
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.margins: 6 anchors.margins: 6
color: "#181818" color: "#111"
Rectangle { Rectangle {
color: "white" color: "white"
width: (parent.width - anchors.margins * 2)/3 width: (parent.width - anchors.margins * 2)/3
@@ -116,7 +115,7 @@ Column {
id: card id: card
required property var data required property var data
required property var label required property var label
color: "#181818" color: "#111"
height: 60 height: 60
width: 100 width: 100
radius: 12 radius: 12

154
Panes/Brightness.qml Normal file
View File

@@ -0,0 +1,154 @@
import Quickshell
import Quickshell.Io
import Quickshell.Hyprland
import QtQuick
import qs.Services
import qs.Widgets as Widgets
Column {
anchors {
top: parent.top
horizontalCenter: parent.horizontalCenter
margins: 6
}
width: 300
height: childrenRect.height + anchors.margins * 2
spacing: 6
Item {
anchors {
left: parent.left
right: parent.right
margins: 12
}
width: childrenRect.width
height: children[1].height
Image {
anchors {
left: parent.left
verticalCenter: parent.verticalCenter
verticalCenterOffset: 1
}
width: 24
height: width
sourceSize {width: width; height: height}
source: Quickshell.iconPath("brightnesssettings")
}
Text {
anchors {
top: parent.top
left: parent.children[0].right
leftMargin: 6
}
font.pixelSize: 16
color: "white"
text: "Laptop display"
}
}
Widgets.Slider {
anchors {
left: parent.left
right: parent.right
margins: 12
}
height: 24
value: Brightness.monitors[0].value / Brightness.monitors[0].max
onMoved: {
Brightness.monitors[0].set(Math.round(Brightness.monitors[0].max * position))
}
}
component ToggleButton: Item {
id: toggleButton
anchors {
left: parent.left
right: parent.right
margins: 12
}
height: children[0].height
property bool active: false
property var text
Text {
anchors {
left: parent.left
verticalCenter: parent.verticalCenter
}
height: 24
font.pixelSize: 14
color: "white"
text: toggleButton.text
}
Rectangle {
anchors {
right: parent.right
verticalCenter: parent.verticalCenter
rightMargin: (24 - width)/2 + (36-24)/2
}
radius: height/2
color: parent.active ? "white" : "#00ffffff"
height: 10
width: parent.active ? 36 : 24
border.width: parent.active ? height/2 : 2
border.color: "white"
Behavior on width {NumberAnimation { duration: 150; easing.type: Easing.OutCubic }}
Behavior on border.width {NumberAnimation { duration: 150; easing.type: Easing.OutCubic }}
}
}
ToggleButton {
id: sunsetToggle
text: "Night Light"
Process {
running: true
command: [ "pgrep", "-x", "sunset" ]
onExited: (exitCode) => {if (!exitCode) sunsetToggle.active = true}
}
TapHandler {
property var idleProc: Process {command: ["hyprsunset"]}
property var idleKill: Process {command: ["pkill", "-x", "hyprsunset"]}
onTapped: {
parent.active = !parent.active
if (parent.active)
idleProc.startDetached()
else
idleKill.startDetached()
}
}
}
ToggleButton {
id: idleToggle
text: "Idle Timer"
Process {
running: true
command: [ "pgrep", "-x", "hypridle" ]
onExited: (exitCode) => {if (!exitCode) idleToggle.active = true}
}
TapHandler {
property var idleProc: Process {command: ["hypridle"]}
property var idleKill: Process {command: ["pkill", "-x", "hypridle"]}
onTapped: {
parent.active = !parent.active
if (parent.active)
idleProc.startDetached()
else
idleKill.startDetached()
}
}
}
ToggleButton {
id: dpmsToggle
text: "Screen on"
active: true
TapHandler {
property var resetTimer: Timer {
interval: 500
running: false
repeat: false
onTriggered: dpmsToggle.active = true
}
onTapped: {
dpmsToggle.active = false;
Hyprland.dispatch("dpms off");
resetTimer.start();
root.close();
}
}
}
}

View File

@@ -38,7 +38,7 @@ Item {
margins: 6 margins: 6
} }
height: 48 height: 48
color: "#181818" color: "#111"
radius: 10 radius: 10
TextInput { TextInput {
id: input id: input
@@ -95,7 +95,6 @@ Item {
property: "x" property: "x"
duration: 300 duration: 300
easing.type: Easing.OutQuint easing.type: Easing.OutQuint
onStarted: console.log("displaced")
} }
NumberAnimation { NumberAnimation {
property: "opacity" property: "opacity"
@@ -146,7 +145,7 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
width: 64 width: 64
height: width height: width
source: Quickshell.iconPath(modelData.icon) source: Quickshell.iconPath(modelData.icon, "application-default")
} }
Text { Text {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter

View File

@@ -20,7 +20,7 @@ Item {
Rectangle { Rectangle {
width: 400 width: 400
height: 300 height: 300
color: "#181818" color: "#111"
radius: 10 radius: 10
Column { Column {
anchors.centerIn: parent anchors.centerIn: parent
@@ -47,7 +47,6 @@ Item {
anchors.rightMargin: anchors.leftMargin anchors.rightMargin: anchors.leftMargin
clip: true clip: true
spacing: 4 spacing: 4
interactive: background.index === 3
add: Transition {NumberAnimation { add: Transition {NumberAnimation {
property: "opacity" property: "opacity"
@@ -69,7 +68,7 @@ Item {
header: Item {height: 4; width: 1} header: Item {height: 4; width: 1}
model: Array.from(notifServer.trackedNotifications.values) model: Array.from(notifServer.trackedNotifications.values)
delegate: Widgets.Notification { delegate: Widgets.Notification {
color: "#222" color: "#181818"
} }
} }
} }
@@ -98,25 +97,32 @@ Item {
} }
} }
Column { Column {
anchors.centerIn: parent anchors {
left: parent.left
right: parent.right
verticalCenter: parent.verticalCenter
margins: 6
}
opacity: Mpris.players.values.length opacity: Mpris.players.values.length
Behavior on opacity {NumberAnimation {duration: 150}} Behavior on opacity {NumberAnimation {duration: 150}}
Shape { Shape {
id: progressShape
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
width: 180 width: 160
height: 180 height: width
property var strokeWidth: 6
preferredRendererType: Shape.CurveRenderer preferredRendererType: Shape.CurveRenderer
ShapePath { ShapePath {
capStyle: ShapePath.RoundCap capStyle: ShapePath.RoundCap
strokeColor: "#444" strokeColor: "#444"
fillColor: "transparent" fillColor: "transparent"
strokeWidth: 4 strokeWidth: progressShape.strokeWidth
PathAngleArc { PathAngleArc {
moveToStart: true moveToStart: true
radiusX: 90 - 6 radiusX: (progressShape.width-progressShape.strokeWidth)/2
radiusY: 90 - 6 radiusY: (progressShape.height-progressShape.strokeWidth)/2
centerX: 90 centerX: progressShape.width/2
centerY: 90 centerY: progressShape.height/2
startAngle: 90 + 20 startAngle: 90 + 20
sweepAngle: 360 - 40 sweepAngle: 360 - 40
} }
@@ -125,13 +131,13 @@ Item {
capStyle: ShapePath.RoundCap capStyle: ShapePath.RoundCap
strokeColor: "white" strokeColor: "white"
fillColor: "transparent" fillColor: "transparent"
strokeWidth: 4 strokeWidth: 6
PathAngleArc { PathAngleArc {
moveToStart: true moveToStart: true
radiusX: 90 - 6 radiusX: (progressShape.width-progressShape.strokeWidth)/2
radiusY: 90 - 6 radiusY: (progressShape.height-progressShape.strokeWidth)/2
centerX: 90 centerX: progressShape.width/2
centerY: 90 centerY: progressShape.height/2
startAngle: 90 + 20 startAngle: 90 + 20
sweepAngle: (player.modelData?.position/player.modelData.length) * (360 - 40) sweepAngle: (player.modelData?.position/player.modelData.length) * (360 - 40)
} }
@@ -140,9 +146,12 @@ Item {
color: "transparent" color: "transparent"
radius: height/2 radius: height/2
anchors.fill: parent anchors.fill: parent
anchors.margins: 12 anchors.margins: progressShape.strokeWidth*2
Image { Image {
anchors.fill: parent anchors.fill: parent
fillMode: Image.PreserveAspectCrop
mipmap: true
smooth: true
source: player.modelData?.trackArtUrl ?? source source: player.modelData?.trackArtUrl ?? source
} }
NumberAnimation on rotation { NumberAnimation on rotation {
@@ -159,15 +168,25 @@ Item {
} }
Item {width: 1; height: 10} Item {width: 1; height: 10}
Text { Text {
anchors {
left: parent.left
right: parent.right
}
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
color: "white" color: "white"
text: player.modelData?.trackTitle ?? "" text: player.modelData?.trackTitle ?? ""
anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: 16 font.pixelSize: 16
} }
Text { Text {
anchors {
left: parent.left
right: parent.right
}
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
color: "white" color: "white"
text: player.modelData?.trackArtist ?? "" text: player.modelData?.trackArtist ?? ""
anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: 12 font.pixelSize: 12
} }
Item {width: 1; height: 8} Item {width: 1; height: 8}

View File

@@ -9,7 +9,7 @@ Item {
horizontalCenter: parent.horizontalCenter horizontalCenter: parent.horizontalCenter
} }
width: 350 width: 350
height: childrenRect.height height: childrenRect.height + 12
Connections { Connections {
target: notifServer target: notifServer
function onNotification(notif) { function onNotification(notif) {
@@ -22,6 +22,7 @@ Item {
} }
Widgets.Notification { Widgets.Notification {
id: notifPopup id: notifPopup
y: 6
anchors.margins: 6 anchors.margins: 6
modelData: notifServer.trackedNotifications.values[0] ?? undefined modelData: notifServer.trackedNotifications.values[0] ?? undefined
color: "transparent" color: "transparent"
@@ -32,4 +33,8 @@ Item {
interval: 3000 interval: 3000
onTriggered: root.close() onTriggered: root.close()
} }
Connections {
target: background
function onIndexChanged() { timeout.stop() }
}
} }

View File

@@ -16,6 +16,8 @@ Item {
bottom: parent.bottom bottom: parent.bottom
} }
Widgets.Battery {} Widgets.Battery {}
Widgets.Volume {}
Widgets.Brightness {}
} }
Widgets.Workspaces { Widgets.Workspaces {
height: parent.height height: parent.height
@@ -31,6 +33,7 @@ Item {
right: parent.right right: parent.right
bottom: parent.bottom bottom: parent.bottom
} }
Widgets.Uptime {}
Widgets.Time {} Widgets.Time {}
} }
} }

104
Panes/Volume.qml Normal file
View File

@@ -0,0 +1,104 @@
import QtQuick
import QtQuick.Effects
import QtQuick.Controls
import Quickshell
import Quickshell.Widgets
import Quickshell.Services.Pipewire
import qs.Widgets as Widgets
Row {
anchors {
top: parent.top
horizontalCenter: parent.horizontalCenter
}
padding: 6
height: 316
spacing: 6
PwObjectTracker {
objects: Pipewire.nodes.values.filter(node => [17, 21].includes(node.type))
}
component NodeList: ClippingRectangle {
id: nodeListRect
width: 350
color: "transparent"
anchors {
top: parent.top
bottom: parent.bottom
bottomMargin: 6
}
radius: 10
property var model
clip: true
ListView {
anchors.fill: parent
spacing: 6
header: Item {width: 1; height: 6}
footer: header
model: nodeListRect.model
delegate: Rectangle {
anchors {
left: parent.left
right: parent.right
}
radius: 12
color: "#111"
height: children[1].height
Image {
anchors {
left: parent.left
verticalCenter: parent.verticalCenter
leftMargin: 6
}
sourceSize {width: width; height: height}
source: Quickshell.iconPath((() => {
const description = modelData.description.toLowerCase();
if (description.search("hdmi") !== -1)
return "display"
if (description.search("speaker") !== -1)
return "audio-speakers"
if (description.search("earphone") !== -1 || description.search("headphone") !== -1)
return "audio-headset"
if (modelData.properties["device.icon-name"])
return modelData.properties["device.icon-name"]
return modelData.properties["application.name"]
})()?.toLowerCase(), "audio-on")
width: 32
height: width
}
Column {
anchors {
left: parent.children[0].right
right: parent.right
verticalCenter: parent.verticalCenter
margins: 6
rightMargin: 12
}
topPadding: 6
bottomPadding: 6
spacing: 2
Text {
text: {
if (modelData.nickname !== "") return modelData.nickname
if (modelData.description !== "") return description
return modelData.name
}
color: "white"
font.pixelSize: 16
}
Widgets.Slider {
value: modelData.audio.volume
onMoved: modelData.audio.volume = position
}
}
}
}
}
NodeList {
model: Pipewire.nodes.values.filter(node => node.type === 17)
}
NodeList {
model: Pipewire.nodes.values.filter(node => node.type === 21)
}
}

68
Services/Brightness.qml Normal file
View File

@@ -0,0 +1,68 @@
pragma Singleton
import QtQuick
import Quickshell
import Quickshell.Io
import Quickshell.Hyprland
Singleton {
id: brightness
property var monitors: []
Process {
id: lsbacklight
running: true
command: ["find", "/sys/class/backlight", "-maxdepth", "1", "-mindepth", "1"]
stdout: StdioCollector {
onStreamFinished: brightness.monitors = this.text.split('\n')
.filter(mon => mon)
.map(mon => brightnessMonitorGen.createObject(brightness, {path: mon}))
}
}
Component {
id: brightnessMonitorGen
BrightnessMonitor {}
}
component BrightnessMonitor: QtObject {
id: monitor
property var path
property var value
property var max
property var get: Process {
running: true
command: ["brightnessctl", "i", "-m"]
stdout: StdioCollector {
onStreamFinished: [,,value,,max] = this.text.split(",")
}
}
property var setInterp: Process {
running: false
command: ["brillo", "-r", "-u", "300000", "-S", value]
}
property var setInstant: Process {
running: false
command: ["brightnessctl", "s", value]
}
function increase() {
value += value * 0.1 + max * 0.01
value = Math.min(max, value)
setInterp.startDetached()
}
function decrease() {
value -= value * 0.1 + max * 0.01
value = Math.max(0, value)
setInterp.startDetached()
}
function set(value) {
this.value = Math.max(Math.min(value, max), 0)
setInstant.startDetached()
}
}
GlobalShortcut {
name: "increase_brightness"
onPressed: monitors[0]?.increase()
}
GlobalShortcut {
name: "decrease_brightness"
onPressed: monitors[0]?.decrease()
}
}

View File

@@ -36,7 +36,7 @@ PanelWindow {
GlobalShortcut { GlobalShortcut {
id: shortcut id: shortcut
name: "topbar" name: "peek_bar"
description: "Hold to peek, tap to toggle topbar" description: "Hold to peek, tap to toggle topbar"
onPressed: { onPressed: {
background.index = 0 background.index = 0
@@ -70,7 +70,7 @@ PanelWindow {
id: background id: background
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top anchors.top: parent.top
color: "#222222" color: "#181818"
radius: 16 radius: 16
width: children[0].width + radius*2 width: children[0].width + radius*2
height: children[0].height height: children[0].height
@@ -107,6 +107,7 @@ PanelWindow {
} }
width: children[0].width width: children[0].width
height: children[0].height height: children[0].height
visible: opacity
opacity: 0 opacity: 0
property var fadeIn: SequentialAnimation { property var fadeIn: SequentialAnimation {
PauseAnimation {duration: 200} PauseAnimation {duration: 200}
@@ -156,6 +157,8 @@ PanelWindow {
Pane { Panes.Battery {} } Pane { Panes.Battery {} }
Pane { Panes.NotificationCenter {} } Pane { Panes.NotificationCenter {} }
Pane { Panes.Notifications {} } Pane { Panes.Notifications {} }
Pane { Panes.Volume {} }
Pane { Panes.Brightness {} }
property var entry: SequentialAnimation { property var entry: SequentialAnimation {
PauseAnimation {duration: 2} PauseAnimation {duration: 2}
@@ -180,6 +183,9 @@ PanelWindow {
launcher.clear() launcher.clear()
} }
} }
HoverHandler {id: hover} HoverHandler {
id: hover
onHoveredChanged: { if (!hovered && background.index === 0) root.close() }
}
} }
} }

View File

@@ -15,6 +15,11 @@ Variants {
aboveWindows: false aboveWindows: false
property var modelData property var modelData
screen: modelData screen: modelData
color: "#141414" color: "#111"
Image {
source: Quickshell.shellPath("wallpaper")
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
}
} }
} }

View File

@@ -9,11 +9,13 @@ Item {
top: parent.top top: parent.top
bottom: parent.bottom bottom: parent.bottom
} }
width: children[1].width + 20 width: children[1].width + 16
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
anchors.margins: 4 anchors.margins: 4
anchors.rightMargin: 2
color: hover.hovered ? "#11ffffff" : "#00ffffff" color: hover.hovered ? "#11ffffff" : "#00ffffff"
Behavior on color {ColorAnimation {duration: 150}}
radius: 8 radius: 8
bottomLeftRadius: 12 bottomLeftRadius: 12
} }

40
Widgets/Brightness.qml Normal file
View File

@@ -0,0 +1,40 @@
import Quickshell
import QtQuick.Shapes
import qs.Services
import QtQuick
Item {
anchors {
top: parent.top
bottom: parent.bottom
}
width: children[1].width + 16
Rectangle {
anchors.fill: parent
anchors.margins: 4
anchors.leftMargin: 2
anchors.rightMargin: 2
color: hover.hovered ? "#11ffffff" : "#00ffffff"
Behavior on color {ColorAnimation {duration: 150}}
radius: 8
}
PercentIndicator {
x: 8
anchors.verticalCenter: parent.verticalCenter
width: 26
height: width
percent: Brightness.monitors[0].value / Brightness.monitors[0].max
Image {
anchors.centerIn: parent
width: 20
height: width
sourceSize {width: width; height: height}
source: Quickshell.iconPath("brightnesssettings")
}
}
HoverHandler {id: hover}
TapHandler {onTapped: {
background.index = 6
}}
}

View File

@@ -0,0 +1,40 @@
import Quickshell
import QtQuick.Shapes
import Quickshell.Services.Pipewire
import QtQuick
Shape {
id: root
preferredRendererType: Shape.CurveRenderer
property var percent
ShapePath {
capStyle: ShapePath.RoundCap
fillColor: "transparent"
strokeColor: "#333"
strokeWidth: 2
PathAngleArc {
moveToStart: true
centerX: root.width/2
centerY: root.height/2
radiusX: root.width/2
radiusY: root.height/2
startAngle: 90 + 40
sweepAngle: 360 - 80
}
}
ShapePath {
capStyle: ShapePath.RoundCap
fillColor: "transparent"
strokeColor: "white"
strokeWidth: 2
PathAngleArc {
moveToStart: true
centerX: root.width/2
centerY: root.height/2
radiusX: root.width/2 - 1
radiusY: root.height/2 - 1
startAngle: 90 + 40
sweepAngle: root.percent * (360 - 80)
}
}
}

42
Widgets/Slider.qml Normal file
View File

@@ -0,0 +1,42 @@
import QtQuick.Controls as QQC
import QtQuick
QQC.Slider {
anchors {
left: parent.left
right: parent.right
}
height: 24
orientation: Qt.Horizontal
handle: Rectangle {
x: parent.visualPosition * (parent.availableWidth - width)
y: parent.availableHeight / 2 - height / 2
height: 16
width: 4
radius: width/2
}
background: Rectangle {
height: 6
anchors {
verticalCenter: parent.verticalCenter
left: parent.handle.right
right: parent.right
leftMargin: 4
}
color: "#333"
topRightRadius: height/2
bottomRightRadius: topRightRadius
}
Rectangle {
height: 6
anchors {
verticalCenter: parent.verticalCenter
left: parent.left
right: parent.handle.left
rightMargin: 4
}
color: "white"
topLeftRadius: height/2
bottomLeftRadius: topLeftRadius
}
}

View File

@@ -17,7 +17,7 @@ Item {
radius: 8 radius: 8
bottomRightRadius: 12 bottomRightRadius: 12
color: hover.hovered ? "#11ffffff" : "#00ffffff" color: hover.hovered ? "#11ffffff" : "#00ffffff"
Behavior on color {ColorAnimation {duration: 100}} Behavior on color {ColorAnimation {duration: 150}}
} }
Row { Row {
spacing: 12 spacing: 12

7
Widgets/Uptime.qml Normal file
View File

@@ -0,0 +1,7 @@
import Quickshell
import QtQuick
Item {
anchors {
}
}

44
Widgets/Volume.qml Normal file
View File

@@ -0,0 +1,44 @@
import Quickshell
import QtQuick.Shapes
import Quickshell.Services.Pipewire
import QtQuick
Item {
anchors {
top: parent.top
bottom: parent.bottom
}
width: children[1].width + 16
PwObjectTracker {
objects: [Pipewire.defaultAudioSink]
}
Rectangle {
anchors.fill: parent
anchors.margins: 4
anchors.leftMargin: 2
anchors.rightMargin: 2
color: hover.hovered ? "#11ffffff" : "#00ffffff"
Behavior on color {ColorAnimation {duration: 150}}
radius: 8
}
PercentIndicator {
x: 8
anchors.verticalCenter: parent.verticalCenter
width: 26
height: width
percent: Pipewire.defaultAudioSink.audio.volume
Image {
anchors.centerIn: parent
width: 20
height: width
sourceSize {width: width; height: height}
source: Quickshell.iconPath("volume-level-high")
}
}
HoverHandler {id: hover}
TapHandler {onTapped: {
background.index = 5
}}
}

View File

@@ -18,9 +18,11 @@ Item {
width: 24 width: 24
property var workspace: Hyprland.workspaces.values.find(ws => ws.id === modelData+1) property var workspace: Hyprland.workspaces.values.find(ws => ws.id === modelData+1)
property var icon: { property var icon: {
const appId = workspace ? Array.from(workspace.toplevels.values).sort( let appId
(a, b) => b.lastIpcObject.focusHistoryId - a.lastIpcObject.focusHistoryId if (workspace) {
)[0]?.wayland?.appId : undefined let toplevel = Array.from(workspace.toplevels.values).reduce((prev, curr) => (prev.lastIpcObject.focusHistoryID < curr.lastIpcObject.focusHistoryID) ? prev : curr)
appId = toplevel.wayland?.appId
}
return DesktopEntries.applications.values.find( return DesktopEntries.applications.values.find(
app => app.startupClass === appId || app.id === appId app => app.startupClass === appId || app.id === appId
)?.icon; )?.icon;
@@ -59,4 +61,8 @@ Item {
height: 4 height: 4
radius: height/2 radius: height/2
} }
Connections {
target: Hyprland
function onActiveToplevelChanged() {Hyprland.refreshToplevels()}
}
} }

View File

@@ -1,3 +1,4 @@
import QtQuick
import Quickshell import Quickshell
import Quickshell.Io import Quickshell.Io
import Quickshell.Services.Notifications import Quickshell.Services.Notifications
@@ -9,12 +10,20 @@ ShellRoot {
onNotification: (notif) => notif.tracked = true onNotification: (notif) => notif.tracked = true
} }
Shell.Wall {} Shell.Wall {}
Shell.TopBar {} Shell.TopBar {id: bar}
Shell.Boateye {} Shell.Boateye {}
Shell.Lock { Shell.Lock {
id: lock id: lock
animate: true animate: true
} }
PanelWindow {
anchors {
top: true
}
implicitHeight: 1
implicitWidth: 800
HoverHandler {onHoveredChanged: {if (hovered) bar.open() }}
}
IpcHandler { IpcHandler {
target: "lock" target: "lock"
function instalock() {lock.animate = false; lock.locked = true} function instalock() {lock.animate = false; lock.locked = true}