fix: bug keeping location and size of the window

This commit is contained in:
2026-07-15 22:22:14 +02:00
parent 5b96f53930
commit 75548812d0
2 changed files with 45 additions and 20 deletions
+18 -14
View File
@@ -1010,12 +1010,18 @@ func (a *App) startup(ctx context.Context) {
go a.liveStatusLoop() // multi-op: heartbeat current activity to shared MySQL go a.liveStatusLoop() // multi-op: heartbeat current activity to shared MySQL
go a.chatLoop() // multi-op: poll the shared chat + heartbeat presence go a.chatLoop() // multi-op: poll the shared chat + heartbeat presence
// Reopen where the window was last left (size + position).
a.restoreWindowState()
fmt.Println("OpsLog: db ready at", a.dbPath) fmt.Println("OpsLog: db ready at", a.dbPath)
} }
// domReady fires once the frontend has painted. The window was created hidden
// (StartHidden), so we place it at its saved geometry FIRST and only then show
// it — it appears already sized and positioned, never jumping into place after
// launch. Show is unconditional: whatever happens above, the window must appear.
func (a *App) domReady(ctx context.Context) {
a.restoreWindowPosition()
wruntime.WindowShow(ctx)
}
// StartupStatus returns a diagnostic snapshot for the frontend. // StartupStatus returns a diagnostic snapshot for the frontend.
// dbPath is always populated; err is empty when the app is healthy. // dbPath is always populated; err is empty when the app is healthy.
type StartupStatus struct { type StartupStatus struct {
@@ -1353,24 +1359,22 @@ func (a *App) saveWindowState() {
writeWindowState(a.dataDir, ws) writeWindowState(a.dataDir, ws)
} }
// restoreWindowState reopens the window where it was last left. The window is // restoreWindowPosition places the window at its saved X/Y. Size and maximised
// CREATED maximised (WindowStartState in main.go), which is also the first-run // state are already applied at creation (main.go, from options), so only the
// default — so we only act when a windowed geometry was saved, leaving the // position — which options can't express — remains, and it is set here while the
// maximised majority untouched and flash-free. // window is still hidden, so there is no visible jump. Nothing to do for a
func (a *App) restoreWindowState() { // maximised or first-run window.
func (a *App) restoreWindowPosition() {
if a.ctx == nil { if a.ctx == nil {
return return
} }
ws, ok := readWindowState(a.dataDir) ws, ok := readWindowState(a.dataDir)
if !ok || ws.Maximised { if !ok || ws.Maximised {
return // first run, or last closed maximised — the default already covers it
}
// Guard against a corrupt / absurd size that would open an unusable window.
if ws.Width < normalMinW || ws.Height < normalMinH || ws.Width > maxW || ws.Height > maxH {
return return
} }
wruntime.WindowUnmaximise(a.ctx) if ws.Width < normalMinW || ws.Height < normalMinH || ws.Width > maxW || ws.Height > maxH {
wruntime.WindowSetSize(a.ctx, ws.Width, ws.Height) return // corrupt / absurd — leave the default placement
}
wruntime.WindowSetPosition(a.ctx, ws.X, ws.Y) wruntime.WindowSetPosition(a.ctx, ws.X, ws.Y)
} }
+24 -3
View File
@@ -49,19 +49,40 @@ func main() {
app := NewApp() app := NewApp()
app.startupProfile = profileArg(os.Args[1:]) 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 // Create application with options
err := wails.Run(&options.App{ err := wails.Run(&options.App{
Title: "OpsLog", Title: "OpsLog",
Width: 1400, Width: width,
Height: 900, Height: height,
MinWidth: 1100, MinWidth: 1100,
MinHeight: 700, MinHeight: 700,
WindowStartState: options.Maximised, 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{ AssetServer: &assetserver.Options{
Assets: assets, Assets: assets,
}, },
BackgroundColour: &options.RGBA{R: 250, G: 250, B: 249, A: 1}, BackgroundColour: &options.RGBA{R: 250, G: 250, B: 249, A: 1},
OnStartup: app.startup, OnStartup: app.startup,
OnDomReady: app.domReady,
OnBeforeClose: app.beforeClose, OnBeforeClose: app.beforeClose,
OnShutdown: app.shutdown, OnShutdown: app.shutdown,
Bind: []interface{}{ Bind: []interface{}{