i3 - improved tiling WM


Suppport _NET_WM_MOVERESIZE, simplified resizing

Patch status: superseded

Patch by Lukas K

Long description:

This patch supersedes the previous ones regarding _NET_WM_MOVERESIZE.
Handling all resizing directions has been dropped because of increased
complexity and few clients using it. Instead i3 decides on the resizing
directions by itself, as for i3-initiated resizing.
fixes #1432

To apply this patch, use:
curl http://cr.i3wm.org/patch/705/raw.patch | git am

b/include/atoms.xmacro

20
@@ -1,6 +1,7 @@
21
 xmacro(_NET_SUPPORTED)
22
 xmacro(_NET_SUPPORTING_WM_CHECK)
23
 xmacro(_NET_WM_NAME)
24
+xmacro(_NET_WM_MOVERESIZE)
25
 xmacro(_NET_WM_STATE_FULLSCREEN)
26
 xmacro(_NET_WM_STATE_DEMANDS_ATTENTION)
27
 xmacro(_NET_WM_STATE_MODAL)

b/src/ewmh.c

32
@@ -234,5 +234,6 @@ void ewmh_setup_hints(void) {
33
     /* I’m not entirely sure if we need to keep _NET_WM_NAME on root. */
34
     xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_WM_NAME, A_UTF8_STRING, 8, strlen("i3"), "i3");
35
 
36
-    xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_SUPPORTED, XCB_ATOM_ATOM, 32, 23, supported_atoms);
37
+    /* only send the first 24 atoms (last one is _NET_CLOSE_WINDOW) increment that number when adding supported atoms */
38
+    xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_SUPPORTED, XCB_ATOM_ATOM, 32, 24, supported_atoms);
39
 }

b/src/handlers.c

44
@@ -651,6 +651,19 @@ static void handle_expose_event(xcb_expose_event_t *event) {
45
     return;
46
 }
47
 
48
+#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT      0
49
+#define _NET_WM_MOVERESIZE_SIZE_TOP          1
50
+#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT     2
51
+#define _NET_WM_MOVERESIZE_SIZE_RIGHT        3
52
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT  4
53
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOM       5
54
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT   6
55
+#define _NET_WM_MOVERESIZE_SIZE_LEFT         7
56
+#define _NET_WM_MOVERESIZE_MOVE              8   /* movement only */
57
+#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD     9   /* size via keyboard */
58
+#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD    10   /* move via keyboard */
59
+#define _NET_WM_MOVERESIZE_CANCEL           11   /* cancel operation */
60
+
61
 /*
62
  * Handle client messages (EWMH)
63
  *
64
@@ -856,6 +869,35 @@ static void handle_client_message(xcb_client_message_event_t *event) {
65
         } else {
66
             DLOG("Couldn't find con for _NET_CLOSE_WINDOW request. (window = %d)\n", event->window);
67
         }
68
+    } else if (event->type == A__NET_WM_MOVERESIZE) {
69
+        /*
70
+         * Client-side decorated Gtk3 windows emit this signal when being
71
+         * dragged by their GtkHeaderBar
72
+         */
73
+         Con *con = con_by_window_id(event->window);
74
+         if (con && con_is_floating(con)) {
75
+             DLOG("Handling _NET_WM_MOVERESIZE request (con = %p)\n", con);
76
+             uint32_t direction = event->data.data32[2];
77
+             uint32_t x_root = event->data.data32[0];
78
+             uint32_t y_root = event->data.data32[1];
79
+             /* construct fake xcb_button_press_event_t */
80
+             xcb_button_press_event_t fake = {
81
+                 .root_x = x_root,
82
+                 .root_y = y_root,
83
+                 .event_x = x_root-(con->rect.x),
84
+                 .event_y = y_root-(con->rect.y)
85
+             };
86
+             if(direction == _NET_WM_MOVERESIZE_MOVE) {
87
+                 floating_drag_window(con->parent, &fake);
88
+             } else if(direction >= _NET_WM_MOVERESIZE_SIZE_TOPLEFT && direction <= _NET_WM_MOVERESIZE_SIZE_LEFT) {
89
+                 floating_resize_window(con->parent, FALSE, &fake);
90
+             } else {
91
+                DLOG("_NET_WM_MOVERESIZE direction %d not implemented\n", direction);
92
+             }
93
+
94
+         } else {
95
+             DLOG("Couldn't find con for _NET_WM_MOVERESIZE request. or con not floating (window = %d)\n", event->window);
96
+         }
97
     } else {
98
         DLOG("unhandled clientmessage\n");
99
         return;