]> git.sur5r.net Git - i3/i3/commitdiff
Implement support for user configuration of constraints on floating window dimensions.
authorD Thompson <thompdump@gmail.com>
Thu, 16 Feb 2012 14:36:46 +0000 (06:36 -0800)
committerMichael Stapelberg <michael@stapelberg.de>
Thu, 16 Feb 2012 18:31:28 +0000 (18:31 +0000)
docs/userguide
include/config.h
src/cfgparse.l
src/cfgparse.y
src/floating.c

index c753455296e8a41ed97b3e799fd0905235cd150f..32879e6fa4681414fb1edf774743365bca013053 100644 (file)
@@ -370,6 +370,27 @@ floating_modifier <Modifiers>
 floating_modifier Mod1
 --------------------------------
 
+=== Constraining floating window size
+
+The maximum and minimum dimensions of floating windows can be specified. If
+either dimension of +floating_maximum_size+ is specified as -1, that dimension
+will be unconstrained with respect to its maximum value. If either dimension of
++floating_maximum_size+ is undefined, or specified as 0, i3 will use a default
+value to constrain the maximum size. +floating_minimum_size+ is treated in a
+manner analogous to +floating_maximum_size+.
+
+*Syntax*:
+----------------------------------------
+floating_minimum_size <width> x <height>
+floating_maximum_size <width> x <height>
+----------------------------------------
+
+*Example*:
+--------------------------------------
+floating_minimum_size 75 x 50
+floating_maximum_size -1 x -1
+--------------------------------------
+
 === Orientation for new workspaces
 
 New workspaces get a reasonable default orientation: Wide-screen monitors
