Initial work on X11 implementation of SDL_SetWindowDragAreas().
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
diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c
index 50e7394..db6a301 100644
--- a/src/video/x11/SDL_x11events.c
+++ b/src/video/x11/SDL_x11events.c
@@ -273,6 +273,51 @@ X11_DispatchUnmapNotify(SDL_WindowData *data)
}
static void
+InitiateWindowMove(SDL_Window *window)
+{
+ SDL_SysWMinfo info;
+ SDL_VERSION(&info.version);
+ SDL_GetWindowWMInfo(window, &info);
+ Display *display = info.info.x11.display;
+
+ int bx, by, dx, dy;
+ SDL_GetWindowPosition(window, &bx, &by);
+ SDL_GetMouseState(&dx, &dy);
+ X11_XUngrabPointer(display, 0L);
+ X11_XFlush(display);
+
+ XEvent evt;
+ evt.xclient.type = ClientMessage;
+ evt.xclient.window = info.info.x11.window;
+ evt.xclient.message_type = X11_XInternAtom(display, "_NET_WM_MOVERESIZE", False);
+ evt.xclient.format = 32;
+ evt.xclient.data.l[0] = bx + dx;
+ evt.xclient.data.l[1] = by + dy;
+ evt.xclient.data.l[2] = 8; /* _NET_WM_MOVERESIZE_MOVE */
+ evt.xclient.data.l[3] = Button1;
+ evt.xclient.data.l[4] = 0;
+ X11_XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &evt);
+
+ X11_XSync(display, 0);
+}
+
+static void
+ProcessDragArea(SDL_WindowData* data)
+{
+ SDL_Window* window = data->window;
+ SDL_Mouse* mouse = SDL_GetMouse();
+ int i;
+ const int num_areas = window->num_drag_areas;
+ const SDL_Point point = {mouse->x, mouse->y};
+ const SDL_Rect *areas = window->drag_areas;
+ for(i = 0;i < num_areas;++i) {
+ if (SDL_PointInRect(&point, &areas[i])) {
+ InitiateWindowMove(window);
+ }
+ }
+}
+
+static void
X11_DispatchEvent(_THIS)
{
SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
@@ -709,6 +754,9 @@ X11_DispatchEvent(_THIS)
if (X11_IsWheelEvent(display,&xevent,&ticks)) {
SDL_SendMouseWheel(data->window, 0, 0, ticks);
} else {
+ if(xevent.xbutton.button == SDL_BUTTON_LEFT) {
+ ProcessDragArea(data);
+ }
SDL_SendMouseButton(data->window, 0, SDL_PRESSED, xevent.xbutton.button);
}
}
diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c
index ca9faee..4cece01 100644
--- a/src/video/x11/SDL_x11video.c
+++ b/src/video/x11/SDL_x11video.c
@@ -457,6 +457,7 @@ X11_CreateDevice(int devindex)
device->UpdateWindowFramebuffer = X11_UpdateWindowFramebuffer;
device->DestroyWindowFramebuffer = X11_DestroyWindowFramebuffer;
device->GetWindowWMInfo = X11_GetWindowWMInfo;
+ device->SetWindowDragAreas = X11_SetWindowDragAreas;
device->shape_driver.CreateShaper = X11_CreateShaper;
device->shape_driver.SetWindowShape = X11_SetWindowShape;
diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c
index b4de15b..2c0c9e4 100644
--- a/src/video/x11/SDL_x11window.c
+++ b/src/video/x11/SDL_x11window.c
@@ -1444,6 +1444,12 @@ X11_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
}
}
+int
+X11_SetWindowDragAreas(SDL_Window *window, const SDL_Rect *areas, int num_areas)
+{
+ return 0; // nothing to do, will be handled in event handler
+}
+
#endif /* SDL_VIDEO_DRIVER_X11 */
/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/video/x11/SDL_x11window.h b/src/video/x11/SDL_x11window.h
index cf0d7f7..6a00c1a 100644
--- a/src/video/x11/SDL_x11window.h
+++ b/src/video/x11/SDL_x11window.h
@@ -93,6 +93,7 @@ extern void X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
extern void X11_DestroyWindow(_THIS, SDL_Window * window);
extern SDL_bool X11_GetWindowWMInfo(_THIS, SDL_Window * window,
struct SDL_SysWMinfo *info);
+extern int X11_SetWindowDragAreas(SDL_Window *window, const SDL_Rect *areas, int num_areas);
#endif /* _SDL_x11window_h */