From f4d01d2d9f7a921f40a3b192637959ddf9129669 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Wed, 8 Jul 2026 22:51:44 +0200 Subject: ... --- accounts/gkleen@sif/shell/quickshell/Bar.qml | 14 +- .../shell/quickshell/Services/NiriService.qml | 1 + .../gkleen@sif/shell/quickshell/YtDlpWidget.qml | 190 +++++++++++++++++++++ 3 files changed, 203 insertions(+), 2 deletions(-) create mode 100644 accounts/gkleen@sif/shell/quickshell/YtDlpWidget.qml (limited to 'accounts/gkleen@sif/shell/quickshell') diff --git a/accounts/gkleen@sif/shell/quickshell/Bar.qml b/accounts/gkleen@sif/shell/quickshell/Bar.qml index bce72077..33909884 100644 --- a/accounts/gkleen@sif/shell/quickshell/Bar.qml +++ b/accounts/gkleen@sif/shell/quickshell/Bar.qml @@ -89,7 +89,7 @@ PanelWindow { KeyboardLayout {} Item { - visible: privacy.visible + visible: privacy.visible || ytDlp.visible height: parent.height width: 8 - 4 } @@ -99,7 +99,17 @@ PanelWindow { } Item { - visible: privacy.visible + visible: privacy.visible && ytDlp.visible + height: parent.height + width: 8 - 4 + } + + YtDlpWidget { + id: ytDlp + } + + Item { + visible: privacy.visible || ytDlp.visible height: parent.height width: 8 - 4 } diff --git a/accounts/gkleen@sif/shell/quickshell/Services/NiriService.qml b/accounts/gkleen@sif/shell/quickshell/Services/NiriService.qml index cd4ed125..e9e86f95 100644 --- a/accounts/gkleen@sif/shell/quickshell/Services/NiriService.qml +++ b/accounts/gkleen@sif/shell/quickshell/Services/NiriService.qml @@ -80,6 +80,7 @@ Singleton { eventCastStopped(event.CastStopped); else if (event.Ok && !eventStreamSocket.acked) { eventStreamSocket.acked = true; } else if (event.OverviewOpenedOrClosed) {} + else if (event.ScreenshotCaptured) {} else if (event.ConfigLoaded) {} else console.log(JSON.stringify(event)); diff --git a/accounts/gkleen@sif/shell/quickshell/YtDlpWidget.qml b/accounts/gkleen@sif/shell/quickshell/YtDlpWidget.qml new file mode 100644 index 00000000..ff338d49 --- /dev/null +++ b/accounts/gkleen@sif/shell/quickshell/YtDlpWidget.qml @@ -0,0 +1,190 @@ +import QtQml.Models +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls.Material +import Quickshell +import Quickshell.Io +import Quickshell.Widgets +import Custom as Custom + +Item { + id: root + + height: parent.height + width: icon.width + anchors.verticalCenter: parent.verticalCenter + + visible: Boolean(unitsModel.values.length) + + WrapperMouseArea { + id: widgetMouseArea + + anchors.fill: parent + hoverEnabled: true + + Item { + anchors.fill: parent + + MaterialDesignIcon { + id: icon + + implicitSize: 14 + anchors.centerIn: parent + + icon: "tray-arrow-down" + color: "white" + } + } + } + + PopupWindow { + id: tooltip + + property bool openPopup: false + property bool nextVisible: widgetMouseArea.containsMouse || tooltipMouseArea.containsMouse || openPopup + + anchor { + item: widgetMouseArea + edges: Edges.Bottom | Edges.Left + } + visible: false + + onNextVisibleChanged: hangTimer.restart() + + Timer { + id: hangTimer + interval: 100 + onTriggered: tooltip.visible = tooltip.nextVisible + } + + implicitWidth: tooltipContent.width + implicitHeight: tooltipContent.height + color: "transparent" + + Rectangle { + width: tooltip.width + height: tooltipLayout.childrenRect.height + 16 + color: "black" + } + + WrapperItem { + id: tooltipContent + + WrapperMouseArea { + id: tooltipMouseArea + + hoverEnabled: true + enabled: true + + WrapperItem { + margin: 8 + + child: GridLayout { + id: tooltipLayout + + columns: 2 + } + + Repeater { + model: ScriptModel { + id: unitsModel + + values: [...Custom.Systemd.userUnits.values].filter(unit => unit.id.match(/^yt-dlp@.+\.service$/) && unit.activeState === "active" && unit.runtimeDirectory) + } + + Item { + id: unitDelegate + + Component.onCompleted: { + while (children.length) { children[0].parent = tooltipLayout; } + } + + required property var modelData + required property int index + + property var state: null + + Socket { + id: socket + + path: Quickshell.env("XDG_RUNTIME_DIR") + "/" + unitDelegate.modelData.runtimeDirectory[0] + "/status.sock" + connected: true + onError: e => { + console.warn("YtDlpWidget: Error in Socket:", socket.path, e); + } + parser: SplitParser { + onRead: line => { + try { + unitDelegate.state = JSON.parse(line) + } catch (e) { + console.warn("YtDlpWidget: Failed to parse state:", line, e) + } + } + } + } + + WrapperItem { + Layout.column: 0 + Layout.row: unitDelegate.index + + implicitWidth: descText.contentWidth + implicitHeight: descText.contentHeight + + Text { + id: descText + + color: "white" + font.pointSize: 10 + font.family: "Fira Sans" + + text: unitDelegate.state?.title || unitDelegate.modelData.id + } + } + + /* + WrapperItem { + Layout.column: 1 + Layout.row: unitDelegate.index + + implicitWidth: fragText.contentWidth + implicitHeight: fragText.contentHeight + + visible: Boolean(unitDelegate.state) + + Text { + id: fragText + + color: "white" + font.pointSize: 10 + font.family: "Fira Sans" + + text: `${unitDelegate.state?.fragment_index}/${unitDelegate.state?.fragment_count}` + } + } + */ + + WrapperItem { + Layout.column: 1 + Layout.row: unitDelegate.index + + visible: Boolean(unitDelegate.state) + + ProgressBar { + id: progress + + Material.background: "black" + Material.accent: "white" + + from: 0 + to: unitDelegate.state?.total_bytes || unitDelegate.state?.total_bytes_estimate || 0 + value: unitDelegate.state?.downloaded_bytes || 0 + indeterminate: !Boolean(unitDelegate.state?.total_bytes || unitDelegate.state?.total_bytes_estimate) || unitDelegate.state?.status !== "downloading" + } + } + } + } + } + } + } + } +} -- cgit v1.2.3