mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-27 18:57:35 +00:00
cmd/systray: set app icon and title consistently
Refactor code to set app icon and title as part of rebuild, rather than separately in eventLoop. This fixes several cases where they weren't getting updated properly. This change also makes use of the new exit node icons. Updates #1708 Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d Signed-off-by: Will Norris <will@tailscale.com>
This commit is contained in:
parent
2bdbe5b2ab
commit
86f273d930
@ -136,6 +136,7 @@ var (
|
||||
1, 1, 1,
|
||||
0, 1, 0,
|
||||
},
|
||||
// draw an arrow mask in the bottom right corner with a reasonably thick line width.
|
||||
dotMask: func(dc *gg.Context, borderUnits int, radius int) *image.Alpha {
|
||||
bu, r := float64(borderUnits), float64(radius)
|
||||
|
||||
@ -144,13 +145,14 @@ var (
|
||||
x2 := x1 + (r * 5)
|
||||
|
||||
mc := gg.NewContext(dc.Width(), dc.Height())
|
||||
mc.DrawLine(x1, y, x2, y)
|
||||
mc.DrawLine(x2-(1.5*r), y-(1.5*r), x2, y)
|
||||
mc.DrawLine(x2-(1.5*r), y+(1.5*r), x2, y)
|
||||
mc.DrawLine(x1, y, x2, y) // arrow center line
|
||||
mc.DrawLine(x2-(1.5*r), y-(1.5*r), x2, y) // top of arrow tip
|
||||
mc.DrawLine(x2-(1.5*r), y+(1.5*r), x2, y) // bottom of arrow tip
|
||||
mc.SetLineWidth(r * 3)
|
||||
mc.Stroke()
|
||||
return mc.AsMask()
|
||||
},
|
||||
// draw an arrow in the bottom right corner over the masked area.
|
||||
overlay: func(dc *gg.Context, borderUnits int, radius int) {
|
||||
bu, r := float64(borderUnits), float64(radius)
|
||||
|
||||
@ -158,9 +160,9 @@ var (
|
||||
y := r * (bu + 7)
|
||||
x2 := x1 + (r * 5)
|
||||
|
||||
dc.DrawLine(x1, y, x2, y)
|
||||
dc.DrawLine(x2-(1.5*r), y-(1.5*r), x2, y)
|
||||
dc.DrawLine(x2-(1.5*r), y+(1.5*r), x2, y)
|
||||
dc.DrawLine(x1, y, x2, y) // arrow center line
|
||||
dc.DrawLine(x2-(1.5*r), y-(1.5*r), x2, y) // top of arrow tip
|
||||
dc.DrawLine(x2-(1.5*r), y+(1.5*r), x2, y) // bottom of arrow tip
|
||||
dc.SetColor(fg)
|
||||
dc.SetLineWidth(r)
|
||||
dc.Stroke()
|
||||
@ -174,6 +176,7 @@ var (
|
||||
1, 1, 1,
|
||||
0, 1, 0,
|
||||
},
|
||||
// Draw a square that hides the four dots in the bottom right corner,
|
||||
dotMask: func(dc *gg.Context, borderUnits int, radius int) *image.Alpha {
|
||||
bu, r := float64(borderUnits), float64(radius)
|
||||
x := r * (bu + 3)
|
||||
@ -183,13 +186,14 @@ var (
|
||||
mc.Fill()
|
||||
return mc.AsMask()
|
||||
},
|
||||
// draw a red "x" over the bottom right corner.
|
||||
overlay: func(dc *gg.Context, borderUnits int, radius int) {
|
||||
bu, r := float64(borderUnits), float64(radius)
|
||||
|
||||
x1 := r * (bu + 4)
|
||||
x2 := x1 + (r * 3.5)
|
||||
dc.DrawLine(x1, x1, x2, x2)
|
||||
dc.DrawLine(x1, x2, x2, x1)
|
||||
dc.DrawLine(x1, x1, x2, x2) // top-left to bottom-right stroke
|
||||
dc.DrawLine(x1, x2, x2, x1) // bottom-left to top-right stroke
|
||||
dc.SetColor(red)
|
||||
dc.SetLineWidth(r)
|
||||
dc.Stroke()
|
||||
|
@ -34,11 +34,8 @@ import (
|
||||
|
||||
var (
|
||||
localClient tailscale.LocalClient
|
||||
chState chan ipn.State // tailscale state changes
|
||||
|
||||
chRebuild chan struct{} // triggers a menu rebuild
|
||||
|
||||
appIcon *os.File
|
||||
rebuildCh chan struct{} // triggers a menu rebuild
|
||||
appIcon *os.File
|
||||
|
||||
// newMenuDelay is the amount of time to sleep after creating a new menu,
|
||||
// but before adding items to it. This works around a bug in some dbus implementations.
|
||||
@ -112,8 +109,7 @@ func onReady() {
|
||||
appIcon, _ = os.CreateTemp("", "tailscale-systray.png")
|
||||
io.Copy(appIcon, connected.renderWithBorder(3))
|
||||
|
||||
chState = make(chan ipn.State, 1)
|
||||
chRebuild = make(chan struct{}, 1)
|
||||
rebuildCh = make(chan struct{}, 1)
|
||||
|
||||
menu := new(Menu)
|
||||
menu.rebuild(fetchState(ctx))
|
||||
@ -170,6 +166,34 @@ func (menu *Menu) rebuild(state state) {
|
||||
menu.disconnect.Hide()
|
||||
systray.AddSeparator()
|
||||
|
||||
// Set systray menu icon and title.
|
||||
// Also adjust connect/disconnect menu items if needed.
|
||||
switch menu.status.BackendState {
|
||||
case ipn.Running.String():
|
||||
if state.status.ExitNodeStatus != nil && !state.status.ExitNodeStatus.ID.IsZero() {
|
||||
if state.status.ExitNodeStatus.Online {
|
||||
systray.SetTitle("Using exit node")
|
||||
setAppIcon(exitNodeOnline)
|
||||
} else {
|
||||
systray.SetTitle("Exit node offline")
|
||||
setAppIcon(exitNodeOffline)
|
||||
}
|
||||
} else {
|
||||
systray.SetTitle(fmt.Sprintf("Connected to %s", state.status.CurrentTailnet.Name))
|
||||
setAppIcon(connected)
|
||||
}
|
||||
menu.connect.SetTitle("Connected")
|
||||
menu.connect.Disable()
|
||||
menu.disconnect.Show()
|
||||
menu.disconnect.Enable()
|
||||
case ipn.Starting.String():
|
||||
systray.SetTitle("Connecting")
|
||||
setAppIcon(loading)
|
||||
default:
|
||||
systray.SetTitle("Disconnected")
|
||||
setAppIcon(disconnected)
|
||||
}
|
||||
|
||||
account := "Account"
|
||||
if pt := profileTitle(state.curProfile); pt != "" {
|
||||
account = pt
|
||||
@ -268,27 +292,8 @@ func (menu *Menu) eventLoop(ctx context.Context) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-chRebuild:
|
||||
case <-rebuildCh:
|
||||
menu.rebuild(fetchState(ctx))
|
||||
case state := <-chState:
|
||||
switch state {
|
||||
case ipn.Running:
|
||||
setAppIcon(loading)
|
||||
menu.rebuild(fetchState(ctx))
|
||||
setAppIcon(connected)
|
||||
menu.connect.SetTitle("Connected")
|
||||
menu.connect.Disable()
|
||||
menu.disconnect.Show()
|
||||
menu.disconnect.Enable()
|
||||
case ipn.NoState, ipn.Stopped:
|
||||
setAppIcon(disconnected)
|
||||
menu.rebuild(fetchState(ctx))
|
||||
menu.connect.SetTitle("Connect")
|
||||
menu.connect.Enable()
|
||||
menu.disconnect.Hide()
|
||||
case ipn.Starting:
|
||||
setAppIcon(loading)
|
||||
}
|
||||
case <-menu.connect.ClickedCh:
|
||||
_, err := localClient.EditPrefs(ctx, &ipn.MaskedPrefs{
|
||||
Prefs: ipn.Prefs{
|
||||
@ -397,12 +402,16 @@ func watchIPNBusInner(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("ipnbus error: %w", err)
|
||||
}
|
||||
var rebuild bool
|
||||
if n.State != nil {
|
||||
chState <- *n.State
|
||||
log.Printf("new state: %v", n.State)
|
||||
rebuild = true
|
||||
}
|
||||
if n.Prefs != nil {
|
||||
chRebuild <- struct{}{}
|
||||
rebuild = true
|
||||
}
|
||||
if rebuild {
|
||||
rebuildCh <- struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user