I just checked how my non-SDL backend handles this issue. What I do is use
the _NET_FRAME_EXTENTS atom to retrieve the size of the window borders and
adjust the window position using those. I update the border size on startup
and whenever I receive a ConfigureNotify event. In short, something like
the following code:
static Atom _atom_net_frame_extents;
…
// on startup:
_atom_net_frame_extents = XInternAtom(display, “_NET_FRAME_EXTENTS”, 0);
…
// on ConfigureNotify event:
// get current border size
Atom type, format;
unsigned long nitems, bytes_after;
unsigned char *property;
XGetWindowProperty(display, window,
_atom_net_frame_extents, 0, 16, 0,
XA_CARDINAL, &type, &format,
&nitems, &bytes_after, &property);
long border_left = ((long*)property)[0];
long border_right = ((long*)property)[1];
long border_top = ((long*)property)[2];
long border_bottom = ((long*)property)[3];
// adjust window location
window_x = e->ConfigureEvent.x - border_left;
window_y = e->ConfigureEvent.y - border_top;
// no need to adjust width and height
window_w = e->ConfigureEvent.width;
window_h = e->ConfigureEvent.height;
…
This works as expected on every desktop environment / window manager I have
ever tested: gnome 2, gnome 3, kwin 3.x, kwin 4.x, compiz and a few more
esoteric ones.
It would be awesome if someone with knowledge of SDL internals could turn
this into a proper patch.
2013/10/20 Stefanos A. <@Stefanos_A>> Hi all,
while testing my application on Linux, I am seeing an issue where
SDL_GetWindowPosition and SDL_SetWindowPosition have differing origins when
using a bordered window.
This is trivial to reproduce:
int x, y;
SDL_WindowID id = SDL_CreateWindow(“Test”,
100, 100, 100, 100, SDL_WINDOW_RESIZABLE);
SDL_GetWindowPosition(id, &x, &y);
SDL_SetWindowPosition(id, x, y);
On my systems (Ubuntu 13.10 (Unity), Archlinux (Gnome 3.10), SDL 2.0.0),
the window will move down, even though I am setting the exact same
coordinates.
This seems to be caused by not taking into account the size of the window
decorations. If I turn them off using:
SDL_SetWindowBordered(id, SDL_FALSE);
Then the problem goes away.
This problem does not occur on Windows or Mac OS X.