aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorAnthony Dong <aanthony.dong@gmail.com>2019-03-25 18:18:43 +0100
committerAlexander Neumann <alexander.neumann@picos-software.com>2019-04-23 11:04:59 +0200
commitce4b5c36f0e3288d047e406830125a00bb387e3d (patch)
tree967b30f8fd15e31773de7638941ba03419f40f46
parentui: split tray logic into tray component (diff)
downloadwireguard-windows-ce4b5c36f0e3288d047e406830125a00bb387e3d.tar.xz
wireguard-windows-ce4b5c36f0e3288d047e406830125a00bb387e3d.zip
ui: bind all new components together
Signed-off-by: Anthony Dong <aanthony.dong@gmail.com> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--ui/ui.go265
1 files changed, 35 insertions, 230 deletions
diff --git a/ui/ui.go b/ui/ui.go
index 2cd558b7..4acd4a76 100644
--- a/ui/ui.go
+++ b/ui/ui.go
@@ -12,26 +12,9 @@ import (
"time"
"github.com/lxn/walk"
- "github.com/lxn/win"
- "golang.zx2c4.com/wireguard/windows/conf"
- "golang.zx2c4.com/wireguard/windows/ringlogger"
"golang.zx2c4.com/wireguard/windows/service"
- "golang.zx2c4.com/wireguard/windows/ui/syntax"
)
-const testInterfaceName = "test"
-
-const demoConfig = `[Interface]
-PrivateKey = 6KpcbNFK4tKBciKBT2Rj6Z/sHBqxdV+p+nuNA5AlWGI=
-Address = 192.168.4.84/24
-DNS = 8.8.8.8, 8.8.4.4, 1.1.1.1, 1.0.0.1
-
-[Peer]
-PublicKey = JRI8Xc0zKP9kXk8qP84NdUQA04h6DLfFbwJn4g+/PFs=
-Endpoint = demo.wireguard.com:12912
-AllowedIPs = 0.0.0.0/0
-`
-
const nagMessage = `It looks like you're still using this WireGuard pre-alpha build. Great!
We're glad you like it, and we'd appreciate you sharing both your successes and your tribulations with us via team@wireguard.com or #wireguard on Freenode.
@@ -40,11 +23,9 @@ But because this is pre-release software, we're not confident it's something you
Would you like to quit WireGuard now? If not, you'll be nagged again in two minutes about the same thing.`
-var quit func()
-
func nag() {
if walk.MsgBox(nil, "THANKS FOR REPORTING BUGS COME AGAIN ANOTHER DAY", nagMessage, walk.MsgBoxIconError|walk.MsgBoxYesNo|0x00001000) != walk.DlgCmdNo {
- quit()
+ onQuit()
}
time.AfterFunc(time.Minute*2, nag)
}
@@ -52,223 +33,48 @@ func nag() {
func RunUI() {
runtime.LockOSThread()
- icon, _ := walk.NewIconFromResourceId(1)
-
- mw, _ := walk.NewMainWindowWithName("WireGuard")
- tray, _ := walk.NewNotifyIcon(mw)
- defer tray.Dispose()
- tray.SetIcon(icon)
- tray.SetToolTip("WireGuard: Deactivated")
- tray.SetVisible(true)
-
- mw.SetSize(walk.Size{900, 1400})
- mw.SetLayout(walk.NewVBoxLayout())
- mw.SetIcon(icon)
- mw.Closing().Attach(func(canceled *bool, reason walk.CloseReason) {
- *canceled = true
- mw.Hide()
- })
-
- tl, _ := walk.NewTextLabel(mw)
- tl.SetText("Public key: (unknown)")
-
- se, _ := syntax.NewSyntaxEdit(mw)
- lastPrivate := ""
- se.PrivateKeyChanged().Attach(func(privateKey string) {
- if privateKey == lastPrivate {
- return
- }
- lastPrivate = privateKey
- key, err := conf.NewPrivateKeyFromString(privateKey)
- if err == nil {
- tl.SetText("Public key: " + key.Public().String())
- } else {
- tl.SetText("Public key: (unknown)")
- }
- })
-
- tunnels, err := service.IPCClientTunnels()
- didFind := false
- if err == nil {
- for _, tunnel := range tunnels {
- if tunnel.Name == testInterfaceName {
- storedConfig, err := tunnel.StoredConfig()
- if err == nil {
- se.SetText(storedConfig.ToWgQuick())
- didFind = true
- }
- }
- }
- }
- if !didFind {
- se.SetText(demoConfig)
- }
-
- cv, _ := NewConfView(mw)
- cv.SetVisible(false)
- cv.SetEnabled(false)
-
- var runningTunnel *service.Tunnel
- updateConfView := func() {
- tun := runningTunnel
- if tun == nil || !mw.Visible() || !cv.Visible() {
- return
- }
- conf, err := tun.RuntimeConfig()
- if err != nil {
- return
- }
- cv.SetConfiguration(&conf)
- }
- go func() {
- t := time.NewTicker(time.Second)
- for {
- updateConfView()
- <-t.C
- }
- }()
- showRunningView := func(on bool) {
- cv.SetVisible(on)
- cv.SetEnabled(on)
- se.SetVisible(!on)
- tl.SetVisible(!on)
- if on {
- updateConfView()
- }
+ icon, err := walk.NewIconFromResourceId(1)
+ if err != nil {
+ panic(err)
}
+ defer icon.Dispose()
- pb, _ := walk.NewPushButton(mw)
- pb.SetText("Start")
- pb.Clicked().Attach(func() {
- restoreState := true
- pbE := pb.Enabled()
- seE := se.Enabled()
- pbT := pb.Text()
- defer func() {
- if restoreState {
- pb.SetEnabled(pbE)
- se.SetEnabled(seE)
- pb.SetText(pbT)
- }
- }()
-
- mw.SetSuspended(true)
- pb.SetEnabled(false)
- se.SetEnabled(false)
- pb.SetText("Requesting..")
- mw.SetSuspended(false)
- if runningTunnel != nil {
- err := runningTunnel.Stop()
- if err != nil {
- walk.MsgBox(mw, "Unable to stop tunnel", err.Error(), walk.MsgBoxIconError)
- return
- }
- restoreState = false
- return
- }
- c, err := conf.FromWgQuick(se.Text(), testInterfaceName)
- if err != nil {
- walk.MsgBox(mw, "Invalid configuration", err.Error(), walk.MsgBoxIconError)
- return
- }
- cv.SetConfiguration(c)
- tunnel, err := service.IPCClientNewTunnel(c)
- if err != nil {
- walk.MsgBox(mw, "Unable to create tunnel", err.Error(), walk.MsgBoxIconError)
- return
- }
- err = tunnel.Start()
- if err != nil {
- walk.MsgBox(mw, "Unable to start tunnel", err.Error(), walk.MsgBoxIconError)
- return
- }
- restoreState = false
- })
-
- logger, err := ringlogger.NewRingloggerFromInheritedMappingHandle(os.Args[5], "GUI")
+ mtw, err := NewManageTunnelsWindow(icon)
if err != nil {
- walk.MsgBox(nil, "Unable to initialize logging", fmt.Sprint(err), walk.MsgBoxIconError)
- return
+ panic(err)
}
- NewLogView(mw, logger)
+ defer mtw.Dispose()
- quitAction := walk.NewAction()
- quitAction.SetText("Exit")
- quit = func() {
- tray.Dispose()
- onQuit()
+ tray, err := NewTray(mtw, icon)
+ if err != nil {
+ panic(err)
}
- quitAction.Triggered().Attach(quit)
- tray.ContextMenu().Actions().Add(quitAction)
- tray.MouseDown().Attach(func(x, y int, button walk.MouseButton) {
- if button == walk.LeftButton {
- mw.Show()
- win.SetForegroundWindow(mw.Handle())
- win.BringWindowToTop(mw.Handle())
- updateConfView()
- }
- })
+ defer tray.Dispose()
- setServiceState := func(tunnel *service.Tunnel, state service.TunnelState, showNotifications bool) {
- if tunnel.Name != testInterfaceName {
+ // Bind to updates
+ service.IPCClientRegisterTunnelChange(func(tunnel *service.Tunnel, state service.TunnelState, err error) {
+ if err == nil {
return
}
- mw.SetSuspended(true)
- //TODO: also set tray icon to reflect state
- switch state {
- case service.TunnelStarting:
- runningTunnel = tunnel
- showRunningView(false)
- se.SetEnabled(false)
- pb.SetText("Starting...")
- pb.SetEnabled(false)
- tray.SetToolTip("WireGuard: Activating...")
- case service.TunnelStarted:
- runningTunnel = tunnel
- showRunningView(true)
- se.SetEnabled(false)
- pb.SetText("Stop")
- pb.SetEnabled(true)
- tray.SetToolTip("WireGuard: Activated")
- if showNotifications {
- //TODO: ShowCustom with right icon
- tray.ShowInfo("WireGuard Activated", fmt.Sprintf("The %s tunnel has been activated.", tunnel.Name))
- }
- case service.TunnelStopping:
- runningTunnel = tunnel
- showRunningView(false)
- se.SetEnabled(false)
- pb.SetText("Stopping...")
- pb.SetEnabled(false)
- tray.SetToolTip("WireGuard: Deactivating...")
- case service.TunnelStopped:
- showRunningView(false)
- se.SetEnabled(true)
- pb.SetText("Start")
- pb.SetEnabled(true)
- tray.SetToolTip("WireGuard: Deactivated")
- if showNotifications && runningTunnel != nil {
- //TODO: ShowCustom with right icon
- tray.ShowInfo("WireGuard Deactivated", fmt.Sprintf("The %s tunnel has been deactivated.", tunnel.Name))
+
+ if mtw.Visible() {
+ errMsg := err.Error()
+ if len(errMsg) > 0 && errMsg[len(errMsg)-1] != '.' {
+ errMsg += "."
}
- runningTunnel = nil
+ walk.MsgBox(mtw, "Tunnel Error", errMsg+"\n\nPlease consult the Windows Event Log for more information.", walk.MsgBoxIconWarning)
+ } else {
+ tray.ShowError("WireGuard Tunnel Error", err.Error())
}
- mw.SetSuspended(false)
- }
+ })
service.IPCClientRegisterTunnelChange(func(tunnel *service.Tunnel, state service.TunnelState, err error) {
- setServiceState(tunnel, state, err == nil)
- if err != nil {
- if mw.Visible() {
- errMsg := err.Error()
- if len(errMsg) > 0 && errMsg[len(errMsg)-1] != '.' {
- errMsg += "."
- }
- walk.MsgBox(mw, "Tunnel Error", errMsg+"\n\nPlease consult the log for more information.", walk.MsgBoxIconWarning)
- } else {
- tray.ShowError("WireGuard Tunnel Error", err.Error())
- }
- }
+ tray.SetTunnelStateWithNotification(tunnel, state, err == nil)
+ })
+ service.IPCClientRegisterTunnelChange(func(tunnel *service.Tunnel, state service.TunnelState, err error) {
+ mtw.SetTunnelState(tunnel, state)
})
+
+ // Fetch current state
go func() {
tunnels, err := service.IPCClientTunnels()
if err != nil {
@@ -279,16 +85,13 @@ func RunUI() {
if err != nil {
continue
}
- if tunnel.Name == testInterfaceName && state != service.TunnelStopped {
- runningTunnel = &tunnel
- setServiceState(&tunnel, state, false)
- }
+ tray.SetTunnelStateWithNotification(&tunnel, state, false)
+ mtw.SetTunnelState(&tunnel, state)
}
}()
time.AfterFunc(time.Minute*15, nag)
-
- mw.Run()
+ mtw.Run()
}
func onQuit() {
@@ -297,6 +100,8 @@ func onQuit() {
walk.MsgBox(nil, "Error Exiting WireGuard", fmt.Sprintf("Unable to exit service due to: %s. You may want to stop WireGuard from the service manager.", err), walk.MsgBoxIconError)
os.Exit(1)
}
+
+ walk.App().Exit(0)
}
const aboutText = `