diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-04-29 15:52:17 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-04-29 15:52:17 +0200 |
commit | 3245ef2f821fee0580f7d97c6f05223c2673e318 (patch) | |
tree | a37424f17b611c6d5d04da9fceb4a756dadf52ab | |
parent | ui: account for IPC failures in UI initialization (diff) | |
download | wireguard-windows-3245ef2f821fee0580f7d97c6f05223c2673e318.tar.xz wireguard-windows-3245ef2f821fee0580f7d97c6f05223c2673e318.zip |
service: pass global state with notification
-rw-r--r-- | service/ipc_client.go | 11 | ||||
-rw-r--r-- | service/ipc_server.go | 4 | ||||
-rw-r--r-- | ui/confview.go | 43 | ||||
-rw-r--r-- | ui/managewindow.go | 12 | ||||
-rw-r--r-- | ui/tray.go | 21 | ||||
-rw-r--r-- | ui/tunnelspage.go | 28 | ||||
-rw-r--r-- | ui/tunnelsview.go | 2 |
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() { @@ -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 { |