package main import ( "embed" "os" "strings" "github.com/wailsapp/wails/v2" "github.com/wailsapp/wails/v2/pkg/options" "github.com/wailsapp/wails/v2/pkg/options/assetserver" ) //go:embed all:frontend/dist var assets embed.FS // profileArg extracts a profile name from the command line. Accepts // "--profile NAME", "--profile=NAME", "-profile NAME", "-p NAME" so a desktop // shortcut can launch OpsLog straight into a given profile (e.g. F4BPO / TM2Q). func profileArg(args []string) string { for i := 0; i < len(args); i++ { a := args[i] switch { case a == "--profile" || a == "-profile" || a == "-p": if i+1 < len(args) { return strings.TrimSpace(args[i+1]) } case strings.HasPrefix(a, "--profile="): return strings.TrimSpace(strings.TrimPrefix(a, "--profile=")) case strings.HasPrefix(a, "-profile="): return strings.TrimSpace(strings.TrimPrefix(a, "-profile=")) case strings.HasPrefix(a, "-p="): return strings.TrimSpace(strings.TrimPrefix(a, "-p=")) } } return "" } func main() { // Single-instance guard: if OpsLog is already running, focus that window and // exit instead of spawning a duplicate. A second process would open its own // CAT (FlexRadio) connection and Ultrabeam follow loop, and the two would // fight over the rig/antenna frequency — the cause of "the antenna re-tunes on // its own" when a windowless zombie instance was left running. if !acquireSingleInstance() { return } // Create an instance of the app structure app := NewApp() app.startupProfile = profileArg(os.Args[1:]) // Restore the window's SIZE and maximised state at CREATION, from the geometry // saved on last close. Doing it here (not after startup) is what makes the // window open already at the right size instead of maximising then snapping // smaller. Position can't be set through options, so it is applied while the // window is still hidden (domReady) — invisible, so no jump. First run, or a // window closed maximised, keeps the historical maximised default. width, height := 1400, 900 startState := options.Maximised if dataDir, err := userDataDir(); err == nil { if ws, ok := readWindowState(dataDir); ok && !ws.Maximised && ws.Width >= 1100 && ws.Height >= 700 && ws.Width <= 8000 && ws.Height <= 6000 { width, height = ws.Width, ws.Height startState = options.Normal } } // Create application with options err := wails.Run(&options.App{ Title: "OpsLog", Width: width, Height: height, MinWidth: 1100, MinHeight: 700, WindowStartState: startState, // Start hidden and reveal only once the saved position has been applied and // the DOM has painted (OnDomReady → domReady) — so the window appears // already at its final size and position, with no post-launch jump. StartHidden: true, AssetServer: &assetserver.Options{ Assets: assets, }, BackgroundColour: &options.RGBA{R: 250, G: 250, B: 249, A: 1}, OnStartup: app.startup, OnDomReady: app.domReady, OnBeforeClose: app.beforeClose, OnShutdown: app.shutdown, Bind: []interface{}{ app, }, }) if err != nil { println("Error:", err.Error()) } }