progress
This commit is contained in:
parent
cc71593a9b
commit
1a27b905bf
16 changed files with 622 additions and 177 deletions
38
Bar.qml
38
Bar.qml
|
@ -1,38 +0,0 @@
|
||||||
pragma ComponentBehavior: Bound
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import Quickshell
|
|
||||||
|
|
||||||
PanelWindow {
|
|
||||||
id: root
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
top: true
|
|
||||||
bottom: true
|
|
||||||
left: 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
|
|
||||||
wsBaseIndex: root.screen.name == "DP-2" ? 11 : 1
|
|
||||||
}
|
|
||||||
SysTray {
|
|
||||||
bar: root
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +1,26 @@
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: parent.width
|
|
||||||
height: text.height + 10
|
|
||||||
border.color: "black"
|
width: text.width
|
||||||
|
implicitHeight: text.height
|
||||||
|
// border.color: "black"
|
||||||
border.width: 2
|
border.width: 2
|
||||||
radius: 5
|
radius: 0
|
||||||
color: "#30c0ffff"
|
color: "transparent"
|
||||||
|
|
||||||
|
Behavior on implicitHeight {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 100
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: text.height * 2
|
height: text.height
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
@ -26,11 +34,11 @@ Rectangle {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
property var date: Date()
|
property var date: Date()
|
||||||
|
|
||||||
text: Qt.formatDateTime(clock.date, "hh\nmm")
|
text: Qt.formatDateTime(clock.date, "hh mm")
|
||||||
|
|
||||||
font.family: "ComicShannsMono Nerd Font Mono"
|
font.family: "ComicShannsMono Nerd Font Mono"
|
||||||
font.weight: Font.ExtraBold
|
font.weight: Font.ExtraBold
|
||||||
font.pointSize: 18
|
font.pointSize: 12
|
||||||
|
|
||||||
color: "black"
|
color: "black"
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ Rectangle {
|
||||||
border.color: "black"
|
border.color: "black"
|
||||||
border.width: 2
|
border.width: 2
|
||||||
|
|
||||||
ColumnLayout {
|
RowLayout {
|
||||||
id: column
|
id: column
|
||||||
spacing: 10
|
spacing: 10
|
||||||
|
|
||||||
|
|
|
@ -1,116 +0,0 @@
|
||||||
// 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 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: "#30c0ffff"
|
|
||||||
border.width: 2
|
|
||||||
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: wsItem.height - 5
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
46
config/Config.qml
Normal file
46
config/Config.qml
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import Quickshell
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property QtObject bar: QtObject {
|
||||||
|
readonly property int width: 50
|
||||||
|
readonly property var colors: QtObject {
|
||||||
|
readonly property color bar: "#1e1e2e"
|
||||||
|
readonly property color barOutline: "#50ffffff"
|
||||||
|
readonly property color widget: "#25ceffff"
|
||||||
|
readonly property color widgetActive: "#80ceffff"
|
||||||
|
readonly property color widgetOutline: "#40ffffff"
|
||||||
|
readonly property color widgetOutlineSeparate: "#20ffffff"
|
||||||
|
readonly property color separator: "#60ffffff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property QtObject border: QtObject {
|
||||||
|
readonly property int thickness: 8
|
||||||
|
readonly property color color: "#1e1e2e"
|
||||||
|
readonly property int rounding: 25
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property QtObject catppuccin: QtObject {
|
||||||
|
readonly property color base: "#1e1e2e"
|
||||||
|
readonly property color mantle: "#181825"
|
||||||
|
readonly property color surface0: "#313244"
|
||||||
|
readonly property color surface1: "#45475a"
|
||||||
|
readonly property color surface2: "#585b70"
|
||||||
|
readonly property color text: "#cdd6f4"
|
||||||
|
readonly property color rosewater: "#f5e0dc"
|
||||||
|
readonly property color lavender: "#b4befe"
|
||||||
|
readonly property color red: "#f38ba8"
|
||||||
|
readonly property color peach: "#fab387"
|
||||||
|
readonly property color yellow: "#f9e2af"
|
||||||
|
readonly property color green: "#a6e3a1"
|
||||||
|
readonly property color teal: "#a6e3a1"
|
||||||
|
readonly property color blue: "#89b4fa"
|
||||||
|
readonly property color mauve: "#cba6f7"
|
||||||
|
readonly property color flamingo: "#f2cdcd"
|
||||||
|
}
|
||||||
|
}
|
57
modules/bar/Bar.qml
Normal file
57
modules/bar/Bar.qml
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import Quickshell
|
||||||
|
|
||||||
|
import "../../config"
|
||||||
|
import "components"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
color: Config.bar.colors.bar
|
||||||
|
|
||||||
|
required property ShellScreen screen
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
left: parent.left
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitWidth: Config.bar.width
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: child
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitWidth: Math.max(clock.implicitWidth, workspaces.implicitWidth)
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
spacing: 2
|
||||||
|
anchors {
|
||||||
|
top: parent.top
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
margins: 0
|
||||||
|
}
|
||||||
|
Clock {
|
||||||
|
id: clock
|
||||||
|
}
|
||||||
|
Workspaces {
|
||||||
|
id: workspaces
|
||||||
|
screen: root.screen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: root.screen.name
|
||||||
|
color: "green"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
modules/bar/components/Clock.qml
Normal file
34
modules/bar/components/Clock.qml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
|
||||||
|
import "../../../config"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
width: text.width + 5
|
||||||
|
height: text.height + 5
|
||||||
|
implicitWidth: width
|
||||||
|
border.color: Config.catppuccin.rosewater
|
||||||
|
border.width: 0
|
||||||
|
radius: 5
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: text
|
||||||
|
anchors.centerIn: parent
|
||||||
|
property var date: Date()
|
||||||
|
|
||||||
|
text: Qt.formatDateTime(clock.date, "hh mm")
|
||||||
|
|
||||||
|
font.family: "JetBrainsMono NF Mono"
|
||||||
|
font.pointSize: 15
|
||||||
|
|
||||||
|
color: Config.catppuccin.text
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemClock {
|
||||||
|
id: clock
|
||||||
|
precision: SystemClock.Seconds
|
||||||
|
}
|
||||||
|
}
|
103
modules/bar/components/Workspaces.qml
Normal file
103
modules/bar/components/Workspaces.qml
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import "../../../services/niri"
|
||||||
|
import "../../../config"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property ShellScreen screen
|
||||||
|
property var workspaces: Niri.workspaces
|
||||||
|
property var activeWorkspace: Niri.activeWorkspace
|
||||||
|
property var activeWorkspaceIndex: Niri.activeWorkspaceIndex
|
||||||
|
|
||||||
|
property int wsItemHeight: 15
|
||||||
|
|
||||||
|
property bool _: log()
|
||||||
|
function log() {
|
||||||
|
console.debug("Screen name: " + screen.name);
|
||||||
|
console.debug("Found the following workspaces:");
|
||||||
|
for (let i = 0; i < workspaces.length; i++) {
|
||||||
|
console.debug("Workspace " + workspaces[i].id + " On screen " + workspaces[i].output + " With name: " + workspaces[i].name);
|
||||||
|
// console.debug(workspaces[i].output);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Works
|
||||||
|
height: 300
|
||||||
|
|
||||||
|
// Gives warning
|
||||||
|
// height: workspaces.length * root.wsItemHeight
|
||||||
|
implicitWidth: list.implicitWidth
|
||||||
|
color: "transparent"
|
||||||
|
border.color: Config.catppuccin.rosewater
|
||||||
|
border.width: 0
|
||||||
|
radius: 7
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: list
|
||||||
|
model: root.workspaces
|
||||||
|
implicitHeight: contentHeight
|
||||||
|
implicitWidth: contentItem.childrenRect.width
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
|
// anchors.fill: parent
|
||||||
|
|
||||||
|
delegate: Item {
|
||||||
|
id: wsItem
|
||||||
|
// Name of the workspace
|
||||||
|
property string name: "VOID"
|
||||||
|
// ID of the workspace
|
||||||
|
required property string id
|
||||||
|
|
||||||
|
required property string output
|
||||||
|
|
||||||
|
property bool isActive: (id - 1 == root.activeWorkspaceIndex)
|
||||||
|
|
||||||
|
property real animActive: isActive ? 1 : 0.65
|
||||||
|
Behavior on animActive {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 150
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// property bool isCorrectScreen: log()
|
||||||
|
// function log() {
|
||||||
|
// console.log("Screen name: " + root.screen.name);
|
||||||
|
// console.log(wsItem.output);
|
||||||
|
// console.log(wsItem.id);
|
||||||
|
|
||||||
|
// let isCorrect = root.screen.name == wsItem.output;
|
||||||
|
// console.log("isCorrect: ", isCorrect);
|
||||||
|
// return root.screen.name == wsItem.output;
|
||||||
|
// }
|
||||||
|
|
||||||
|
implicitHeight: root.wsItemHeight
|
||||||
|
implicitWidth: 50
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
right: parent.right
|
||||||
|
left: parent.left
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
height: wsItem.height - 5
|
||||||
|
width: parent.width * wsItem.animActive
|
||||||
|
radius: height / 2
|
||||||
|
border.color: Config.catppuccin.mantle
|
||||||
|
border.width: 0
|
||||||
|
color: Config.catppuccin.blue
|
||||||
|
// visible: wsItem.isCorrectScreen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
modules/drawers/Background.qml
Normal file
3
modules/drawers/Background.qml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Shapes
|
||||||
|
|
54
modules/drawers/Border.qml
Normal file
54
modules/drawers/Border.qml
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import Quickshell
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Effects
|
||||||
|
|
||||||
|
import "../../config"
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property Rectangle bar
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: rect
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
color: Config.border.color
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: 150
|
||||||
|
easing.type: Easing.BezierSpline
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: mask
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
layer.enabled: true
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Config.border.thickness
|
||||||
|
anchors.leftMargin: root.bar.implicitWidth
|
||||||
|
radius: Config.border.rounding
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiEffect {
|
||||||
|
anchors.fill: parent
|
||||||
|
maskEnabled: true
|
||||||
|
maskInverted: true
|
||||||
|
maskSource: mask
|
||||||
|
source: rect
|
||||||
|
maskThresholdMin: 0.5
|
||||||
|
maskSpreadAtMin: 1
|
||||||
|
}
|
||||||
|
}
|
117
modules/drawers/Drawers.qml
Normal file
117
modules/drawers/Drawers.qml
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Wayland
|
||||||
|
import Quickshell.Services.Notifications
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Effects
|
||||||
|
|
||||||
|
import "../bar"
|
||||||
|
import "../notifications"
|
||||||
|
|
||||||
|
// import "../../services"
|
||||||
|
|
||||||
|
Variants {
|
||||||
|
model: Quickshell.screens
|
||||||
|
|
||||||
|
Scope {
|
||||||
|
id: scope
|
||||||
|
required property ShellScreen modelData
|
||||||
|
|
||||||
|
Exclusions {
|
||||||
|
screen: scope.modelData
|
||||||
|
bar: bar
|
||||||
|
}
|
||||||
|
|
||||||
|
PanelWindow {
|
||||||
|
id: win
|
||||||
|
|
||||||
|
screen: scope.modelData
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
WlrLayershell.exclusionMode: ExclusionMode.Ignore
|
||||||
|
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||||
|
|
||||||
|
// Clickthrough mask.
|
||||||
|
// Clickable areas of the window are determined by the provided region.
|
||||||
|
mask: Region {
|
||||||
|
x: bar.implicitWidth
|
||||||
|
y: 8
|
||||||
|
width: win.width - bar.implicitWidth
|
||||||
|
height: win.height - 8
|
||||||
|
|
||||||
|
// Setting the intersection mode to Xor will invert the mask and make everything in the mask region not clickable and pass through clicks inside it through the window.
|
||||||
|
intersection: Intersection.Xor
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: true
|
||||||
|
bottom: true
|
||||||
|
left: true
|
||||||
|
right: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: background
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
Border {
|
||||||
|
bar: bar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiEffect {
|
||||||
|
anchors.fill: source
|
||||||
|
source: background
|
||||||
|
shadowEnabled: true
|
||||||
|
blurMax: 15
|
||||||
|
}
|
||||||
|
|
||||||
|
Bar {
|
||||||
|
id: bar
|
||||||
|
screen: scope.modelData
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
id: notifs
|
||||||
|
|
||||||
|
readonly property list<Notif> list: []
|
||||||
|
readonly property list<Notif> popups: list.filter(n => n.popup)
|
||||||
|
|
||||||
|
NotificationServer {
|
||||||
|
id: server
|
||||||
|
|
||||||
|
keepOnReload: false
|
||||||
|
|
||||||
|
onNotification: notif => {
|
||||||
|
notif.tracked = true;
|
||||||
|
console.log("Got notification: " + notif.body);
|
||||||
|
|
||||||
|
root.list.push(notifComp.createObject(root, {
|
||||||
|
popup: true,
|
||||||
|
notification: notif,
|
||||||
|
body: notif.body,
|
||||||
|
appName: notif.appName
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: notifComp
|
||||||
|
|
||||||
|
Notif {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component Notif: QtObject {
|
||||||
|
property bool popup
|
||||||
|
readonly property date time: new Date()
|
||||||
|
|
||||||
|
required property Notification notification
|
||||||
|
readonly property string body: notification.body
|
||||||
|
readonly property string appName: notification.appName
|
||||||
|
}
|
||||||
|
}
|
38
modules/drawers/Exclusions.qml
Normal file
38
modules/drawers/Exclusions.qml
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
import Quickshell
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
import "../../config"
|
||||||
|
|
||||||
|
Scope {
|
||||||
|
id: root
|
||||||
|
required property ShellScreen screen
|
||||||
|
required property Item bar
|
||||||
|
|
||||||
|
ExclusionZone {
|
||||||
|
anchors.left: true
|
||||||
|
exclusiveZone: root.bar.implicitWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
ExclusionZone {
|
||||||
|
anchors.top: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ExclusionZone {
|
||||||
|
anchors.right: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ExclusionZone {
|
||||||
|
anchors.bottom: true
|
||||||
|
}
|
||||||
|
|
||||||
|
component ExclusionZone: PanelWindow {
|
||||||
|
screen: root.screen
|
||||||
|
color: "transparent"
|
||||||
|
exclusiveZone: Config.border.thickness
|
||||||
|
implicitHeight: Config.border.thickness
|
||||||
|
implicitWidth: Config.border.thickness
|
||||||
|
mask: Region {}
|
||||||
|
}
|
||||||
|
}
|
18
modules/notifications/Notification.qml
Normal file
18
modules/notifications/Notification.qml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Widgets
|
||||||
|
import Quickshell.Services.Notifications
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import "../../config"
|
||||||
|
import "../../services"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
color: "transparent"
|
||||||
|
required property Notification.Notif modelData
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: root.modelData.summary
|
||||||
|
}
|
||||||
|
}
|
42
services/Notification.qml
Normal file
42
services/Notification.qml
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
pragma Singleton
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Services.Notifications
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property list<Notif> list: []
|
||||||
|
readonly property list<Notif> popups: list.filter(n => n.popup)
|
||||||
|
|
||||||
|
NotificationServer {
|
||||||
|
id: server
|
||||||
|
|
||||||
|
keepOnReload: false
|
||||||
|
|
||||||
|
onNotification: notif => {
|
||||||
|
notif.tracked = true;
|
||||||
|
|
||||||
|
root.list.push(notifComp.createObject(root, {
|
||||||
|
popup: true,
|
||||||
|
notification: notif
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component Notif: QtObject {
|
||||||
|
property bool popup
|
||||||
|
readonly property date time: new Date()
|
||||||
|
|
||||||
|
required property Notification notification
|
||||||
|
readonly property string summary: notification.summary
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: notifComp
|
||||||
|
|
||||||
|
Notif {}
|
||||||
|
}
|
||||||
|
}
|
85
services/niri/Niri.qml
Normal file
85
services/niri/Niri.qml
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
// Kind thanks to https://github.com/MapoMagpie/nixos-flakes/blob/main/home/ui/quickshell/config/Data/Niri.qml
|
||||||
|
// This file was taken from there and further modified.
|
||||||
|
|
||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
// property var data
|
||||||
|
property var workspaces: []
|
||||||
|
property var activeWorkspace: "VOID"
|
||||||
|
property var activeWorkspaceIndex: 0
|
||||||
|
property var windows: []
|
||||||
|
// property var activedWindowId: 0
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: proc
|
||||||
|
command: ["niri", "msg", "-j", "event-stream"]
|
||||||
|
|
||||||
|
running: true
|
||||||
|
stdout: SplitParser {
|
||||||
|
onRead: data => {
|
||||||
|
var event = JSON.parse(data);
|
||||||
|
let workspaces = [];
|
||||||
|
if (event.WorkspacesChanged) {
|
||||||
|
root.workspaces = event.WorkspacesChanged.workspaces.filter(w => w.name);
|
||||||
|
root.workspaces = root.workspaces.sort((a, b) => a.id - b.id);
|
||||||
|
root.activeWorkspaceIndex = root.workspaces.findIndex(w => w.is_focused);
|
||||||
|
if (root.activeWorkspaceIndex < 0) {
|
||||||
|
root.activeWorkspaceIndex = 0;
|
||||||
|
}
|
||||||
|
root.activeWorkspace = root.workspaces[root.activeWorkspaceIndex].name;
|
||||||
|
}
|
||||||
|
if (event.WindowsChanged) {
|
||||||
|
root.windows = [...event.WindowsChanged.windows].sort((a, b) => a.id - b.id);
|
||||||
|
}
|
||||||
|
if (event.WindowOpenedOrChanged) {
|
||||||
|
const window = event.WindowOpenedOrChanged.window;
|
||||||
|
const index = root.windows.findIndex(w => w.id === window.id);
|
||||||
|
// console.log("window opened or changed: ", index, ", win id: ", window.id);
|
||||||
|
if (index >= 0) {
|
||||||
|
// console.log("replace window, old: ", root.windows[index].id, ", new: ", window.id);
|
||||||
|
root.windows[index] = window;
|
||||||
|
} else {
|
||||||
|
// console.log("push window, new: ", window.id);
|
||||||
|
root.windows.push(window);
|
||||||
|
}
|
||||||
|
root.windows = [...root.windows.sort((a, b) => a.id - b.id)];
|
||||||
|
}
|
||||||
|
if (event.WindowClosed) {
|
||||||
|
const index = root.windows.findIndex(w => w.id === event.WindowClosed.id);
|
||||||
|
// console.log("window closed: ", index, ", win id: ", event.WindowClosed.id);
|
||||||
|
if (index >= 0) {
|
||||||
|
root.windows.splice(index, 1);
|
||||||
|
}
|
||||||
|
root.windows = [...root.windows.sort((a, b) => a.id - b.id)];
|
||||||
|
}
|
||||||
|
if (event.WorkspaceActivated) {
|
||||||
|
root.activeWorkspaceIndex = root.workspaces.findIndex(w => w.id === event.WorkspaceActivated.id);
|
||||||
|
if (root.activeWorkspaceIndex < 0) {
|
||||||
|
root.activeWorkspaceIndex = 0;
|
||||||
|
}
|
||||||
|
root.activeWorkspace = root.workspaces[root.activeWorkspaceIndex].name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// {
|
||||||
|
// "workspaces": [
|
||||||
|
// {
|
||||||
|
// "id": 5,
|
||||||
|
// "idx": 4,
|
||||||
|
// "name": "GAME",
|
||||||
|
// "output": "DP-3",
|
||||||
|
// "is_active": false,
|
||||||
|
// "is_focused": false,
|
||||||
|
// "active_window_id": null
|
||||||
|
// },
|
||||||
|
// ]
|
||||||
|
// }
|
20
shell.qml
20
shell.qml
|
@ -1,24 +1,18 @@
|
||||||
pragma ComponentBehavior: Bound
|
//@ pragma Env QS_NO_RELOAD_POPUP=1
|
||||||
|
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
|
||||||
|
import "modules"
|
||||||
|
import "modules/drawers"
|
||||||
|
// import "modules/background"
|
||||||
|
|
||||||
ShellRoot {
|
ShellRoot {
|
||||||
id: shellroot
|
id: shellroot
|
||||||
|
|
||||||
Component.onCompleted: [Launcher.init()]
|
Component.onCompleted: [Launcher.init()]
|
||||||
|
|
||||||
ReloadPopup {}
|
Drawers {}
|
||||||
|
// Background {}
|
||||||
|
|
||||||
Variants {
|
|
||||||
model: Quickshell.screens
|
|
||||||
|
|
||||||
Scope {
|
|
||||||
property var modelData
|
|
||||||
|
|
||||||
Bar {
|
|
||||||
screen: modelData
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue