]> git.lizzy.rs Git - bspwm.git/commitdiff
Add new setting: automatic_scheme
authorBastien Dejean <nihilhill@gmail.com>
Fri, 31 Aug 2018 09:33:00 +0000 (11:33 +0200)
committerBastien Dejean <nihilhill@gmail.com>
Fri, 31 Aug 2018 09:33:00 +0000 (11:33 +0200)
Fixes #764.

17 files changed:
README.md
contrib/bash_completion
contrib/fish_completion
contrib/zsh_completion
doc/bspwm.1
doc/bspwm.1.asciidoc
examples/external_rules/pseudo_automatic_mode/README.md [deleted file]
examples/external_rules/pseudo_automatic_mode/external_rules [deleted file]
src/helpers.h
src/messages.c
src/parse.c
src/parse.h
src/settings.c
src/settings.h
src/tree.c
src/types.h
tests/run

index a4e586bc7ff1eefad6513c1dceb82af7d5fe37b8..a5d0cd5920bfce3aba1b12e85118569210622db6 100644 (file)
--- a/README.md
+++ b/README.md
@@ -51,49 +51,7 @@ When *bspwm* receives a new window, it inserts it into a window tree at the spec
 
 The insertion mode tells *bspwm* how it should alter the tree in order to insert new windows on a given insertion point.
 
-By default the insertion point is the focused window and its default insertion mode is *automatic*.
-
-### Automatic Mode
-
-The *automatic* mode, as opposed to the *manual* mode, doesn't require any user choice: the new window will *take the space* of the insertion point.
-
-For example, let's consider the following scenario:
-
-```
-             a                          a                          a
-            / \                        / \                        / \
-           1   b         --->         1   c         --->         1   d
-              / \                        / \                        / \
-             2   3                      4   b                      5   c
-             ^                          ^  / \                     ^  / \
-                                          3   2                      b   4
-                                                                    / \ 
-                                                                   3   2
-
- +-----------------------+  +-----------------------+  +-----------------------+
- |           |           |  |           |           |  |           |           |
- |           |     2     |  |           |     4     |  |           |     5     |
- |           |     ^     |  |           |     ^     |  |           |     ^     |
- |     1     |-----------|  |     1     |-----------|  |     1     |-----------|
- |           |           |  |           |     |     |  |           |  3  |     |
- |           |     3     |  |           |  3  |  2  |  |           |-----|  4  |
- |           |           |  |           |     |     |  |           |  2  |     |
- +-----------------------+  +-----------------------+  +-----------------------+
-
-              X                         Y                          Z 
-```
-
-In state *X*, the insertion point, *2* is in automatic mode.
-
-When we add a new window, *4*, the whole tree rooted at *b* is reattached, as the second child of a new internal node, *c*.
-
-The splitting parameters of *b* (type: *horizontal*, ratio: *½*) are copied to *c* and *b* is rotated by 90° clockwise.
-
-The tiling rectangle of *4* in state *Y* is equal to the tiling rectangle of *2* in state *X*.
-
-Then the insertion of *5*, with *4* as insertion point, leads to *Z*.
-
-The automatic mode generates window spirals that rotate clockwise (resp. anti-clockwise) if the insertion point is the first (resp. second) child of its parent.
+By default the insertion point is the focused window and its insertion mode is *automatic*.
 
 ### Manual Mode
 
