]> git.sur5r.net Git - i3/i3/commitdiff
Obey minimum size when resizing floating windows
authorMichael Stapelberg <michael@stapelberg.de>
Sun, 6 Mar 2011 13:15:46 +0000 (14:15 +0100)
committerMichael Stapelberg <michael@stapelberg.de>
Sun, 6 Mar 2011 13:15:46 +0000 (14:15 +0100)
Fixes #285

include/con.h
src/con.c
src/floating.c

index 8faf43fc22edceae13bb638a9813a3f186c9aaee..8ffa7ce2a260184227d6ab92c99621e2cc7d3d7a 100644 (file)
@@ -195,4 +195,11 @@ int con_border_style(Con *con);
  */
 void con_set_layout(Con *con, int layout);
 
+/**
+ * Determines the minimum size of the given con by looking at its children (for
+ * split/stacked/tabbed cons). Will be called when resizing floating cons
+ *
+ */
+Rect con_minimum_size(Con *con);
+
 #endif
index 01381206d2bf67920793b2858ef3e43568db30a9..91f11d243db3609d5af4bae6f78f9f7aab318c52 100644 (file)
--- a/src/con.c
+++ b/src/con.c
@@ -820,3 +820,61 @@ static void con_on_remove_child(Con *con) {
         return;
     }
 }
+
+/*
+ * Determines the minimum size of the given con by looking at its children (for
+ * split/stacked/tabbed cons). Will be called when resizing floating cons
+ *
+ */
+Rect con_minimum_size(Con *con) {
+    DLOG("Determining minimum size for con %p\n", con);
+
+    if (con_is_leaf(con)) {
+        DLOG("leaf node, returning 75x50\n");
+        return (Rect){ 0, 0, 75, 50 };
+    }
+
+    if (con->type == CT_FLOATING_CON) {
+        DLOG("floating con\n");
+        Con *child = TAILQ_FIRST(&(con->nodes_head));
+        return con_minimum_size(child);
+    }
+
+    if (con->layout == L_STACKED || con->layout == L_TABBED) {
+        uint32_t max_width = 0, max_height = 0, deco_height = 0;
+        Con *child;
+        TAILQ_FOREACH(child, &(con->nodes_head), nodes) {
+            Rect min = con_minimum_size(child);
+            deco_height += child->deco_rect.height;
+            max_width = max(max_width, min.width);
+            max_height = max(max_height, min.height);
+        }
+        DLOG("stacked/tabbed now, returning %d x %d + deco_rect = %d\n",
+             max_width, max_height, deco_height);
+        return (Rect){ 0, 0, max_width, max_height + deco_height };
+    }
+
+    /* For horizontal/vertical split containers we sum up the width (h-split)
+     * or height (v-split) and use the maximum of the height (h-split) or width
+     * (v-split) as minimum size. */
+    if (con->orientation == HORIZ || con->orientation == VERT) {
+        uint32_t width = 0, height = 0;
+        Con *child;
+        TAILQ_FOREACH(child, &(con->nodes_head), nodes) {
+            Rect min = con_minimum_size(child);
+            if (con->orientation == HORIZ) {
+                width += min.width;
+                height = max(height, min.height);
+            } else {
+                height += min.height;
+                width = max(width, min.width);
+            }
+        }
+        DLOG("split container, returning width = %d x height = %d\n", width, height);
+        return (Rect){ 0, 0, width, height };
+    }
+
+    ELOG("Unhandled case, type = %d, layout = %d, orientation = %d\n",
+         con->type, con->layout, con->orientation);
+    assert(false);
+}
index 2218da29c1bdb2588454ffd013304a4492b60621..6aea7a91636ca4dd6cb5cf8a01bf74238a50defe 100644 (file)
@@ -284,12 +284,10 @@ DRAGGING_CB(resize_window_callback) {
         dest_height = old_rect->height - (new_y - event->root_y);
     else dest_height = old_rect->height + (new_y - event->root_y);
 
-    /* TODO: minimum window size */
-#if 0
     /* Obey minimum window size */
-    dest_width = max(dest_width, client_min_width(client));
-    dest_height = max(dest_height, client_min_height(client));
-#endif
+    Rect minimum = con_minimum_size(con);
+    dest_width = max(dest_width, minimum.width);
+    dest_height = max(dest_height, minimum.height);
 
     /* User wants to keep proportions, so we may have to adjust our values */
     if (params->proportional) {