golang.zx2c4.com/wireguard/windows@v0.5.4-0.20230123132234-dcc0eb72a04b/ui/ui.go (about) 1 /* SPDX-License-Identifier: MIT 2 * 3 * Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved. 4 */ 5 6 package ui 7 8 import ( 9 "fmt" 10 "runtime" 11 "runtime/debug" 12 "time" 13 14 "github.com/lxn/walk" 15 "github.com/lxn/win" 16 "golang.org/x/sys/windows" 17 18 "golang.zx2c4.com/wireguard/windows/l18n" 19 "golang.zx2c4.com/wireguard/windows/manager" 20 "golang.zx2c4.com/wireguard/windows/version" 21 ) 22 23 var ( 24 noTrayAvailable = false 25 shouldQuitManagerWhenExiting = false 26 startTime = time.Now() 27 IsAdmin = false // A global, because this really is global for the process 28 ) 29 30 func RunUI() { 31 runtime.LockOSThread() 32 windows.SetProcessPriorityBoost(windows.CurrentProcess(), false) 33 defer func() { 34 if err := recover(); err != nil { 35 showErrorCustom(nil, "Panic", fmt.Sprint(err, "\n\n", string(debug.Stack()))) 36 panic(err) 37 } 38 }() 39 40 var ( 41 err error 42 mtw *ManageTunnelsWindow 43 tray *Tray 44 ) 45 46 for mtw == nil { 47 mtw, err = NewManageTunnelsWindow() 48 if err != nil { 49 time.Sleep(time.Millisecond * 400) 50 } 51 } 52 53 for tray == nil { 54 tray, err = NewTray(mtw) 55 if err != nil { 56 if version.OsIsCore() { 57 noTrayAvailable = true 58 break 59 } 60 time.Sleep(time.Millisecond * 400) 61 } 62 } 63 64 manager.IPCClientRegisterManagerStopping(func() { 65 mtw.Synchronize(func() { 66 walk.App().Exit(0) 67 }) 68 }) 69 70 onUpdateNotification := func(updateState manager.UpdateState) { 71 if updateState == manager.UpdateStateUnknown { 72 return 73 } 74 mtw.Synchronize(func() { 75 switch updateState { 76 case manager.UpdateStateFoundUpdate: 77 mtw.UpdateFound() 78 if tray != nil && IsAdmin { 79 tray.UpdateFound() 80 } 81 case manager.UpdateStateUpdatesDisabledUnofficialBuild: 82 mtw.SetTitle(l18n.Sprintf("%s (unsigned build, no updates)", mtw.Title())) 83 } 84 }) 85 } 86 manager.IPCClientRegisterUpdateFound(onUpdateNotification) 87 go func() { 88 updateState, err := manager.IPCClientUpdateState() 89 if err == nil { 90 onUpdateNotification(updateState) 91 } 92 }() 93 94 if tray == nil { 95 win.ShowWindow(mtw.Handle(), win.SW_MINIMIZE) 96 } 97 98 mtw.Run() 99 if tray != nil { 100 tray.Dispose() 101 } 102 mtw.Dispose() 103 104 if shouldQuitManagerWhenExiting { 105 _, err := manager.IPCClientQuit(true) 106 if err != nil { 107 showErrorCustom(nil, l18n.Sprintf("Error Exiting WireGuard"), l18n.Sprintf("Unable to exit service due to: %v. You may want to stop WireGuard from the service manager.", err)) 108 } 109 } 110 } 111 112 func onQuit() { 113 shouldQuitManagerWhenExiting = true 114 walk.App().Exit(0) 115 } 116 117 func showError(err error, owner walk.Form) bool { 118 if err == nil { 119 return false 120 } 121 122 showErrorCustom(owner, l18n.Sprintf("Error"), err.Error()) 123 124 return true 125 } 126 127 func showErrorCustom(owner walk.Form, title, message string) { 128 walk.MsgBox(owner, title, message, walk.MsgBoxIconError) 129 } 130 131 func showWarningCustom(owner walk.Form, title, message string) { 132 walk.MsgBox(owner, title, message, walk.MsgBoxIconWarning) 133 }