diff --git a/tailscalectl/TailscaleWidget.qml b/tailscalectl/TailscaleWidget.qml index e9d5f27..4bdc647 100644 --- a/tailscalectl/TailscaleWidget.qml +++ b/tailscalectl/TailscaleWidget.qml @@ -18,6 +18,7 @@ PluginComponent { property string _copyText: "" property string _copyCurrentTool: "" property int _copyAttempted: 0 + property bool _pendingToggle: false // transient one-shot for poll-then-act (#42) — reset immediately after use, no "desired state" cache layerNamespacePlugin: "tailscalectl" popoutWidth: 360 @@ -111,12 +112,21 @@ PluginComponent { root.peers = [] ToastService.showError("tailscalectl", TailscaleLib.errorMessage("status")) } + + // #42 poll-then-act: if a toggle was requested, use the *fresh* state we just received + if (root._pendingToggle) { + root._pendingToggle = false + toggleProcess.command = TailscaleLib.buildToggleCommand(root.isConnected) + toggleProcess.running = true + } } } function toggleTailscale() { - toggleProcess.command = TailscaleLib.buildToggleCommand(root.isConnected) - toggleProcess.running = true + // #42: poll-then-act — never decide up/down from potentially stale root.isConnected. + // Force a fresh statusCheck; the decision happens in its onExited using the just-received value. + root._pendingToggle = true + statusCheck.running = true } function setExitNode(hostname) {