ebiten: RestoreWindow silently does nothing when a maximum window size is set
Ebitengine Version
v2.10.0-alpha.13 (main @ 4f474b00d)
Operating System
- Windows
- macOS
- Linux
Go Version (paste your go version output)
go1.26.7 linux/amd64
What steps will reproduce the problem?
desktopWindow.Restore() (internal/ui/window_desktop.go:379-392) guards on isWindowMaximizable():
func (w *desktopWindow) Restore() {
if w.ui.isTerminated() {
return
}
if !w.isWindowMaximizable() { // ← wrong precondition for a restore
return
}
...
b.Window().Restore()
}and isWindowMaximizable() returns false whenever a maximum window size is set:
func (w *desktopWindow) isWindowMaximizable() bool {
_, _, maxw, maxh := w.getWindowSizeLimitsInDIP()
return maxw == glfw.DontCare && maxh == glfw.DontCare
}That check exists to prevent maximizing beyond a size limit (the same guard is correctly used in Maximize() at window_desktop.go:350). Reusing it in Restore() means: any game that sets a maximum window size — e.g. a fixed-aspect-ratio game using SetWindowSizeLimits — can never restore the window from the minimized state. Restore() returns silently and the window stays iconified.
Reproduction on Windows/Linux/macOS:
func (g *Game) Update() error {
switch {
case inpututil.IsKeyJustPressed(ebiten.KeyM):
ebiten.MinimizeWindow()
case inpututil.IsKeyJustPressed(ebiten.KeyR):
// panics only if neither maximized nor minimized; here minimized → passes,
// but ui Restore() is a silent no-op because a max size is set.
ebiten.RestoreWindow()
}
return nil
}
func main() {
ebiten.SetWindowSize(640, 480)
ebiten.SetWindowSizeLimits(320, 240, 1280, 960) // any finite maximum triggers this
ebiten.SetWindowResizingMode(ebiten.WindowResizingModeEnabled)
ebiten.RunGame(&Game{})
}Press M, then R: the window never comes back (clicking the taskbar icon does, which shows the OS side is fine). Remove the maximum limits and R restores correctly.
What is the expected result?
RestoreWindow() restores the window from either the maximized or the minimized state regardless of the window size limits. The "not maximizable" guard belongs to Maximize() only.
What happens instead?
With a finite maximum window size set, RestoreWindow() after MinimizeWindow() is silently ignored. The game's own "restore/unminimize" action does nothing, and from the player's perspective the window is stuck minimized until they click it in the taskbar — no error, no panic, nothing in the logs.
Anything else you feel useful to add?
Proposed fix: drop the isWindowMaximizable() early-return from Restore() (the maximized-state precondition is already enforced by the public RestoreWindow), and let the backends' Restore() implementations handle the actual work as they already do for maximized windows.
Source: hajimehoshi/ebiten