Moved bar to quickshell
This commit is contained in:
parent
ab0a71784e
commit
5a3a18f9f7
30 changed files with 971 additions and 206 deletions
18
quickshell/.config/quickshell/Globals.qml
Normal file
18
quickshell/.config/quickshell/Globals.qml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
property var popupContext: PopupContext {};
|
||||
property var date: new Date()
|
||||
|
||||
Timer {
|
||||
interval: 1000
|
||||
repeat: true
|
||||
running: true
|
||||
|
||||
onTriggered: root.date = new Date()
|
||||
}
|
||||
}
|
||||
6
quickshell/.config/quickshell/PopupContext.qml
Normal file
6
quickshell/.config/quickshell/PopupContext.qml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import QtQuick
|
||||
|
||||
// Tracks which popup of a set is active.
|
||||
QtObject {
|
||||
property var popup: null;
|
||||
}
|
||||
57
quickshell/.config/quickshell/bar/Bar.qml
Normal file
57
quickshell/.config/quickshell/bar/Bar.qml
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import "blocks" as Blocks
|
||||
|
||||
Scope {
|
||||
Variants {
|
||||
model: Quickshell.screens
|
||||
|
||||
PanelWindow {
|
||||
property var modelData
|
||||
screen: modelData
|
||||
|
||||
color: "#cc000000"
|
||||
height: 27
|
||||
|
||||
anchors {
|
||||
top: true
|
||||
left: true
|
||||
right: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
// Left side
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
|
||||
Blocks.Icon {}
|
||||
Blocks.Workspaces {}
|
||||
Blocks.ActiveWorkspace {}
|
||||
}
|
||||
|
||||
// Right side
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
Layout.alignment: Qt.AlignRight
|
||||
|
||||
Blocks.SystemTray {}
|
||||
Blocks.Test {}
|
||||
Blocks.Notifications {}
|
||||
Blocks.Memory {}
|
||||
Blocks.Sound {}
|
||||
Blocks.Battery {}
|
||||
Blocks.Date {}
|
||||
Blocks.Time {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
89
quickshell/.config/quickshell/bar/BarBlock.qml
Normal file
89
quickshell/.config/quickshell/bar/BarBlock.qml
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
Layout.preferredWidth: wsText.implicitWidth + 10
|
||||
Layout.preferredHeight: 27
|
||||
|
||||
property string text
|
||||
property bool dim: false
|
||||
property bool underline
|
||||
property var onClicked: function() {}
|
||||
property int leftPadding
|
||||
property int rightPadding
|
||||
|
||||
property string fgColor: "white"
|
||||
property string dimFgColor: "#999999"
|
||||
property string hoveredBgColor: "#444444"
|
||||
|
||||
// Background color
|
||||
color: {
|
||||
if (mouseArea.containsMouse)
|
||||
return hoveredBgColor;
|
||||
return "transparent";
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
when: mouseArea.containsMouse
|
||||
PropertyChanges {
|
||||
target: root
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
|
||||
BarText {
|
||||
id: wsText
|
||||
text: root.text
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: root.leftPadding
|
||||
rightMargin: root.rightPadding
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
color: {
|
||||
if (mouseArea.containsMouse || !root.dim)
|
||||
return fgColor
|
||||
return dimFgColor
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: 100
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: root
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onClicked: root.onClicked()
|
||||
}
|
||||
|
||||
// While line underneath workspace
|
||||
Rectangle {
|
||||
id: wsLine
|
||||
width: parent.width
|
||||
height: 3
|
||||
|
||||
color: {
|
||||
if (parent.underline)
|
||||
return fgColor;
|
||||
return "transparent";
|
||||
}
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
|
||||
39
quickshell/.config/quickshell/bar/BarText.qml
Normal file
39
quickshell/.config/quickshell/bar/BarText.qml
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
property string text
|
||||
property string color: "white"
|
||||
property string mainFont: "FiraCode"
|
||||
property string symbolFont: "Symbols Nerd Font Mono"
|
||||
property int pointSize: 11
|
||||
|
||||
implicitWidth: thetext.implicitWidth
|
||||
implicitHeight: thetext.implicitHeight
|
||||
|
||||
function wrapSymbols(text) {
|
||||
const isSymbol = (codePoint) =>
|
||||
(codePoint >= 0xE000 && codePoint <= 0xF8FF) // Private Use Area
|
||||
|| (codePoint >= 0xF0000 && codePoint <= 0xFFFFF) // Supplementary Private Use Area-A
|
||||
|| (codePoint >= 0x100000 && codePoint <= 0x10FFFF); // Supplementary Private Use Area-B
|
||||
|
||||
return text.replace(/./gu, (c) => isSymbol(c.codePointAt(0))
|
||||
? `<span style='font-family: ${symbolFont}; letter-spacing: -5px; font-size: ${pointSize + 4}px'>${c}</span>`
|
||||
: c);
|
||||
}
|
||||
|
||||
Text {
|
||||
id: thetext
|
||||
text: wrapSymbols(parent.text)
|
||||
color: parent.color
|
||||
anchors.centerIn: parent
|
||||
|
||||
font {
|
||||
family: parent.mainFont
|
||||
pointSize: parent.pointSize
|
||||
}
|
||||
textFormat: Text.RichText
|
||||
}
|
||||
}
|
||||
|
||||
11
quickshell/.config/quickshell/bar/Notification.qml
Normal file
11
quickshell/.config/quickshell/bar/Notification.qml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import QtQuick
|
||||
|
||||
Text {
|
||||
required property int id
|
||||
required property string body
|
||||
required property string summary
|
||||
property int margin
|
||||
|
||||
text: `- ${summary}: ${body}`
|
||||
}
|
||||
|
||||
101
quickshell/.config/quickshell/bar/NotificationPanel.qml
Normal file
101
quickshell/.config/quickshell/bar/NotificationPanel.qml
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Services.Notifications
|
||||
|
||||
PanelWindow {
|
||||
// required property font custom_font
|
||||
required property color text_color
|
||||
property list<QtObject> notification_objects
|
||||
|
||||
width: 500
|
||||
height: 600
|
||||
|
||||
color: "#171a18"
|
||||
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
|
||||
Rectangle {
|
||||
border.width: 5
|
||||
border.color: "#8ec07c"
|
||||
anchors.fill: parent
|
||||
color: "transparent"
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
anchors {
|
||||
left: parent.left
|
||||
leftMargin: 10
|
||||
right: parent.right
|
||||
rightMargin: 10
|
||||
top: parent.top
|
||||
topMargin: 10
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
text: "Notifications:"
|
||||
// font: custom_font
|
||||
color: text_color
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "clear"
|
||||
// font: custom_font
|
||||
color: text_color
|
||||
|
||||
TapHandler {
|
||||
id: tapHandler
|
||||
gesturePolicy: TapHandler.ReleaseWithinBounds
|
||||
onTapped: {
|
||||
server.trackedNotifications.values.forEach((notification) => {
|
||||
notification.tracked = false
|
||||
})
|
||||
notification_objects.forEach((object) => {
|
||||
object.destroy();
|
||||
})
|
||||
notification_objects = [];
|
||||
}
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
id: mouse
|
||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NotificationServer {
|
||||
id: server
|
||||
onNotification: (notification) => {
|
||||
notification.tracked = true
|
||||
console.log(JSON.stringify(notification));
|
||||
var notification_component = Qt.createComponent("Notification.qml");
|
||||
var notification_object = notification_component
|
||||
.createObject(content,
|
||||
{
|
||||
id: notification.id,
|
||||
body: notification.body,
|
||||
summary: notification.summary,
|
||||
// font: custom_font,
|
||||
color: text_color,
|
||||
margin: 10
|
||||
}
|
||||
)
|
||||
if (notification_object == null) {
|
||||
console.log("Error creating notification")
|
||||
} else {
|
||||
notification_objects.push(notification_object);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
89
quickshell/.config/quickshell/bar/Tooltip.qml
Normal file
89
quickshell/.config/quickshell/bar/Tooltip.qml
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
import QtQuick
|
||||
import Quickshell
|
||||
import "root:/" // for Globals
|
||||
|
||||
LazyLoader {
|
||||
id: root
|
||||
|
||||
// The item to display the tooltip at. If set to null the tooltip will be hidden.
|
||||
property Item relativeItem: null
|
||||
|
||||
// Tracks the item after relativeItem is unset.
|
||||
property Item displayItem: null
|
||||
|
||||
property PopupContext popupContext: Globals.popupContext
|
||||
|
||||
property bool hoverable: false;
|
||||
readonly property bool hovered: item?.hovered ?? false
|
||||
|
||||
// The content to show in the tooltip.
|
||||
required default property Component contentDelegate
|
||||
|
||||
active: displayItem != null && popupContext.popup == this
|
||||
|
||||
onRelativeItemChanged: {
|
||||
if (relativeItem == null) {
|
||||
if (item != null) item.hideTimer.start();
|
||||
} else {
|
||||
if (item != null) item.hideTimer.stop();
|
||||
displayItem = relativeItem;
|
||||
popupContext.popup = this;
|
||||
}
|
||||
}
|
||||
|
||||
PopupWindow {
|
||||
anchor {
|
||||
window: root.displayItem.QsWindow.window
|
||||
rect.y: anchor.window.height + 3
|
||||
rect.x: anchor.window.contentItem.mapFromItem(root.displayItem, root.displayItem.width / 2, 0).x
|
||||
edges: Edges.Top
|
||||
gravity: Edges.Bottom
|
||||
}
|
||||
|
||||
visible: true
|
||||
|
||||
property alias hovered: body.containsMouse;
|
||||
|
||||
property Timer hideTimer: Timer {
|
||||
interval: 250
|
||||
|
||||
// unloads the popup by causing active to become false
|
||||
onTriggered: root.popupContext.popup = null;
|
||||
}
|
||||
|
||||
color: "transparent"
|
||||
|
||||
// don't accept mouse input if !hoverable
|
||||
Region { id: emptyRegion }
|
||||
mask: root.hoverable ? null : emptyRegion
|
||||
|
||||
width: body.implicitWidth
|
||||
height: body.implicitHeight
|
||||
|
||||
MouseArea {
|
||||
id: body
|
||||
|
||||
anchors.fill: parent
|
||||
implicitWidth: content.implicitWidth + 10
|
||||
implicitHeight: content.implicitHeight + 10
|
||||
|
||||
hoverEnabled: root.hoverable
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
|
||||
radius: 5
|
||||
border.width: 1
|
||||
color: palette.active.toolTipBase
|
||||
border.color: palette.active.light
|
||||
|
||||
Loader {
|
||||
id: content
|
||||
anchors.centerIn: parent
|
||||
sourceComponent: contentDelegate
|
||||
active: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
quickshell/.config/quickshell/bar/blocks/ActiveWorkspace.qml
Normal file
33
quickshell/.config/quickshell/bar/blocks/ActiveWorkspace.qml
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import QtQuick
|
||||
import Quickshell.Io
|
||||
import Quickshell.Hyprland
|
||||
import "../"
|
||||
|
||||
BarText {
|
||||
text: {
|
||||
var str = activeWindowTitle
|
||||
return str.length > chopLength ? str.slice(0, chopLength) + '...' : str;
|
||||
}
|
||||
|
||||
property int chopLength: 70
|
||||
property string activeWindowTitle
|
||||
|
||||
Process {
|
||||
id: titleProc
|
||||
command: ["sh", "-c", "hyprctl activewindow | grep title: | sed 's/^[^:]*: //'"]
|
||||
running: true
|
||||
|
||||
stdout: SplitParser {
|
||||
onRead: data => activeWindowTitle = data
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
Hyprland.rawEvent.connect(hyprEvent)
|
||||
}
|
||||
|
||||
function hyprEvent(e) {
|
||||
titleProc.running = true
|
||||
}
|
||||
}
|
||||
|
||||
26
quickshell/.config/quickshell/bar/blocks/Battery.qml
Normal file
26
quickshell/.config/quickshell/bar/blocks/Battery.qml
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import QtQuick
|
||||
import Quickshell.Io
|
||||
import "../"
|
||||
|
||||
BarBlock {
|
||||
property string battery
|
||||
text: battery
|
||||
|
||||
Process {
|
||||
id: batteryProc
|
||||
command: ["block_battery"]
|
||||
running: true
|
||||
|
||||
stdout: SplitParser {
|
||||
onRead: data => battery = data
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 1000
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: batteryProc.running = true
|
||||
}
|
||||
}
|
||||
|
||||
37
quickshell/.config/quickshell/bar/blocks/CPU.qml
Normal file
37
quickshell/.config/quickshell/bar/blocks/CPU.qml
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import "../"
|
||||
|
||||
Item {
|
||||
implicitHeight: text.implicitHeight
|
||||
implicitWidth: text.implicitWidth
|
||||
|
||||
property string percentUsed
|
||||
|
||||
Process {
|
||||
id: cpuProc
|
||||
command: ["sh", "-c", "top -bn 1 | grep \"%Cpu(s)\" | awk '{usage=100-$8; printf \"%02d%%\\n\", usage}'"]
|
||||
running: true
|
||||
|
||||
stdout: SplitParser {
|
||||
onRead: data => percentUsed = data
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 2000
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: cpuProc.running = true
|
||||
}
|
||||
|
||||
BarText {
|
||||
id: text
|
||||
text: "<div style = 'font-family: Symbols Nerd Font Mono'>%1</div>%2"
|
||||
.arg(" ") // The rest of the string
|
||||
.arg(percentUsed) // Symbol needs its own font
|
||||
}
|
||||
}
|
||||
8
quickshell/.config/quickshell/bar/blocks/Date.qml
Normal file
8
quickshell/.config/quickshell/bar/blocks/Date.qml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import QtQuick
|
||||
import "../"
|
||||
|
||||
BarBlock {
|
||||
id: text
|
||||
text: ` ${Datetime.date}`
|
||||
}
|
||||
|
||||
31
quickshell/.config/quickshell/bar/blocks/Datetime.qml
Normal file
31
quickshell/.config/quickshell/bar/blocks/Datetime.qml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
pragma Singleton
|
||||
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
|
||||
Singleton {
|
||||
property string time;
|
||||
property string date;
|
||||
|
||||
Process {
|
||||
id: dateProc
|
||||
command: ["date", "+%a %e %b|%R"]
|
||||
running: true
|
||||
|
||||
stdout: SplitParser {
|
||||
onRead: data => {
|
||||
date = data.split("|")[0]
|
||||
time = data.split("|")[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 1000
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: dateProc.running = true
|
||||
}
|
||||
}
|
||||
|
||||
11
quickshell/.config/quickshell/bar/blocks/Icon.qml
Normal file
11
quickshell/.config/quickshell/bar/blocks/Icon.qml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import "../"
|
||||
|
||||
BarBlock {
|
||||
Layout.preferredWidth: 30
|
||||
rightPadding: 5
|
||||
text: ""
|
||||
}
|
||||
|
||||
29
quickshell/.config/quickshell/bar/blocks/Memory.qml
Normal file
29
quickshell/.config/quickshell/bar/blocks/Memory.qml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import "../"
|
||||
|
||||
BarBlock {
|
||||
id: text
|
||||
text: ` ${Math.floor(percentFree)}%`
|
||||
|
||||
property real percentFree
|
||||
|
||||
Process {
|
||||
id: memProc
|
||||
command: ["sh", "-c", "free | grep Mem | awk '{print $3/$2 * 100.0}'"]
|
||||
running: true
|
||||
|
||||
stdout: SplitParser {
|
||||
onRead: data => percentFree = data
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 2000
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: memProc.running = true
|
||||
}
|
||||
}
|
||||
34
quickshell/.config/quickshell/bar/blocks/Notifications.qml
Normal file
34
quickshell/.config/quickshell/bar/blocks/Notifications.qml
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import QtQuick
|
||||
import Quickshell.Services.Notifications
|
||||
import "../"
|
||||
|
||||
BarBlock {
|
||||
id: root
|
||||
property bool showNotification: false
|
||||
|
||||
text: " " + notifServer.trackedNotifications.values.length
|
||||
onClicked: function() {
|
||||
showNotification = !showNotification
|
||||
}
|
||||
|
||||
NotificationServer {
|
||||
id: notifServer
|
||||
onNotification: (notification) => {
|
||||
notification.tracked = true
|
||||
}
|
||||
}
|
||||
|
||||
NotificationPanel {
|
||||
text_color: root.color
|
||||
visible: showNotification
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
}
|
||||
|
||||
margins {
|
||||
top: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
quickshell/.config/quickshell/bar/blocks/Sound.qml
Normal file
15
quickshell/.config/quickshell/bar/blocks/Sound.qml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Services.Pipewire
|
||||
import "../"
|
||||
|
||||
BarBlock {
|
||||
id: text
|
||||
text: ` ${Math.floor(sink?.audio.volume * 100)}%`
|
||||
|
||||
property PwNode sink: Pipewire.defaultAudioSink
|
||||
PwObjectTracker { objects: [ sink ] }
|
||||
}
|
||||
|
||||
74
quickshell/.config/quickshell/bar/blocks/SystemTray.qml
Normal file
74
quickshell/.config/quickshell/bar/blocks/SystemTray.qml
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.SystemTray
|
||||
import "../" as Bar
|
||||
|
||||
RowLayout {
|
||||
spacing: 5
|
||||
|
||||
Repeater {
|
||||
model: SystemTray.items
|
||||
|
||||
MouseArea {
|
||||
id: delegate
|
||||
required property SystemTrayItem modelData
|
||||
property alias item: delegate.modelData
|
||||
|
||||
Layout.fillHeight: true
|
||||
implicitWidth: icon.implicitWidth + 5
|
||||
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
||||
hoverEnabled: true
|
||||
|
||||
onClicked: event => {
|
||||
if (event.button == Qt.LeftButton) {
|
||||
item.activate();
|
||||
} else if (event.button == Qt.MiddleButton) {
|
||||
item.secondaryActivate();
|
||||
} else if (event.button == Qt.RightButton) {
|
||||
menuAnchor.open();
|
||||
}
|
||||
}
|
||||
|
||||
onWheel: event => {
|
||||
event.accepted = true;
|
||||
const points = event.angleDelta.y / 120
|
||||
item.scroll(points, false);
|
||||
}
|
||||
|
||||
IconImage {
|
||||
id: icon
|
||||
anchors.centerIn: parent
|
||||
source: item.icon
|
||||
|
||||
implicitSize: 16
|
||||
}
|
||||
|
||||
QsMenuAnchor {
|
||||
id: menuAnchor
|
||||
menu: item.menu
|
||||
|
||||
anchor.window: delegate.QsWindow.window
|
||||
anchor.adjustment: PopupAdjustment.Flip
|
||||
|
||||
anchor.onAnchoring: {
|
||||
const window = delegate.QsWindow.window;
|
||||
const widgetRect = window.contentItem.mapFromItem(delegate, 0, delegate.height, delegate.width, delegate.height);
|
||||
|
||||
menuAnchor.anchor.rect = widgetRect;
|
||||
}
|
||||
}
|
||||
|
||||
Bar.Tooltip {
|
||||
relativeItem: delegate.containsMouse ? delegate : null
|
||||
|
||||
Label {
|
||||
text: delegate.item.tooltipTitle || delegate.item.id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
77
quickshell/.config/quickshell/bar/blocks/Test.qml
Normal file
77
quickshell/.config/quickshell/bar/blocks/Test.qml
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Services.SystemTray
|
||||
import "../"
|
||||
|
||||
Repeater {
|
||||
// model: SystemTray.items
|
||||
model: ScriptModel {
|
||||
values: SystemTray.items.values
|
||||
.filter((item) => item.id == "nm-tray")
|
||||
}
|
||||
|
||||
|
||||
BarBlock {
|
||||
id: block
|
||||
Layout.preferredWidth: 30
|
||||
leftPadding: 4
|
||||
text: " "
|
||||
|
||||
required property SystemTrayItem modelData
|
||||
property alias item: block.modelData
|
||||
|
||||
MouseArea {
|
||||
id: delegate
|
||||
anchors.fill: block
|
||||
|
||||
property alias item: block.item
|
||||
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
||||
hoverEnabled: true
|
||||
|
||||
onClicked: event => {
|
||||
if (event.button == Qt.LeftButton) {
|
||||
item.activate();
|
||||
} else if (event.button == Qt.MiddleButton) {
|
||||
item.secondaryActivate();
|
||||
} else if (event.button == Qt.RightButton) {
|
||||
menuAnchor.open();
|
||||
}
|
||||
}
|
||||
|
||||
onWheel: event => {
|
||||
event.accepted = true;
|
||||
const points = event.angleDelta.y / 120
|
||||
item.scroll(points, false);
|
||||
}
|
||||
|
||||
QsMenuAnchor {
|
||||
id: menuAnchor
|
||||
menu: item.menu
|
||||
|
||||
anchor.window: delegate.QsWindow.window
|
||||
anchor.adjustment: PopupAdjustment.Flip
|
||||
|
||||
anchor.onAnchoring: {
|
||||
console.log("here2")
|
||||
const window = delegate.QsWindow.window;
|
||||
const widgetRect = window.contentItem.mapFromItem(delegate, 0, delegate.height, delegate.width, delegate.height);
|
||||
|
||||
menuAnchor.anchor.rect = widgetRect;
|
||||
}
|
||||
}
|
||||
|
||||
Tooltip {
|
||||
relativeItem: delegate.containsMouse ? delegate : null
|
||||
|
||||
Label {
|
||||
text: delegate.item.tooltipTitle || delegate.item.id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
8
quickshell/.config/quickshell/bar/blocks/Time.qml
Normal file
8
quickshell/.config/quickshell/bar/blocks/Time.qml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import QtQuick
|
||||
import "../"
|
||||
|
||||
BarBlock {
|
||||
id: text
|
||||
text: ` ${Datetime.time}`
|
||||
}
|
||||
|
||||
63
quickshell/.config/quickshell/bar/blocks/Workspaces.qml
Normal file
63
quickshell/.config/quickshell/bar/blocks/Workspaces.qml
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Hyprland
|
||||
import "root:/"
|
||||
import "../"
|
||||
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
property HyprlandMonitor monitor: Hyprland.monitorFor(screen)
|
||||
|
||||
Repeater {
|
||||
model: ScriptModel {
|
||||
values: {
|
||||
var seenEmpty = false
|
||||
return [...Hyprland.workspaces.values]
|
||||
.filter((ws) => {
|
||||
if (ws.monitor !== monitor || ws.name.includes("special"))
|
||||
return false
|
||||
|
||||
// There is a flickering that can happen when switching from one
|
||||
// empty workspace to another where both empty workspaces are shown
|
||||
// on the bar at the same time. This ensures that only the first
|
||||
// empty workspace is shown.
|
||||
const isNumeric = /^\d+$/.test(ws.name);
|
||||
if (!isNumeric)
|
||||
return true;
|
||||
if (!seenEmpty) {
|
||||
seenEmpty = true
|
||||
return true
|
||||
}
|
||||
return false;
|
||||
})
|
||||
// Sort workspaces by id
|
||||
.sort((a, b) => a.id - b.id)
|
||||
}
|
||||
}
|
||||
|
||||
BarBlock {
|
||||
property HyprlandWorkspace ws: modelData
|
||||
property bool isActive: Hyprland.focusedMonitor?.activeWorkspace?.id === ws.id
|
||||
property bool isOpen: monitor.activeWorkspace?.id === ws.id
|
||||
property bool hasClients: ws.name.length > 2
|
||||
|
||||
dim: true
|
||||
underline: isActive || isOpen
|
||||
onClicked: function() {
|
||||
Hyprland.dispatch(`workspace ${ws.id}`);
|
||||
}
|
||||
leftPadding: hasClients ? 2 : 0
|
||||
text: {
|
||||
if (isActive) {
|
||||
if (!hasClients)
|
||||
return `<span style='color:${fgColor};'>${ws.name}</span>`
|
||||
var split_i = ws.id > 9 ? 3 : 2
|
||||
return `<span style='color:${fgColor};'>${ws.name.slice(0, split_i)}</span>${ws.name.slice(split_i)}`
|
||||
}
|
||||
return ws.name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
8
quickshell/.config/quickshell/shell.qml
Normal file
8
quickshell/.config/quickshell/shell.qml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
//@ pragma UseQApplication
|
||||
import Quickshell
|
||||
import "bar" as Bar
|
||||
|
||||
ShellRoot {
|
||||
Bar.Bar {}
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue