Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for 8 and 9 mouse buttons #843

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ VERCMD ?= git describe --tags 2> /dev/null
VERSION := $(shell $(VERCMD) || cat VERSION)

CPPFLAGS += -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\"
CFLAGS += -std=c99 -pedantic -Wall -Wextra -DJSMN_STRICT
CFLAGS += -std=c99 -pedantic -Wall -Wextra -DJSMN_STRICT -fcommon
LDFLAGS ?=
LDLIBS = $(LDFLAGS) -lm -lxcb -lxcb-util -lxcb-keysyms -lxcb-icccm -lxcb-ewmh -lxcb-randr -lxcb-xinerama -lxcb-shape

Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

#### Hvsplit scheme

This is a generalized longest side scheme. It takes into account parameter hvsplit_ratio which indicates maximum ratio of width to hight after which the split is vertical. With hvsplit_ratio it behaves like longest side scheme.

#### 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.
Expand Down
2 changes: 1 addition & 1 deletion contrib/bash_completion
Original file line number Diff line number Diff line change
@@ -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 top_monocle_padding right_monocle_padding bottom_monocle_padding left_monocle_padding split_ratio automatic_scheme removal_adjustment initial_polarity directional_focus_tightness presel_feedback 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 ignore_ewmh_struts 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 top_monocle_padding right_monocle_padding bottom_monocle_padding left_monocle_padding split_ratio hvsplit_ratio automatic_scheme removal_adjustment initial_polarity directional_focus_tightness presel_feedback borderless_monocle gapless_monocle single_monocle pointer_motion_interval pointer_modifier pointer_action1 pointer_action2 pointer_action3 pointer_action8 pointer_action9 click_to_focus swallow_first_click focus_follows_pointer pointer_follows_focus pointer_follows_monitor mapping_events_count ignore_ewmh_focus ignore_ewmh_fullscreen ignore_ewmh_struts center_pseudo_tiled honor_size_hints remove_disabled_monitors remove_unplugged_monitors merge_overlapping_monitors'

COMPREPLY=()

