From d8a62155e16d6e59a8fee0584f143adc311ce0dd Mon Sep 17 00:00:00 2001 From: Emanuele Torre Date: Sun, 24 Apr 2022 03:52:10 +0200 Subject: [PATCH 01/15] Refocus the focused window when receiving a FOCUS_IN event for root Closes #1378 Fixes #1160 --- src/bspwm.h | 2 +- src/events.c | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/bspwm.h b/src/bspwm.h index 139d4c30..30f972eb 100644 --- a/src/bspwm.h +++ b/src/bspwm.h @@ -34,7 +34,7 @@ #define STATE_PATH_TPL "/tmp/bspwm%s_%i_%i-state" -#define ROOT_EVENT_MASK (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_BUTTON_PRESS) +#define ROOT_EVENT_MASK (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_FOCUS_CHANGE) #define CLIENT_EVENT_MASK (XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_FOCUS_CHANGE) #define BSPWM_CLASS_NAME "Bspwm" #define META_WINDOW_IC "wm\0" BSPWM_CLASS_NAME diff --git a/src/events.c b/src/events.c index 3b82c96f..3e23c94e 100644 --- a/src/events.c +++ b/src/events.c @@ -350,8 +350,16 @@ void focus_in(xcb_generic_event_t *evt) return; } - if (mon->desk->focus != NULL && e->event == mon->desk->focus->id) { - return; + if (mon->desk->focus != NULL) { + if (e->event == mon->desk->focus->id) { + return; + } + if (e->event == root) { + /* Some clients expect the window manager to refocus the + focused window in this case */ + focus_node(mon, mon->desk, mon->desk->focus); + return; + } } coordinates_t loc; From 05ee5f902e325b29f4d4b60784ff76ba97435422 Mon Sep 17 00:00:00 2001 From: Emanuele Torre Date: Sat, 4 Jun 2022 09:04:31 +0200 Subject: [PATCH 02/15] Always return 1 when execvp() fails bspwm uses execvp() to replace itself with a new instance in response to "wm -r", and exits with the return value of execvp() if it fails. execvp() only returns when it fails; and, when it returns, it always returns -1 which is not a valid exit code (it is treated as 255: &0xff). The return value of execvp() is not really meaningful; let's just exit with `1' if execvp() fails. Closes #1393. --- src/bspwm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bspwm.c b/src/bspwm.c index 8b9b5d14..4619a0c2 100644 --- a/src/bspwm.c +++ b/src/bspwm.c @@ -312,7 +312,9 @@ int main(int argc, char *argv[]) rargv[rargc + 3] = sock_fd_arg; rargv[rargc + 4] = 0; - exit_status = execvp(*rargv, rargv); + execvp(*rargv, rargv); + + exit_status = 1; free(rargv); } From d1aaed5c425248e645426f68b2281b0ca5dced7f Mon Sep 17 00:00:00 2001 From: Emanuele Torre Date: Mon, 5 Sep 2022 15:42:40 +0200 Subject: [PATCH 03/15] Avoid unnecessary relayouts for unchanged values Closes #1415. --- src/messages.c | 9 ++++----- src/tree.c | 14 ++++++++------ src/tree.h | 4 ++-- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/messages.c b/src/messages.c index c3a42014..6f54e754 100644 --- a/src/messages.c +++ b/src/messages.c @@ -472,13 +472,13 @@ void cmd_node(char **args, int num, FILE *rsp) split_type_t typ; if (parse_cycle_direction(*args, &cyc)) { set_type(trg.node, (trg.node->split_type + 1) % 2); + changed = true; } else if (parse_split_type(*args, &typ)) { - set_type(trg.node, typ); + changed |= set_type(trg.node, typ); } else { fail(rsp, ""); break; } - changed = true; } else if (streq("-r", *args) || streq("--ratio", *args)) { num--, args++; if (num < 1) { @@ -500,7 +500,7 @@ void cmd_node(char **args, int num, FILE *rsp) rat = ((max * rat) + delta) / max; } if (rat > 0 && rat < 1) { - set_ratio(trg.node, rat); + changed |= set_ratio(trg.node, rat); } else { fail(rsp, ""); break; @@ -512,13 +512,12 @@ void cmd_node(char **args, int num, FILE *rsp) } else { double rat; if (sscanf(*args, "%lf", &rat) == 1 && rat > 0 && rat < 1) { - set_ratio(trg.node, rat); + changed |= set_ratio(trg.node, rat); } else { fail(rsp, "node %s: Invalid argument: '%s'.\n", *(args - 1), *args); break; } } - changed = true; } else if (streq("-F", *args) || streq("--flip", *args)) { num--, args++; if (num < 1) { diff --git a/src/tree.c b/src/tree.c index db8208d8..00f43b9f 100644 --- a/src/tree.c +++ b/src/tree.c @@ -190,24 +190,26 @@ presel_t *make_presel(void) return p; } -void set_type(node_t *n, split_type_t typ) +bool set_type(node_t *n, split_type_t typ) { - if (n == NULL) { - return; + if (n == NULL || n->split_type == typ) { + return false; } n->split_type = typ; update_constraints(n); rebuild_constraints_towards_root(n); + return true; } -void set_ratio(node_t *n, double rat) +bool set_ratio(node_t *n, double rat) { - if (n == NULL) { - return; + if (n == NULL || n->split_ratio == rat) { + return false; } n->split_ratio = rat; + return true; } void presel_dir(monitor_t *m, desktop_t *d, node_t *n, direction_t dir) diff --git a/src/tree.h b/src/tree.h index aa04cde2..0523a64b 100644 --- a/src/tree.h +++ b/src/tree.h @@ -31,8 +31,8 @@ void arrange(monitor_t *m, desktop_t *d); void apply_layout(monitor_t *m, desktop_t *d, node_t *n, xcb_rectangle_t rect, xcb_rectangle_t root_rect); presel_t *make_presel(void); -void set_type(node_t *n, split_type_t typ); -void set_ratio(node_t *n, double rat); +bool set_type(node_t *n, split_type_t typ); +bool set_ratio(node_t *n, double rat); void presel_dir(monitor_t *m, desktop_t *d, node_t *n, direction_t dir); void presel_ratio(monitor_t *m, desktop_t *d, node_t *n, double ratio); void cancel_presel(monitor_t *m, desktop_t *d, node_t *n); From 679d56ef8ba09e6d287c5fec3579ee5ad7d1da6a Mon Sep 17 00:00:00 2001 From: virchau13 Date: Tue, 8 Mar 2022 22:55:24 +0800 Subject: [PATCH 04/15] Add --print-socket-path option Closes #1367. --- doc/bspwm.1 | 15 ++++++++++++--- doc/bspwm.1.asciidoc | 5 +++++ src/bspc.c | 14 ++++++++++---- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/doc/bspwm.1 b/doc/bspwm.1 index 9863c2d5..e0a2cd28 100644 --- a/doc/bspwm.1 +++ b/doc/bspwm.1 @@ -2,12 +2,12 @@ .\" Title: bspwm .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 02/15/2022 +.\" Date: 03/08/2022 .\" Manual: Bspwm Manual -.\" Source: Bspwm 0.9.10-34-g3403bb2 +.\" Source: Bspwm 0.9.10-36-g1560df3 .\" Language: English .\" -.TH "BSPWM" "1" "02/15/2022" "Bspwm 0\&.9\&.10\-34\-g3403bb2" "Bspwm Manual" +.TH "BSPWM" "1" "03/08/2022" "Bspwm 0\&.9\&.10\-36\-g1560df3" "Bspwm Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -33,6 +33,8 @@ bspwm \- Binary space partitioning window manager .sp \fBbspwm\fR [\fB\-h\fR|\fB\-v\fR|\fB\-c\fR \fICONFIG_PATH\fR] .sp +\fBbspc \-\-print\-socket\-path\fR +.sp \fBbspc\fR \fIDOMAIN\fR [\fISELECTOR\fR] \fICOMMANDS\fR .sp \fBbspc\fR \fICOMMAND\fR [\fIOPTIONS\fR] [\fIARGUMENTS\fR] @@ -57,6 +59,13 @@ Print the version and exit\&. .RS 4 Use the given configuration file\&. .RE +.PP +\fB\-\-print\-socket\-path\fR +.RS 4 +Print the +\fBbspwm\fR +socket path and exit\&. +.RE .SH "COMMON DEFINITIONS" .sp .if n \{\ diff --git a/doc/bspwm.1.asciidoc b/doc/bspwm.1.asciidoc index e84150bf..41a5f990 100644 --- a/doc/bspwm.1.asciidoc +++ b/doc/bspwm.1.asciidoc @@ -15,6 +15,8 @@ Synopsis *bspwm* [*-h*|*-v*|*-c* 'CONFIG_PATH'] +*bspc --print-socket-path* + *bspc* 'DOMAIN' ['SELECTOR'] 'COMMANDS' *bspc* 'COMMAND' ['OPTIONS'] ['ARGUMENTS'] @@ -39,6 +41,9 @@ Options *-c* 'CONFIG_PATH':: Use the given configuration file. +*--print-socket-path*:: + Print the *bspwm* socket path and exit. + Common Definitions ------------------ diff --git a/src/bspc.c b/src/bspc.c index 5dd807cd..2d158553 100644 --- a/src/bspc.c +++ b/src/bspc.c @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -46,10 +47,6 @@ int main(int argc, char *argv[]) sock_address.sun_family = AF_UNIX; char *sp; - if ((sock_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { - err("Failed to create the socket.\n"); - } - sp = getenv(SOCKET_ENV_VAR); if (sp != NULL) { snprintf(sock_address.sun_path, sizeof(sock_address.sun_path), "%s", sp); @@ -62,6 +59,15 @@ int main(int argc, char *argv[]) free(host); } + if (streq(argv[1], "--print-socket-path")) { + printf("%s\n", sock_address.sun_path); + return EXIT_SUCCESS; + } + + if ((sock_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + err("Failed to create the socket.\n"); + } + if (connect(sock_fd, (struct sockaddr *) &sock_address, sizeof(sock_address)) == -1) { err("Failed to connect to the socket.\n"); } From b20d3fb48e161392f8ce67f36ad4b5b5e778fe0c Mon Sep 17 00:00:00 2001 From: Abraham Raji <32333507+abrahamparayil@users.noreply.github.com> Date: Thu, 11 Aug 2022 05:09:41 +0530 Subject: [PATCH 05/15] Update info for Debian Closes #1408. --- doc/INSTALL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/INSTALL.md b/doc/INSTALL.md index 4a9b3f18..8bc54989 100644 --- a/doc/INSTALL.md +++ b/doc/INSTALL.md @@ -21,8 +21,8 @@ - [bspwm (i686)](https://www.archlinux.org/packages/community/i686/bspwm) - Debian - - [packages](http://download.opensuse.org/repositories/home:/Head_on_a_Stick:/bspwm/Debian_8.0/) - - [guide](http://forums.debian.net/viewtopic.php?f=16&t=127708) + - [bspwm](https://tracker.debian.org/pkg/bspwm) + - [wiki page](https://wiki.debian.org/bspwm) - Gentoo Linux - [bspwm](https://packages.gentoo.org/packages/x11-wm/bspwm) From 79464766bb949b88751c756661d7883bbe3bcb01 Mon Sep 17 00:00:00 2001 From: Jade Lovelace Date: Wed, 5 Jan 2022 13:55:53 -0800 Subject: [PATCH 06/15] Allow escaping colons in rule tokenization Fix #1071. Closes #1351. Closes #1330. --- doc/bspwm.1 | 12 ++++++++---- doc/bspwm.1.asciidoc | 3 ++- src/helpers.c | 36 ++++++++++++++++++++++++++++++++++++ src/helpers.h | 7 +++++++ src/messages.c | 25 ++++++++++++++++++++----- src/rule.c | 17 ++++++++++++++--- tests/node/flags | 4 ++-- tests/prelude | 5 ++++- tests/test_window.c | 28 ++++++++++++++++++++++++++-- 9 files changed, 119 insertions(+), 18 deletions(-) diff --git a/doc/bspwm.1 b/doc/bspwm.1 index e0a2cd28..3bfc2803 100644 --- a/doc/bspwm.1 +++ b/doc/bspwm.1 @@ -2,12 +2,12 @@ .\" Title: bspwm .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 03/08/2022 +.\" Date: 11/19/2022 .\" Manual: Bspwm Manual -.\" Source: Bspwm 0.9.10-36-g1560df3 +.\" Source: Bspwm 0.9.10-41-gb20d3fb .\" Language: English .\" -.TH "BSPWM" "1" "03/08/2022" "Bspwm 0\&.9\&.10\-36\-g1560df3" "Bspwm Manual" +.TH "BSPWM" "1" "11/19/2022" "Bspwm 0\&.9\&.10\-41\-gb20d3fb" "Bspwm Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -1068,7 +1068,11 @@ rule \fICOMMANDS\fR .PP \fB\-a\fR, \fB\-\-add\fR (|*)[:(|*)[:(|*)]] [\fB\-o\fR|\fB\-\-one\-shot\fR] [monitor=MONITOR_SEL|desktop=DESKTOP_SEL|node=NODE_SEL] [state=STATE] [layer=LAYER] [split_dir=DIR] [split_ratio=RATIO] [(hidden|sticky|private|locked|marked|center|follow|manage|focus|border)=(on|off)] [rectangle=WxH+X+Y] .RS 4 -Create a new rule\&. +Create a new rule\&. Colons in the +\fIinstance_name\fR, +\fIclass_name\fR, or +\fIname\fR +fields can be escaped with a backslash\&. .RE .PP \fB\-r\fR, \fB\-\-remove\fR ^|head|tail|(|*)[:(|*)[:(|*)]]\&... diff --git a/doc/bspwm.1.asciidoc b/doc/bspwm.1.asciidoc index 41a5f990..d8131c16 100644 --- a/doc/bspwm.1.asciidoc +++ b/doc/bspwm.1.asciidoc @@ -633,7 +633,8 @@ Commands ^^^^^^^^ *-a*, *--add* (|\*)[:(|\*)[:(|\*)]] [*-o*|*--one-shot*] [monitor=MONITOR_SEL|desktop=DESKTOP_SEL|node=NODE_SEL] [state=STATE] [layer=LAYER] [split_dir=DIR] [split_ratio=RATIO] [(hidden|sticky|private|locked|marked|center|follow|manage|focus|border)=(on|off)] [rectangle=WxH+X+Y]:: - Create a new rule. + Create a new rule. Colons in the 'instance_name', 'class_name', or 'name' + fields can be escaped with a backslash. *-r*, *--remove* ^|head|tail|(|\*)[:(|\*)[:(|*)]]...:: Remove the given rules. diff --git a/src/helpers.c b/src/helpers.c index 57a82bdd..785d2dd4 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -193,3 +193,39 @@ bool is_hex_color(const char *color) } return true; } + +char *tokenize_with_escape(struct tokenize_state *state, const char *s, char sep) +{ + if (s != NULL) { + // first call + state->in_escape = false; + state->pos = s; + state->len = strlen(s) + 1; + } + + char *outp = calloc(state->len, 1); + char *ret = outp; + if (!outp) return NULL; + + char cur; + while (*state->pos) { + --state->len; + cur = *state->pos++; + + if (state->in_escape) { + *outp++ = cur; + state->in_escape = false; + continue; + } + + if (cur == '\\') { + state->in_escape = !state->in_escape; + } else if (cur == sep) { + return ret; + } else { + *outp++ = cur; + } + } + + return ret; +} diff --git a/src/helpers.h b/src/helpers.h index c65ebbe5..829289a1 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -84,4 +84,11 @@ int asprintf(char **buf, const char *fmt, ...); int vasprintf(char **buf, const char *fmt, va_list args); bool is_hex_color(const char *color); +struct tokenize_state { + bool in_escape; + const char *pos; + size_t len; +}; +char *tokenize_with_escape(struct tokenize_state *state, const char *s, char sep); + #endif diff --git a/src/messages.c b/src/messages.c index 6f54e754..67aac880 100644 --- a/src/messages.c +++ b/src/messages.c @@ -1173,12 +1173,27 @@ void cmd_rule(char **args, int num, FILE *rsp) return; } rule_t *rule = make_rule(); - char *class_name = strtok(*args, COL_TOK); - char *instance_name = strtok(NULL, COL_TOK); - char *name = strtok(NULL, COL_TOK); + + struct tokenize_state state; + char *class_name = tokenize_with_escape(&state, args[0], COL_TOK[0]); + char *instance_name = tokenize_with_escape(&state, NULL, COL_TOK[0]); + char *name = tokenize_with_escape(&state, NULL, COL_TOK[0]); + if (!class_name || !instance_name || !name) { + free(class_name); + free(instance_name); + free(name); + return; + } + snprintf(rule->class_name, sizeof(rule->class_name), "%s", class_name); - snprintf(rule->instance_name, sizeof(rule->instance_name), "%s", instance_name==NULL?MATCH_ANY:instance_name); - snprintf(rule->name, sizeof(rule->name), "%s", name==NULL?MATCH_ANY:name); + snprintf(rule->instance_name, sizeof(rule->instance_name), "%s", + instance_name[0] == '\0' ? MATCH_ANY : instance_name); + snprintf(rule->name, sizeof(rule->name), "%s", + name[0] == '\0' ? MATCH_ANY : name); + free(class_name); + free(instance_name); + free(name); + num--, args++; size_t i = 0; while (num > 0) { diff --git a/src/rule.c b/src/rule.c index 583b2382..a9d9d232 100644 --- a/src/rule.c +++ b/src/rule.c @@ -81,9 +81,17 @@ void remove_rule(rule_t *r) void remove_rule_by_cause(char *cause) { rule_t *r = rule_head; - char *class_name = strtok(cause, COL_TOK); - char *instance_name = strtok(NULL, COL_TOK); - char *name = strtok(NULL, COL_TOK); + struct tokenize_state state; + char *class_name = tokenize_with_escape(&state, cause, COL_TOK[0]); + char *instance_name = tokenize_with_escape(&state, NULL, COL_TOK[0]); + char *name = tokenize_with_escape(&state, NULL, COL_TOK[0]); + if (!class_name || !instance_name || !name) { + free(class_name); + free(instance_name); + free(name); + return; + } + while (r != NULL) { rule_t *next = r->next; if ((class_name != NULL && (streq(class_name, MATCH_ANY) || streq(r->class_name, class_name))) && @@ -93,6 +101,9 @@ void remove_rule_by_cause(char *cause) } r = next; } + free(class_name); + free(instance_name); + free(name); } bool remove_rule_by_index(int idx) diff --git a/tests/node/flags b/tests/node/flags index 7fa9e541..e27db483 100755 --- a/tests/node/flags +++ b/tests/node/flags @@ -12,9 +12,9 @@ bspc node -g sticky sticky_node_id=$(bspc query -N -n) -bspc rule -a Test:test -o desktop="test-sticky-b" +bspc rule -a 'Blah\:\:2:test' -o desktop="test-sticky-b" -window add +CLASS_NAME=Blah::2 INSTANCE_NAME=test window add bspc desktop -f "test-sticky-b" diff --git a/tests/prelude b/tests/prelude index 63d51592..393ffbb1 100644 --- a/tests/prelude +++ b/tests/prelude @@ -10,9 +10,12 @@ window() { local iter=${2:-1} local delta=${3:-1} local event=node_${action} + local instance_name=${INSTANCE_NAME:-test} + local class_name=${CLASS_NAME:-Test} + local cmd case "$action" in - add) cmd=./test_window ;; + add) cmd="./test_window $instance_name $class_name" ;; remove) cmd="bspc node -c" ;; esac while [ $iter -gt 0 ] ; do diff --git a/tests/test_window.c b/tests/test_window.c index 6b6ed38e..a76ad6d0 100644 --- a/tests/test_window.c +++ b/tests/test_window.c @@ -57,8 +57,27 @@ void render_text(xcb_connection_t *dpy, xcb_window_t win, int16_t x, int16_t y) } -int main(void) +int main(int argc, char **argv) { + char *wm_class = TEST_WINDOW_IC; + size_t wm_class_len = sizeof (TEST_WINDOW_IC); + bool will_free_wm_class = false; + + // test instance-name class-name + if (argc > 2) { + will_free_wm_class = true; + size_t len1 = strlen(argv[1]); + size_t len2 = strlen(argv[2]); + // 2 null terminators + wm_class_len = len1 + len2 + 2; + wm_class = malloc(wm_class_len); + + if (!wm_class) return 1; + + memcpy(wm_class, argv[1], len1 + 1); + memcpy(wm_class + len1 + 1, argv[2], len2 + 1); + } + xcb_connection_t *dpy = xcb_connect(NULL, NULL); if (dpy == NULL) { fprintf(stderr, "Can't connect to X.\n"); @@ -82,7 +101,7 @@ int main(void) uint32_t values[] = {0xff111111, XCB_EVENT_MASK_EXPOSURE}; xcb_create_window(dpy, XCB_COPY_FROM_PARENT, win, screen->root, 0, 0, 320, 240, 2, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, mask, values); - xcb_icccm_set_wm_class(dpy, win, sizeof(TEST_WINDOW_IC), TEST_WINDOW_IC); + xcb_icccm_set_wm_class(dpy, win, wm_class_len, wm_class); xcb_map_window(dpy, win); xcb_flush(dpy); xcb_generic_event_t *evt; @@ -101,5 +120,10 @@ int main(void) } xcb_destroy_window(dpy, win); xcb_disconnect(dpy); + + if (will_free_wm_class) { + free(wm_class); + } + return EXIT_SUCCESS; } From 527864d8716462e52f85a419f97a776c0643a68c Mon Sep 17 00:00:00 2001 From: Connor-GH <72793802+Connor-GH@users.noreply.github.com> Date: Tue, 26 Jul 2022 06:59:05 +0000 Subject: [PATCH 07/15] Remove non-needed Zero initializer Closes #1404. --- src/helpers.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/helpers.c b/src/helpers.c index 785d2dd4..98909f0a 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -152,10 +152,9 @@ char *mktempfifo(const char *template) int asprintf(char **buf, const char *fmt, ...) { - int size = 0; va_list args; va_start(args, fmt); - size = vasprintf(buf, fmt, args); + int size = vasprintf(buf, fmt, args); va_end(args); return size; } From fcfdbb089c1f3eb671e21be0c25e0a31ead4be44 Mon Sep 17 00:00:00 2001 From: Bastien Dejean Date: Sat, 25 Mar 2023 08:37:44 +0100 Subject: [PATCH 08/15] Set Emanuele Torre as the IRC channel maintainer --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4846a52b..22287210 100644 --- a/README.md +++ b/README.md @@ -190,5 +190,5 @@ The *spiral* automatic scheme generates window spirals that rotate clockwise (re Want to get in touch with other *bspwm* users or you need help? Join us on our: - Subreddit at [r/bspwm](https://www.reddit.com/r/bspwm/). -- IRC channel at `#bspwm` on `irc.libera.chat` (maintained by [@dannycolin](https://github.com/dannycolin) / sdk on IRC). +- IRC channel at `#bspwm` on `irc.libera.chat` (maintained by [Emanuele Torre](https://github.com/emanuele6) / emanuele6 on IRC). - Matrix room at https://matrix.to/#/#bspwm:matrix.org From 7848e7f5f60ce771920d27ead9e7779607360177 Mon Sep 17 00:00:00 2001 From: Emanuele Torre Date: Sat, 4 Feb 2023 17:09:21 +0100 Subject: [PATCH 09/15] Account for vacant nodes when adjusting ratios Closes #1431. --- src/tree.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/tree.c b/src/tree.c index 00f43b9f..ea732474 100644 --- a/src/tree.c +++ b/src/tree.c @@ -1280,7 +1280,8 @@ int balance_tree(node_t *n) * despite the potential alteration of their rectangle. */ void adjust_ratios(node_t *n, xcb_rectangle_t rect) { - if (n == NULL) { +#define NULL_OR_VACANT(n) ((n) == NULL || (n)->vacant) + if (NULL_OR_VACANT(n)) { return; } @@ -1302,6 +1303,16 @@ void adjust_ratios(node_t *n, xcb_rectangle_t rect) xcb_rectangle_t second_rect; unsigned int fence; + if (NULL_OR_VACANT(n->first_child)) { + adjust_ratios(n->second_child, rect); + return; + } + if (NULL_OR_VACANT(n->second_child)) { + adjust_ratios(n->first_child, rect); + return; + } +#undef NULL_OR_VACANT + if (n->split_type == TYPE_VERTICAL) { fence = rect.width * n->split_ratio; first_rect = (xcb_rectangle_t) {rect.x, rect.y, fence, rect.height}; From 4c74987face0e51bdb3332a5371b4fc980d93a5e Mon Sep 17 00:00:00 2001 From: Emanuele Torre Date: Sun, 5 Feb 2023 07:29:42 +0100 Subject: [PATCH 10/15] Adjust ratios for both fences when resizing Instead of adjusting ratios only for the horizontal fence. Closes #1432. --- src/window.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/window.c b/src/window.c index cd2340df..b45aab2d 100644 --- a/src/window.c +++ b/src/window.c @@ -574,6 +574,7 @@ bool resize_client(coordinates_t *loc, resize_handle_t rh, int dx, int dy, bool sr = MAX(0, sr); sr = MIN(1, sr); vertical_fence->split_ratio = sr; + adjust_ratios(vertical_fence, vertical_fence->rectangle); } if (horizontal_fence != NULL) { double sr = 0.0; @@ -585,9 +586,8 @@ bool resize_client(coordinates_t *loc, resize_handle_t rh, int dx, int dy, bool sr = MAX(0, sr); sr = MIN(1, sr); horizontal_fence->split_ratio = sr; + adjust_ratios(horizontal_fence, horizontal_fence->rectangle); } - node_t *target_fence = horizontal_fence != NULL ? horizontal_fence : vertical_fence; - adjust_ratios(target_fence, target_fence->rectangle); arrange(loc->monitor, loc->desktop); } else { int w = width, h = height; From cbed61787e740fe35432f5891dfbe7d725297057 Mon Sep 17 00:00:00 2001 From: Emanuele Torre Date: Sun, 19 Feb 2023 19:01:22 +0100 Subject: [PATCH 11/15] Notify subscribers when a desktop's status changes Fixes #1437. Closes #1438. --- src/tree.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tree.c b/src/tree.c index ea732474..4401e49b 100644 --- a/src/tree.c +++ b/src/tree.c @@ -294,6 +294,8 @@ node_t *insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f) return NULL; } + bool d_was_not_occupied = d->root == NULL; + /* n: inserted node */ /* c: new internal node */ /* f: focus or insertion anchor */ @@ -452,6 +454,10 @@ node_t *insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f) d->focus = n; } + if (d_was_not_occupied) { + put_status(SBSC_MASK_REPORT); + } + return f; } @@ -1338,6 +1344,7 @@ void unlink_node(monitor_t *m, desktop_t *d, node_t *n) if (p == NULL) { d->root = NULL; d->focus = NULL; + put_status(SBSC_MASK_REPORT); } else { if (d->focus == p || is_descendant(d->focus, n)) { d->focus = NULL; From b2b76f1edeb83f3e0f5dea5f71293063d934aa25 Mon Sep 17 00:00:00 2001 From: Emanuele Torre Date: Sat, 25 Mar 2023 00:37:07 +0100 Subject: [PATCH 12/15] Remove unwanted space after comma Closes #1445. --- doc/bspwm.1 | 8 ++++---- doc/bspwm.1.asciidoc | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/bspwm.1 b/doc/bspwm.1 index 3bfc2803..2be56f73 100644 --- a/doc/bspwm.1 +++ b/doc/bspwm.1 @@ -2,12 +2,12 @@ .\" Title: bspwm .\" Author: [see the "Author" section] .\" Generator: DocBook XSL Stylesheets vsnapshot -.\" Date: 11/19/2022 +.\" Date: 04/05/2023 .\" Manual: Bspwm Manual -.\" Source: Bspwm 0.9.10-41-gb20d3fb +.\" Source: Bspwm 0.9.10-48-gbcc8377 .\" Language: English .\" -.TH "BSPWM" "1" "11/19/2022" "Bspwm 0\&.9\&.10\-41\-gb20d3fb" "Bspwm Manual" +.TH "BSPWM" "1" "04/05/2023" "Bspwm 0\&.9\&.10\-48\-gbcc8377" "Bspwm Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -971,7 +971,7 @@ Print a JSON representation of the matching item\&. \fBOptions\fR .RS 4 .PP -\fB\-m\fR,\fB\-\-monitor\fR [\fIMONITOR_SEL\fR|\fIMONITOR_MODIFIERS\fR], \fB\-d\fR,\fB\-\-desktop\fR [\fIDESKTOP_SEL\fR|\fIDESKTOP_MODIFIERS\fR], \fB\-n\fR, \fB\-\-node\fR [\fINODE_SEL\fR|\fINODE_MODIFIERS\fR] +\fB\-m\fR,\fB\-\-monitor\fR [\fIMONITOR_SEL\fR|\fIMONITOR_MODIFIERS\fR], \fB\-d\fR,\fB\-\-desktop\fR [\fIDESKTOP_SEL\fR|\fIDESKTOP_MODIFIERS\fR], \fB\-n\fR,\fB\-\-node\fR [\fINODE_SEL\fR|\fINODE_MODIFIERS\fR] .RS 4 Constrain matches to the selected monitors, desktops or nodes\&. .RE diff --git a/doc/bspwm.1.asciidoc b/doc/bspwm.1.asciidoc index d8131c16..bd9496b2 100644 --- a/doc/bspwm.1.asciidoc +++ b/doc/bspwm.1.asciidoc @@ -580,7 +580,7 @@ Options *-m*,*--monitor* ['MONITOR_SEL'|'MONITOR_MODIFIERS']:: *-d*,*--desktop* ['DESKTOP_SEL'|'DESKTOP_MODIFIERS']:: -*-n*, *--node* ['NODE_SEL'|'NODE_MODIFIERS']:: +*-n*,*--node* ['NODE_SEL'|'NODE_MODIFIERS']:: Constrain matches to the selected monitors, desktops or nodes. *--names*:: From c58c67a6590c1aa65eec5798be49837eeddb7667 Mon Sep 17 00:00:00 2001 From: Emanuele Torre Date: Sat, 1 Apr 2023 16:52:57 +0200 Subject: [PATCH 13/15] Turn `honor_size_hints` into a node setting Now honor_size_hints can be set to floating or tiled. When it is set to tiled, bspwm honours hints only for tiled windows, and when it is set to floating, bspwm honours hints only for floating, and pseudo tiled windows. Fixes #1447. Closes #1448. --- doc/bspwm.1.asciidoc | 8 ++++---- src/helpers.h | 10 ++++++++++ src/messages.c | 45 ++++++++++++++++++++++++++++++++++++++++++-- src/parse.c | 16 ++++++++++++++++ src/parse.h | 1 + src/pointer.c | 5 +++-- src/query.c | 3 ++- src/rule.c | 5 +++++ src/settings.c | 2 +- src/settings.h | 4 ++-- src/tree.c | 1 + src/types.h | 10 ++++++++++ src/window.c | 10 +++++----- 13 files changed, 103 insertions(+), 17 deletions(-) diff --git a/doc/bspwm.1.asciidoc b/doc/bspwm.1.asciidoc index bd9496b2..dad47de6 100644 --- a/doc/bspwm.1.asciidoc +++ b/doc/bspwm.1.asciidoc @@ -632,7 +632,7 @@ rule 'COMMANDS' Commands ^^^^^^^^ -*-a*, *--add* (|\*)[:(|\*)[:(|\*)]] [*-o*|*--one-shot*] [monitor=MONITOR_SEL|desktop=DESKTOP_SEL|node=NODE_SEL] [state=STATE] [layer=LAYER] [split_dir=DIR] [split_ratio=RATIO] [(hidden|sticky|private|locked|marked|center|follow|manage|focus|border)=(on|off)] [rectangle=WxH+X+Y]:: +*-a*, *--add* (|\*)[:(|\*)[:(|\*)]] [*-o*|*--one-shot*] [monitor=MONITOR_SEL|desktop=DESKTOP_SEL|node=NODE_SEL] [state=STATE] [layer=LAYER] [honor_size_hints=(true|false|tiled|floating)] [split_dir=DIR] [split_ratio=RATIO] [(hidden|sticky|private|locked|marked|center|follow|manage|focus|border)=(on|off)] [rectangle=WxH+X+Y]:: Create a new rule. Colons in the 'instance_name', 'class_name', or 'name' fields can be escaped with a backslash. @@ -786,9 +786,6 @@ Global Settings 'center_pseudo_tiled':: Center pseudo tiled windows into their tiling rectangles. Defaults to 'true'. -'honor_size_hints':: - Apply ICCCM window size hints. - 'remove_disabled_monitors':: Consider disabled monitors as disconnected. @@ -819,6 +816,9 @@ Node Settings 'border_width':: Window border width. +'honor_size_hints':: + If 'true', apply ICCCM window size hints to all windows. If 'floating', only apply them to floating and pseudo tiled windows. If 'tiled', only apply them to tiled windows. If 'false', don't apply them. Defaults to 'false'. + Pointer Bindings ---------------- diff --git a/src/helpers.h b/src/helpers.h index 829289a1..444730f3 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -54,11 +54,21 @@ #define STATE_STR(A) ((A) == STATE_TILED ? "tiled" : ((A) == STATE_FLOATING ? "floating" : ((A) == STATE_FULLSCREEN ? "fullscreen" : "pseudo_tiled"))) #define STATE_CHR(A) ((A) == STATE_TILED ? 'T' : ((A) == STATE_FLOATING ? 'F' : ((A) == STATE_FULLSCREEN ? '=' : 'P'))) #define LAYER_STR(A) ((A) == LAYER_BELOW ? "below" : ((A) == LAYER_NORMAL ? "normal" : "above")) +#define HSH_MODE_STR(A) ((A) == HONOR_SIZE_HINTS_TILED ? "tiled" : ((A) == HONOR_SIZE_HINTS_FLOATING ? "floating" : BOOL_STR(A))) #define XCB_CONFIG_WINDOW_X_Y (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y) #define XCB_CONFIG_WINDOW_WIDTH_HEIGHT (XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT) #define XCB_CONFIG_WINDOW_X_Y_WIDTH_HEIGHT (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT) +#define SHOULD_HONOR_SIZE_HINTS(hsh, state) \ + ((hsh) && \ + (((hsh) == HONOR_SIZE_HINTS_YES && \ + (state) != STATE_FULLSCREEN) || \ + ((hsh) == HONOR_SIZE_HINTS_TILED && \ + (state) == STATE_TILED) || \ + ((hsh) == HONOR_SIZE_HINTS_FLOATING && \ + ((state) == STATE_FLOATING || (state) == STATE_PSEUDO_TILED)))) + #define MAXLEN 256 #define SMALEN 32 #define INIT_CAP 8 diff --git a/src/messages.c b/src/messages.c index 67aac880..666845b5 100644 --- a/src/messages.c +++ b/src/messages.c @@ -1509,6 +1509,47 @@ void set_setting(coordinates_t loc, char *name, char *value, FILE *rsp) } SET_DEF_DEFMON_DEFDESK_WIN(border_width, bw) #undef SET_DEF_DEFMON_DEFDESK_WIN +#define SET_DEF_WIN(k, v) \ + if (loc.node != NULL) { \ + for (node_t *n = first_extrema(loc.node); n != NULL; n = next_leaf(n, loc.node)) { \ + if (n->client != NULL) { \ + n->client->k = v; \ + } \ + } \ + } else if (loc.desktop != NULL) { \ + for (node_t *n = first_extrema(loc.desktop->root); n != NULL; n = next_leaf(n, loc.desktop->root)) { \ + if (n->client != NULL) { \ + n->client->k = v; \ + } \ + } \ + } else if (loc.monitor != NULL) { \ + for (desktop_t *d = loc.monitor->desk_head; d != NULL; d = d->next) { \ + for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) { \ + if (n->client != NULL) { \ + n->client->k = v; \ + } \ + } \ + } \ + } else { \ + k = v; \ + for (monitor_t *m = mon_head; m != NULL; m = m->next) { \ + for (desktop_t *d = m->desk_head; d != NULL; d = d->next) { \ + for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) { \ + if (n->client != NULL) { \ + n->client->k = v; \ + } \ + } \ + } \ + } \ + } + } else if (streq("honor_size_hints", name)) { + honor_size_hints_mode_t hsh; + if (!parse_honor_size_hints_mode(value, &hsh)) { + fail(rsp, "config: %s: Invalid value: '%s'.\n", name, value); + return; + } + SET_DEF_WIN(honor_size_hints, hsh) +#undef SET_DEF_WIN #define SET_DEF_DEFMON_DESK(k, v) \ if (loc.desktop != NULL) { \ loc.desktop->k = v; \ @@ -1753,7 +1794,6 @@ void set_setting(coordinates_t loc, char *name, char *value, FILE *rsp) 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 #define SET_MON_BOOL(s) \ @@ -1844,6 +1884,8 @@ 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("honor_size_hints", name)) { + fprintf(rsp, "%s", HSH_MODE_STR(honor_size_hints)); } else if (streq("mapping_events_count", name)) { fprintf(rsp, "%" PRIi8, mapping_events_count); } else if (streq("directional_focus_tightness", name)) { @@ -1884,7 +1926,6 @@ void get_setting(coordinates_t loc, char *name, FILE* rsp) GET_BOOL(ignore_ewmh_focus) GET_BOOL(ignore_ewmh_struts) GET_BOOL(center_pseudo_tiled) - GET_BOOL(honor_size_hints) GET_BOOL(removal_adjustment) GET_BOOL(remove_disabled_monitors) GET_BOOL(remove_unplugged_monitors) diff --git a/src/parse.c b/src/parse.c index 05adf448..124fb710 100644 --- a/src/parse.c +++ b/src/parse.c @@ -282,6 +282,22 @@ bool parse_automatic_scheme(char *s, automatic_scheme_t *a) return false; } +bool parse_honor_size_hints_mode(char *s, honor_size_hints_mode_t *a) +{ + bool b; + if (parse_bool(s, &b)) { + *a = b ? HONOR_SIZE_HINTS_YES : HONOR_SIZE_HINTS_NO; + return true; + } else if (streq("floating", s)) { + *a = HONOR_SIZE_HINTS_FLOATING; + return true; + } else if (streq("tiled", s)) { + *a = HONOR_SIZE_HINTS_TILED; + return true; + } + return false; +} + bool parse_state_transition(char *s, state_transition_t *m) { if (streq("none", s)) { diff --git a/src/parse.h b/src/parse.h index 89ba6e1c..94df96da 100644 --- a/src/parse.h +++ b/src/parse.h @@ -26,6 +26,7 @@ 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_honor_size_hints_mode(char *s, honor_size_hints_mode_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); diff --git a/src/pointer.c b/src/pointer.c index 5eb93c34..a0c5026d 100644 --- a/src/pointer.c +++ b/src/pointer.c @@ -288,8 +288,9 @@ void track_pointer(coordinates_t loc, pointer_action_t pac, xcb_point_t pos) int16_t dy = e->root_y - last_motion_y; if (pac == ACTION_MOVE) { move_client(&loc, dx, dy); - } else { - if (honor_size_hints) { + } else if (n) { + client_t *c = n->client; + if (c && SHOULD_HONOR_SIZE_HINTS(c->honor_size_hints, c->state)) { resize_client(&loc, rh, e->root_x, e->root_y, false); } else { resize_client(&loc, rh, dx, dy, true); diff --git a/src/query.c b/src/query.c index aaaf3eec..2935ba5a 100644 --- a/src/query.c +++ b/src/query.c @@ -455,10 +455,11 @@ void print_rule_consequence(char **buf, rule_consequence_t *csq) *rect_buf = '\0'; } - asprintf(buf, "monitor=%s desktop=%s node=%s state=%s layer=%s split_dir=%s split_ratio=%lf hidden=%s sticky=%s private=%s locked=%s marked=%s center=%s follow=%s manage=%s focus=%s border=%s rectangle=%s", + asprintf(buf, "monitor=%s desktop=%s node=%s state=%s layer=%s honor_size_hints=%s split_dir=%s split_ratio=%lf hidden=%s sticky=%s private=%s locked=%s marked=%s center=%s follow=%s manage=%s focus=%s border=%s rectangle=%s", csq->monitor_desc, csq->desktop_desc, csq->node_desc, csq->state == NULL ? "" : STATE_STR(*csq->state), csq->layer == NULL ? "" : LAYER_STR(*csq->layer), + csq->honor_size_hints == HONOR_SIZE_HINTS_DEFAULT ? "" : HSH_MODE_STR(csq->honor_size_hints), csq->split_dir == NULL ? "" : SPLIT_DIR_STR(*csq->split_dir), csq->split_ratio, ON_OFF_STR(csq->hidden), ON_OFF_STR(csq->sticky), ON_OFF_STR(csq->private), ON_OFF_STR(csq->locked), ON_OFF_STR(csq->marked), ON_OFF_STR(csq->center), ON_OFF_STR(csq->follow), diff --git a/src/rule.c b/src/rule.c index a9d9d232..b7e55aac 100644 --- a/src/rule.c +++ b/src/rule.c @@ -124,6 +124,7 @@ rule_consequence_t *make_rule_consequence(void) rc->layer = NULL; rc->state = NULL; rc->rect = NULL; + rc->honor_size_hints = HONOR_SIZE_HINTS_DEFAULT; return rc; } @@ -433,6 +434,10 @@ void parse_key_value(char *key, char *value, rule_consequence_t *csq) free(csq->rect); csq->rect = NULL; } + } else if (streq("honor_size_hints", key)) { + if (!parse_honor_size_hints_mode(value, &csq->honor_size_hints)) { + csq->honor_size_hints = HONOR_SIZE_HINTS_DEFAULT; + } } else if (parse_bool(value, &v)) { if (streq("hidden", key)) { csq->hidden = v; diff --git a/src/settings.c b/src/settings.c index 52358f7a..bd0f935f 100644 --- a/src/settings.c +++ b/src/settings.c @@ -67,7 +67,7 @@ bool ignore_ewmh_struts; state_transition_t ignore_ewmh_fullscreen; bool center_pseudo_tiled; -bool honor_size_hints; +honor_size_hints_mode_t honor_size_hints; bool remove_disabled_monitors; bool remove_unplugged_monitors; diff --git a/src/settings.h b/src/settings.h index 248860d0..251c79ca 100644 --- a/src/settings.h +++ b/src/settings.h @@ -61,7 +61,7 @@ #define IGNORE_EWMH_STRUTS false #define CENTER_PSEUDO_TILED true -#define HONOR_SIZE_HINTS false +#define HONOR_SIZE_HINTS HONOR_SIZE_HINTS_NO #define MAPPING_EVENTS_COUNT 1 #define REMOVE_DISABLED_MONITORS false @@ -107,7 +107,7 @@ extern bool ignore_ewmh_struts; extern state_transition_t ignore_ewmh_fullscreen; extern bool center_pseudo_tiled; -extern bool honor_size_hints; +extern honor_size_hints_mode_t honor_size_hints; extern bool remove_disabled_monitors; extern bool remove_unplugged_monitors; diff --git a/src/tree.c b/src/tree.c index 4401e49b..52055c59 100644 --- a/src/tree.c +++ b/src/tree.c @@ -758,6 +758,7 @@ client_t *make_client(void) c->icccm_props.take_focus = false; c->icccm_props.delete_window = false; c->size_hints.flags = 0; + c->honor_size_hints = honor_size_hints; return c; } diff --git a/src/types.h b/src/types.h index c11b591c..96c3eeb9 100644 --- a/src/types.h +++ b/src/types.h @@ -50,6 +50,14 @@ typedef enum { SCHEME_SPIRAL } automatic_scheme_t; +typedef enum { + HONOR_SIZE_HINTS_NO = 0, + HONOR_SIZE_HINTS_YES, + HONOR_SIZE_HINTS_FLOATING, + HONOR_SIZE_HINTS_TILED, + HONOR_SIZE_HINTS_DEFAULT +} honor_size_hints_mode_t; + typedef enum { STATE_TILED, STATE_PSEUDO_TILED, @@ -224,6 +232,7 @@ typedef struct { stack_layer_t last_layer; xcb_rectangle_t floating_rectangle; xcb_rectangle_t tiled_rectangle; + honor_size_hints_mode_t honor_size_hints; xcb_size_hints_t size_hints; icccm_props_t icccm_props; wm_flags_t wm_flags; @@ -364,6 +373,7 @@ typedef struct { double split_ratio; stack_layer_t *layer; client_state_t *state; + honor_size_hints_mode_t honor_size_hints; bool hidden; bool sticky; bool private; diff --git a/src/window.c b/src/window.c index b45aab2d..7edf5d45 100644 --- a/src/window.c +++ b/src/window.c @@ -185,6 +185,10 @@ bool manage_window(xcb_window_t win, rule_consequence_t *csq, int fd) set_state(m, d, n, *(csq->state)); } + if (csq->honor_size_hints != HONOR_SIZE_HINTS_DEFAULT) { + c->honor_size_hints = csq->honor_size_hints; + } + set_hidden(m, d, n, csq->hidden); set_sticky(m, d, n, csq->sticky); set_private(m, d, n, csq->private); @@ -632,17 +636,13 @@ bool resize_client(coordinates_t *loc, resize_handle_t rh, int dx, int dy, bool /* taken from awesomeWM */ void apply_size_hints(client_t *c, uint16_t *width, uint16_t *height) { - if (!honor_size_hints) { + if (!SHOULD_HONOR_SIZE_HINTS(c->honor_size_hints, c->state)) { return; } int32_t minw = 0, minh = 0; int32_t basew = 0, baseh = 0, real_basew = 0, real_baseh = 0; - if (c->state == STATE_FULLSCREEN) { - return; - } - if (c->size_hints.flags & XCB_ICCCM_SIZE_HINT_BASE_SIZE) { basew = c->size_hints.base_width; baseh = c->size_hints.base_height; From 8fc2269fe0f29a785885bcd9122812eae7226d7b Mon Sep 17 00:00:00 2001 From: Bastien Dejean Date: Wed, 5 Apr 2023 10:25:49 +0200 Subject: [PATCH 14/15] Update manual --- doc/bspwm.1 | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/doc/bspwm.1 b/doc/bspwm.1 index 2be56f73..f034e8cf 100644 --- a/doc/bspwm.1 +++ b/doc/bspwm.1 @@ -4,10 +4,10 @@ .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 04/05/2023 .\" Manual: Bspwm Manual -.\" Source: Bspwm 0.9.10-48-gbcc8377 +.\" Source: Bspwm 0.9.10-49-gc58c67a .\" Language: English .\" -.TH "BSPWM" "1" "04/05/2023" "Bspwm 0\&.9\&.10\-48\-gbcc8377" "Bspwm Manual" +.TH "BSPWM" "1" "04/05/2023" "Bspwm 0\&.9\&.10\-49\-gc58c67a" "Bspwm Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -1066,7 +1066,7 @@ rule \fICOMMANDS\fR \fBCommands\fR .RS 4 .PP -\fB\-a\fR, \fB\-\-add\fR (|*)[:(|*)[:(|*)]] [\fB\-o\fR|\fB\-\-one\-shot\fR] [monitor=MONITOR_SEL|desktop=DESKTOP_SEL|node=NODE_SEL] [state=STATE] [layer=LAYER] [split_dir=DIR] [split_ratio=RATIO] [(hidden|sticky|private|locked|marked|center|follow|manage|focus|border)=(on|off)] [rectangle=WxH+X+Y] +\fB\-a\fR, \fB\-\-add\fR (|*)[:(|*)[:(|*)]] [\fB\-o\fR|\fB\-\-one\-shot\fR] [monitor=MONITOR_SEL|desktop=DESKTOP_SEL|node=NODE_SEL] [state=STATE] [layer=LAYER] [honor_size_hints=(true|false|tiled|floating)] [split_dir=DIR] [split_ratio=RATIO] [(hidden|sticky|private|locked|marked|center|follow|manage|focus|border)=(on|off)] [rectangle=WxH+X+Y] .RS 4 Create a new rule\&. Colons in the \fIinstance_name\fR, @@ -1371,11 +1371,6 @@ Center pseudo tiled windows into their tiling rectangles\&. Defaults to \fItrue\fR\&. .RE .PP -\fIhonor_size_hints\fR -.RS 4 -Apply ICCCM window size hints\&. -.RE -.PP \fIremove_disabled_monitors\fR .RS 4 Consider disabled monitors as disconnected\&. @@ -1408,6 +1403,16 @@ Size of the gap that separates windows\&. .RS 4 Window border width\&. .RE +.PP +\fIhonor_size_hints\fR +.RS 4 +If +\fItrue\fR, apply ICCCM window size hints to all windows\&. If +\fIfloating\fR, only apply them to floating and pseudo tiled windows\&. If +\fItiled\fR, only apply them to tiled windows\&. If +\fIfalse\fR, don\(cqt apply them\&. Defaults to +\fIfalse\fR\&. +.RE .SH "POINTER BINDINGS" .PP \fIclick_to_focus\fR From af3bd8b4351f4478fe0fe3cfd6c09e44cb108b4b Mon Sep 17 00:00:00 2001 From: Babakinha <59146844+Babakinha@users.noreply.github.com> Date: Tue, 20 Jun 2023 11:37:29 -0300 Subject: [PATCH 15/15] Account for border width in configure requests When moving and/or resizing managed floating windows. Fixes #863. Closes #1456. --- src/events.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/events.c b/src/events.c index 3e23c94e..8c9468ae 100644 --- a/src/events.c +++ b/src/events.c @@ -171,6 +171,9 @@ void configure_request(xcb_generic_event_t *evt) c->floating_rectangle.height = height; xcb_rectangle_t r = c->floating_rectangle; + r.x -= c->border_width; + r.y -= c->border_width; + window_move_resize(e->window, r.x, r.y, r.width, r.height); put_status(SBSC_MASK_NODE_GEOMETRY, "node_geometry 0x%08X 0x%08X 0x%08X %ux%u+%i+%i\n", loc.monitor->id, loc.desktop->id, e->window, r.width, r.height, r.x, r.y);