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
* 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;
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; }
%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"
| for_window
| mode
| bar
+ | floating_maximum_size
+ | floating_minimum_size
| floating_modifier
| orientation
| workspace_layout
}
;
+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
{
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);
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 */