]> git.lizzy.rs Git - bspwm.git/commitdiff
Add automatic insertion scheme: alternate
authorBastien Dejean <nihilhill@gmail.com>
Wed, 12 Dec 2018 21:35:38 +0000 (22:35 +0100)
committerBastien Dejean <nihilhill@gmail.com>
Wed, 12 Dec 2018 21:35:38 +0000 (22:35 +0100)
Fixes #876.
Fixes #878.

14 files changed:
README.md
contrib/zsh_completion
doc/bspwm.1
doc/bspwm.1.asciidoc
src/bspwm.c
src/bspwm.h
src/helpers.h
src/messages.c
src/parse.c
src/parse.h
src/settings.h
src/tree.c
src/types.h
src/window.c

index 490e773327525da85995f06f64c4a041e8d1cdba..035e88761615525d50fe35cb41cd29f5dbf76315 100644 (file)
--- a/README.md
+++ b/README.md
@@ -100,7 +100,7 @@ The *automatic* mode, as opposed to the *manual* mode, doesn't require any user
 
 #### Longest side scheme
 
-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.
+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 chosen 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`:
 
@@ -131,6 +131,10 @@ Since *1* is wide, it gets split vertically and *2* is added as *a*'s second chi
 
 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.
 
+#### Alternate scheme
+
+When the value of the automatic scheme is `alternate`, the window will be attached as if the insertion point was in manual mode and the split direction was chosen based on the split type of the insertion point's parent and the initial polarity. If the parent is split horizontally, the insertion point will be split vertically and vice versa.
+
 #### Spiral scheme
 
 When the value of the automatic scheme is `spiral`, the window will *take the space* of the insertion point.
index e696288acfe4b38a3e0a7a887bf450d9ecdaf0c4..4e9948ded2d86ae7c5c78d0c8685118693f98d87 100644 (file)
@@ -317,8 +317,8 @@ _bspc() {
                        local -a {look,behaviour,input}{_bool,}
                        look_bool=(borderless_monocle gapless_monocle)
                        look=({normal,active,focused}_border_color {top,right,bottom,left}_padding {top,right,bottom,left}_monocle_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 automatic_scheme removal_adjustment initial_polarity directional_focus_tightness status_prefix)
+                       behaviour_bool=(single_monocle removal_adjustment 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 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 0600972e9fe0de9861864da5e0933f9937dfa2a9..3503b87913d36e25488ad64978fd1558936161de 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: 11/14/2018
+.\"      Date: 12/12/2018
 .\"    Manual: Bspwm Manual
-.\"    Source: Bspwm 0.9.5-20-gdb27b84
+.\"    Source: Bspwm 0.9.5-24-g0f5a69b
 .\"  Language: English
 .\"
-.TH "BSPWM" "1" "11/14/2018" "Bspwm 0\&.9\&.5\-20\-gdb27b84" "Bspwm Manual"
+.TH "BSPWM" "1" "12/12/2018" "Bspwm 0\&.9\&.5\-24\-g0f5a69b" "Bspwm Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -1155,16 +1155,10 @@ command)\&.
 .RS 4
 The insertion scheme used when the insertion point is in automatic mode\&. Accept the following values:
 \fBlongest_side\fR,
+\fBalternate\fR,
 \fBspiral\fR\&.
 .RE
 .PP
-\fIremoval_adjustment\fR
-.RS 4
-The adjustment applied on the split types of a tree, after removing one of its nodes\&. Accept the following values:
-\fBlongest_side\fR,
-\fBnone\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:
@@ -1181,6 +1175,11 @@ side of another window\&. Accept the following values:
 \fBlow\fR\&.
 .RE
 .PP
+\fIremoval_adjustment\fR
+.RS 4
+Adjust the brother when unlinking a node from the tree in accordance with the automatic insertion scheme\&.
+.RE
+.PP
 \fIborderless_monocle\fR
 .RS 4
 Remove borders of tiled windows for the
index b5c75d6c4c104da3d27697aaa90a2b79c7ba8038..3febdc489ccd57d0ed71d910871d2d48162d01dd 100644 (file)
@@ -678,10 +678,7 @@ Global Settings
        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*.
-
-'removal_adjustment'::
-       The adjustment applied on the split types of a tree, after removing one of its nodes. Accept the following values: *longest_side*, *none*.
+       The insertion scheme used when the insertion point is in automatic mode. Accept the following values: *longest_side*, *alternate*, *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*.
@@ -689,6 +686,9 @@ Global Settings
 'directional_focus_tightness'::
        The tightness of the algorithm used to decide whether a window is on the 'DIR' side of another window. Accept the following values: *high*, *low*.
 
+'removal_adjustment'::
+       Adjust the brother when unlinking a node from the tree in accordance with the automatic insertion scheme.
+
 'borderless_monocle'::
        Remove borders of tiled windows for the *monocle* desktop layout.
 
index 33acc81ac9aa483c756fd720de4bc808c6815e9c..91fc0971da614dd7ea93d1ea9bcf42677d92a11c 100644 (file)
@@ -216,7 +216,6 @@ void init(void)
        subscribe_head = subscribe_tail = NULL;
        pending_rule_head = pending_rule_tail = NULL;
        auto_raise = sticky_still = hide_sticky = record_history = true;
-       auto_split_type = false;
        randr_base = 0;
        exit_status = 0;
 }
index 746e851bf50af77c98d2955bc7d9b616da3d9337..834c15596ea1a48688379feacc3a033d4a309409 100644 (file)
@@ -77,7 +77,6 @@ xcb_atom_t WM_DELETE_WINDOW;
 int exit_status;
 
 bool auto_raise;
-bool auto_split_type;
 bool sticky_still;
 bool hide_sticky;
 bool record_history;
index 4478797184632932257078532bc844f0c3ff1fe5..af82ecbaa879334cdf0a8b89645d5dac1f4521d2 100644 (file)
@@ -47,8 +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 REM_ADJ_STR(A)    ((A) == ADJUSTMENT_LONGEST_SIDE ? "longest_side" : "none")
+#define AUTO_SCM_STR(A)   ((A) == SCHEME_LONGEST_SIDE ? "longest_side" : ((A) == SCHEME_ALTERNATE ? "alternate" : "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 7c3d4e39182fd6382ae4561a6a36598dbf669798..5d798013168346554166f25ca12aff7efe46c154 100644 (file)
@@ -1579,14 +1579,6 @@ 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("removal_adjustment", name)) {
-               removal_adjustment_t r;
-               if (parse_removal_adjustment(value, &r)) {
-                       removal_adjustment = r;
-               } 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);
@@ -1683,6 +1675,7 @@ void set_setting(coordinates_t loc, char *name, char *value, FILE *rsp)
                SET_BOOL(ignore_ewmh_focus)
                SET_BOOL(center_pseudo_tiled)
                SET_BOOL(honor_size_hints)
+               SET_BOOL(removal_adjustment)
 #undef SET_BOOL
 #define SET_MON_BOOL(s) \
        } else if (streq(#s, name)) { \
@@ -1772,8 +1765,6 @@ void get_setting(coordinates_t loc, char *name, FILE* rsp)
                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("removal_adjustment", name)) {
-               fprintf(rsp, "%s", REM_ADJ_STR(removal_adjustment));
        } else if (streq("mapping_events_count", name)) {
                fprintf(rsp, "%" PRIi8, mapping_events_count);
        } else if (streq("directional_focus_tightness", name)) {
@@ -1812,6 +1803,7 @@ void get_setting(coordinates_t loc, char *name, FILE* rsp)
        GET_BOOL(ignore_ewmh_focus)
        GET_BOOL(center_pseudo_tiled)
        GET_BOOL(honor_size_hints)
+       GET_BOOL(removal_adjustment)
        GET_BOOL(remove_disabled_monitors)
        GET_BOOL(remove_unplugged_monitors)
        GET_BOOL(merge_overlapping_monitors)
index c75f9221f6b6137566e41ea7f5d9bbdd5363b32c..c389c2f4513e058c7447091368f277be051e6b70 100644 (file)
@@ -272,6 +272,9 @@ bool parse_automatic_scheme(char *s, automatic_scheme_t *a)
        if (streq("longest_side", s)) {
                *a = SCHEME_LONGEST_SIDE;
                return true;
+       } else if (streq("alternate", s)) {
+               *a = SCHEME_ALTERNATE;
+               return true;
        } else if (streq("spiral", s)) {
                *a = SCHEME_SPIRAL;
                return true;
@@ -279,18 +282,6 @@ bool parse_automatic_scheme(char *s, automatic_scheme_t *a)
        return false;
 }
 
-bool parse_removal_adjustment(char *s, removal_adjustment_t *r)
-{
-       if (streq("longest_side", s)) {
-               *r = ADJUSTMENT_LONGEST_SIDE;
-               return true;
-       } else if (streq("none", s)) {
-               *r = ADJUSTMENT_NONE;
-               return true;
-       }
-       return false;
-}
-
 bool parse_state_transition(char *s, state_transition_t *m)
 {
        if (streq("none", s)) {
index b33c5f959832229cd1f025e2698098947deb6187..89ba6e1c5699f092629dd2c842f63dcf03c8266c 100644 (file)
@@ -26,7 +26,6 @@ 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_removal_adjustment(char *s, removal_adjustment_t *r);
 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 b19518ec901f0412253ea40f1216a12d5186c12d..b7e9bf7564f6f8e7c6274eb7b0457f009a3c862f 100644 (file)
@@ -43,7 +43,7 @@
 #define BORDER_WIDTH         1
 #define SPLIT_RATIO          0.5
 #define AUTOMATIC_SCHEME     SCHEME_LONGEST_SIDE
-#define REMOVAL_ADJUSTMENT   ADJUSTMENT_LONGEST_SIDE
+#define REMOVAL_ADJUSTMENT   true
 
 #define BORDERLESS_MONOCLE          false
 #define GAPLESS_MONOCLE             false
@@ -80,7 +80,7 @@ unsigned int border_width;
 double split_ratio;
 child_polarity_t initial_polarity;
 automatic_scheme_t automatic_scheme;
-removal_adjustment_t removal_adjustment;
+bool removal_adjustment;
 tightness_t directional_focus_tightness;
 
 uint16_t pointer_modifier;
index aeeb1d81292f3b5bfd74abd8f6e92a6aa42a046b..bf5d3965f8e6ebe49f447d2dd496e769c10d79dc 100644 (file)
@@ -153,9 +153,6 @@ void apply_layout(monitor_t *m, desktop_t *d, node_t *n, layout_t l, xcb_rectang
                        first_rect = second_rect = rect;
                } else {
                        unsigned int fence;
-                       if (auto_split_type) {
-                               n->split_type = n->rectangle.width > n->rectangle.height ? TYPE_VERTICAL : TYPE_HORIZONTAL;
-                       }
                        if (n->split_type == TYPE_VERTICAL) {
                                fence = rect.width * n->split_ratio;
                                if ((n->first_child->constraints.min_width + n->second_child->constraints.min_width) <= rect.width) {
@@ -332,7 +329,8 @@ 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 || automatic_scheme == SCHEME_LONGEST_SIDE || (f->client != NULL && IS_TILED(f->client) && tiled_count(d->root, true) == 1)) {
+                       bool single_tiled = f->client != NULL && IS_TILED(f->client) && tiled_count(d->root, true) == 1;
+                       if (p == NULL || automatic_scheme != SCHEME_SPIRAL || single_tiled) {
                                if (p != NULL) {
                                        if (is_first_child(f)) {
                                                p->first_child = c;
@@ -351,10 +349,18 @@ 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 (f->rectangle.width > f->rectangle.height) {
-                                       c->split_type = TYPE_VERTICAL;
+                               if (p == NULL || automatic_scheme == SCHEME_LONGEST_SIDE || single_tiled) {
+                                       if (f->rectangle.width > f->rectangle.height) {
+                                               c->split_type = TYPE_VERTICAL;
+                                       } else {
+                                               c->split_type = TYPE_HORIZONTAL;
+                                       }
                                } else {
-                                       c->split_type = TYPE_HORIZONTAL;
+                                       if (p->split_type == TYPE_HORIZONTAL) {
+                                               c->split_type = TYPE_VERTICAL;
+                                       } else {
+                                               c->split_type = TYPE_HORIZONTAL;
+                                       }
                                }
                        } else {
                                node_t *g = p->parent;
@@ -1204,6 +1210,24 @@ void unlink_node(monitor_t *m, desktop_t *d, node_t *n)
                        d->root = b;
                }
 
+               if (!n->vacant && removal_adjustment) {
+                       if (automatic_scheme == SCHEME_LONGEST_SIDE || g == NULL) {
+                               if (p != NULL) {
+                                       if (p->rectangle.width > p->rectangle.height) {
+                                               b->split_type = TYPE_VERTICAL;
+                                       } else {
+                                               b->split_type = TYPE_HORIZONTAL;
+                                       }
+                               }
+                       } else if (automatic_scheme == SCHEME_ALTERNATE) {
+                               if (g->split_type == TYPE_HORIZONTAL) {
+                                       b->split_type = TYPE_VERTICAL;
+                               } else {
+                                       b->split_type = TYPE_HORIZONTAL;
+                               }
+                       }
+               }
+
                free(p);
                n->parent = NULL;
 
index b7445c41d12101da3095dde51f5a35e49f6ca919..26c0b755057982b5a0d472a588085fd68172f477 100644 (file)
@@ -46,14 +46,10 @@ typedef enum {
 
 typedef enum {
        SCHEME_LONGEST_SIDE,
+       SCHEME_ALTERNATE,
        SCHEME_SPIRAL
 } automatic_scheme_t;
 
-typedef enum {
-       ADJUSTMENT_LONGEST_SIDE,
-       ADJUSTMENT_NONE
-} removal_adjustment_t;
-
 typedef enum {
        STATE_TILED,
        STATE_PSEUDO_TILED,
index c867ee581ffe464cf14c3db35ab898e055e8a614..2641d02079ccc141cc921b2cd568852c3804afcf 100644 (file)
@@ -231,12 +231,8 @@ void unmanage_window(xcb_window_t win)
        coordinates_t loc;
        if (locate_window(win, &loc)) {
                put_status(SBSC_MASK_NODE_REMOVE, "node_remove 0x%08X 0x%08X 0x%08X\n", loc.monitor->id, loc.desktop->id, win);
-               if (removal_adjustment == ADJUSTMENT_LONGEST_SIDE) {
-                       auto_split_type = true;
-               }
                remove_node(loc.monitor, loc.desktop, loc.node);
                arrange(loc.monitor, loc.desktop);
-               auto_split_type = false;
        } else {
                for (pending_rule_t *pr = pending_rule_head; pr != NULL; pr = pr->next) {
                        if (pr->win == win) {