|
@@ -40,8 +40,40 @@
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
+#ifndef _NET_WM_MOVERESIZE_SIZE_TOPLEFT
|
|
|
+#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifndef _NET_WM_MOVERESIZE_SIZE_TOP
|
|
|
+#define _NET_WM_MOVERESIZE_SIZE_TOP 1
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifndef _NET_WM_MOVERESIZE_SIZE_TOPRIGHT
|
|
|
+#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifndef _NET_WM_MOVERESIZE_SIZE_RIGHT
|
|
|
+#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT
|
|
|
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOM
|
|
|
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT
|
|
|
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifndef _NET_WM_MOVERESIZE_SIZE_LEFT
|
|
|
+#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
|
|
|
+#endif
|
|
|
+
|
|
|
#ifndef _NET_WM_MOVERESIZE_MOVE
|
|
|
-#define _NET_WM_MOVERESIZE_MOVE 8
|
|
|
+#define _NET_WM_MOVERESIZE_MOVE 8
|
|
|
#endif
|
|
|
|
|
|
typedef struct {
|
|
@@ -290,7 +322,7 @@ InitiateWindowMove(_THIS, const SDL_WindowData *data, const SDL_Point *point)
|
|
|
XEvent evt;
|
|
|
evt.xclient.type = ClientMessage;
|
|
|
evt.xclient.window = data->xwindow;
|
|
|
- evt.xclient.message_type = X11_XInternAtom(display, "_NET_WM_MOVERESIZE", False);
|
|
|
+ evt.xclient.message_type = X11_XInternAtom(display, "_NET_WM_MOVERESIZE", True);
|
|
|
evt.xclient.format = 32;
|
|
|
evt.xclient.data.l[0] = window->x + point->x;
|
|
|
evt.xclient.data.l[1] = window->y + point->y;
|
|
@@ -302,21 +334,96 @@ InitiateWindowMove(_THIS, const SDL_WindowData *data, const SDL_Point *point)
|
|
|
X11_XSync(display, 0);
|
|
|
}
|
|
|
|
|
|
+static void
|
|
|
+InitiateWindowResize(_THIS, const SDL_WindowData *data, const SDL_Point *point, int direction)
|
|
|
+{
|
|
|
+ SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
|
|
|
+ SDL_Window* window = data->window;
|
|
|
+ Display *display = viddata->display;
|
|
|
+
|
|
|
+ if (direction < _NET_WM_MOVERESIZE_SIZE_TOPLEFT || direction > _NET_WM_MOVERESIZE_SIZE_LEFT)
|
|
|
+ return;
|
|
|
+
|
|
|
+ /* !!! FIXME: we need to regrab this if necessary when the drag is done. */
|
|
|
+ X11_XUngrabPointer(display, 0L);
|
|
|
+ X11_XFlush(display);
|
|
|
+
|
|
|
+ XEvent evt;
|
|
|
+ evt.xclient.type = ClientMessage;
|
|
|
+ evt.xclient.window = data->xwindow;
|
|
|
+ evt.xclient.message_type = X11_XInternAtom(display, "_NET_WM_MOVERESIZE", True);
|
|
|
+ evt.xclient.format = 32;
|
|
|
+ evt.xclient.data.l[0] = window->x + point->x;
|
|
|
+ evt.xclient.data.l[1] = window->y + point->y;
|
|
|
+ evt.xclient.data.l[2] = direction;
|
|
|
+ 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 SDL_bool
|
|
|
ProcessHitTest(_THIS, const SDL_WindowData *data, const XEvent *xev)
|
|
|
{
|
|
|
SDL_Window *window = data->window;
|
|
|
+ SDL_bool ret = SDL_FALSE;
|
|
|
|
|
|
if (window->hit_test) {
|
|
|
const SDL_Point point = { xev->xbutton.x, xev->xbutton.y };
|
|
|
const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data);
|
|
|
- if (rc == SDL_HITTEST_DRAGGABLE) {
|
|
|
- InitiateWindowMove(_this, data, &point);
|
|
|
- return SDL_TRUE; /* dragging, drop this event. */
|
|
|
+ switch (rc) {
|
|
|
+ case SDL_HITTEST_DRAGGABLE: {
|
|
|
+ InitiateWindowMove(_this, data, &point);
|
|
|
+ ret = SDL_TRUE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case SDL_HITTEST_RESIZE_TOPLEFT: {
|
|
|
+ InitiateWindowResize(_this, data, &point, _NET_WM_MOVERESIZE_SIZE_TOPLEFT);
|
|
|
+ ret = SDL_TRUE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case SDL_HITTEST_RESIZE_TOP: {
|
|
|
+ InitiateWindowResize(_this, data, &point, _NET_WM_MOVERESIZE_SIZE_TOP);
|
|
|
+ ret = SDL_TRUE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case SDL_HITTEST_RESIZE_TOPRIGHT: {
|
|
|
+ InitiateWindowResize(_this, data, &point, _NET_WM_MOVERESIZE_SIZE_TOPRIGHT);
|
|
|
+ ret = SDL_TRUE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case SDL_HITTEST_RESIZE_RIGHT: {
|
|
|
+ InitiateWindowResize(_this, data, &point, _NET_WM_MOVERESIZE_SIZE_RIGHT);
|
|
|
+ ret = SDL_TRUE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case SDL_HITTEST_RESIZE_BOTTOMRIGHT: {
|
|
|
+ InitiateWindowResize(_this, data, &point, _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT);
|
|
|
+ ret = SDL_TRUE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case SDL_HITTEST_RESIZE_BOTTOM: {
|
|
|
+ InitiateWindowResize(_this, data, &point, _NET_WM_MOVERESIZE_SIZE_BOTTOM);
|
|
|
+ ret = SDL_TRUE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case SDL_HITTEST_RESIZE_BOTTOMLEFT: {
|
|
|
+ InitiateWindowResize(_this, data, &point, _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT);
|
|
|
+ ret = SDL_TRUE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case SDL_HITTEST_RESIZE_LEFT: {
|
|
|
+ InitiateWindowResize(_this, data, &point, _NET_WM_MOVERESIZE_SIZE_LEFT);
|
|
|
+ ret = SDL_TRUE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return SDL_FALSE; /* not a drag area. */
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static void
|