Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Base window size and position is not remembered #12006

Open
flowCRANE opened this issue Jan 17, 2025 · 12 comments · Fixed by #12011
Open

Base window size and position is not remembered #12006

flowCRANE opened this issue Jan 17, 2025 · 12 comments · Fixed by #12011
Assignees
Milestone

Comments

@flowCRANE
Copy link

flowCRANE commented Jan 17, 2025

Windows 10, SDL 3.1.10

The full description of the issue can be found in the thread Base window size and position is not remembered with lists of steps to reproduce issues, below are direct links for easier navigation. In this thread I have added an attachment for each of the three tests and the attachments contain the source code of the testers (Free Pascal, sources are also provided in the posts) and compiled exe's to test without having to compile anything.

Window with standard decoration:

  • The first test showing that SDL does not remember the base window size and position when entering fullscreen while the window is maximized.

Borderless window with custom decoration and hit-test:

  • The second test showing that SDL cannot correctly restore a window from a minimized form if a maximized window was minimized.
  • The third test showing that SDL does not remember the base window size and position when entering fullscreen while the window is maximized.

In short, there are two problems. Only the size and position of the window before the window style change are remembered, so if you maximize the window and then go fullscreen, the size of the window before maximization is lost. So when you exit fullscreen, the window is restored to its maximized form, but it is not possible to restore a window from maximized to windowed form. This is true for both standard decorated and borderless windows.

The second problem only affects borderless windows that have their own hit-test callback. If you maximize and then minimize such a window, after restoring it from the taskbar the window takes on a completely incorrect size and position. SDL does not restore a maximized borderless window to its maximized form (its form before minimization).

@slouken slouken added this to the 3.2.0 milestone Jan 17, 2025
@slouken
Copy link
Collaborator

slouken commented Jan 17, 2025

@Kontrabant, is this something you can look into?

@Kontrabant
Copy link
Contributor

Kontrabant commented Jan 17, 2025

I tried your examples on both Win 10 and Win 11 (latest updates in both cases), and they behave correctly for me, as does performing the same sequence of operations with testsprite in the SDL test suite, as well as the automated tests, which tests the maximize->enter fullscreen->leave fullscreen->restore pattern as well.

On all platforms, SDL defers managing the window size and position to the desktop wherever possible, unless an explicit change was requested. In this case, when leaving the maximized state, SDL just removes the maximized style, and it's up to Windows to put the window back to the previous size/position.

@Kontrabant
Copy link
Contributor

I think we hit a bug like this before (#9338), and it was related to Windows not restoring the proper size when leaving the maximized state.

@Kontrabant
Copy link
Contributor

@flowCRANE if you run testsprite --resizable --noframe and do the following:

  • ctrl+m to maximize
  • alt+enter to enter fullscreen
  • alt+enter to leave fullscreen
  • ctrl+m to restore

does it restore properly? Problems like this are much easier to debug when they can be replicated via the test suite.

@flowCRANE
Copy link
Author

flowCRANE commented Jan 17, 2025

Please, send me the compiled test and I'll check it out. I don't work with C and I don't have the tools for it right now, so I won't compile these tests for now. But I promise that in the near future, when I finally deal with the problems with handling window modes, I'll take care of this topic so that I can compile the sources myself and test them. :)

I'm guessing the problem is that I have two monitors (extended desktop) and the secondary monitor is to the left of the primary monitor, causing it to have a negative X coordinate (i.e. -1280.0). Because of this monitor arrangement, even though it is completely correct, I constantly find bugs in various programs, including for example the Lazarus IDE, because it also does not handle this for some functions (like the popup of the designer window). Complete mess.

@Kontrabant
Copy link
Contributor

I'm guessing the problem is that I have two monitors (extended desktop) and the secondary monitor is to the left of the primary monitor, causing it to have a negative X coordinate (i.e. -1280.0). Because of this monitor arrangement, even though it is completely correct, I constantly find bugs in various programs, including for example the Lazarus IDE, because it also does not handle this for some functions (like the popup of the designer window). Complete mess.

Just to be sure, I tried this display configuration as well, and, unfortunately, I still can't replicate your issue. Your supplied reproduction cases work correctly on my system, even on a dual-display setup with one display having negative coordinates.

@flowCRANE
Copy link
Author

Damn. As usual the problem only occurs with me... I can reproduce this problem 100% of the time myself, both in my test program (the code for which I provided in the linked thread) and in my actual game project that I'm working on.

And did you check how your tester behaves when the taskbar is pinned to the top of the screen (on both screens), like mine is? Maybe that's the reason why Windows can't handle maximization correctly.

@Kontrabant
Copy link
Contributor

Yes, Win 10 still works correctly, and Win 11 is moot as it doesn't allow moving the taskbar to the top anymore.

@flowCRANE
Copy link
Author

flowCRANE commented Jan 17, 2025

I've changed the taskbar location to the Bottom and there is no difference — still there is a problem. I maximize the borderless window, minimize it, and when I click the application button on the taskbar to restore the window, the effect is as follows:

Image

The window is moved to the -1280,0 location (who knows why) and its size is huge. When I press Alt+Space to show the system popup menu in the top left corner of the window, I see this:

Image

The window is completely messed up — its top left corner is on the second monitor. :(

And if I click the Resotre item in this system popup menu, the window actually restores the correct size and position:

Image

@Kontrabant
Copy link
Contributor

Kontrabant commented Jan 17, 2025

Ok, I can reproduce this now. The problem is that borderless windows need their size corrected to avoid spilling over the side of the desktop due to Windows quirkiness, so the display for the window is queried and the desktop dimensions from it are used to calculate the client area. If the window is being restored from minimized, the monitor returned by MonitorFromWindow can be incorrect (null, or the 'nearest', which in this case is the display to the left since the window size spills over slightly), so we'll need to fallback to retrieving the monitor from the last known window position in this case.

@flowCRANE
Copy link
Author

flowCRANE commented Jan 17, 2025

Ok, so there is hope that this problem will be fixed. Great!

In theory I could fix this, just like I fixed the problem with fullscreen support. The problem is that the SDL_EVENT_WINDOW_RESTORED event is sent both after restoring the window from the maximized state and from the minimized state. To do a workaround, I would have to remember whether the window was minimized or not, and this only complicates the implementation. If SDL doesn't help me fix the problem of minimizing a borderless maximized window, I will have no choice but to implement such dirty hacks.

It would be much easier if there were separate events for these two cases. Then the application would know whether the window was restored from the minimized or maximized state. But that's just a loose thought.

@Kontrabant
Copy link
Contributor

The minimization issue is fixed. Still not sure about why the base size is being lost, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants