diff --git a/modules/bar/Bar.qml b/modules/bar/Bar.qml index bd6f0e8..5e1b62c 100644 --- a/modules/bar/Bar.qml +++ b/modules/bar/Bar.qml @@ -8,43 +8,57 @@ Variants { delegate: PanelWindow { id: root + required property var modelData implicitHeight: Settings.config.barHeight aboveWindows: true - required property var modelData - color: Qt.rgba(Colors.background.r, Colors.background.g, Colors.background.b, 0.6) screen: modelData + margins { + top: Settings.config.margins + left: Settings.config.margins + right: Settings.config.margins + } + anchors { top: true left: true right: true } - Row { - id: leftStuff - leftPadding: 10 - spacing: 20 - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - Workspaces { - property var screen: root.modelData + color: "transparent" + Rectangle { + id: container + implicitHeight: Settings.config.barHeight + anchors.fill: parent + color: Colors.background + radius: implicitHeight / 2 + + Row { + id: leftStuff + leftPadding: 10 + spacing: 20 + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + Workspaces { + property var screen: root.modelData + } + Title {} } - Title {} - } - Row { - id: centerStuff - anchors.centerIn: parent - Clock {} - } + Row { + id: centerStuff + anchors.centerIn: parent + Clock {} + } - Row { - id: rightStuff - rightPadding: 10 - spacing: 10 - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - Volume {} - Battery {} - SystemTray {} + Row { + id: rightStuff + rightPadding: 10 + spacing: 10 + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + Volume {} + Battery {} + SystemTray {} + } } } } diff --git a/modules/bar/Clock.qml b/modules/bar/Clock.qml index 6c0d667..f29b34b 100644 --- a/modules/bar/Clock.qml +++ b/modules/bar/Clock.qml @@ -2,18 +2,28 @@ import Quickshell import QtQuick import "../../reusables/" import "../../settings/" +import "../../" -Item { - id: root - implicitWidth: clockText.implicitWidth - implicitHeight: Settings.config.barHeight - SystemClock { - id: clock - precision: SystemClock.Minutes - } - CustomText { - id: clockText +Rectangle { + id: container + radius: implicitHeight / 2 + color: Colors.color0 + anchors.verticalCenter: parent.verticalCenter + implicitHeight: Settings.config.barHeight - 10 + implicitWidth: root.implicitWidth + 20 + Item { + id: root anchors.centerIn: parent - text: Qt.formatDateTime(clock.date, "hh:mm") + implicitWidth: clockText.implicitWidth + implicitHeight: Settings.config.barHeight + SystemClock { + id: clock + precision: SystemClock.Minutes + } + CustomText { + id: clockText + anchors.centerIn: parent + text: Qt.formatDateTime(clock.date, "hh:mm") + } } } diff --git a/modules/bar/Title.qml b/modules/bar/Title.qml index 9c9a126..7beb776 100644 --- a/modules/bar/Title.qml +++ b/modules/bar/Title.qml @@ -1,19 +1,26 @@ import QtQuick import "../../reusables/" import "../../settings/" -import Quickshell.Hyprland +import "../../" +import Quickshell.Wayland -Item { - id: root - readonly property var activeWindow: Hyprland.activeToplevel - implicitWidth: Math.min(text.implicitWidth, 500) - implicitHeight: Settings.config.barHeight - CustomText { - anchors.left: parent.left - anchors.right: parent.right - id: text - anchors.verticalCenter: parent.verticalCenter - text: root.activeWindow ? Hyprland.activeToplevel.title : "Desktop" - elide: Text.ElideRight +Rectangle { + id: container + radius: implicitHeight / 2 + color: Colors.color0 + anchors.verticalCenter: parent.verticalCenter + implicitWidth: root.implicitWidth + implicitHeight: Settings.config.barHeight - 10 + Item { + id: root + readonly property var activeWindow: ToplevelManager.activeToplevel + implicitWidth:titleText.implicitWidth + 20 + implicitHeight: Settings.config.barHeight + CustomText { + anchors.horizontalCenter: parent.horizontalCenter + id: titleText + text: root.activeWindow.activated ? root.activeWindow.appId : "Desktop" + elide: Text.ElideRight + } } } diff --git a/modules/bar/Volume.qml b/modules/bar/Volume.qml index 9bd301a..d25fc4a 100644 --- a/modules/bar/Volume.qml +++ b/modules/bar/Volume.qml @@ -6,60 +6,69 @@ import "../../reusables/" import "../../settings/" import "../../" -Item { - id: root - implicitWidth: textRow.width - implicitHeight: Settings.config.barHeight - property var sink: Pipewire.defaultAudioSink - function getVolumeIcon() { - // Safety check: if Pipewire is dead or sink is missing - if (!sink) - return "volume_off"; +Rectangle { + id: container + radius: implicitHeight / 2 + color: Colors.color0 + anchors.verticalCenter: parent.verticalCenter + implicitWidth: root.implicitWidth + 20 + implicitHeight: Settings.config.barHeight - 10 + Item { + id: root + anchors.centerIn: parent + implicitWidth: textRow.width + implicitHeight: Settings.config.barHeight + property var sink: Pipewire.defaultAudioSink + function getVolumeIcon() { + // Safety check: if Pipewire is dead or sink is missing + if (!sink) + return "volume_off"; - // If muted, show the hush icon - if (sink.audio.muted) - return "volume_off"; + // If muted, show the hush icon + if (sink.audio.muted) + return "volume_off"; - // Volume is usually 0.0 to 1.0 (0% to 100%) - const vol = sink.audio.volume; + // Volume is usually 0.0 to 1.0 (0% to 100%) + const vol = sink.audio.volume; - if (vol <= 0.25) - return "volume_mute"; - if (vol < 0.75) - return "volume_down"; - if (vol <= 1.00) + if (vol <= 0.25) + return "volume_mute"; + if (vol < 0.75) + return "volume_down"; + if (vol <= 1.00) + return "volume_up"; + + // If it's loud, prepare the ears! return "volume_up"; - - // If it's loud, prepare the ears! - return "volume_up"; - } - Row { - id: textRow - anchors.verticalCenter: parent.verticalCenter - spacing: 0 - CustomText { - id: volumeText - PwObjectTracker { - objects: Pipewire.ready ? Pipewire.defaultAudioSink : [] + } + Row { + id: textRow + anchors.verticalCenter: parent.verticalCenter + spacing: 0 + CustomText { + id: volumeText + PwObjectTracker { + objects: Pipewire.ready ? Pipewire.defaultAudioSink : [] + } + text: Pipewire.ready ? Math.round(root.sink.audio.volume * 100) + "%" : "failure" + opacity: Pipewire.ready ? root.sink.audio.muted ? 0.5 : 1 : 0 + } + CustomIcon { + id: volumeIcon + opacity: Pipewire.ready ? root.sink.audio.muted ? 0.5 : 1 : 0 + text: Pipewire.ready ? root.getVolumeIcon() : null } - text: Pipewire.ready ? Math.round(root.sink.audio.volume * 100) + "%" : "failure" - opacity: Pipewire.ready ? root.sink.audio.muted ? 0.5 : 1 : 0 } - CustomIcon { - id: volumeIcon - opacity: Pipewire.ready ? root.sink.audio.muted ? 0.5 : 1 : 0 - text: Pipewire.ready ? root.getVolumeIcon() : null + MouseArea { + id: pavuArea + Process { + id: pavuLauncher + command: ["sh", "-c", "pavucontrol"] + } + anchors.fill: root + onClicked: pavuLauncher.exec(pavuLauncher.command) + acceptedButtons: Qt.LeftButton + cursorShape: Qt.PointingHandCursor } } - MouseArea { - id: pavuArea - Process { - id: pavuLauncher - command: ["sh", "-c", "pavucontrol"] - } - anchors.fill: root - onClicked: pavuLauncher.exec(pavuLauncher.command) - acceptedButtons: Qt.LeftButton - cursorShape: Qt.PointingHandCursor - } } diff --git a/modules/notifications/Notification.qml b/modules/notifications/Notification.qml index bba7600..8339974 100644 --- a/modules/notifications/Notification.qml +++ b/modules/notifications/Notification.qml @@ -2,13 +2,7 @@ pragma ComponentBehavior: Bound import QtQuick import Quickshell import Quickshell.Wayland -import Quickshell.Hyprland -import "." -import "../../" -import QtQuick.Layouts -import Quickshell.Widgets import "../../settings/" -import "../../reusables/" Variants { model: Quickshell.screens @@ -23,7 +17,7 @@ Variants { bottom: true } margins { - top: Settings.config.barHeight + 10 + top: Settings.config.barHeight + Settings.config.margins + 10 right: 10 left: 10 } @@ -48,80 +42,7 @@ Variants { height: contentHeight model: NotiServer.trackedNotifications - delegate: Item { - id: notifyItem - required property var index - required property var modelData - anchors.right: parent ? parent.right : root.anchors.right - implicitWidth: root.modelData.width / 8 - implicitHeight: notiIcon.implicitHeight + 20 - Timer { - id: dismissTimer - interval: 5000 - running: true - onTriggered: parent.modelData.dismiss() - } - - Rectangle { - anchors.fill: parent - color: Colors.background - border.color: Colors.color5 - border.width: 2 - - RowLayout { - id: fullLayout - anchors.margins: 10 - anchors.fill: parent - spacing: 10 - - ClippingWrapperRectangle { - id: notiIcon - radius: 0 - implicitWidth: 64 - implicitHeight: 64 - visible: notifyItem.modelData.image !== "" - IconImage { - source: notifyItem.modelData.image - visible: notifyItem.modelData.image !== "" - implicitSize: 30 - asynchronous: true - } - } - - ColumnLayout { - id: textLayout - Layout.fillWidth: true - Layout.alignment: Qt.AlignTop - spacing: 2 - - CustomText { - text: notifyItem.modelData.summary - font.bold: true - elide: Text.ElideRight - Layout.fillWidth: true - onTextChanged: dismissTimer.restart() - } - - CustomText { - text: notifyItem.modelData.body - - maximumLineCount: 3 - wrapMode: Text.WordWrap - elide: Text.ElideRight - Layout.fillWidth: true - } - } - } - - MouseArea { - anchors.fill: parent - Layout.fillWidth: true - Layout.fillHeight: true - acceptedButtons: Qt.LeftButton - onClicked: notifyItem.modelData.dismiss() - } - } - } + delegate: NotificationCard {} } } } diff --git a/modules/notifications/NotificationCard.qml b/modules/notifications/NotificationCard.qml new file mode 100644 index 0000000..6b16978 --- /dev/null +++ b/modules/notifications/NotificationCard.qml @@ -0,0 +1,77 @@ +import QtQuick +import QtQuick.Layouts +import "../../" +import "../../reusables" +import Quickshell.Widgets + +Rectangle { + id: notifyItem + required property var modelData + implicitWidth: ListView.view ? ListView.view.width : 300 + implicitHeight: fullLayout.implicitHeight + 20 + color: Colors.background + border.color: dismissArea.containsMouse ? Colors.foreground : Colors.color8 + radius: 24 + Timer { + id: dismissTimer + interval: 5000 + running: true + onTriggered: notifyItem.modelData.dismiss() + } + + RowLayout { + id: fullLayout + anchors.margins: 10 + anchors.fill: parent + spacing: 10 + + ClippingWrapperRectangle { + id: notiIcon + radius: notifyItem.radius - notifyItem.radius / 3 + implicitWidth: 64 + implicitHeight: 64 + visible: notifyItem.modelData.image !== "" + IconImage { + source: notifyItem.modelData.image + visible: notifyItem.modelData.image !== "" + implicitSize: 30 + asynchronous: true + } + } + + ColumnLayout { + id: textLayout + Layout.fillWidth: true + Layout.alignment: Qt.AlignTop + spacing: 2 + + CustomText { + id: summary + text: notifyItem.modelData.summary + font.bold: true + elide: Text.ElideRight + Layout.fillWidth: true + onTextChanged: { + dismissTimer.restart(); + } + } + + CustomText { + text: notifyItem.modelData.body + maximumLineCount: 2 + wrapMode: Text.WordWrap + elide: Text.ElideRight + Layout.fillWidth: true + } + } + } + + MouseArea { + id: dismissArea + anchors.fill: parent + acceptedButtons: Qt.LeftButton + onClicked: notifyItem.modelData.dismiss() + cursorShape: Qt.PointingHandCursor + hoverEnabled: true + } +} diff --git a/modules/notifications/qmldir b/modules/notifications/qmldir index 8bec7da..3d7b319 100644 --- a/modules/notifications/qmldir +++ b/modules/notifications/qmldir @@ -1,2 +1,4 @@ singleton NotiServer 1.0 NotiServer.qml Notification 1.0 Notification.qml +NotificationCard 1.0 NotificationCard.qml + diff --git a/modules/polkit/Polkit.qml b/modules/polkit/Polkit.qml new file mode 100644 index 0000000..4833dd1 --- /dev/null +++ b/modules/polkit/Polkit.qml @@ -0,0 +1,5 @@ +import Quickshell +import Quickshell.Services.Polkit + + + diff --git a/settings/Settings.qml b/settings/Settings.qml index 91073db..537dbe8 100644 --- a/settings/Settings.qml +++ b/settings/Settings.qml @@ -21,6 +21,7 @@ Singleton { adapter: JsonAdapter { id: settingsAdapter + property var margins: 10 property var currentWall: "" property var barHeight: 28 property var font: "Google Sans"