1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
/* SPDX-License-Identifier: MIT
*
* Copyright (C) 2019 WireGuard LLC. All Rights Reserved.
*/
package ui
import (
"github.com/lxn/walk"
"github.com/lxn/win"
"golang.zx2c4.com/wireguard/windows/service"
)
type ManageTunnelsWindow struct {
*walk.MainWindow
tabs *walk.TabWidget
tunnelsPage *TunnelsPage
logPage *LogPage
updatePage *UpdatePage
tunnelChangedCB *service.TunnelChangeCallback
}
func NewManageTunnelsWindow() (*ManageTunnelsWindow, error) {
var err error
var disposables walk.Disposables
defer disposables.Treat()
mtw := &ManageTunnelsWindow{}
mtw.MainWindow, err = walk.NewMainWindowWithName("WireGuard")
if err != nil {
return nil, err
}
disposables.Add(mtw)
iconProvider, err = NewIconProvider(mtw.DPI())
if err != nil {
return nil, err
}
mtw.SetIcon(iconProvider.wireguardIcon)
mtw.SetTitle("WireGuard")
font, err := walk.NewFont("Segoe UI", 9, 0)
if err != nil {
return nil, err
}
mtw.AddDisposable(font)
mtw.SetFont(font)
mtw.SetSize(walk.Size{mtw.DPI() * 27 / 4, mtw.DPI() * 5}) //TODO: calculate DPI dynamically
vlayout := walk.NewVBoxLayout()
vlayout.SetMargins(walk.Margins{5, 5, 5, 5})
mtw.SetLayout(vlayout)
mtw.Closing().Attach(func(canceled *bool, reason walk.CloseReason) {
// "Close to tray" instead of exiting application
*canceled = true
mtw.Hide()
})
mtw.VisibleChanged().Attach(func() {
if mtw.Visible() {
mtw.tunnelsPage.updateConfView()
win.SetForegroundWindow(mtw.Handle())
win.BringWindowToTop(mtw.Handle())
mtw.logPage.scrollToBottom()
}
})
mtw.tabs, _ = walk.NewTabWidget(mtw)
if mtw.tunnelsPage, err = NewTunnelsPage(); err != nil {
return nil, err
}
mtw.tabs.Pages().Add(mtw.tunnelsPage.TabPage)
mtw.tunnelsPage.CreateToolbar()
if mtw.logPage, err = NewLogPage(); err != nil {
return nil, err
}
mtw.tabs.Pages().Add(mtw.logPage.TabPage)
disposables.Spare()
mtw.tunnelChangedCB = service.IPCClientRegisterTunnelChange(mtw.onTunnelChange)
globalState, _ := service.IPCClientGlobalState()
mtw.onTunnelChange(nil, service.TunnelUnknown, globalState, nil)
return mtw, nil
}
func (mtw *ManageTunnelsWindow) Dispose() {
if mtw.tunnelChangedCB != nil {
mtw.tunnelChangedCB.Unregister()
mtw.tunnelChangedCB = nil
}
mtw.MainWindow.Dispose()
}
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 {
mtw.SetIcon(icon)
}
if err != nil && mtw.Visible() {
errMsg := err.Error()
if len(errMsg) > 0 && errMsg[len(errMsg)-1] != '.' {
errMsg += "."
}
walk.MsgBox(mtw, "Tunnel Error", errMsg+"\n\nPlease consult the log for more information.", walk.MsgBoxIconWarning)
}
})
}
func (mtw *ManageTunnelsWindow) UpdateFound() {
if mtw.updatePage != nil {
return
}
mtw.SetTitle(mtw.Title() + " (out of date)")
updatePage, err := NewUpdatePage()
if err == nil {
mtw.updatePage = updatePage
mtw.tabs.Pages().Add(updatePage.TabPage)
}
}
|