Expand Down
2 changes: 1 addition & 1 deletion contrib/fish_completion
Original file line number Diff line number Diff line change
Expand Up @@ -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 top_monocle_padding right_monocle_padding bottom_monocle_padding left_monocle_padding split_ratio automatic_scheme removal_adjustment initial_polarity directional_focus_tightness presel_feedback 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 ignore_ewmh_struts 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 top_monocle_padding right_monocle_padding bottom_monocle_padding left_monocle_padding split_ratio hvsplit_ratio automatic_scheme removal_adjustment initial_polarity directional_focus_tightness presel_feedback borderless_monocle gapless_monocle single_monocle pointer_motion_interval pointer_modifier pointer_action1 pointer_action2 pointer_action3 pointer_action8 pointer_action9 click_to_focus swallow_first_click focus_follows_pointer pointer_follows_focus pointer_follows_monitor mapping_events_count ignore_ewmh_focus ignore_ewmh_fullscreen ignore_ewmh_struts center_pseudo_tiled honor_size_hints remove_disabled_monitors remove_unplugged_monitors merge_overlapping_monitors'
4 changes: 2 additions & 2 deletions contrib/zsh_completion
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ _bspc() {
behaviour_bool=(single_monocle removal_adjustment ignore_ewmh_focus ignore_ewmh_struts 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})
input=(click_to_focus pointer_motion_interval pointer_modifier pointer_action{1,2,3,8,9})
if [[ "$CURRENT" == (2|3) ]];then
_arguments \
'-d[Set settings for the selected desktop]: :_bspc_selector -- desktop'\
Expand All @@ -347,7 +347,7 @@ _bspc() {
(initial_polarity)
_values "set $setting" first_child second_child
;;
(pointer_action(1|2|3))
(pointer_action(1|2|3|8|9))
_values "set $setting" move resize_side resize_corner focus none
;;
(pointer_modifier)
Expand Down
2 changes: 1 addition & 1 deletion doc/bspwm.1
Original file line number Diff line number Diff line change
Expand Up @@ -1243,7 +1243,7 @@ Keyboard modifier used for moving or resizing windows\&. Accept the following va
\fBmod5\fR\&.
.RE
.PP
\fIpointer_action1\fR, \fIpointer_action2\fR, \fIpointer_action3\fR
\fIpointer_action1\fR, \fIpointer_action2\fR, \fIpointer_action3\fR, \fIpointer_action8\fR, \fIpointer_action9\fR
.RS 4
Action performed when pressing
\fIpointer_modifier\fR
Expand Down
2 changes: 2 additions & 0 deletions doc/bspwm.1.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,8 @@ Global Settings
'pointer_action1'::
'pointer_action2'::
'pointer_action3'::
'pointer_action8'::
'pointer_action9'::
Action performed when pressing 'pointer_modifier' + 'button<n>'. Accept the following values: *move*, *resize_side*, *resize_corner*, *focus*, *none*.

'click_to_focus'::
Expand Down
2 changes: 1 addition & 1 deletion src/events.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#define ERROR_CODE_BAD_WINDOW 3

uint8_t randr_base;
static const xcb_button_index_t BUTTONS[] = {XCB_BUTTON_INDEX_1, XCB_BUTTON_INDEX_2, XCB_BUTTON_INDEX_3};
static const xcb_button_index_t BUTTONS[] = {XCB_BUTTON_INDEX_1, XCB_BUTTON_INDEX_2, XCB_BUTTON_INDEX_3, 8, 9 };

void handle_event(xcb_generic_event_t *evt);
void map_request(xcb_generic_event_t *evt);
Expand Down
2 changes: 1 addition & 1 deletion src/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,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" : ((A) == SCHEME_ALTERNATE ? "alternate" : "spiral"))
#define AUTO_SCM_STR(A) ((A) == SCHEME_LONGEST_SIDE ? "longest_side" : ((A) == SCHEME_HVSPLIT ? "hvsplit" : ((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")
Expand Down
35 changes: 32 additions & 3 deletions src/messages.c
Original file line number Diff line number Diff line change
Expand Up @@ -1554,6 +1554,15 @@ void set_setting(coordinates_t loc, char *name, char *value, FILE *rsp)
return;
}
return;
} else if (streq("hvsplit_ratio", name)) {
double r;
if (sscanf(value, "%lf", &r) == 1 && r > 0) {
hvsplit_ratio = r;
} else {
fail(rsp, "config: %s: Invalid value: '%s'.\n", name, value); \
return;
}
return;
#define SET_COLOR(s) \
} else if (streq(#s, name)) { \
if (!is_hex_color(value)) { \
Expand Down Expand Up @@ -1620,8 +1629,13 @@ void set_setting(coordinates_t loc, char *name, char *value, FILE *rsp)
}
} else if (streq("pointer_action1", name) ||
streq("pointer_action2", name) ||
streq("pointer_action3", name)) {
streq("pointer_action3", name) ||
streq("pointer_action8", name) ||
streq("pointer_action9", name)) {
int index = name[14] - '1';
if (index > 2) {
index -= 4;
}
if (parse_pointer_action(value, &pointer_actions[index])) {
ungrab_buttons();
grab_buttons();
Expand Down Expand Up @@ -1693,14 +1707,22 @@ void set_setting(coordinates_t loc, char *name, char *value, FILE *rsp)
SET_BOOL(borderless_monocle)
SET_BOOL(gapless_monocle)
SET_BOOL(swallow_first_click)
SET_BOOL(pointer_follows_focus)
SET_BOOL(pointer_follows_monitor)
SET_BOOL(ignore_ewmh_focus)
SET_BOOL(ignore_ewmh_struts)
SET_BOOL(center_pseudo_tiled)
SET_BOOL(honor_size_hints)
SET_BOOL(removal_adjustment)
#undef SET_BOOL
} else if (streq("pointer_follows_focus", name)) {
bool pff = pointer_follows_focus;
if (!parse_bool(value, &pointer_follows_focus)) {
fail(rsp, "config: %s: Invalid value: '%s'.\n", name, value);
return;
}
if (pff == pointer_follows_focus) {
return;
}
#define SET_MON_BOOL(s) \
} else if (streq(#s, name)) { \
if (!parse_bool(value, &s)) { \
Expand Down Expand Up @@ -1733,6 +1755,8 @@ void get_setting(coordinates_t loc, char *name, FILE* rsp)
{
if (streq("split_ratio", name)) {
fprintf(rsp, "%lf", split_ratio);
} else if (streq("hvsplit_ratio", name)) {
fprintf(rsp, "%lf", hvsplit_ratio);
} else if (streq("border_width", name)) {
if (loc.node != NULL) {
for (node_t *n = first_extrema(loc.node); n != NULL; n = next_leaf(n, loc.node)) {
Expand Down Expand Up @@ -1803,8 +1827,13 @@ void get_setting(coordinates_t loc, char *name, FILE* rsp)
fprintf(rsp, "%u", pointer_motion_interval);
} else if (streq("pointer_action1", name) ||
streq("pointer_action2", name) ||
streq("pointer_action3", name)) {
streq("pointer_action3", name) ||
streq("pointer_action8", name) ||
streq("pointer_action9", name)) {
int index = name[14] - '1';
if (index > 2) {
index -= 4;
}
print_pointer_action(pointer_actions[index], rsp);
#define GET_COLOR(s) \
} else if (streq(#s, name)) { \
Expand Down
9 changes: 9 additions & 0 deletions src/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,12 @@ bool parse_button_index(char *s, int8_t *b)
} else if (strcmp(s, "button3") == 0) {
*b = XCB_BUTTON_INDEX_3;
return true;
} else if (strcmp(s, "button8") == 0) {
*b = 8;
return true;
} else if (strcmp(s, "button9") == 0) {
*b = 9;
return true;
} else if (strcmp(s, "none") == 0) {
*b = -1;
return true;
Expand Down Expand Up @@ -272,6 +278,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("hvsplit", s)) {
*a = SCHEME_HVSPLIT;
return true;
} else if (streq("alternate", s)) {
*a = SCHEME_ALTERNATE;
return true;
Expand Down
6 changes: 5 additions & 1 deletion src/pointer.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ void window_grab_buttons(xcb_window_t win)
window_grab_button(win, BUTTONS[i], XCB_NONE);
}
if (pointer_actions[i] != ACTION_NONE) {
window_grab_button(win, BUTTONS[i], pointer_modifier);
if (BUTTONS[i] == 8 || BUTTONS[i] == 9) {
window_grab_button(win, BUTTONS[i], 0);
} else {
window_grab_button(win, BUTTONS[i], pointer_modifier);
}
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/query.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,12 @@ void print_button_index(int8_t b, FILE *rsp)
case XCB_BUTTON_INDEX_3:
fprintf(rsp, "button3");
break;
case 8:
fprintf(rsp, "button8");
break;
case 9:
fprintf(rsp, "button9");
break;
case -1:
fprintf(rsp, "none");
break;
Expand Down
3 changes: 3 additions & 0 deletions src/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ void load_settings(void)
window_gap = WINDOW_GAP;
border_width = BORDER_WIDTH;
split_ratio = SPLIT_RATIO;
hvsplit_ratio = HVSPLIT_RATIO;
initial_polarity = SECOND_CHILD;
automatic_scheme = AUTOMATIC_SCHEME;
removal_adjustment = REMOVAL_ADJUSTMENT;
Expand All @@ -67,6 +68,8 @@ void load_settings(void)
pointer_actions[0] = ACTION_MOVE;
pointer_actions[1] = ACTION_RESIZE_SIDE;
pointer_actions[2] = ACTION_RESIZE_CORNER;
pointer_actions[3] = ACTION_NONE;
pointer_actions[4] = ACTION_NONE;
mapping_events_count = MAPPING_EVENTS_COUNT;

presel_feedback = PRESEL_FEEDBACK;
Expand Down
4 changes: 3 additions & 1 deletion src/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#define WINDOW_GAP 6
#define BORDER_WIDTH 1
#define SPLIT_RATIO 0.5
#define HVSPLIT_RATIO 1
#define AUTOMATIC_SCHEME SCHEME_LONGEST_SIDE
#define REMOVAL_ADJUSTMENT true

Expand Down Expand Up @@ -80,14 +81,15 @@ padding_t monocle_padding;
int window_gap;
unsigned int border_width;
double split_ratio;
double hvsplit_ratio;
child_polarity_t initial_polarity;
automatic_scheme_t automatic_scheme;
bool removal_adjustment;
tightness_t directional_focus_tightness;

uint16_t pointer_modifier;
uint32_t pointer_motion_interval;
pointer_action_t pointer_actions[3];
pointer_action_t pointer_actions[5];
int8_t mapping_events_count;

bool presel_feedback;
Expand Down
21 changes: 17 additions & 4 deletions src/tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,14 @@ 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 (p == NULL || automatic_scheme == SCHEME_LONGEST_SIDE || single_tiled) {
if (f->rectangle.width > f->rectangle.height) {
if (p == NULL || automatic_scheme == SCHEME_LONGEST_SIDE || automatic_scheme == SCHEME_HVSPLIT || single_tiled) {
// TODO
double ratio = 1;
if (automatic_scheme == SCHEME_HVSPLIT) {
ratio = hvsplit_ratio;
}

if (f->rectangle.width > f->rectangle.height * ratio) {
c->split_type = TYPE_VERTICAL;
} else {
c->split_type = TYPE_HORIZONTAL;
Expand Down Expand Up @@ -1260,9 +1266,16 @@ void unlink_node(monitor_t *m, desktop_t *d, node_t *n)
} else {
rotate_tree(b, 90);
}
} else if (automatic_scheme == SCHEME_LONGEST_SIDE || g == NULL) {
} else if (automatic_scheme == SCHEME_LONGEST_SIDE ||
automatic_scheme == SCHEME_HVSPLIT ||
g == NULL) {
double ratio = 1;
if (automatic_scheme == SCHEME_HVSPLIT) {
ratio = hvsplit_ratio;
}

if (p != NULL) {
if (p->rectangle.width > p->rectangle.height) {
if (p->rectangle.width > p->rectangle.height * ratio) {
b->split_type = TYPE_VERTICAL;
} else {
b->split_type = TYPE_HORIZONTAL;
Expand Down
3 changes: 3 additions & 0 deletions src/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ typedef enum {

typedef enum {
SCHEME_LONGEST_SIDE,
SCHEME_HVSPLIT,
SCHEME_ALTERNATE,
SCHEME_SPIRAL
} automatic_scheme_t;
Expand Down Expand Up @@ -240,6 +241,7 @@ struct node_t {
uint32_t id;
split_type_t split_type;
double split_ratio;
double hvsplit_ratio;
presel_t *presel;
xcb_rectangle_t rectangle;
constraints_t constraints;
Expand Down Expand Up @@ -353,6 +355,7 @@ typedef struct {
char node_desc[MAXLEN];
char split_dir[SMALEN];
double split_ratio;
double hvsplit_ratio;
stack_layer_t *layer;
client_state_t *state;
bool hidden;
Expand Down