index 680830fd06e3846b36383e4c23c0f903defbcb51..9b5b01cbc0d89c2a53837f8683debcc01db165e7 100644 (file)
@@ -150,6 +150,12 @@ struct Config {
      * buttons to do things with floating windows (move, resize) */
     uint32_t floating_modifier;
 
+    /** Maximum and minimum dimensions of a floating window */
+    uint16_t floating_maximum_width;
+    uint16_t floating_maximum_height;
+    uint16_t floating_minimum_width;
+    uint16_t floating_minimum_height;
+
     /* Color codes are stored here */
     struct config_client {
         uint32_t background;
index d829b336682fb001079a78574631e7bcec396c02..4885c66dc72aabb7273cdf7d26009f6643ccdd7d 100644 (file)
@@ -176,6 +176,8 @@ mode                            { return TOKMODE; }
 bind                            { yy_push_state(WANT_STRING); yy_push_state(EAT_WHITESPACE); yy_push_state(EAT_WHITESPACE); return TOKBINDCODE; }
 bindcode                        { yy_push_state(WANT_STRING); yy_push_state(EAT_WHITESPACE); yy_push_state(EAT_WHITESPACE); return TOKBINDCODE; }
 bindsym                         { yy_push_state(BINDSYM_COND); yy_push_state(EAT_WHITESPACE); return TOKBINDSYM; }
+floating_maximum_size           { return TOKFLOATING_MAXIMUM_SIZE; }
+floating_minimum_size           { return TOKFLOATING_MINIMUM_SIZE; }
 floating_modifier               { return TOKFLOATING_MODIFIER; }
 workspace                       { return TOKWORKSPACE; }
 output                          { yy_push_state(OUTPUT_COND); yy_push_state(EAT_WHITESPACE); return TOKOUTPUT; }
index e357fb7070492272d73d86e2e304cf4c504fe3c7..676e0d111181d0c9124a08e7c34e9386e1d63e47 100644 (file)
@@ -664,6 +664,8 @@ void parse_file(const char *f) {
 %token                  TOKCONTROL                  "control"
 %token                  TOKSHIFT                    "shift"
 %token                  TOKFLOATING_MODIFIER        "floating_modifier"
+%token                  TOKFLOATING_MAXIMUM_SIZE    "floating_maximum_size"
+%token                  TOKFLOATING_MINIMUM_SIZE    "floating_minimum_size"
 %token  <string>        QUOTEDSTRING                "<quoted string>"
 %token                  TOKWORKSPACE                "workspace"
 %token                  TOKOUTPUT                   "output"
@@ -778,6 +780,8 @@ line:
     | for_window
     | mode
     | bar
+    | floating_maximum_size
+    | floating_minimum_size
     | floating_modifier
     | orientation
     | workspace_layout
@@ -1292,6 +1296,26 @@ bar_color_urgent_workspace:
     }
     ;
 
+floating_maximum_size:
+    TOKFLOATING_MAXIMUM_SIZE NUMBER WORD NUMBER
+    {
+        printf("floating_maximum_width = %d\n", $2);
+        printf("floating_maximum_height = %d\n", $4);
+        config.floating_maximum_width = $2;
+        config.floating_maximum_height = $4;
+    }
+    ;
+
+floating_minimum_size:
+    TOKFLOATING_MINIMUM_SIZE NUMBER WORD NUMBER
+    {
+        printf("floating_minimum_width = %d\n", $2);
+        printf("floating_minimum_height = %d\n", $4);
+        config.floating_minimum_width = $2;
+        config.floating_minimum_height = $4;
+    }
+    ;
+
 floating_modifier:
     TOKFLOATING_MODIFIER binding_modifiers
     {
index 0637521fbce020630c22ec98bd8f2efffee3785a..3f38761f1e34dfb72d516438fb2a8a330dde70c6 100644 (file)
 
 extern xcb_connection_t *conn;
 
+/*
+ * Calculates sum of heights and sum of widths of all currently active outputs
+ *
+ */
+Rect total_outputs_dimensions() {
+    Output *output;
+    /* Use Rect to encapsulate dimensions, ignoring x/y */
+    Rect outputs_dimensions = {0, 0, 0, 0};
+    TAILQ_FOREACH(output, &outputs, outputs) {
+        outputs_dimensions.height += output->rect.height;
+        outputs_dimensions.width += output->rect.width;
+    }
+    return outputs_dimensions;
+}
+
 void floating_enable(Con *con, bool automatic) {
     bool set_focus = (con == focused);
 
@@ -120,9 +135,45 @@ void floating_enable(Con *con, bool automatic) {
             nc->rect.height = max(nc->rect.height, child->geometry.height);
         }
     }
-    /* Raise the width/height to at least 75x50 (minimum size for windows) */
-    nc->rect.width = max(nc->rect.width, 75);
-    nc->rect.height = max(nc->rect.height, 50);
+
+    /* Define reasonable minimal and maximal sizes for floating windows */
+    const int floating_sane_min_height = 50;
+    const int floating_sane_min_width = 75;
+
+    Rect floating_sane_max_dimensions;
+    floating_sane_max_dimensions = total_outputs_dimensions();
+
+    /* Unless user requests otherwise (-1), ensure width/height do not exceed
+     * configured maxima or, if unconfigured, limit to combined width of all
+     * outputs */
+    if (config.floating_maximum_height != -1) {
+        if (config.floating_maximum_height == 0)
+            nc->rect.height = min(nc->rect.height, floating_sane_max_dimensions.height);
+        else
+            nc->rect.height = min(nc->rect.height, config.floating_maximum_height);
+    }
+    if (config.floating_maximum_width != -1) {
+        if (config.floating_maximum_width == 0)
+            nc->rect.width = min(nc->rect.width, floating_sane_max_dimensions.width);
+        else
+            nc->rect.width = min(nc->rect.width, config.floating_maximum_width);
+    }
+
+    /* Unless user requests otherwise (-1), raise the width/height to
+     * reasonable minimum dimensions */
+    if (config.floating_minimum_height != -1) {
+        if (config.floating_minimum_height == 0)
+            nc->rect.height = max(nc->rect.height, floating_sane_min_height);
+        else
+            nc->rect.height = max(nc->rect.height, config.floating_minimum_height);
+    }
+    if (config.floating_minimum_width != -1) {
+        if (config.floating_minimum_width == 0)
+            nc->rect.width = max(nc->rect.width, floating_sane_min_width);
+        else
+            nc->rect.width = max(nc->rect.width, config.floating_minimum_width);
+    }
+
     /* add pixels for the decoration */
     /* TODO: don’t add them when the user automatically puts new windows into
      * 1pixel/borderless mode */