_bspc() {
local commands='node desktop monitor query rule restore 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 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 ignore_ewmh_focus 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 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 ignore_ewmh_focus center_pseudo_tiled honor_size_hints remove_disabled_monitors remove_unplugged_monitors merge_overlapping_monitors'
COMPREPLY=()
end
complete -f -c bspc -n '__fish_bspc_needs_command' -a 'node desktop monitor query rule restore 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 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 ignore_ewmh_focus 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 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 ignore_ewmh_focus center_pseudo_tiled honor_size_hints remove_disabled_monitors remove_unplugged_monitors merge_overlapping_monitors'
_bspc() {
local -a commands settings
commands=('node' 'desktop' 'monitor' 'query' 'rule' 'restore' 'wm' 'subscribe' 'config' 'quit')
- 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' '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' 'ignore_ewmh_focus' 'center_pseudo_tiled' 'honor_size_hints' 'remove_disabled_monitors' 'remove_unplugged_monitors' 'merge_overlapping_monitors')
+ 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' 'ignore_ewmh_focus' 'center_pseudo_tiled' 'honor_size_hints' 'remove_disabled_monitors' 'remove_unplugged_monitors' 'merge_overlapping_monitors')
if (( CURRENT == 2 )) ; then
_values 'command' "$commands[@]"
elif (( CURRENT == 3 )) ; then
.\" Title: bspwm
.\" Author: [see the "Author" section]
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 06/04/2017
.\" Manual: Bspwm Manual
-.\" Source: Bspwm 0.9.2-25-g048230e
+.\" Source: Bspwm 0.9.2-48-gfab441b
.\" Language: English
.\"
-.TH "BSPWM" "1" "01/30/2017" "Bspwm 0\&.9\&.2\-25\-g048230e" "Bspwm Manual"
+.TH "BSPWM" "1" "06/04/2017" "Bspwm 0\&.9\&.2\-48\-gfab441b" "Bspwm Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
\fBsecond_child\fR\&.
.RE
.PP
+\fIdirectional_focus_tightness\fR
+.RS 4
+The tightness of the algorithm used to decide whether a window is on the
+\fIDIR\fR
+side of another window\&. Accept the following values:
+\fBhigh\fR,
+\fBlow\fR\&.
+.RE
+.PP
\fIborderless_monocle\fR
.RS 4
Remove borders of tiled windows for the
'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*.
+'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*.
+
'borderless_monocle'::
Remove borders of tiled windows for the *monocle* desktop layout.
#include <math.h>
#include "types.h"
+#include "settings.h"
#include "geometry.h"
bool is_inside(xcb_point_t p, xcb_rectangle_t r)
/* Is `r2` on the `dir` side of `r1`? */
bool on_dir_side(xcb_rectangle_t r1, xcb_rectangle_t r2, direction_t dir)
{
- if (rect_eq(r1, r2)) {
- return false;
- }
-
xcb_point_t r1_max = {r1.x + r1.width - 1, r1.y + r1.height - 1};
xcb_point_t r2_max = {r2.x + r2.width - 1, r2.y + r2.height - 1};
/* Eliminate rectangles on the opposite side */
- switch (dir) {
- case DIR_NORTH:
- if (r2.y > r1_max.y) {
- return false;
+ switch (directional_focus_tightness) {
+ case TIGHTNESS_LOW:
+ switch (dir) {
+ case DIR_NORTH:
+ if (r2.y > r1_max.y) {
+ return false;
+ }
+ break;
+ case DIR_WEST:
+ if (r2.x > r1_max.x) {
+ return false;
+ }
+ break;
+ case DIR_SOUTH:
+ if (r2_max.y < r1.y) {
+ return false;
+ }
+ break;
+ case DIR_EAST:
+ if (r2_max.x < r1.x) {
+ return false;
+ }
+ break;
+ default:
+ return false;
}
break;
- case DIR_WEST:
- if (r2.x > r1_max.x) {
- return false;
- }
- break;
- case DIR_SOUTH:
- if (r2_max.y < r1.y) {
- return false;
- }
- break;
- case DIR_EAST:
- if (r2_max.x < r1.x) {
- return false;
+ case TIGHTNESS_HIGH:
+ switch (dir) {
+ case DIR_NORTH:
+ if (r2.y >= r1.y) {
+ return false;
+ }
+ break;
+ case DIR_WEST:
+ if (r2.x >= r1.x) {
+ return false;
+ }
+ break;
+ case DIR_SOUTH:
+ if (r2_max.y <= r1_max.y) {
+ return false;
+ }
+ break;
+ case DIR_EAST:
+ if (r2_max.x <= r1_max.x) {
+ return false;
+ }
+ break;
+ default:
+ return false;
}
break;
default:
#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 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")
#define SPLIT_DIR_STR(A) ((A) == DIR_NORTH ? "north" : ((A) == DIR_WEST ? "west" : ((A) == DIR_SOUTH ? "south" : "east")))
fail(rsp, "config: %s: Invalid value: '%s'.\n", name, value);
return;
}
+ } else if (streq("directional_focus_tightness", name)) {
+ tightness_t p;
+ if (parse_tightness(value, &p)) {
+ directional_focus_tightness = p;
+ } else {
+ fail(rsp, "config: %s: Invalid value: '%s'.\n", name, value);
+ return;
+ }
} else if (streq("pointer_modifier", name)) {
if (parse_modifier_mask(value, &pointer_modifier)) {
ungrab_buttons();
fprintf(rsp, "%s", status_prefix);
} else if (streq("initial_polarity", name)) {
fprintf(rsp, "%s", CHILD_POL_STR(initial_polarity));
+ } else if (streq("directional_focus_tightness", name)) {
+ fprintf(rsp, "%s", TIGHTNESS_STR(directional_focus_tightness));
} else if (streq("pointer_modifier", name)) {
print_modifier_mask(pointer_modifier, rsp);
} else if (streq("pointer_motion_interval", name)) {
return false;
}
+bool parse_tightness(char *s, tightness_t *t)
+{
+ if (streq("high", s)) {
+ *t = TIGHTNESS_HIGH;
+ return true;
+ } else if (streq("low", s)) {
+ *t = TIGHTNESS_LOW;
+ return true;
+ }
+ return false;
+}
+
bool parse_degree(char *s, int *d)
{
int i = atoi(s);
bool parse_modifier_mask(char *s, uint16_t *m);
bool parse_pointer_action(char *s, pointer_action_t *a);
bool parse_child_polarity(char *s, child_polarity_t *p);
+bool parse_tightness(char *s, tightness_t *t);
bool parse_degree(char *s, int *d);
bool parse_id(char *s, uint32_t *id);
bool parse_bool_declaration(char *s, char **key, bool *value, alter_state_t *state);
border_width = BORDER_WIDTH;
split_ratio = SPLIT_RATIO;
initial_polarity = FIRST_CHILD;
+ directional_focus_tightness = TIGHTNESS_HIGH;
pointer_modifier = POINTER_MODIFIER;
pointer_motion_interval = POINTER_MOTION_INTERVAL;
double split_ratio;
child_polarity_t initial_polarity;
+tightness_t directional_focus_tightness;
uint16_t pointer_modifier;
uint32_t pointer_motion_interval;
pointer_action_t pointer_actions[3];
SECOND_CHILD
} child_polarity_t;
+typedef enum {
+ TIGHTNESS_LOW,
+ TIGHTNESS_HIGH,
+} tightness_t;
+
typedef struct {
option_bool_t automatic;
option_bool_t focused;