f533739d6e
Give the window titlebar, taskbar, and tray a size-appropriate icon with a transparent boundary on both Windows and Linux, instead of scaling one PNG to every size. Assets: - Regenerate the PNGs and gosentry.ico with feathered color-to-alpha so the rounded-tile boundary is transparent; a binary white-key had left an opaque halo that read as a border on dark taskbars/trays. - Rebuild gosentry.ico as multi-size (16 hand-tuned + 32/48/256 from big) and add a single-frame 16x16 gosentry-icon-16x16.ico for the Windows tray. - assets.go: add IconSmall() and IconSmallICO(). Wiring: - Windows window/taskbar: embed gosentry.ico under the GLFW_ICON resource and skip a.SetIcon so GLFW selects the right frame per size (hand-tuned 16 for the titlebar, a larger frame for the taskbar). - Windows tray: SetSystemTrayIcon(IconSmallICO()), a 16x16 ICO frame. - Linux window titlebar: a.SetIcon(IconSmall()) for a crisp ~16px _NET_WM_ICON; tray uses the big PNG since StatusNotifierItem renders larger. Also bump Fyne 2.6.3 -> 2.7.4 (systray 1.11.0 -> 1.12.1) and document the full cross-platform icon strategy in assets.go, gosentry.rc, run.go, and tray.go. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
71 lines
2.6 KiB
Go
71 lines
2.6 KiB
Go
package ui
|
|
|
|
import (
|
|
"runtime"
|
|
"time"
|
|
|
|
"gitea.mixdep.ru/mix/gosentry/assets"
|
|
"gitea.mixdep.ru/mix/gosentry/src/app"
|
|
|
|
"fyne.io/fyne/v2"
|
|
fyneapp "fyne.io/fyne/v2/app"
|
|
)
|
|
|
|
const appID = "ru.mixdep.gosentry.desktop"
|
|
|
|
// Run is the application entry point. It owns the process lifecycle — single
|
|
// instance arbitration, Fyne app + window construction, tray wiring, and the
|
|
// startup-timing record — and delegates all view construction to newMainView in
|
|
// mainwindow.go. Keeping lifecycle here and the view there is the run.go /
|
|
// mainwindow.go split introduced in T4.1.
|
|
func Run(startInTray bool) {
|
|
started := time.Now()
|
|
instanceListener, primary := acquireSingleInstance(!startInTray)
|
|
if !primary {
|
|
return
|
|
}
|
|
if instanceListener != nil {
|
|
defer instanceListener.Close()
|
|
}
|
|
|
|
// A stable app ID lets Fyne persist desktop preferences consistently across
|
|
// launches and gives tray/window integration a predictable identity.
|
|
a := fyneapp.NewWithID(appID)
|
|
// On Windows the multi-resolution gosentry.ico (embedded under the GLFW_ICON
|
|
// resource name) drives the window: GLFW picks the hand-tuned 16x16 for the
|
|
// titlebar and the large artwork for the bigger taskbar icon — size-appropriate
|
|
// in a way a single Fyne SetIcon resource cannot be, since one PNG would be
|
|
// scaled to both sizes.
|
|
//
|
|
// Other platforms have no PE icon. Fyne's single SetIcon resource feeds
|
|
// _NET_WM_ICON, which the window manager renders small (~16px) in the titlebar,
|
|
// so use the hand-tuned small icon there to keep it crisp. The larger
|
|
// dock/launcher icon comes from the .desktop entry installed by
|
|
// InstallDesktopIcon, which uses the big artwork.
|
|
if runtime.GOOS != "windows" {
|
|
a.SetIcon(assets.IconSmall())
|
|
}
|
|
|
|
w := a.NewWindow("GoSentry " + app.Version)
|
|
configureSystemTray(a, w)
|
|
w.Resize(fyne.NewSize(1120, 720))
|
|
content, recordStartup := newMainView(w)
|
|
w.SetContent(content)
|
|
serveSingleInstance(instanceListener, w)
|
|
if startInTray {
|
|
// Autostart launches intentionally stay hidden, so "window shown" would be
|
|
// a misleading metric. Record a separate startup event for the tray path
|
|
// instead of forcing one timing definition onto two different UX flows.
|
|
recordStartup(time.Since(started), false)
|
|
a.Run()
|
|
return
|
|
}
|
|
// Show the window before recording startup time. Measuring earlier, during
|
|
// widget construction, looked cheaper in History than the user-perceived
|
|
// startup really was. The current point is less abstract: it ends when the
|
|
// window has actually been handed to the desktop for display.
|
|
w.Show()
|
|
recordStartup(time.Since(started), true)
|
|
a.Run()
|
|
}
|