initial commit
This commit is contained in:
commit
35524b5e6e
7 changed files with 412 additions and 0 deletions
37
Bar.qml
Normal file
37
Bar.qml
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
|
||||||
|
PanelWindow {
|
||||||
|
id: root
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: true
|
||||||
|
bottom: true
|
||||||
|
right: true
|
||||||
|
}
|
||||||
|
width: 60
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
// anchors.fill: parent
|
||||||
|
anchors.margins: 2
|
||||||
|
spacing: 2
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
top: parent.top
|
||||||
|
margins: 2
|
||||||
|
}
|
||||||
|
|
||||||
|
ClockWidget {}
|
||||||
|
|
||||||
|
WorkspaceWidget {
|
||||||
|
bar: root
|
||||||
|
}
|
||||||
|
// SysTray {
|
||||||
|
// bar: root
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
39
ClockWidget.qml
Normal file
39
ClockWidget.qml
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: width
|
||||||
|
border.color: "black"
|
||||||
|
border.width: 1
|
||||||
|
radius: 5
|
||||||
|
// color: "green"
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: parent.width
|
||||||
|
height: text.height * 2
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: text
|
||||||
|
anchors.centerIn: parent
|
||||||
|
property var date: Date()
|
||||||
|
|
||||||
|
text: Qt.formatDateTime(date, "hh\nmm")
|
||||||
|
|
||||||
|
font.family: "Iosevka NF"
|
||||||
|
font.weight: Font.ExtraBold
|
||||||
|
font.pointSize: 18
|
||||||
|
|
||||||
|
color: "black"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
interval: 1000 * 60
|
||||||
|
running: true
|
||||||
|
repeat: true
|
||||||
|
onTriggered: text.date = new Date()
|
||||||
|
}
|
||||||
|
}
|
34
Launcher.qml
Normal file
34
Launcher.qml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
pragma Singleton
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import Quickshell.Widgets
|
||||||
|
import Quickshell.Services.SystemTray
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
PersistentProperties {
|
||||||
|
id: persist
|
||||||
|
property bool launcherOpen: false
|
||||||
|
}
|
||||||
|
|
||||||
|
IpcHandler {
|
||||||
|
target: "launcher"
|
||||||
|
|
||||||
|
function open(): void {
|
||||||
|
persist.launcherOpen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function close(): void {
|
||||||
|
persist.launcherOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggle(): void {
|
||||||
|
persist.launcherOpen = !persist.launcherOpen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
127
ReloadPopup.qml
Normal file
127
ReloadPopup.qml
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
|
||||||
|
Scope {
|
||||||
|
id: root
|
||||||
|
property bool failed
|
||||||
|
property string errorString
|
||||||
|
|
||||||
|
// Connect to the Quickshell global to listen for the reload signals.
|
||||||
|
Connections {
|
||||||
|
target: Quickshell
|
||||||
|
|
||||||
|
function onReloadCompleted() {
|
||||||
|
root.failed = false;
|
||||||
|
popupLoader.loading = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onReloadFailed(error: string) {
|
||||||
|
// Close any existing popup before making a new one.
|
||||||
|
popupLoader.active = false;
|
||||||
|
|
||||||
|
root.failed = true;
|
||||||
|
root.errorString = error;
|
||||||
|
popupLoader.loading = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep the popup in a loader because it isn't needed most of the timeand will take up
|
||||||
|
// memory that could be used for something else.
|
||||||
|
LazyLoader {
|
||||||
|
id: popupLoader
|
||||||
|
|
||||||
|
PanelWindow {
|
||||||
|
id: popup
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: true
|
||||||
|
right: true
|
||||||
|
}
|
||||||
|
|
||||||
|
margins {
|
||||||
|
top: 25
|
||||||
|
left: 25
|
||||||
|
}
|
||||||
|
|
||||||
|
width: rect.width
|
||||||
|
height: rect.height
|
||||||
|
|
||||||
|
// color blending is a bit odd as detailed in the type reference.
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: rect
|
||||||
|
color: root.failed ? "#40802020" : "#40009020"
|
||||||
|
|
||||||
|
implicitHeight: layout.implicitHeight + 50
|
||||||
|
implicitWidth: layout.implicitWidth + 30
|
||||||
|
|
||||||
|
// Fills the whole area of the rectangle, making any clicks go to it,
|
||||||
|
// which dismiss the popup.
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: popupLoader.active = false
|
||||||
|
|
||||||
|
// makes the mouse area track mouse hovering, so the hide animation
|
||||||
|
// can be paused when hovering.
|
||||||
|
hoverEnabled: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: layout
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
topMargin: 20
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: root.failed ? "Reload failed." : "Reloaded completed!"
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: root.errorString
|
||||||
|
color: "white"
|
||||||
|
// When visible is false, it also takes up no space.
|
||||||
|
visible: root.errorString != ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A progress bar on the bottom of the screen, showing how long until the
|
||||||
|
// popup is removed.
|
||||||
|
Rectangle {
|
||||||
|
id: bar
|
||||||
|
color: "#20ffffff"
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
height: 20
|
||||||
|
|
||||||
|
PropertyAnimation {
|
||||||
|
id: anim
|
||||||
|
target: bar
|
||||||
|
property: "width"
|
||||||
|
from: rect.width
|
||||||
|
to: 0
|
||||||
|
duration: failed ? 10000 : 800
|
||||||
|
onFinished: popupLoader.active = false
|
||||||
|
|
||||||
|
// Pause the animation when the mouse is hovering over the popup,
|
||||||
|
// so it stays onscreen while reading. This updates reactively
|
||||||
|
// when the mouse moves on and off the popup.
|
||||||
|
paused: mouseArea.containsMouse
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We could set `running: true` inside the animation, but the width of the
|
||||||
|
// rectangle might not be calculated yet, due to the layout.
|
||||||
|
// In the `Component.onCompleted` event handler, all of the component's
|
||||||
|
// properties and children have been initialized.
|
||||||
|
Component.onCompleted: anim.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
SysTray.qml
Normal file
35
SysTray.qml
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Effects
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Services.SystemTray
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
required property var bar
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: column
|
||||||
|
spacing: 5
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
margins: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: SystemTray.items
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: item
|
||||||
|
|
||||||
|
required property SystemTrayItem modelData
|
||||||
|
|
||||||
|
implicitHeight: width
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
118
WorkspaceWidget.qml
Normal file
118
WorkspaceWidget.qml
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
// A workspace indicator.
|
||||||
|
// This is in big parts taken from outfoxxed, the creator of quickshell.
|
||||||
|
// Please make sure to check out his setup.
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell.Hyprland
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
required property var bar
|
||||||
|
|
||||||
|
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(bar.screen)
|
||||||
|
|
||||||
|
// Amount of workspaces
|
||||||
|
property int wsCount: 10
|
||||||
|
// Base index for the workspaces
|
||||||
|
property int wsBaseIndex: 1
|
||||||
|
|
||||||
|
// index of the current workspace
|
||||||
|
property int currentIndex: 0
|
||||||
|
// count how many workspaces currently exist
|
||||||
|
property int existsCount: 0
|
||||||
|
|
||||||
|
implicitHeight: column.implicitHeight + 10
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
height: width
|
||||||
|
border.color: "black"
|
||||||
|
// color: "blue"
|
||||||
|
border.width: 1
|
||||||
|
radius: 5
|
||||||
|
|
||||||
|
// destructor takes care of nulling
|
||||||
|
signal workspaceAdded(workspace: HyprlandWorkspace)
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: column
|
||||||
|
spacing: 0
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
margins: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.wsCount
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: wsItem
|
||||||
|
implicitHeight: 15
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
right: parent.right
|
||||||
|
left: parent.left
|
||||||
|
}
|
||||||
|
|
||||||
|
// index of the current workspace
|
||||||
|
required property int index
|
||||||
|
property int wsIndex: root.wsBaseIndex + index
|
||||||
|
|
||||||
|
property HyprlandWorkspace workspace: null
|
||||||
|
// check if workspace exists
|
||||||
|
property bool exists: workspace != null
|
||||||
|
|
||||||
|
property bool active: (root.monitor?.activeWorkspace ?? false) && root.monitor.activeWorkspace == workspace
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root
|
||||||
|
|
||||||
|
function onWorkspaceAdded(workspace: HyprlandWorkspace) {
|
||||||
|
if (workspace.id == wsItem.wsIndex) {
|
||||||
|
wsItem.workspace = workspace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property real animActive: active ? 1 : 0.65
|
||||||
|
Behavior on animActive {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 150
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property real animExists: exists ? 1 : 0
|
||||||
|
Behavior on animExists {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
height: 10
|
||||||
|
// width: (wsItem.active ? parent.width : parent.width - 20)
|
||||||
|
width: parent.width * wsItem.animActive
|
||||||
|
radius: height / 2
|
||||||
|
border.color: "black"
|
||||||
|
border.width: 1
|
||||||
|
color: "black"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: Hyprland.workspaces
|
||||||
|
|
||||||
|
function onObjectInsertedPost(workspace) {
|
||||||
|
root.workspaceAdded(workspace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
Hyprland.workspaces.values.forEach(workspace => {
|
||||||
|
root.workspaceAdded(workspace);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
22
shell.qml
Normal file
22
shell.qml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
ShellRoot {
|
||||||
|
id: shellroot
|
||||||
|
|
||||||
|
Variants {
|
||||||
|
model: Quickshell.screens
|
||||||
|
|
||||||
|
Scope {
|
||||||
|
property var modelData
|
||||||
|
|
||||||
|
Bar {
|
||||||
|
screen: modelData
|
||||||
|
}
|
||||||
|
|
||||||
|
ReloadPopup {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue