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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c
index 59f4db3..8e58508 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 ba5e872..b2136da 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 5ffc579..912cf48 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 0917676..348276b 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);
- }
- return result;
+ *left = data->border_left;
+ *right = data->border_right;
+ *top = data->border_top;
+ *bottom = data->border_bottom;
+
+ return 0;
}
int
diff --git a/src/video/x11/SDL_x11window.h b/src/video/x11/SDL_x11window.h
index 5dafba4..3a3e894 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;