aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-04-29 15:52:17 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2019-04-29 15:52:17 +0200
commit3245ef2f821fee0580f7d97c6f05223c2673e318 (patch)
treea37424f17b611c6d5d04da9fceb4a756dadf52ab
parentui: account for IPC failures in UI initialization (diff)
downloadwireguard-windows-3245ef2f821fee0580f7d97c6f05223c2673e318.tar.xz
wireguard-windows-3245ef2f821fee0580f7d97c6f05223c2673e318.zip
service: pass global state with notification
-rw-r--r--service/ipc_client.go11
-rw-r--r--service/ipc_server.go4
-rw-r--r--ui/confview.go43
-rw-r--r--ui/managewindow.go12
-rw-r--r--ui/tray.go21
-rw-r--r--ui/tunnelspage.go28
-rw-r--r--ui/tunnelsview.go2
7 files changed, 64 insertions, 57 deletions
diff --git a/service/ipc_client.go b/service/ipc_client.go
index 55fc043d..a6241af2 100644
--- a/service/ipc_client.go
+++ b/service/ipc_client.go
@@ -37,7 +37,7 @@ const (
var rpcClient *rpc.Client
type TunnelChangeCallback struct {
- cb func(tunnel *Tunnel, state TunnelState, err error)
+ cb func(tunnel *Tunnel, state TunnelState, globalState TunnelState, err error)
}
var tunnelChangeCallbacks = make(map[*TunnelChangeCallback]bool)
@@ -70,6 +70,11 @@ func InitializeIPCClient(reader *os.File, writer *os.File, events *os.File) {
if err != nil {
continue
}
+ var globalState TunnelState
+ err = decoder.Decode(&globalState)
+ if err != nil {
+ continue
+ }
var errStr string
err = decoder.Decode(&errStr)
if err != nil {
@@ -84,7 +89,7 @@ func InitializeIPCClient(reader *os.File, writer *os.File, events *os.File) {
}
t := &Tunnel{tunnel}
for cb := range tunnelChangeCallbacks {
- cb.cb(t, state, retErr)
+ cb.cb(t, state, globalState, retErr)
}
case TunnelsChangeNotificationType:
for cb := range tunnelsChangeCallbacks {
@@ -160,7 +165,7 @@ func IPCClientQuit(stopTunnelsOnQuit bool) (bool, error) {
return alreadyQuit, rpcClient.Call("ManagerService.Quit", stopTunnelsOnQuit, &alreadyQuit)
}
-func IPCClientRegisterTunnelChange(cb func(tunnel *Tunnel, state TunnelState, err error)) *TunnelChangeCallback {
+func IPCClientRegisterTunnelChange(cb func(tunnel *Tunnel, state TunnelState, globalState TunnelState, err error)) *TunnelChangeCallback {
s := &TunnelChangeCallback{cb}
tunnelChangeCallbacks[s] = true
return s
diff --git a/service/ipc_server.go b/service/ipc_server.go
index 4dd36b2d..0b0b3a05 100644
--- a/service/ipc_server.go
+++ b/service/ipc_server.go
@@ -294,9 +294,9 @@ func notifyAll(notificationType NotificationType, ifaces ...interface{}) {
func IPCServerNotifyTunnelChange(name string, state TunnelState, err error) {
if err == nil {
- notifyAll(TunnelChangeNotificationType, name, state, "")
+ notifyAll(TunnelChangeNotificationType, name, state, trackedTunnelsGlobalState(), "")
} else {
- notifyAll(TunnelChangeNotificationType, name, state, err.Error())
+ notifyAll(TunnelChangeNotificationType, name, state, trackedTunnelsGlobalState(), err.Error())
}
}
diff --git a/ui/confview.go b/ui/confview.go
index 52883291..57d0b0bf 100644
--- a/ui/confview.go
+++ b/ui/confview.go
@@ -173,28 +173,30 @@ func (tal *toggleActiveLine) widgets() (walk.Widget, walk.Widget) {
return nil, tal.composite
}
+func (tal *toggleActiveLine) updateGlobal(globalState service.TunnelState) {
+ tal.button.SetEnabled(globalState == service.TunnelStarted || globalState == service.TunnelStopped)
+}
+
func (tal *toggleActiveLine) update(state service.TunnelState) {
- var enabled bool
var text string
switch state {
case service.TunnelStarted:
- enabled, text = true, "Deactivate"
+ text = "Deactivate"
case service.TunnelStarting:
- enabled, text = false, "Activating..."
+ text = "Activating..."
case service.TunnelStopped:
- enabled, text = true, "Activate"
+ text = "Activate"
case service.TunnelStopping:
- enabled, text = false, "Deactivating..."
+ text = "Deactivating..."
default:
- enabled, text = false, ""
+ text = ""
}
- tal.button.SetEnabled(enabled)
tal.button.SetText(text)
tal.button.SetVisible(state != service.TunnelUnknown)
}
@@ -397,6 +399,8 @@ func NewConfView(parent walk.Container) (*ConfView, error) {
cv.peers = make(map[conf.Key]*peerView)
cv.tunnelChangedCB = service.IPCClientRegisterTunnelChange(cv.onTunnelChanged)
cv.SetTunnel(nil)
+ globalState, _ := service.IPCClientGlobalState()
+ cv.interfaze.toggleActive.updateGlobal(globalState)
if err := walk.InitWrapperWindow(cv); err != nil {
return nil, err
@@ -426,27 +430,23 @@ func (cv *ConfView) onToggleActiveClicked() {
walk.MsgBox(cv.Form(), "Failed to deactivate tunnel", err.Error(), walk.MsgBoxIconError)
}
}
- cv.SetTunnel(cv.tunnel)
}
-func (cv *ConfView) onTunnelChanged(tunnel *service.Tunnel, state service.TunnelState, err error) {
- if cv.tunnel == nil || cv.tunnel.Name != tunnel.Name {
- return
- }
-
- cv.updateTunnelStatus(state)
-}
-
-func (cv *ConfView) updateTunnelStatus(state service.TunnelState) {
- cv.interfaze.status.update(state)
- cv.interfaze.toggleActive.update(state)
+func (cv *ConfView) onTunnelChanged(tunnel *service.Tunnel, state service.TunnelState, globalState service.TunnelState, err error) {
+ cv.Synchronize(func() {
+ cv.interfaze.toggleActive.updateGlobal(globalState)
+ if cv.tunnel != nil || cv.tunnel.Name == tunnel.Name {
+ cv.interfaze.status.update(state)
+ cv.interfaze.toggleActive.update(state)
+ }
+ })
}
func (cv *ConfView) SetTunnel(tunnel *service.Tunnel) {
cv.tunnel = tunnel
- var state service.TunnelState
var config conf.Config
+ var state service.TunnelState
if tunnel != nil {
if state, _ = tunnel.State(); state == service.TunnelStarted {
config, _ = tunnel.RuntimeConfig()
@@ -475,7 +475,8 @@ func (cv *ConfView) SetTunnel(tunnel *service.Tunnel) {
cv.name.SetTitle(title)
}
cv.interfaze.apply(&config.Interface)
- cv.updateTunnelStatus(state)
+ cv.interfaze.status.update(state)
+ cv.interfaze.toggleActive.update(state)
inverse := make(map[*peerView]bool, len(cv.peers))
for _, pv := range cv.peers {
inverse[pv] = true
diff --git a/ui/managewindow.go b/ui/managewindow.go
index 626b5efb..b3e0c832 100644
--- a/ui/managewindow.go
+++ b/ui/managewindow.go
@@ -76,7 +76,8 @@ func NewManageTunnelsWindow() (*ManageTunnelsWindow, error) {
disposables.Spare()
mtw.tunnelChangedCB = service.IPCClientRegisterTunnelChange(mtw.onTunnelChange)
- mtw.onTunnelChange(nil, service.TunnelUnknown, nil)
+ globalState, _ := service.IPCClientGlobalState()
+ mtw.onTunnelChange(nil, service.TunnelUnknown, globalState, nil)
return mtw, nil
}
@@ -89,14 +90,11 @@ func (mtw *ManageTunnelsWindow) Dispose() {
mtw.MainWindow.Dispose()
}
-func (mtw *ManageTunnelsWindow) onTunnelChange(tunnel *service.Tunnel, state service.TunnelState, err error) {
- globalState, err2 := service.IPCClientGlobalState()
+func (mtw *ManageTunnelsWindow) onTunnelChange(tunnel *service.Tunnel, state service.TunnelState, globalState service.TunnelState, err error) {
mtw.Synchronize(func() {
+ icon, err2 := iconProvider.IconWithOverlayForState(globalState)
if err2 == nil {
- icon, err2 := iconProvider.IconWithOverlayForState(globalState)
- if err2 == nil {
- mtw.SetIcon(icon)
- }
+ mtw.SetIcon(icon)
}
if err != nil && mtw.Visible() {
diff --git a/ui/tray.go b/ui/tray.go
index ca839a83..b2a6446b 100644
--- a/ui/tray.go
+++ b/ui/tray.go
@@ -92,7 +92,8 @@ func (tray *Tray) setup() error {
tray.tunnelChangedCB = service.IPCClientRegisterTunnelChange(tray.onTunnelChange)
tray.tunnelsChangedCB = service.IPCClientRegisterTunnelsChange(tray.onTunnelsChange)
tray.onTunnelsChange()
- tray.updateGlobalState()
+ globalState, _ := service.IPCClientGlobalState()
+ tray.updateGlobalState(globalState)
return nil
}
@@ -185,22 +186,18 @@ func (tray *Tray) removeTunnelAction(tunnelName string) {
delete(tray.tunnels, tunnelName)
}
-func (tray *Tray) onTunnelChange(tunnel *service.Tunnel, state service.TunnelState, err error) {
+func (tray *Tray) onTunnelChange(tunnel *service.Tunnel, state service.TunnelState, globalState service.TunnelState, err error) {
tray.mtw.Synchronize(func() {
tray.SetTunnelState(tunnel, state, err == nil)
+ tray.updateGlobalState(globalState)
if !tray.mtw.Visible() && err != nil {
tray.ShowError("WireGuard Tunnel Error", err.Error())
}
})
}
-func (tray *Tray) updateGlobalState() {
- state, err := service.IPCClientGlobalState()
- if err != nil {
- return
- }
-
- if icon, err := iconProvider.IconWithOverlayForState(state); err == nil {
+func (tray *Tray) updateGlobalState(globalState service.TunnelState) {
+ if icon, err := iconProvider.IconWithOverlayForState(globalState); err == nil {
tray.SetIcon(icon)
}
@@ -215,14 +212,14 @@ func (tray *Tray) updateGlobalState() {
}
}
- switch state {
+ switch globalState {
case service.TunnelStarting:
statusAction.SetText("Status: Activating")
setTunnelActionsEnabled(false)
tray.SetToolTip("WireGuard: Activating...")
case service.TunnelStarted:
- activeCIDRsAction.SetVisible(err == nil)
+ activeCIDRsAction.SetVisible(true)
statusAction.SetText("Status: Active")
setTunnelActionsEnabled(true)
tray.SetToolTip("WireGuard: Activated")
@@ -275,8 +272,6 @@ func (tray *Tray) SetTunnelState(tunnel *service.Tunnel, state service.TunnelSta
tray.ShowInfo("WireGuard Deactivated", fmt.Sprintf("The %s tunnel has been deactivated.", tunnel.Name))
}
}
-
- tray.updateGlobalState()
}
func (tray *Tray) UpdateFound() {
diff --git a/ui/tunnelspage.go b/ui/tunnelspage.go
index 469ecdeb..5df74d05 100644
--- a/ui/tunnelspage.go
+++ b/ui/tunnelspage.go
@@ -265,17 +265,25 @@ func (tp *TunnelsPage) deleteTunnel(tunnel *service.Tunnel) {
// Handlers
func (tp *TunnelsPage) onTunnelsViewItemActivated() {
- oldState, err := tp.tunnelsView.CurrentTunnel().Toggle()
- if err != nil {
- if oldState == service.TunnelUnknown {
- walk.MsgBox(tp.Form(), "Failed to determine tunnel state", err.Error(), walk.MsgBoxIconError)
- } else if oldState == service.TunnelStopped {
- walk.MsgBox(tp.Form(), "Failed to activate tunnel", err.Error(), walk.MsgBoxIconError)
- } else if oldState == service.TunnelStarted {
- walk.MsgBox(tp.Form(), "Failed to deactivate tunnel", err.Error(), walk.MsgBoxIconError)
+ go func() {
+ globalState, err := service.IPCClientGlobalState()
+ if err != nil || (globalState != service.TunnelStarted && globalState != service.TunnelStopped) {
+ return
}
- return
- }
+ oldState, err := tp.tunnelsView.CurrentTunnel().Toggle()
+ if err != nil {
+ tp.Synchronize(func() {
+ if oldState == service.TunnelUnknown {
+ walk.MsgBox(tp.Form(), "Failed to determine tunnel state", err.Error(), walk.MsgBoxIconError)
+ } else if oldState == service.TunnelStopped {
+ walk.MsgBox(tp.Form(), "Failed to activate tunnel", err.Error(), walk.MsgBoxIconError)
+ } else if oldState == service.TunnelStarted {
+ walk.MsgBox(tp.Form(), "Failed to deactivate tunnel", err.Error(), walk.MsgBoxIconError)
+ }
+ })
+ return
+ }
+ }()
}
func (tp *TunnelsPage) onEditTunnel() {
diff --git a/ui/tunnelsview.go b/ui/tunnelsview.go
index 2a963b58..4adf8902 100644
--- a/ui/tunnelsview.go
+++ b/ui/tunnelsview.go
@@ -132,7 +132,7 @@ func (tv *TunnelsView) CurrentTunnel() *service.Tunnel {
return &tv.model.tunnels[idx]
}
-func (tv *TunnelsView) onTunnelChange(tunnel *service.Tunnel, state service.TunnelState, err error) {
+func (tv *TunnelsView) onTunnelChange(tunnel *service.Tunnel, state service.TunnelState, globalState service.TunnelState, err error) {
tv.Synchronize(func() {
idx := -1
for i := range tv.model.tunnels {