We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 4646

Summary: [patch] SDL_SetWindowPosition failure causes SDL_GetWindowPosition to return the unused values
Product: SDL Reporter: R.E. Rust <rerust>
Component: videoAssignee: Ryan C. Gordon <icculus>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: icculus, inolen
Version: 2.0.9Keywords: target-2.0.12
Hardware: x86_64   
OS: Linux   
Attachments: Query display server for window position after move attempt

Description R.E. Rust 2019-05-30 05:20:17 UTC
Created attachment 3801 [details]
Query display server for window position after move attempt

If the window is still grabbed while attempting to set it's position on X11 (Only tested on xfce4), then the call fails to change the position. But as you know, the x/y values in the window structure are from user code and there is no checking for success, and SDL_GetWindowPosition is simply a getter for these values.

To remedy this, I query the system for the actual current position and read that into the window structure. This ensures that the values in the window structure are never thrown out of sync by an SDL_SetWindowPosition call.

Now, I have limited knowledge of xlib (I prefer SDL), but after a quick look at the documentation, I couldn't find any mention of what it would do if X11 doesn't obey the move request, and even if it reported a bad status somewhere, given the design of the current driver interface, you'd still have to restore these values. But I could be missing something, and in that case I apologize for wasting your time! :)

Patch was tested against 2.0.9 and the current tip as of this writing.
Comment 1 Ryan C. Gordon 2019-07-30 17:49:38 UTC
(Sorry if you get several emails like this, we're marking a bunch of bugs.)

We're hoping to ship SDL 2.0.11 on a much shorter timeframe than we have historically done releases, so I'm starting to tag bugs we hope to have closed in this release cycle.

Note that this tag means we just intend to scrutinize this bug for the 2.0.11 release: we may fix it, reject it, or even push it back to a later release for now, but this helps give us both a goal and a wishlist for the next release.

If this bug has been quiet for a few months and you have new information (such as, "this is definitely still broken" or "this got fixed at some point"), please feel free to retest and/or add more notes to the bug.

--ryan.
Comment 2 Ryan C. Gordon 2019-09-20 20:47:38 UTC
We're changing how we do SDL release versions; now releases will be even numbers (2.0.10, 2.0.12, etc), and as soon as we tag a release, we'll move the internal version number to an odd number (2.0.12 ships, we tag the latest in revision control as 2.0.13 immediately, which will become 2.0.14 on release, etc).

As such, I'm moving the bugs tagged with target-2.0.11 to target 2.0.12. Sorry if you get a lot of email from this change!

Thanks,
--ryan.
Comment 3 Ryan C. Gordon 2019-09-20 20:48:41 UTC
We're changing how we do SDL release versions; now releases will be even numbers (2.0.10, 2.0.12, etc), and as soon as we tag a release, we'll move the internal version number to an odd number (2.0.12 ships, we tag the latest in revision control as 2.0.13 immediately, which will become 2.0.14 on release, etc).

As such, I'm moving the bugs tagged with target-2.0.11 to target 2.0.12. Sorry if you get a lot of email from this change!

Thanks,
--ryan.
Comment 4 Ryan C. Gordon 2019-10-27 03:59:33 UTC
This patch is now https://hg.libsdl.org/SDL/rev/31a961c87edb, thanks!

--ryan.
Comment 5 Anthony Pesch 2020-01-02 01:07:13 UTC
Hey,

I just updated to the latest HEAD and ran into and issue where my window was no longer centered on startup sometimes. In general, my window creation looks like:

win = SDL_CreateWindow(..., SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 0, 0, ...);
... some code that checks if fullscreen or windowed ...
SDL_SetWindowSize(win, width, height);
SDL_SetWindowPosition(win SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);

It looks like after this patch, X11_XGetWindowAttributes sometimes returns an old position (as opposed to the one just passed to X11_XMoveWindow) even when the window has moved. Slipping in a sleep(1) after the XFlush worked around the issue, but I'm not familiar enough with X to identify the correct solution here.
Comment 6 Sam Lantinga 2020-01-03 22:20:49 UTC
Ryan, can you take a look at this again?
Comment 7 Ryan C. Gordon 2020-01-04 00:53:47 UTC
(In reply to Sam Lantinga from comment #6)
> Ryan, can you take a look at this again?

Yep.

--ryan.
Comment 8 Ryan C. Gordon 2020-01-28 18:52:13 UTC
Anthony, can you see if this is resolved by https://hg.libsdl.org/SDL/rev/09ace8a928db ?

Thanks,
--ryan.
Comment 9 Anthony Pesch 2020-02-04 21:46:30 UTC
Hey Ryan,

Sorry for the slow response, but it doesn't unfortunately fix it. If it helps repro, I'm on Fedora w/ XFCE.
Comment 10 Ryan C. Gordon 2020-02-14 18:26:27 UTC
Okay, this _should_ be fixed by https://hg.libsdl.org/SDL/rev/f22dd67ec07b for everyone's purposes.

Basically, calling XMoveWindow() will move the window immediately if there's no window manager running (which is rare). In most cases, though, this will generate an event that the window manager process receives and then decides what to do with the window...which might be accept the move, alter it, or reject it. Depending on what happens here, our XMoveWindow process might get a new resize event after an arbitrary time, or nothing at all.

So now we wait a little to see if the window changes in any way (even if not to the requested size, because a window manager might decide to move it elsewhere anyhow), so in most reasonable cases, we're in sync with the SDL_SetWindowPosition request upon return, or at least in sync with the reality of where the window actually landed.

In the worst case (the system is overloaded and the window manager didn't reply in 100ms), your next call to SDL_GetWindowPosition may be wrong, but that's the best we can do in an asynchronous system like X11. It should catch up and send an SDL_WINDOWEVENT_MOVED later.

--ryan.