[client/ui] Center windows on show under minimal WMs (XEmbed tray)

On minimal window managers (fluxbox et al, the in-process XEmbed-tray
path) the WM neither centers small windows nor restores their position
across a hide -> show round-trip, so the main, Settings, and dialog
windows opened in the top-left corner instead of centered.

These windows are created Hidden, so Wails' Linux/GTK4 backend skips its
post-Show centering pass (gated on !Hidden) and InitialPosition has no
effect on an unrealized window. Re-center from Go after Show, gated on
the minimal-WM environment via a recenterOnShow predicate (set to
xembedTrayAvailable on Linux, nil on macOS/Windows where the WM handles
placement). centerWhenReady polls from a background goroutine until the
move actually lands -- Center() moves via raw X11, which no-ops while the
GdkSurface is still nil and GTK4 realizes it asynchronously after Show().

Also reorder xembed_host_linux.go so the static helpers (xembedTrayAvailable,
goMenuItemClicked) sit at the end, after the constructor and methods.
This commit is contained in:
Zoltán Papp
2026-06-05 11:42:03 +02:00
parent 296d3f124b
commit 3967864172
6 changed files with 172 additions and 42 deletions
+17
View File
@@ -0,0 +1,17 @@
//go:build linux && !(linux && 386)
package main
// recenterOnShowPredicate returns the predicate WindowManager uses to decide
// whether to re-center its Go-shown windows (main, Settings) on each show.
//
// On Linux this is xembedTrayAvailable: re-centering is needed only in the
// minimal-WM / in-process-XEmbed-tray environment, where the window manager
// neither centers small windows for us nor restores their position across a
// hide -> show round-trip. The predicate is evaluated per show (not once at
// startup) because the XEmbed tray can appear after the UI starts — the panel
// and the autostarted app race at login — and xembedTrayAvailable is a cheap,
// side-effect-free selection-owner probe, fine to call repeatedly.
func recenterOnShowPredicate() func() bool {
return xembedTrayAvailable
}