fix(window): place the window in absolute desktop coordinates
Wails saves and restores in two different coordinate systems. WindowGetPosition
returns GetWindowRect — absolute. WindowSetPosition is winc's ControlBase.SetPos,
which adds the CURRENT monitor's work-area origin:
w32.SetWindowPos(hwnd, HWND_TOP, int(info.RcWork.Left)+x, ...)
On the primary monitor that origin is 0 and nothing shows. With a monitor to the
LEFT it compounds: a station with its left screen at x=-3840 saved -3844,
reopened there, had -3840 added, and stored -7684 — then -11524, one screen
further out at every launch, until the window was off the desktop entirely.
So the placement is done here, with SetWindowPos and no offset, falling back to
the toolkit when the handle cannot be found. Compact mode had the same pairing
and is fixed with it.
This commit is contained in:
@@ -2124,6 +2124,21 @@ func (a *App) saveWindowState() {
|
||||
// position — which options can't express — remains, and it is set here while the
|
||||
// window is still hidden, so there is no visible jump. Nothing to do for a
|
||||
// maximised or first-run window.
|
||||
// moveWindowTo places the window at an ABSOLUTE desktop coordinate — the same
|
||||
// coordinate system WindowGetPosition reports and window.json stores.
|
||||
//
|
||||
// Wails' WindowSetPosition is relative to the current monitor's work area (see
|
||||
// windowpos_windows.go), so on a monitor left of the primary one it added that
|
||||
// monitor's negative origin to an already-absolute value and the window walked
|
||||
// one screen further off the desktop at every launch. Fall back to it only when
|
||||
// we cannot place the window ourselves — on the primary monitor the two agree.
|
||||
func (a *App) moveWindowTo(x, y int) {
|
||||
if setWindowPosAbsolute(x, y) {
|
||||
return
|
||||
}
|
||||
wruntime.WindowSetPosition(a.ctx, x, y)
|
||||
}
|
||||
|
||||
func (a *App) restoreWindowPosition() {
|
||||
if a.ctx == nil {
|
||||
return
|
||||
@@ -2151,7 +2166,7 @@ func (a *App) restoreWindowPosition() {
|
||||
return
|
||||
}
|
||||
wruntime.WindowUnmaximise(a.ctx)
|
||||
wruntime.WindowSetPosition(a.ctx, ws.X, ws.Y)
|
||||
a.moveWindowTo(ws.X, ws.Y)
|
||||
wruntime.WindowMaximise(a.ctx)
|
||||
gx, gy := wruntime.WindowGetPosition(a.ctx)
|
||||
applog.Printf("window: re-maximised at the saved corner — now at %d,%d", gx, gy)
|
||||
@@ -2179,10 +2194,13 @@ func (a *App) restoreWindowPosition() {
|
||||
}
|
||||
applog.Printf("window: saved position %d,%d is off every monitor (%s) — moved to %d,%d",
|
||||
ws.X, ws.Y, describeMonitors(monitorRects()), nx, ny)
|
||||
wruntime.WindowSetPosition(a.ctx, nx, ny)
|
||||
a.moveWindowTo(nx, ny)
|
||||
return
|
||||
}
|
||||
wruntime.WindowSetPosition(a.ctx, ws.X, ws.Y)
|
||||
a.moveWindowTo(ws.X, ws.Y)
|
||||
if gx, gy := wruntime.WindowGetPosition(a.ctx); gx != ws.X || gy != ws.Y {
|
||||
applog.Printf("window: asked for %d,%d and the window reports %d,%d", ws.X, ws.Y, gx, gy)
|
||||
}
|
||||
}
|
||||
|
||||
// onSomeMonitor reports whether a window at these coordinates would land on the
|
||||
@@ -7234,7 +7252,9 @@ func (a *App) SetCompactMode(on bool) {
|
||||
wruntime.WindowSetMinSize(a.ctx, normalMinW, normalMinH)
|
||||
if a.preCompactValid {
|
||||
wruntime.WindowSetSize(a.ctx, a.preCompactW, a.preCompactH)
|
||||
wruntime.WindowSetPosition(a.ctx, a.preCompactX, a.preCompactY)
|
||||
// Absolute, like the capture — see moveWindowTo. Leaving compact mode on a
|
||||
// monitor left of the primary one moved the window a screen further out.
|
||||
a.moveWindowTo(a.preCompactX, a.preCompactY)
|
||||
if a.preCompactMax {
|
||||
wruntime.WindowMaximise(a.ctx)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user