From eafc417a1734aec649425a633db427391a1eda1a Mon Sep 17 00:00:00 2001 From: voidarc Date: Wed, 10 Jun 2026 21:18:32 +0100 Subject: [PATCH] some nonsense --- .nvim.lua | 3 +- Bar.qml | 39 +++++- Components/Pill.qml | 5 +- Components/Utils.qml | 41 +++++++ Components/Utils/Battery.qml | 8 ++ Components/Utils/Mpris.qml | 4 + Components/Workspace.qml | 225 +++++++++++++++++++++++++++++++++++ 7 files changed, 315 insertions(+), 10 deletions(-) create mode 100644 Components/Utils.qml create mode 100644 Components/Utils/Battery.qml create mode 100644 Components/Utils/Mpris.qml create mode 100644 Components/Workspace.qml diff --git a/.nvim.lua b/.nvim.lua index d5f9ede..62ba8b5 100644 --- a/.nvim.lua +++ b/.nvim.lua @@ -1,3 +1,2 @@ -vim.lsp.enable("qmlls") - require("nvim-treesitter").install({ "qmljs" }) +vim.lsp.enable("qmlls") diff --git a/Bar.qml b/Bar.qml index 79d013e..3018b26 100644 --- a/Bar.qml +++ b/Bar.qml @@ -1,10 +1,11 @@ import Quickshell import Quickshell.Hyprland + import QtQuick -import "Components/Color.js" as Colors +import QtQuick.Effects import "Components" -import "Components/Pill" +import "Components/Color.js" as Colors Scope { Variants { @@ -28,7 +29,12 @@ Scope { exclusionMode: ExclusionMode.Normal mask: Region { - item: container + Region { + item: workspaceSwitcher + } + Region { + item: pillItem + } } anchors { @@ -38,12 +44,33 @@ Scope { } implicitHeight: 1000 - exclusiveZone: 15 + exclusiveZone: 20 - Pill { - id: container + Workspace { + id: workspaceSwitcher monitor: win.monitor } + + RectangularShadow { + anchors.fill: pillItem + offset.x: 3 + offset.y: 3 + radius: pillItem.radius + blur: 20 + spread: 7 + color: Colors.crust + } + Pill { + id: pillItem + monitor: win.monitor + } + + Item { + anchors.fill: parent + Utils { + monitor: win.monitor + } + } } } } diff --git a/Components/Pill.qml b/Components/Pill.qml index f28e1e2..5af3d2e 100644 --- a/Components/Pill.qml +++ b/Components/Pill.qml @@ -2,6 +2,7 @@ import Quickshell import Quickshell.Hyprland import QtQuick import QtQuick.Controls +import QtQuick.Effects import "Color.js" as Colors import "./Pill" @@ -48,9 +49,10 @@ Rectangle { gradient: Gradient { GradientStop { position: 0.0; color: Colors.surface0 } GradientStop { position: container.gradientMidpoint; color: Colors.surface0 } - GradientStop { position: 1.0; color: Colors.overlay0 } + GradientStop { position: 1.0; color: Colors.surface2 } } + border {color: Colors.lavender; width: 2} component SmoothAnim: SpringAnimation { spring: 3 @@ -104,7 +106,6 @@ Rectangle { onClicked: { container.state == 'expanded' ? container.state = "" : container.state = 'expanded'; - print("clicked") } onExited: { diff --git a/Components/Utils.qml b/Components/Utils.qml new file mode 100644 index 0000000..13a11f0 --- /dev/null +++ b/Components/Utils.qml @@ -0,0 +1,41 @@ + +pragma ComponentBehavior: Bound + +import Quickshell +import Quickshell.Hyprland +import QtQuick +import QtQuick.Layouts + +import "./Utils" + +RowLayout { + id: utilsContainer + required property HyprlandMonitor monitor + state: "" + + anchors { + right: parent.right + top: parent.top + } + + states: [ + State { + name: "" + } + ] + + Rectangle { + color: "red" + implicitWidth: 40 + implicitHeight: 40 + } + Rectangle { + color: "blue" + implicitWidth: 40 + implicitHeight: 40 + } + + // Battery {} + // Mpris {} + +} diff --git a/Components/Utils/Battery.qml b/Components/Utils/Battery.qml new file mode 100644 index 0000000..67e59f5 --- /dev/null +++ b/Components/Utils/Battery.qml @@ -0,0 +1,8 @@ +import Quickshell +import QtQuick + +Item { + Text { + text: "some" + } +} diff --git a/Components/Utils/Mpris.qml b/Components/Utils/Mpris.qml new file mode 100644 index 0000000..bc1c4ec --- /dev/null +++ b/Components/Utils/Mpris.qml @@ -0,0 +1,4 @@ +import QtQuick +import Quickshell + +Item {} diff --git a/Components/Workspace.qml b/Components/Workspace.qml new file mode 100644 index 0000000..e5d98ca --- /dev/null +++ b/Components/Workspace.qml @@ -0,0 +1,225 @@ +pragma ComponentBehavior: Bound + +import Quickshell +import Quickshell.Hyprland +import QtQuick +import QtQuick.Layouts +import QtQuick.Effects + +import "Color.js" as Colors + +Item { + id: workspaceRowContainer + required property HyprlandMonitor monitor + state: "" + + function getNextEmptyWorkspaceId() { + let maxId = 0; + let workspaces = Hyprland.workspaces.values; + + for (let i = 0; i < workspaces.length; i++) { + let ws = workspaces[i]; + // Look at all numerical workspaces globally (ignoring special workspaces like scratchpads) + if (ws.id > maxId && ws.id < 99) { + maxId = ws.id; + } + } + + // Returns the next global workspace ID (e.g., if max is 3, returns 4) + console.log(maxId + 1) + return maxId === 0 ? 1 : maxId + 1; + } + + anchors { + top: parent.top + left: parent.left + leftMargin: 15 + topMargin: -33 + } + + HoverHandler { + id: workspaceHoverHandler + } + + Behavior on anchors.topMargin { + NumberAnimation { duration: 100 } + } + + property int textBottomMargin: 0 + + Behavior on textBottomMargin { + NumberAnimation {duration: 80} + } + + states: [ + State { + name: "" + // When not hovered, stay at default + when: !workspaceHoverHandler.hovered + PropertyChanges { workspaceRowContainer.anchors.topMargin: -33 } + }, + State { + name: "hovered" + // Keep the workspace dropped whenever hovered is true + when: workspaceHoverHandler.hovered + PropertyChanges { workspaceRowContainer.anchors.topMargin: -20 } + PropertyChanges { workspaceRowContainer.textBottomMargin: 7 } + } + ] + + implicitWidth: 200 + implicitHeight: 65 + + Row { + id: workspaceRow + spacing: 5 + + + Repeater { + model: Hyprland.workspaces.values + + Item { + id: selectorContainer + required property int index + property HyprlandWorkspace currentWorkspace: Hyprland.workspaces.values[index] + property HyprlandWorkspace globalFocusedWorkspace: Hyprland.focusedWorkspace + implicitHeight: 50 + implicitWidth: currentWorkspace.focused && workspaceRowContainer.state == "hovered" ? 50 : workspaceRowContainer.state == "hovered" ? 30 : 25 + + onGlobalFocusedWorkspaceChanged: { + if (globalFocusedWorkspace.id === currentWorkspace.id) { + selectorContainer.state = "workspaceSwitched" + switchFeedbackTimer.restart() + } + } + + Timer { + id: switchFeedbackTimer + interval: 200 + repeat: false + onTriggered: selectorContainer.state = "" + } + + anchors { + top: parent.top + topMargin: 0 + } + + HoverHandler { + id: selectorHoverHandler + } + + MouseArea { + id: selectorMouseArea + anchors.fill: parent + hoverEnabled: true + propagateComposedEvents: true + + onClicked: selectorContainer.currentWorkspace.activate() + } + + Behavior on anchors.topMargin { + NumberAnimation {duration: 100} + } + + Behavior on implicitWidth { + NumberAnimation {duration: 100} + } + + states: [ + State { + name: "" + when: !selectorHoverHandler.hovered + PropertyChanges { selectorContainer.anchors.topMargin: 0 } + }, + State { + name: "individualHovered" + when: selectorHoverHandler.hovered + PropertyChanges { selectorContainer.anchors.topMargin: 10 } + }, + State { + name: "workspaceSwitched" + PropertyChanges { selectorContainer.anchors.topMargin: 5 } + } + ] + + visible: Hyprland.workspaces.values[index].monitor == monitor && index > 0 && selectorContainer.currentWorkspace.name != "special:scratch" && selectorContainer.currentWorkspace.name != "special:music" + + RectangularShadow { + anchors.fill: selector + offset.x: 3 + offset.y: 3 + radius: selector.radius + blur: 20 + z: -1 + spread: 7 + color: Colors.crust + } + Rectangle { + z: 1 + id: selector + state: "" + + color: selectorContainer.currentWorkspace.focused ? Colors.mauve : workspaceRowContainer.monitor.activeWorkspace.id == selectorContainer.currentWorkspace.id ? Colors.lavender : Colors.overlay1 + radius: 8 + anchors.fill: parent + + Behavior on color { + ColorAnimation {duration: 100} + } + + Text { + id: workspaceIdentifier + text: selectorContainer.currentWorkspace.name + font.family: "FiraMono Nerd Font" + font.pixelSize: workspaceRowContainer.state == "hovered" ? 15 : 13 + anchors { + bottom: parent.bottom + horizontalCenter: parent.horizontalCenter + bottomMargin: workspaceRowContainer.textBottomMargin + } + } + + } + } + } + Item { + implicitHeight: 40 + implicitWidth: 20 + + + anchors { + top: parent.top + topMargin: workspaceRowContainer.state == "hovered" ? 0 : -10 + } + + Behavior on anchors.topMargin { + NumberAnimation {duration: 100} + } + + MouseArea { + id: newWorkspaceButton + anchors.fill: parent + + onClicked: Hyprland.dispatch(`hl.dsp.focus({workspace = ${workspaceRowContainer.getNextEmptyWorkspaceId()}})`) + } + Rectangle { + color: Colors.surface2 + anchors.fill: parent + radius: 10 + border.color: Colors.text + border.width: 2 + Text { + text: "+" + color: Colors.text + font.family: "FiraMono Nerd Font" + font.pixelSize: 20 + anchors { + bottom: parent.bottom + horizontalCenter: parent.horizontalCenter + } + } + } + } + } +}