import QtQuick import qs.Common import qs.Services import qs.Widgets import qs.Modules.Plugins import Quickshell.Io PluginComponent { id: root property bool isConnected: false Process { id: toggleProcess onExited: (code, status) => { statusCheck.running = true } } Process { id: statusCheck command: ["tailscale", "status", "--json"] stdout: StdioCollector { onStreamFinished: { try { const data = JSON.parse(this.text) root.isConnected = data.BackendState === "Running" } catch (e) { root.isConnected = false } } } onExited: (code, status) => { if (code !== 0) { root.isConnected = false } } } function toggleTailscale() { if (root.isConnected) { toggleProcess.command = ["tailscale", "down"] } else { toggleProcess.command = ["tailscale", "up"] } toggleProcess.running = true } horizontalBarPill: Component { MouseArea { implicitWidth: contentRow.implicitWidth implicitHeight: contentRow.implicitHeight cursorShape: Qt.PointingHandCursor acceptedButtons: Qt.RightButton onClicked: toggleTailscale() Row { id: contentRow spacing: Theme.spacingS DankIcon { name: root.isConnected ? "vpn_key" : "vpn_key_off" size: Theme.iconSize color: root.isConnected ? Theme.primary : Theme.surfaceText anchors.verticalCenter: parent.verticalCenter } } } } verticalBarPill: Component { MouseArea { implicitWidth: contentColumn.implicitWidth implicitHeight: contentColumn.implicitHeight cursorShape: Qt.PointingHandCursor acceptedButtons: Qt.RightButton onClicked: toggleTailscale() Column { id: contentColumn spacing: Theme.spacingXS DankIcon { name: root.isConnected ? "vpn_key" : "vpn_key_off" size: Theme.iconSize color: root.isConnected ? Theme.primary : Theme.surfaceText anchors.horizontalCenter: parent.horizontalCenter } } } } }