@@ -103,7 +61,7 @@ The *DIR* argument allows to specify how the insertion point should be split (ho
 
 After doing so the insertion point goes into *manual* mode.
 
-For example, let's consider the following scenario:
+Let's consider the following scenario:
 
 ```
             a                          a                          a
@@ -138,6 +96,86 @@ Finally we send another message: *node -p west* and add window *5*.
 
 The ratio of the preselection (that ends up being the ratio of the split of the new internal node) can be changed with the *node -o|--presel-ratio* message.
 
+### Automatic Mode
+
+The *automatic* mode, as opposed to the *manual* mode, doesn't require any user choice. The way the new window is inserted is determined by the value of the automatic scheme and the initial polarity settings.
+
+#### Longest side
+
+When the value of the automatic scheme is `longest_side`, the window will be attached as if the insertion point was in manual mode and the split direction was choosen based on the dimensions of the tiling rectangle and the initial polarity.
+
+Let's consider the following scenario, where the initial polarity is set to `second_child`:
+
+```
+             1                          a                          a
+             ^                         / \                        / \
+                         --->         1   2         --->         1   b
+                                          ^                         / \
+                                                                   2   3
+                                                                       ^
+
+ +-----------------------+  +-----------------------+  +-----------------------+
+ |                       |  |           |           |  |           |           |
+ |                       |  |           |           |  |           |     2     |
+ |                       |  |           |           |  |           |           |
+ |           1           |  |     1     |     2     |  |     1     |-----------|
+ |           ^           |  |           |     ^     |  |           |           |
+ |                       |  |           |           |  |           |     3     |
+ |                       |  |           |           |  |           |     ^     |
+ +-----------------------+  +-----------------------+  +-----------------------+
+
+             X                          Y                          Z
+```
+
+In state *X*, a new window is added.
+
+Since *1* is wide, it gets split vertically and *2* is added as *a*'s second child given the initial polarity.
+
+This leads to *Y* where we insert window *3*. *2* is tall and is therefore split horizontally. *3* is once again added as *b*'s second child.
+
+#### Spiral
+
+When the value of the automatic scheme is `spiral`, the window will *take the space* of the insertion point.
+
+Let's dive into the details with the following scenario:
+
+```
+             a                          a                          a
+            / \                        / \                        / \
+           1   b         --->         1   c         --->         1   d
+              / \                        / \                        / \
+             2   3                      4   b                      5   c
+             ^                          ^  / \                     ^  / \
+                                          3   2                      b   4
+                                                                    / \
+                                                                   3   2
+
+ +-----------------------+  +-----------------------+  +-----------------------+
+ |           |           |  |           |           |  |           |           |
+ |           |     2     |  |           |     4     |  |           |     5     |
+ |           |     ^     |  |           |     ^     |  |           |     ^     |
+ |     1     |-----------|  |     1     |-----------|  |     1     |-----------|
+ |           |           |  |           |     |     |  |           |  3  |     |
+ |           |     3     |  |           |  3  |  2  |  |           |-----|  4  |
+ |           |           |  |           |     |     |  |           |  2  |     |
+ +-----------------------+  +-----------------------+  +-----------------------+
+
+             X                          Y                          Z
+```
+
+In state *X*, the insertion point, *2* is in automatic mode.
+
+When we add a new window, *4*, the whole tree rooted at *b* is reattached, as the second child of a new internal node, *c*.
+
+The splitting parameters of *b* (type: *horizontal*, ratio: *½*) are copied to *c* and *b* is rotated by 90° clockwise.
+
+The tiling rectangle of *4* in state *Y* is equal to the tiling rectangle of *2* in state *X*.
+
+Then the insertion of *5*, with *4* as insertion point, leads to *Z*.
+
+The *spiral* automatic scheme generates window spirals that rotate clockwise (resp. anti-clockwise) if the insertion point is the first (resp. second) child of its parent.
+
+
 ## Supported protocols and standards
 
 - The RandR and Xinerama protocols.
index 35c1f298352e3f25eb4f3f79288ae83096f26206..ab57d02e68e5a06a1101a2a63a3a64ae5772cd5e 100644 (file)
@@ -1,7 +1,7 @@
 _bspc() {
        local commands='node desktop monitor query rule wm subscribe config quit'
 
-       local settings='external_rules_command status_prefix normal_border_color active_border_color focused_border_color presel_feedback_color border_width window_gap top_padding right_padding bottom_padding left_padding split_ratio initial_polarity directional_focus_tightness borderless_monocle gapless_monocle single_monocle pointer_motion_interval pointer_modifier pointer_action1 pointer_action2 pointer_action3 click_to_focus swallow_first_click focus_follows_pointer pointer_follows_focus pointer_follows_monitor mapping_events_count ignore_ewmh_focus ignore_ewmh_fullscreen center_pseudo_tiled honor_size_hints remove_disabled_monitors remove_unplugged_monitors merge_overlapping_monitors'
+       local settings='external_rules_command status_prefix normal_border_color active_border_color focused_border_color presel_feedback_color border_width window_gap top_padding right_padding bottom_padding left_padding split_ratio automatic_scheme initial_polarity directional_focus_tightness borderless_monocle gapless_monocle single_monocle pointer_motion_interval pointer_modifier pointer_action1 pointer_action2 pointer_action3 click_to_focus swallow_first_click focus_follows_pointer pointer_follows_focus pointer_follows_monitor mapping_events_count ignore_ewmh_focus ignore_ewmh_fullscreen center_pseudo_tiled honor_size_hints remove_disabled_monitors remove_unplugged_monitors merge_overlapping_monitors'
 
        COMPREPLY=()
 
index 940ad07260632db148f2fec5ccb0d24234aea8f5..a79c483713468db47adf458856ffda3941ca90d7 100644 (file)
@@ -11,4 +11,4 @@ function __fish_bspc_using_command
 end
 
 complete -f -c bspc -n '__fish_bspc_needs_command' -a 'node desktop monitor query rule wm subscribe config quit'
-complete -f -c bspc -n '__fish_bspc_using_command config' -a 'external_rules_command status_prefix normal_border_color active_border_color focused_border_color presel_feedback_color border_width window_gap top_padding right_padding bottom_padding left_padding split_ratio initial_polarity directional_focus_tightness borderless_monocle gapless_monocle single_monocle pointer_motion_interval pointer_modifier pointer_action1 pointer_action2 pointer_action3 click_to_focus swallow_first_click focus_follows_pointer pointer_follows_focus pointer_follows_monitor mapping_events_count ignore_ewmh_focus ignore_ewmh_fullscreen center_pseudo_tiled honor_size_hints remove_disabled_monitors remove_unplugged_monitors merge_overlapping_monitors'
+complete -f -c bspc -n '__fish_bspc_using_command config' -a 'external_rules_command status_prefix normal_border_color active_border_color focused_border_color presel_feedback_color border_width window_gap top_padding right_padding bottom_padding left_padding split_ratio automatic_scheme initial_polarity directional_focus_tightness borderless_monocle gapless_monocle single_monocle pointer_motion_interval pointer_modifier pointer_action1 pointer_action2 pointer_action3 click_to_focus swallow_first_click focus_follows_pointer pointer_follows_focus pointer_follows_monitor mapping_events_count ignore_ewmh_focus ignore_ewmh_fullscreen center_pseudo_tiled honor_size_hints remove_disabled_monitors remove_unplugged_monitors merge_overlapping_monitors'
index 5b663f7ed48f634e8a924ce280111218116aa41a..3f94bfd650555c3cb0d57dfe51aad984a7dbd3a2 100644 (file)
@@ -318,7 +318,7 @@ _bspc() {
                        look_bool=(borderless_monocle gapless_monocle)
                        look=({normal,active,focused}_border_color {top,right,bottom,left}_padding presel_feedback_color border_width window_gap)
                        behaviour_bool=(single_monocle ignore_ewmh_focus center_pseudo_tiled honor_size_hints remove_disabled_monitors remove_unplugged_monitors merge_overlapping_monitors)
-                       behaviour=(mapping_events_count ignore_ewmh_fullscreen external_rules_command split_ratio initial_polarity directional_focus_tightness status_prefix)
+                       behaviour=(mapping_events_count ignore_ewmh_fullscreen external_rules_command split_ratio automatic_scheme initial_polarity directional_focus_tightness status_prefix)
                        input_bool=(swallow_first_click focus_follows_pointer pointer_follows_{focus,monitor})
                        input=(click_to_focus pointer_motion_interval pointer_modifier pointer_action{1,2,3})
                        if [[ "$CURRENT" == (2|3) ]];then
index f545bd159dbdf3a5750c913f50817b16b2f1691f..0b59b74e3481e5390b663492e0cdcbf8698e61c5 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: bspwm
 .\"    Author: [see the "Author" section]
 .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
-.\"      Date: 08/28/2018
+.\"      Date: 08/31/2018
 .\"    Manual: Bspwm Manual
-.\"    Source: Bspwm 0.9.5-10-g336bc86
+.\"    Source: Bspwm 0.9.5-14-g56ad57c
 .\"  Language: English
 .\"
-.TH "BSPWM" "1" "08/28/2018" "Bspwm 0\&.9\&.5\-10\-g336bc86" "Bspwm Manual"
+.TH "BSPWM" "1" "08/31/2018" "Bspwm 0\&.9\&.5\-14\-g56ad57c" "Bspwm Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -1151,6 +1151,13 @@ External command used to retrieve rule consequences\&. The command will receive
 command)\&.
 .RE
 .PP
+\fIautomatic_scheme\fR
+.RS 4
+The insertion scheme used when the insertion point is in automatic mode\&. Accept the following values:
+\fBlongest_side\fR,
+\fBspiral\fR\&.
+.RE
+.PP
 \fIinitial_polarity\fR
 .RS 4
 On which child should a new window be attached when adding a window on a single window tree in automatic mode\&. Accept the following values:
index 70f1919054113f94e895db60ce3618f2db814183..29a455b56445d6941811303ad39d159c66a8640a 100644 (file)
@@ -677,6 +677,9 @@ Global Settings
 'external_rules_command'::
        External command used to retrieve rule consequences. The command will receive the following arguments: window ID, class name, instance name, and intermediate consequences. The output of that command must have the following format: *key1=value1 key2=value2 ...* (the valid key/value pairs are given in the description of the 'rule' command).
 
+'automatic_scheme'::
+       The insertion scheme used when the insertion point is in automatic mode. Accept the following values: *longest_side*, *spiral*.
+
 'initial_polarity'::
        On which child should a new window be attached when adding a window on a single window tree in automatic mode. Accept the following values: *first_child*, *second_child*.
 
diff --git a/examples/external_rules/pseudo_automatic_mode/README.md b/examples/external_rules/pseudo_automatic_mode/README.md
deleted file mode 100644 (file)
index 26284fc..0000000
+++ /dev/null
@@ -1 +0,0 @@
-`wattr` belongs to [wmutils](https://github.com/wmutils/core).
diff --git a/examples/external_rules/pseudo_automatic_mode/external_rules b/examples/external_rules/pseudo_automatic_mode/external_rules
deleted file mode 100755 (executable)
index b8fe0e6..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#! /bin/sh
-
-fwid=$(bspc query -N -n focused.automatic)
-
-if [ -n "$fwid" ] ; then
-       wattr wh $fwid | {
-               read width height
-               if [ $width -gt $height ] ; then
-                       echo "split_dir=west"
-               else
-                       echo "split_dir=south"
-               fi
-               echo "split_ratio=0.5"
-       }
-fi
index 771bbdce98f96eae7e350834a30467fecd564343..8b933bef2dd8889fed5778661b0e73adbfcadca4 100644 (file)
@@ -47,6 +47,7 @@
 #define LAYOUT_STR(A)     ((A) == LAYOUT_TILED ? "tiled" : "monocle")
 #define LAYOUT_CHR(A)     ((A) == LAYOUT_TILED ? 'T' : 'M')
 #define CHILD_POL_STR(A)  ((A) == FIRST_CHILD ? "first_child" : "second_child")
+#define AUTO_SCM_STR(A)   ((A) == SCHEME_LONGEST_SIDE ? "longest_side" : "spiral")
 #define TIGHTNESS_STR(A)  ((A) == TIGHTNESS_HIGH ? "high" : "low")
 #define SPLIT_TYPE_STR(A) ((A) == TYPE_HORIZONTAL ? "horizontal" : "vertical")
 #define SPLIT_MODE_STR(A) ((A) == MODE_AUTOMATIC ? "automatic" : "manual")
index 0ed08660a0849948bd4ec9e9de2cc24e13578316..e12b382285047d98ec56198ee3a5b4e013385da9 100644 (file)
@@ -1555,6 +1555,14 @@ void set_setting(coordinates_t loc, char *name, char *value, FILE *rsp)
                        fail(rsp, "config: %s: Invalid value: '%s'.\n", name, value);
                        return;
                }
+       } else if (streq("automatic_scheme", name)) {
+               automatic_scheme_t a;
+               if (parse_automatic_scheme(value, &a)) {
+                       automatic_scheme = a;
+               } else {
+                       fail(rsp, "config: %s: Invalid value: '%s'.\n", name, value);
+                       return;
+               }
        } else if (streq("mapping_events_count", name)) {
                if (sscanf(value, "%" SCNi8, &mapping_events_count) != 1) {
                        fail(rsp, "config: %s: Invalid value: '%s'.\n", name, value);
@@ -1731,6 +1739,8 @@ void get_setting(coordinates_t loc, char *name, FILE* rsp)
                fprintf(rsp, "%s", status_prefix);
        } else if (streq("initial_polarity", name)) {
                fprintf(rsp, "%s", CHILD_POL_STR(initial_polarity));
+       } else if (streq("automatic_scheme", name)) {
+               fprintf(rsp, "%s", AUTO_SCM_STR(automatic_scheme));
        } else if (streq("mapping_events_count", name)) {
                fprintf(rsp, "%" PRIi8, mapping_events_count);
        } else if (streq("directional_focus_tightness", name)) {
index f7dc1d8e8cfc68024482f32b071ba41ef0f6f9e5..886f944fca7572d574e9b119c1dba0ca5709fa01 100644 (file)
@@ -267,6 +267,18 @@ bool parse_child_polarity(char *s, child_polarity_t *p)
        return false;
 }
 
+bool parse_automatic_scheme(char *s, automatic_scheme_t *a)
+{
+       if (streq("longest_side", s)) {
+               *a = SCHEME_LONGEST_SIDE;
+               return true;
+       } else if (streq("spiral", s)) {
+               *a = SCHEME_SPIRAL;
+               return true;
+       }
+       return false;
+}
+
 bool parse_state_transition(char *s, state_transition_t *m)
 {
        if (streq("none", s)) {
index 370c08f8baf9b3b8397b6fb692b67fd3728cecbe..89ba6e1c5699f092629dd2c842f63dcf03c8266c 100644 (file)
@@ -25,6 +25,7 @@ bool parse_modifier_mask(char *s, uint16_t *m);
 bool parse_button_index(char *s, int8_t *b);
 bool parse_pointer_action(char *s, pointer_action_t *a);
 bool parse_child_polarity(char *s, child_polarity_t *p);
+bool parse_automatic_scheme(char *s, automatic_scheme_t *a);
 bool parse_state_transition(char *s, state_transition_t *m);
 bool parse_tightness(char *s, tightness_t *t);
 bool parse_degree(char *s, int *d);
index f8390b8a2fdec1aad87db896dcf2c76a4b82ea6f..923d9ac703a946983795a1175b2d22dcaa77ccaf 100644 (file)
@@ -56,15 +56,16 @@ void load_settings(void)
        window_gap = WINDOW_GAP;
        border_width = BORDER_WIDTH;
        split_ratio = SPLIT_RATIO;
-       initial_polarity = FIRST_CHILD;
+       initial_polarity = SECOND_CHILD;
+       automatic_scheme = SCHEME_LONGEST_SIDE;
        directional_focus_tightness = TIGHTNESS_HIGH;
+
        pointer_modifier = POINTER_MODIFIER;
        pointer_motion_interval = POINTER_MOTION_INTERVAL;
-       mapping_events_count = MAPPING_EVENTS_COUNT;
-
        pointer_actions[0] = ACTION_MOVE;
        pointer_actions[1] = ACTION_RESIZE_SIDE;
        pointer_actions[2] = ACTION_RESIZE_CORNER;
+       mapping_events_count = MAPPING_EVENTS_COUNT;
 
        borderless_monocle = BORDERLESS_MONOCLE;
        gapless_monocle = GAPLESS_MONOCLE;
index 4c1564405c3156d02ab39d62e0ed99282a8bc30b..c4dcd27dc71da01a5e8ce6dad2d8f8a0a72dec15 100644 (file)
@@ -41,6 +41,7 @@
 #define WINDOW_GAP           6
 #define BORDER_WIDTH         1
 #define SPLIT_RATIO          0.5
+#define AUTOMATIC_SCHEME     SCHEME_LONGEST_SIDE
 
 #define BORDERLESS_MONOCLE          false
 #define GAPLESS_MONOCLE             false
@@ -75,9 +76,10 @@ padding_t padding;
 int window_gap;
 unsigned int border_width;
 double split_ratio;
-
 child_polarity_t initial_polarity;
+automatic_scheme_t automatic_scheme;
 tightness_t directional_focus_tightness;
+
 uint16_t pointer_modifier;
 uint32_t pointer_motion_interval;
 pointer_action_t pointer_actions[3];
index 2e262dd71fb74a1c612169b7c87f9f055d8b2b32..9518c2eab37406ac68a41cd409a0a568c8af879a 100644 (file)
@@ -331,7 +331,7 @@ node_t *insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f)
                }
                n->parent = c;
                if (f->presel == NULL) {
-                       if (p == NULL || (f->client != NULL && IS_TILED(f->client) && tiled_count(d->root, true) == 1)) {
+                       if (p == NULL || automatic_scheme == SCHEME_LONGEST_SIDE || (f->client != NULL && IS_TILED(f->client) && tiled_count(d->root, true) == 1)) {
                                if (p != NULL) {
                                        if (is_first_child(f)) {
                                                p->first_child = c;
@@ -350,7 +350,7 @@ node_t *insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f)
                                        c->first_child = f;
                                        c->second_child = n;
                                }
-                               if (m->rectangle.width > m->rectangle.height) {
+                               if (f->rectangle.width > f->rectangle.height) {
                                        c->split_type = TYPE_VERTICAL;
                                } else {
                                        c->split_type = TYPE_HORIZONTAL;
index 2b43a35d105cca3109c84dbe6977b5d0cc445722..1aebc7754cd2cbc631b43a986ac39c29307dde76 100644 (file)
@@ -44,6 +44,11 @@ typedef enum {
        MODE_MANUAL
 } split_mode_t;
 
+typedef enum {
+       SCHEME_LONGEST_SIDE,
+       SCHEME_SPIRAL
+} automatic_scheme_t;
+
 typedef enum {
        STATE_TILED,
        STATE_PSEUDO_TILED,
index 90cca7ca5661e745409d7378dd03ba8d7f087dac..1b3babc379f22fa7cf3a419222b39e952ac7a854 100755 (executable)
--- a/tests/run
+++ b/tests/run
@@ -2,10 +2,13 @@
 
 focus_follows_pointer=$(bspc config focus_follows_pointer)
 initial_polarity=$(bspc config initial_polarity)
+automatic_scheme=$(bspc config automatic_scheme)
+bspc config automatic_scheme spiral
 bspc config initial_polarity first_child
 bspc config focus_follows_pointer false
 
 cleanup () {
+       bspc config automatic_scheme "$automatic_scheme"
        bspc config initial_polarity "$initial_polarity"
        bspc config focus_follows_pointer "$focus_follows_pointer"
 }