i3 - improved tiling WM


Obey WM_SIZE_HINTS's resize increments in floating

Patch status: merged

Patch by oblique

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

b/src/commands.c

15
@@ -588,9 +588,9 @@ static void cmd_resize_floating(I3_CMD, char *way, char *direction, Con *floatin
16
         return;
17
 
18
     if (strcmp(direction, "up") == 0) {
19
-        floating_con->rect.y -= px;
20
+        floating_con->rect.y -= (floating_con->rect.height - old_rect.height);
21
     } else if (strcmp(direction, "left") == 0) {
22
-        floating_con->rect.x -= px;
23
+        floating_con->rect.x -= (floating_con->rect.width - old_rect.width);
24
     }
25
 }
26
 

b/src/floating.c

31
@@ -39,6 +39,35 @@ void floating_check_size(Con *floating_con) {
32
     const int floating_sane_min_height = 50;
33
     const int floating_sane_min_width = 75;
34
     Rect floating_sane_max_dimensions;
35
+    Con *focused_con = con_descend_focused(floating_con);
36
+
37
+    /* obey size increments */
38
+    if (focused_con->height_increment || focused_con->width_increment) {
39
+        Rect border_rect = con_border_style_rect(focused_con);
40
+
41
+        /* We have to do the opposite calculations that render_con() do
42
+         * to get the exact size we want. */
43
+        border_rect.width = -border_rect.width;
44
+        border_rect.width += 2 * focused_con->border_width;
45
+        border_rect.height = -border_rect.height;
46
+        border_rect.height += 2 * focused_con->border_width;
47
+        if (con_border_style(focused_con) == BS_NORMAL)
48
+            border_rect.height += render_deco_height();
49
+
50
+        if (focused_con->height_increment &&
51
+            floating_con->rect.height >= focused_con->base_height + border_rect.height) {
52
+            floating_con->rect.height -= focused_con->base_height + border_rect.height;
53
+            floating_con->rect.height -= floating_con->rect.height % focused_con->height_increment;
54
+            floating_con->rect.height += focused_con->base_height + border_rect.height;
55
+        }
56
+
57
+        if (focused_con->width_increment &&
58
+            floating_con->rect.width >= focused_con->base_width + border_rect.width) {
59
+            floating_con->rect.width -= focused_con->base_width + border_rect.width;
60
+            floating_con->rect.width -= floating_con->rect.width % focused_con->width_increment;
61
+            floating_con->rect.width += focused_con->base_width + border_rect.width;
62
+        }
63
+    }
64
 
65
     /* Unless user requests otherwise (-1), ensure width/height do not exceed
66
      * configured maxima or, if unconfigured, limit to combined width of all
67
@@ -447,26 +476,27 @@ DRAGGING_CB(resize_window_callback) {
68
         dest_height = old_rect->height - (new_y - event->root_y);
69
     else dest_height = old_rect->height + (new_y - event->root_y);
70
 
71
-    /* Obey minimum window size */
72
-    Rect minimum = con_minimum_size(con);
73
-    dest_width = max(dest_width, minimum.width);
74
-    dest_height = max(dest_height, minimum.height);
75
-
76
     /* User wants to keep proportions, so we may have to adjust our values */
77
     if (params->proportional) {
78
         dest_width = max(dest_width, (int) (dest_height * ratio));
79
         dest_height = max(dest_height, (int) (dest_width / ratio));
80
     }
81
 
82
+    con->rect = (Rect) { dest_x, dest_y, dest_width, dest_height };
83
+
84
+    /* Obey window size */
85
+    floating_check_size(con);
86
+
87
     /* If not the lower right corner is grabbed, we must also reposition
88
      * the client by exactly the amount we resized it */
89
     if (corner & BORDER_LEFT)
90
-        dest_x = old_rect->x + (old_rect->width - dest_width);
91
+        dest_x = old_rect->x + (old_rect->width - con->rect.width);
92
 
93
     if (corner & BORDER_TOP)
94
-        dest_y = old_rect->y + (old_rect->height - dest_height);
95
+        dest_y = old_rect->y + (old_rect->height - con->rect.height);
96
 
97
-    con->rect = (Rect) { dest_x, dest_y, dest_width, dest_height };
98
+    con->rect.x = dest_x;
99
+    con->rect.y = dest_y;
100
 
101
     /* TODO: don’t re-render the whole tree just because we change
102
      * coordinates of a floating window */

b/src/scratchpad.c

107
@@ -173,6 +173,7 @@ void scratchpad_show(Con *con) {
108
         Con *output = con_get_output(con);
109
         con->rect.width = output->rect.width * 0.5;
110
         con->rect.height = output->rect.height * 0.75;
111
+        floating_check_size(con);
112
         con->rect.x = output->rect.x +
113
                       ((output->rect.width / 2.0) - (con->rect.width / 2.0));
114
         con->rect.y = output->rect.y +