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 3085

Summary: SDL_GetWindowPosition on X11 returns the frame position instead of the client area position
Product: SDL Reporter: Drew Bliss <drewb>
Component: videoAssignee: Ryan C. Gordon <icculus>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: cra0zy, icculus
Version: 2.0.3   
Hardware: x86_64   
OS: Linux   

Description Drew Bliss 2015-08-05 21:34:59 UTC
On Windows SDL makes sure to use the screen coordinates of the client area for window positions.

    case WM_WINDOWPOSCHANGED:
        {
            RECT rect;
            int x, y;
            int w, h;
            
            if (data->in_border_change) {
                break;
            }

            if (!GetClientRect(hwnd, &rect) || IsRectEmpty(&rect)) {
                break;
            }
            ClientToScreen(hwnd, (LPPOINT) & rect);
            ClientToScreen(hwnd, (LPPOINT) & rect + 1);

            WIN_UpdateClipCursor(data->window);

            x = rect.left;
            y = rect.top;
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED, x, y);

On X11 the ConfigureNotify event gives the parent coordinates (which for SDL will always be screen coordinates) of the window, but SDL specifically adjusts them to account for the window border.

    case ConfigureNotify:{
#ifdef DEBUG_XEVENTS
            printf("window %p: ConfigureNotify! (position: %d,%d, size: %dx%d)\n", data,
                   xevent.xconfigure.x, xevent.xconfigure.y,
                   xevent.xconfigure.width, xevent.xconfigure.height);
#endif
            long border_left = 0;
            long border_top = 0;
            if (data->xwindow) {
                Atom _net_frame_extents = X11_XInternAtom(display, "_NET_FRAME_EXTENTS", 0);
                Atom type;
                int format;
                unsigned long nitems, bytes_after;
                unsigned char *property;
                if (X11_XGetWindowProperty(display, data->xwindow,
                        _net_frame_extents, 0, 16, 0,
                        XA_CARDINAL, &type, &format,
                        &nitems, &bytes_after, &property) == Success) {
                    if (type != None && nitems == 4)
                    {
                        border_left = ((long*)property)[0];
                        border_top = ((long*)property)[2];
                    }
                    X11_XFree(property);
                }
            }

            if (xevent.xconfigure.x != data->last_xconfigure.x ||
                xevent.xconfigure.y != data->last_xconfigure.y) {
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED,
                                    xevent.xconfigure.x - border_left,
                                    xevent.xconfigure.y - border_top);

As SDL_GetWindowPosition is supposed to return the position of the client area this adjustment seems incorrect and does not match Windows.
Comment 1 cra0zy@gmail.com 2016-03-06 21:44:58 UTC
Same problem with SDL 2.0.4.
Comment 2 Ryan C. Gordon 2016-03-07 03:55:40 UTC
This is fixed in https://hg.libsdl.org/SDL/rev/11b490897d27 plus https://hg.libsdl.org/SDL/rev/9cec5fe32bca

--ryan.
Comment 3 cra0zy@gmail.com 2016-03-28 19:24:58 UTC
This bug is not fixed, it can still be caused by making window resizable, and then maximizing it. Tested with binaries compiled from source.
Comment 4 cra0zy@gmail.com 2016-03-28 19:44:13 UTC
Ok, good news in the end, patch from https://bugzilla.libsdl.org/show_bug.cgi?id=3272 completely fixes this.