From 02f49fdb5335ff0db0df268c0dcc436ddf96216e Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Fri, 4 Mar 2016 18:47:19 -0500 Subject: [PATCH] x11: Deal with window borders better. - Cache the _NET_FRAME_EXTENTS data locally, so we don't have to query the X server for them (instead, we update our cached data when PropertyNotify events alert us to a change). - Use our cached extents for X11_GetWindowBordersSize(), so it's a fast call. - Window position was meant to refer to the client area, not the window decorations, so adjust appropriately when getting/setting the position. --- src/video/x11/SDL_x11events.c | 42 ++++++++++++++++------------------- src/video/x11/SDL_x11video.c | 1 + src/video/x11/SDL_x11video.h | 1 + src/video/x11/SDL_x11window.c | 27 +++++----------------- src/video/x11/SDL_x11window.h | 4 ++++ 5 files changed, 31 insertions(+), 44 deletions(-) diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 59f4db361..8e585083a 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -835,37 +835,15 @@ X11_DispatchEvent(_THIS) /* Have we been resized or moved? */ case ConfigureNotify:{ - long border_left = 0; - long border_top = 0; #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 - 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); + xevent.xconfigure.x, xevent.xconfigure.y); #ifdef SDL_USE_IBUS if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){ /* Update IBus candidate list position */ @@ -1175,6 +1153,24 @@ X11_DispatchEvent(_THIS) right approach, but it seems to work. */ X11_UpdateKeymap(_this); SDL_SendKeymapChangedEvent(); + } else if (xevent.xproperty.atom == videodata->_NET_FRAME_EXTENTS) { + Atom type; + int format; + unsigned long nitems, bytes_after; + unsigned char *property; + if (X11_XGetWindowProperty(display, data->xwindow, videodata->_NET_FRAME_EXTENTS, 0, 16, 0, XA_CARDINAL, &type, &format, &nitems, &bytes_after, &property) == Success) { + if (type != None && nitems == 4) { + data->border_left = (int) ((long*)property)[0]; + data->border_right = (int) ((long*)property)[1]; + data->border_top = (int) ((long*)property)[2]; + data->border_bottom = (int) ((long*)property)[3]; + } + X11_XFree(property); + + #ifdef DEBUG_XEVENTS + printf("New _NET_FRAME_EXTENTS: left=%d right=%d, top=%d, bottom=%d\n", data->border_left, data->border_right, data->border_top, data->border_bottom); + #endif + } } } break; diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index ba5e872f3..b2136daf2 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -414,6 +414,7 @@ X11_VideoInit(_THIS) GET_ATOM(_NET_WM_WINDOW_OPACITY); GET_ATOM(_NET_WM_USER_TIME); GET_ATOM(_NET_ACTIVE_WINDOW); + GET_ATOM(_NET_FRAME_EXTENTS); GET_ATOM(UTF8_STRING); GET_ATOM(PRIMARY); GET_ATOM(XdndEnter); diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h index 5ffc57933..912cf483e 100644 --- a/src/video/x11/SDL_x11video.h +++ b/src/video/x11/SDL_x11video.h @@ -108,6 +108,7 @@ typedef struct SDL_VideoData Atom _NET_WM_WINDOW_OPACITY; Atom _NET_WM_USER_TIME; Atom _NET_ACTIVE_WINDOW; + Atom _NET_FRAME_EXTENTS; Atom UTF8_STRING; Atom PRIMARY; Atom XdndEnter; diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index 091767679..348276b0d 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -781,7 +781,7 @@ X11_SetWindowPosition(_THIS, SDL_Window * window) SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Display *display = data->videodata->display; - X11_XMoveWindow(display, data->xwindow, window->x, window->y); + X11_XMoveWindow(display, data->xwindow, window->x + data->border_left, window->y + data->border_top); X11_XFlush(display); } @@ -898,28 +898,13 @@ int X11_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right) { SDL_WindowData *data = (SDL_WindowData *)window->driverdata; - Display *display = data->videodata->display; - Atom _NET_FRAME_EXTENTS = X11_XInternAtom(display, "_NET_FRAME_EXTENTS", 0); - Atom type; - int format; - unsigned long nitems, bytes_after; - unsigned char *property; - int result = -1; - 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) { - *left = (int) (((long*)property)[0]); - *right = (int) (((long*)property)[1]); - *top = (int) (((long*)property)[2]); - *bottom = (int) (((long*)property)[3]); - result = 0; - } - X11_XFree(property); - } + *left = data->border_left; + *right = data->border_right; + *top = data->border_top; + *bottom = data->border_bottom; - return result; + return 0; } int diff --git a/src/video/x11/SDL_x11window.h b/src/video/x11/SDL_x11window.h index 5dafba463..3a3e894ff 100644 --- a/src/video/x11/SDL_x11window.h +++ b/src/video/x11/SDL_x11window.h @@ -56,6 +56,10 @@ typedef struct GC gc; XIC ic; SDL_bool created; + int border_left; + int border_right; + int border_top; + int border_bottom; PendingFocusEnum pending_focus; Uint32 pending_focus_time; XConfigureEvent last_xconfigure;