From: D Thompson Date: Thu, 16 Feb 2012 14:36:46 +0000 (-0800) Subject: Implement support for user configuration of constraints on floating window dimensions. X-Git-Tag: 4.2~69 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=82146fcebf7e18c4cc16e89ec3ea97b04681f8c6;p=i3%2Fi3 Implement support for user configuration of constraints on floating window dimensions. --- diff --git a/docs/userguide b/docs/userguide index c7534552..32879e6f 100644 --- a/docs/userguide +++ b/docs/userguide @@ -370,6 +370,27 @@ floating_modifier 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 x +floating_maximum_size x +---------------------------------------- + +*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 diff --git a/include/config.h b/include/config.h index 680830fd..9b5b01cb 100644 --- a/include/config.h +++ b/include/config.h @@ -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; diff --git a/src/cfgparse.l b/src/cfgparse.l index d829b336..4885c66d 100644 --- a/src/cfgparse.l +++ b/src/cfgparse.l @@ -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; } diff --git a/src/cfgparse.y b/src/cfgparse.y index e357fb70..676e0d11 100644 --- a/src/cfgparse.y +++ b/src/cfgparse.y @@ -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 QUOTEDSTRING "" %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 { diff --git a/src/floating.c b/src/floating.c index 0637521f..3f38761f 100644 --- a/src/floating.c +++ b/src/floating.c @@ -11,6 +11,21 @@ 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 */