client/systray: use ico image format for windows

Add the golang-image-ico package, which is an incredibly small package
to handle the ICO container format with PNG inside. Some profile photos
look quite pixelated when displayed at this size, but it's better than
nothing, and any Windows support is just a bonus anyway.

Updates #1708

Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
This commit is contained in:
Will Norris
2025-03-31 17:37:21 -07:00
committed by Will Norris
parent 96fe8a6db6
commit e8b5f0b3c4
4 changed files with 35 additions and 7 deletions

View File

@@ -11,10 +11,12 @@ import (
"image"
"image/color"
"image/png"
"runtime"
"sync"
"time"
"fyne.io/systray"
ico "github.com/Kodeworks/golang-image-ico"
"github.com/fogleman/gg"
)
@@ -251,7 +253,13 @@ func (logo tsLogo) renderWithBorder(borderUnits int) *bytes.Buffer {
}
b := bytes.NewBuffer(nil)
png.Encode(b, dc.Image())
// Encode as ICO format on Windows, PNG on all other platforms.
if runtime.GOOS == "windows" {
_ = ico.Encode(b, dc.Image())
} else {
_ = png.Encode(b, dc.Image())
}
return b
}

View File

@@ -7,9 +7,11 @@
package systray
import (
"bytes"
"context"
"errors"
"fmt"
"image"
"io"
"log"
"net/http"
@@ -23,6 +25,7 @@ import (
"time"
"fyne.io/systray"
ico "github.com/Kodeworks/golang-image-ico"
"github.com/atotto/clipboard"
dbus "github.com/godbus/dbus/v5"
"github.com/toqueteos/webbrowser"
@@ -330,6 +333,20 @@ func setRemoteIcon(menu *systray.MenuItem, urlStr string) {
resp, err := http.Get(urlStr)
if err == nil && resp.StatusCode == http.StatusOK {
b, _ = io.ReadAll(resp.Body)
// Convert image to ICO format on Windows
if runtime.GOOS == "windows" {
im, _, err := image.Decode(bytes.NewReader(b))
if err != nil {
return
}
buf := bytes.NewBuffer(nil)
if err := ico.Encode(buf, im); err != nil {
return
}
b = buf.Bytes()
}
httpCache[urlStr] = b
resp.Body.Close()
}