Add node modifiers: {descendant,ancestor}_of

Fixes #473.
This commit is contained in:
Bastien Dejean 2016-05-09 16:55:31 +02:00
parent bbc34068e7
commit e471298d0a
9 changed files with 242 additions and 189 deletions

View file

@ -4,10 +4,10 @@
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
.\" Date: 05/09/2016
.\" Manual: Bspwm Manual
.\" Source: Bspwm 0.9.1-54-gcdc20bb
.\" Source: Bspwm 0.9.1-56-gbbc3406
.\" Language: English
.\"
.TH "BSPWM" "1" "05/09/2016" "Bspwm 0\&.9\&.1\-54\-gcdc20bb" "Bspwm Manual"
.TH "BSPWM" "1" "05/09/2016" "Bspwm 0\&.9\&.1\-56\-gbbc3406" "Bspwm Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@ -94,7 +94,7 @@ Select a node\&.
.RS 4
.\}
.nf
NODE_SEL := (DIR|CYCLE_DIR|PATH|last|older|newer|focused|pointed|biggest|<node_id>)[\&.[!]focused][\&.[!]automatic][\&.[!]local][\&.[!]leaf][\&.[!]window][\&.[!]STATE][\&.[!]FLAG][\&.[!]LAYER][\&.[!]same_class]
NODE_SEL := (DIR|CYCLE_DIR|PATH|last|older|newer|focused|pointed|biggest|<node_id>)[\&.[!]focused][\&.[!]automatic][\&.[!]local][\&.[!]leaf][\&.[!]window][\&.[!]STATE][\&.[!]FLAG][\&.[!]LAYER][\&.[!]same_class][\&.[!]descendant_of][\&.[!]ancestor_of]
STATE := tiled|pseudo_tiled|floating|fullscreen
@ -120,12 +120,12 @@ JUMP := first|1|second|2|brother|parent|DIR
.PP
\fIDIR\fR
.RS 4
Selects the window in the given (spacial) direction relative to the active node\&.
Selects the window in the given (spacial) direction relative to the reference node\&.
.RE
.PP
\fICYCLE_DIR\fR
.RS 4
Selects the window in the given (cyclic) direction\&.
Selects the window in the given (cyclic) direction relative to the reference node\&.
.RE
.PP
\fIPATH\fR
@ -135,17 +135,17 @@ Selects the node at the given path\&.
.PP
last
.RS 4
Selects the previously focused node\&.
Selects the previously focused node relative to the reference node\&.
.RE
.PP
older
.RS 4
Selects the node older than the focused node in the history\&.
Selects the node older than the reference node in the history\&.
.RE
.PP
newer
.RS 4
Selects the node newer than the focused node in the history\&.
Selects the node newer than the reference node in the history\&.
.RE
.PP
focused
@ -160,7 +160,7 @@ Selects the window under the pointer\&.
.PP
biggest
.RS 4
Selects the biggest window on the current desktop\&.
Selects the biggest window\&.
.RE
.PP
<node_id>
@ -177,7 +177,7 @@ Selects the node with the given ID\&.
\fBPath Jumps\fR
.RS 4
.sp
The initial node is the focused node (or the root if the path starts with \fI/\fR) of the focused desktop (or the selected desktop if the path has a \fIDESKTOP_SEL\fR prefix)\&.
The initial node is the focused node (or the root if the path starts with \fI/\fR) of the reference desktop (or the selected desktop if the path has a \fIDESKTOP_SEL\fR prefix)\&.
.PP
1|first
.RS 4
@ -245,7 +245,17 @@ Only consider windows in or not in the given state\&.
.PP
[!]same_class
.RS 4
Only consider windows that have or don\(cqt have the same class as the current window\&.
Only consider windows that have or don\(cqt have the same class as the reference window\&.
.RE
.PP
[!]descendant_of
.RS 4
Only consider nodes that are or aren\(cqt descendants of the reference node\&.
.RE
.PP
[!]ancestor_of
.RS 4
Only consider nodes that are or aren\(cqt ancestors of the reference node\&.
.RE
.PP
[!](hidden|sticky|private|locked|urgent)
@ -793,17 +803,17 @@ query \fICOMMANDS\fR [\fIOPTIONS\fR]
\fBCommands\fR
.RS 4
.PP
\fB\-N\fR, \fB\-\-nodes\fR
\fB\-N\fR, \fB\-\-nodes\fR [\fINODE_SEL\fR]
.RS 4
List the IDs of the matching nodes\&.
.RE
.PP
\fB\-D\fR, \fB\-\-desktops\fR
\fB\-D\fR, \fB\-\-desktops\fR [\fIDESKTOP_SEL\fR]
.RS 4
List the IDs of the matching desktops\&.
.RE
.PP
\fB\-M\fR, \fB\-\-monitors\fR
\fB\-M\fR, \fB\-\-monitors\fR [\fIMONITOR_SEL\fR]
.RS 4
List the IDs of the matching monitors\&.
.RE

View file

@ -66,7 +66,7 @@ Node
Select a node.
----
NODE_SEL := (DIR|CYCLE_DIR|PATH|last|older|newer|focused|pointed|biggest|<node_id>)[.[!]focused][.[!]automatic][.[!]local][.[!]leaf][.[!]window][.[!]STATE][.[!]FLAG][.[!]LAYER][.[!]same_class]
NODE_SEL := (DIR|CYCLE_DIR|PATH|last|older|newer|focused|pointed|biggest|<node_id>)[.[!]focused][.[!]automatic][.[!]local][.[!]leaf][.[!]window][.[!]STATE][.[!]FLAG][.[!]LAYER][.[!]same_class][.[!]descendant_of][.[!]ancestor_of]
STATE := tiled|pseudo_tiled|floating|fullscreen
@ -83,22 +83,22 @@ Descriptors
^^^^^^^^^^^
'DIR'::
Selects the window in the given (spacial) direction relative to the active node.
Selects the window in the given (spacial) direction relative to the reference node.
'CYCLE_DIR'::
Selects the window in the given (cyclic) direction.
Selects the window in the given (cyclic) direction relative to the reference node.
'PATH'::
Selects the node at the given path.
last::
Selects the previously focused node.
Selects the previously focused node relative to the reference node.
older::
Selects the node older than the focused node in the history.
Selects the node older than the reference node in the history.
newer::
Selects the node newer than the focused node in the history.
Selects the node newer than the reference node in the history.
focused::
Selects the currently focused node.
@ -107,7 +107,7 @@ pointed::
Selects the window under the pointer.
biggest::
Selects the biggest window on the current desktop.
Selects the biggest window.
<node_id>::
Selects the node with the given ID.
@ -115,7 +115,7 @@ biggest::
Path Jumps
^^^^^^^^^^
The initial node is the focused node (or the root if the path starts with '/') of the focused desktop (or the selected desktop if the path has a 'DESKTOP_SEL' prefix).
The initial node is the focused node (or the root if the path starts with '/') of the reference desktop (or the selected desktop if the path has a 'DESKTOP_SEL' prefix).
1|first::
Jumps to the first child.
@ -154,7 +154,13 @@ Modifiers
Only consider windows in or not in the given state.
[!]same_class::
Only consider windows that have or don't have the same class as the current window.
Only consider windows that have or don't have the same class as the reference window.
[!]descendant_of::
Only consider nodes that are or aren't descendants of the reference node.
[!]ancestor_of::
Only consider nodes that are or aren't ancestors of the reference node.
[!](hidden|sticky|private|locked|urgent)::
Only consider windows that have or don't have the given flag set.
@ -473,13 +479,13 @@ query 'COMMANDS' ['OPTIONS']
Commands
^^^^^^^^
*-N*, *--nodes*::
*-N*, *--nodes* ['NODE_SEL']::
List the IDs of the matching nodes.
*-D*, *--desktops*::
*-D*, *--desktops* ['DESKTOP_SEL']::
List the IDs of the matching desktops.
*-M*, *--monitors*::
*-M*, *--monitors* ['MONITOR_SEL']::
List the IDs of the matching monitors.
*-T*, *--tree*::

View file

@ -123,11 +123,11 @@ void cmd_node(char **args, int num, FILE *rsp)
}
coordinates_t ref = {mon, mon->desk, mon->desk->focus};
coordinates_t trg = ref;
if ((*args)[0] != OPT_CHR) {
int ret;
if ((ret = node_from_desc(*args, &ref, &trg)) == SELECTOR_OK) {
coordinates_t tmp = ref;
if ((ret = node_from_desc(*args, &tmp, &ref)) == SELECTOR_OK) {
num--, args++;
} else {
handle_failure(ret, "node", *args, rsp);
@ -139,11 +139,11 @@ void cmd_node(char **args, int num, FILE *rsp)
while (num > 0) {
if (streq("-f", *args) || streq("--focus", *args)) {
coordinates_t dst = trg;
coordinates_t dst = ref;
if (num > 1 && *(args + 1)[0] != OPT_CHR) {
num--, args++;
int ret;
if ((ret = node_from_desc(*args, &trg, &dst)) != SELECTOR_OK) {
if ((ret = node_from_desc(*args, &ref, &dst)) != SELECTOR_OK) {
handle_failure(ret, "node -f", *args, rsp);
break;
}
@ -153,11 +153,11 @@ void cmd_node(char **args, int num, FILE *rsp)
break;
}
} else if (streq("-a", *args) || streq("--activate", *args)) {
coordinates_t dst = trg;
coordinates_t dst = ref;
if (num > 1 && *(args + 1)[0] != OPT_CHR) {
num--, args++;
int ret;
if ((ret = node_from_desc(*args, &trg, &dst)) != SELECTOR_OK) {
if ((ret = node_from_desc(*args, &ref, &dst)) != SELECTOR_OK) {
handle_failure(ret, "node -a", *args, rsp);
break;
}
@ -174,10 +174,10 @@ void cmd_node(char **args, int num, FILE *rsp)
}
coordinates_t dst;
int ret;
if ((ret = desktop_from_desc(*args, &trg, &dst)) == SELECTOR_OK) {
if (transfer_node(trg.monitor, trg.desktop, trg.node, dst.monitor, dst.desktop, dst.desktop->focus)) {
trg.monitor = dst.monitor;
trg.desktop = dst.desktop;
if ((ret = desktop_from_desc(*args, &ref, &dst)) == SELECTOR_OK) {
if (transfer_node(ref.monitor, ref.desktop, ref.node, dst.monitor, dst.desktop, dst.desktop->focus)) {
ref.monitor = dst.monitor;
ref.desktop = dst.desktop;
} else {
fail(rsp, "");
break;
@ -194,10 +194,10 @@ void cmd_node(char **args, int num, FILE *rsp)
}
coordinates_t dst;
int ret;
if ((ret = monitor_from_desc(*args, &trg, &dst)) == SELECTOR_OK) {
if (transfer_node(trg.monitor, trg.desktop, trg.node, dst.monitor, dst.monitor->desk, dst.monitor->desk->focus)) {
trg.monitor = dst.monitor;
trg.desktop = dst.monitor->desk;
if ((ret = monitor_from_desc(*args, &ref, &dst)) == SELECTOR_OK) {
if (transfer_node(ref.monitor, ref.desktop, ref.node, dst.monitor, dst.monitor->desk, dst.monitor->desk->focus)) {
ref.monitor = dst.monitor;
ref.desktop = dst.monitor->desk;
} else {
fail(rsp, "");
break;
@ -214,10 +214,10 @@ void cmd_node(char **args, int num, FILE *rsp)
}
coordinates_t dst;
int ret;
if ((ret = node_from_desc(*args, &trg, &dst)) == SELECTOR_OK) {
if (transfer_node(trg.monitor, trg.desktop, trg.node, dst.monitor, dst.desktop, dst.node)) {
trg.monitor = dst.monitor;
trg.desktop = dst.desktop;
if ((ret = node_from_desc(*args, &ref, &dst)) == SELECTOR_OK) {
if (transfer_node(ref.monitor, ref.desktop, ref.node, dst.monitor, dst.desktop, dst.node)) {
ref.monitor = dst.monitor;
ref.desktop = dst.desktop;
} else {
fail(rsp, "");
break;
@ -234,10 +234,10 @@ void cmd_node(char **args, int num, FILE *rsp)
}
coordinates_t dst;
int ret;
if ((ret = node_from_desc(*args, &trg, &dst)) == SELECTOR_OK) {
if (swap_nodes(trg.monitor, trg.desktop, trg.node, dst.monitor, dst.desktop, dst.node)) {
trg.monitor = dst.monitor;
trg.desktop = dst.desktop;
if ((ret = node_from_desc(*args, &ref, &dst)) == SELECTOR_OK) {
if (swap_nodes(ref.monitor, ref.desktop, ref.node, dst.monitor, dst.desktop, dst.node)) {
ref.monitor = dst.monitor;
ref.desktop = dst.desktop;
} else {
fail(rsp, "");
break;
@ -254,7 +254,7 @@ void cmd_node(char **args, int num, FILE *rsp)
}
stack_layer_t lyr;
if (parse_stack_layer(*args, &lyr)) {
if (!set_layer(trg.monitor, trg.desktop, trg.node, lyr)) {
if (!set_layer(ref.monitor, ref.desktop, ref.node, lyr)) {
fail(rsp, "");
break;
}
@ -275,11 +275,11 @@ void cmd_node(char **args, int num, FILE *rsp)
(*args)++;
}
if (parse_client_state(*args, &cst)) {
if (alternate && trg.node != NULL && trg.node->client != NULL &&
trg.node->client->state == cst) {
cst = trg.node->client->last_state;
if (alternate && ref.node != NULL && ref.node->client != NULL &&
ref.node->client->state == cst) {
cst = ref.node->client->last_state;
}
if (!set_state(trg.monitor, trg.desktop, trg.node, cst)) {
if (!set_state(ref.monitor, ref.desktop, ref.node, cst)) {
fail(rsp, "");
break;
}
@ -294,7 +294,7 @@ void cmd_node(char **args, int num, FILE *rsp)
fail(rsp, "node %s: Not enough arguments.\n", *(args - 1));
break;
}
if (trg.node == NULL) {
if (ref.node == NULL) {
fail(rsp, "");
break;
}
@ -313,14 +313,14 @@ void cmd_node(char **args, int num, FILE *rsp)
}
}
if (streq("hidden", key)) {
set_hidden(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->hidden));
set_hidden(ref.monitor, ref.desktop, ref.node, (a == ALTER_SET ? b : !ref.node->hidden));
changed = true;
} else if (streq("sticky", key)) {
set_sticky(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->sticky));
set_sticky(ref.monitor, ref.desktop, ref.node, (a == ALTER_SET ? b : !ref.node->sticky));
} else if (streq("private", key)) {
set_private(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->private));
set_private(ref.monitor, ref.desktop, ref.node, (a == ALTER_SET ? b : !ref.node->private));
} else if (streq("locked", key)) {
set_locked(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->locked));
set_locked(ref.monitor, ref.desktop, ref.node, (a == ALTER_SET ? b : !ref.node->locked));
} else {
fail(rsp, "node %s: Invalid key: '%s'.\n", *(args - 1), key);
break;
@ -331,12 +331,12 @@ void cmd_node(char **args, int num, FILE *rsp)
fail(rsp, "node %s: Not enough arguments.\n", *(args - 1));
break;
}
if (trg.node == NULL || trg.node->vacant) {
if (ref.node == NULL || ref.node->vacant) {
fail(rsp, "");
break;
}
if (streq("cancel", *args)) {
cancel_presel(trg.monitor, trg.desktop, trg.node);
cancel_presel(ref.monitor, ref.desktop, ref.node);
} else {
bool alternate = false;
if ((*args)[0] == '~') {
@ -345,12 +345,12 @@ void cmd_node(char **args, int num, FILE *rsp)
}
direction_t dir;
if (parse_direction(*args, &dir)) {
if (alternate && trg.node->presel != NULL && trg.node->presel->split_dir == dir) {
cancel_presel(trg.monitor, trg.desktop, trg.node);
if (alternate && ref.node->presel != NULL && ref.node->presel->split_dir == dir) {
cancel_presel(ref.monitor, ref.desktop, ref.node);
} else {
presel_dir(trg.monitor, trg.desktop, trg.node, dir);
if (!IS_RECEPTACLE(trg.node)) {
draw_presel_feedback(trg.monitor, trg.desktop, trg.node);
presel_dir(ref.monitor, ref.desktop, ref.node, dir);
if (!IS_RECEPTACLE(ref.node)) {
draw_presel_feedback(ref.monitor, ref.desktop, ref.node);
}
}
} else {
@ -364,7 +364,7 @@ void cmd_node(char **args, int num, FILE *rsp)
fail(rsp, "node %s: Not enough arguments.\n", *(args - 1));
break;
}
if (trg.node == NULL || trg.node->vacant) {
if (ref.node == NULL || ref.node->vacant) {
fail(rsp, "");
break;
}
@ -373,8 +373,8 @@ void cmd_node(char **args, int num, FILE *rsp)
fail(rsp, "node %s: Invalid argument: '%s'.\n", *(args - 1), *args);
break;
} else {
presel_ratio(trg.monitor, trg.desktop, trg.node, rat);
draw_presel_feedback(trg.monitor, trg.desktop, trg.node);
presel_ratio(ref.monitor, ref.desktop, ref.node, rat);
draw_presel_feedback(ref.monitor, ref.desktop, ref.node);
}
} else if (streq("-v", *args) || streq("--move", *args)) {
num--, args++;
@ -386,7 +386,7 @@ void cmd_node(char **args, int num, FILE *rsp)
if (sscanf(*args, "%i", &dx) == 1) {
num--, args++;
if (sscanf(*args, "%i", &dy) == 1) {
if (!move_client(&trg, dx, dy)) {
if (!move_client(&ref, dx, dy)) {
fail(rsp, "");
break;
}
@ -411,7 +411,7 @@ void cmd_node(char **args, int num, FILE *rsp)
if (sscanf(*args, "%i", &dx) == 1) {
num--, args++;
if (sscanf(*args, "%i", &dy) == 1) {
if (!resize_client(&trg, rh, dx, dy)) {
if (!resize_client(&ref, rh, dx, dy)) {
fail(rsp, "");
break;
}
@ -433,17 +433,17 @@ void cmd_node(char **args, int num, FILE *rsp)
fail(rsp, "node %s: Not enough arguments.\n", *(args - 1));
break;
}
if (trg.node == NULL) {
if (ref.node == NULL) {
fail(rsp, "");
break;
}
if ((*args)[0] == '+' || (*args)[0] == '-') {
int pix;
if (sscanf(*args, "%i", &pix) == 1) {
int max = (trg.node->split_type == TYPE_HORIZONTAL ? trg.node->rectangle.height : trg.node->rectangle.width);
double rat = ((max * trg.node->split_ratio) + pix) / max;
int max = (ref.node->split_type == TYPE_HORIZONTAL ? ref.node->rectangle.height : ref.node->rectangle.width);
double rat = ((max * ref.node->split_ratio) + pix) / max;
if (rat > 0 && rat < 1) {
set_ratio(trg.node, rat);
set_ratio(ref.node, rat);
} else {
fail(rsp, "");
break;
@ -455,7 +455,7 @@ 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);
set_ratio(ref.node, rat);
} else {
fail(rsp, "node %s: Invalid argument: '%s'.\n", *(args - 1), *args);
break;
@ -468,13 +468,13 @@ void cmd_node(char **args, int num, FILE *rsp)
fail(rsp, "node %s: Not enough arguments.\n", *(args - 1));
break;
}
if (trg.node == NULL) {
if (ref.node == NULL) {
fail(rsp, "");
break;
}
flip_t flp;
if (parse_flip(*args, &flp)) {
flip_tree(trg.node, flp);
flip_tree(ref.node, flp);
changed = true;
} else {
fail(rsp, "");
@ -486,31 +486,31 @@ void cmd_node(char **args, int num, FILE *rsp)
fail(rsp, "node %s: Not enough arguments.\n", *(args - 1));
break;
}
if (trg.node == NULL) {
if (ref.node == NULL) {
fail(rsp, "");
break;
}
int deg;
if (parse_degree(*args, &deg)) {
rotate_tree(trg.node, deg);
rotate_tree(ref.node, deg);
changed = true;
} else {
fail(rsp, "node %s: Invalid argument: '%s'.\n", *(args - 1), *args);
break;
}
} else if (streq("-E", *args) || streq("--equalize", *args)) {
if (trg.node == NULL) {
if (ref.node == NULL) {
fail(rsp, "");
break;
}
equalize_tree(trg.node);
equalize_tree(ref.node);
changed = true;
} else if (streq("-B", *args) || streq("--balance", *args)) {
if (trg.node == NULL) {
if (ref.node == NULL) {
fail(rsp, "");
break;
}
balance_tree(trg.node);
balance_tree(ref.node);
changed = true;
} else if (streq("-C", *args) || streq("--circulate", *args)) {
num--, args++;
@ -518,42 +518,42 @@ void cmd_node(char **args, int num, FILE *rsp)
fail(rsp, "node %s: Not enough arguments.\n", *(args - 1));
break;
}
if (trg.node == NULL) {
if (ref.node == NULL) {
fail(rsp, "");
break;
}
circulate_dir_t cir;
if (parse_circulate_direction(*args, &cir)) {
circulate_leaves(trg.monitor, trg.desktop, trg.node, cir);
circulate_leaves(ref.monitor, ref.desktop, ref.node, cir);
changed = true;
} else {
fail(rsp, "node %s: Invalid argument: '%s'.\n", *(args - 1), *args);
break;
}
} else if (streq("-i", *args) || streq("--insert-receptacle", *args)) {
insert_receptacle(trg.monitor, trg.desktop, trg.node);
insert_receptacle(ref.monitor, ref.desktop, ref.node);
changed = true;
} else if (streq("-c", *args) || streq("--close", *args)) {
if (num > 1) {
fail(rsp, "node %s: Trailing commands.\n", *args);
break;
}
if (trg.node == NULL || locked_count(trg.node) > 0) {
if (ref.node == NULL || locked_count(ref.node) > 0) {
fail(rsp, "");
break;
}
close_node(trg.node);
close_node(ref.node);
break;
} else if (streq("-k", *args) || streq("--kill", *args)) {
if (num > 1) {
fail(rsp, "node %s: Trailing commands.\n", *args);
break;
}
if (trg.node == NULL) {
if (ref.node == NULL) {
fail(rsp, "");
break;
}
kill_node(trg.monitor, trg.desktop, trg.node);
kill_node(ref.monitor, ref.desktop, ref.node);
changed = true;
break;
} else {
@ -565,7 +565,7 @@ void cmd_node(char **args, int num, FILE *rsp)
}
if (changed) {
arrange(trg.monitor, trg.desktop);
arrange(ref.monitor, ref.desktop);
}
}
@ -577,11 +577,11 @@ void cmd_desktop(char **args, int num, FILE *rsp)
}
coordinates_t ref = {mon, mon->desk, NULL};
coordinates_t trg = ref;
if ((*args)[0] != OPT_CHR) {
int ret;
if ((ret = desktop_from_desc(*args, &ref, &trg)) == SELECTOR_OK) {
coordinates_t tmp = ref;
if ((ret = desktop_from_desc(*args, &tmp, &ref)) == SELECTOR_OK) {
num--, args++;
} else {
handle_failure(ret, "desktop", *args, rsp);
@ -593,22 +593,22 @@ void cmd_desktop(char **args, int num, FILE *rsp)
while (num > 0) {
if (streq("-f", *args) || streq("--focus", *args)) {
coordinates_t dst = trg;
coordinates_t dst = ref;
if (num > 1 && *(args + 1)[0] != OPT_CHR) {
num--, args++;
int ret;
if ((ret = desktop_from_desc(*args, &trg, &dst)) != SELECTOR_OK) {
if ((ret = desktop_from_desc(*args, &ref, &dst)) != SELECTOR_OK) {
handle_failure(ret, "desktop -f", *args, rsp);
break;
}
}
focus_node(dst.monitor, dst.desktop, dst.desktop->focus);
} else if (streq("-a", *args) || streq("--activate", *args)) {
coordinates_t dst = trg;
coordinates_t dst = ref;
if (num > 1 && *(args + 1)[0] != OPT_CHR) {
num--, args++;
int ret;
if ((ret = desktop_from_desc(*args, &trg, &dst)) != SELECTOR_OK) {
if ((ret = desktop_from_desc(*args, &ref, &dst)) != SELECTOR_OK) {
handle_failure(ret, "desktop -a", *args, rsp);
break;
}
@ -623,15 +623,15 @@ void cmd_desktop(char **args, int num, FILE *rsp)
fail(rsp, "desktop %s: Not enough arguments.\n", *(args - 1));
break;
}
if (trg.monitor->desk_head == trg.monitor->desk_tail) {
if (ref.monitor->desk_head == ref.monitor->desk_tail) {
fail(rsp, "");
break;
}
coordinates_t dst;
int ret;
if ((ret = monitor_from_desc(*args, &trg, &dst)) == SELECTOR_OK) {
if (transfer_desktop(trg.monitor, dst.monitor, trg.desktop)) {
trg.monitor = dst.monitor;
if ((ret = monitor_from_desc(*args, &ref, &dst)) == SELECTOR_OK) {
if (transfer_desktop(ref.monitor, dst.monitor, ref.desktop)) {
ref.monitor = dst.monitor;
} else {
fail(rsp, "");
break;
@ -648,9 +648,9 @@ void cmd_desktop(char **args, int num, FILE *rsp)
}
coordinates_t dst;
int ret;
if ((ret = desktop_from_desc(*args, &trg, &dst)) == SELECTOR_OK) {
if (swap_desktops(trg.monitor, trg.desktop, dst.monitor, dst.desktop)) {
trg.monitor = dst.monitor;
if ((ret = desktop_from_desc(*args, &ref, &dst)) == SELECTOR_OK) {
if (swap_desktops(ref.monitor, ref.desktop, dst.monitor, dst.desktop)) {
ref.monitor = dst.monitor;
} else {
fail(rsp, "");
break;
@ -667,22 +667,22 @@ void cmd_desktop(char **args, int num, FILE *rsp)
}
cycle_dir_t cyc;
if (parse_cycle_direction(*args, &cyc)) {
desktop_t *d = trg.desktop;
desktop_t *d = ref.desktop;
if (cyc == CYCLE_PREV) {
if (d->prev == NULL) {
while (d->next != NULL) {
swap_desktops(trg.monitor, d, trg.monitor, d->next);
swap_desktops(ref.monitor, d, ref.monitor, d->next);
}
} else {
swap_desktops(trg.monitor, d, trg.monitor, d->prev);
swap_desktops(ref.monitor, d, ref.monitor, d->prev);
}
} else {
if (d->next == NULL) {
while (d->prev != NULL) {
swap_desktops(trg.monitor, d, trg.monitor, d->prev);
swap_desktops(ref.monitor, d, ref.monitor, d->prev);
}
} else {
swap_desktops(trg.monitor, d, trg.monitor, d->next);
swap_desktops(ref.monitor, d, ref.monitor, d->next);
}
}
} else {
@ -698,9 +698,9 @@ void cmd_desktop(char **args, int num, FILE *rsp)
layout_t lyt;
cycle_dir_t cyc;
if (parse_cycle_direction(*args, &cyc)) {
change_layout(trg.monitor, trg.desktop, (trg.desktop->layout + 1) % 2);
change_layout(ref.monitor, ref.desktop, (ref.desktop->layout + 1) % 2);
} else if (parse_layout(*args, &lyt)) {
change_layout(trg.monitor, trg.desktop, lyt);
change_layout(ref.monitor, ref.desktop, lyt);
} else {
fail(rsp, "desktop %s: Invalid argument: '%s'.\n", *(args - 1), *args);
break;
@ -711,15 +711,15 @@ void cmd_desktop(char **args, int num, FILE *rsp)
fail(rsp, "desktop %s: Not enough arguments.\n", *(args - 1));
break;
}
rename_desktop(trg.monitor, trg.desktop, *args);
rename_desktop(ref.monitor, ref.desktop, *args);
} else if (streq("-r", *args) || streq("--remove", *args)) {
if (num > 1) {
fail(rsp, "desktop %s: Trailing commands.\n", *args);
break;
}
if (trg.desktop->root == NULL &&
trg.monitor->desk_head != trg.monitor->desk_tail) {
remove_desktop(trg.monitor, trg.desktop);
if (ref.desktop->root == NULL &&
ref.monitor->desk_head != ref.monitor->desk_tail) {
remove_desktop(ref.monitor, ref.desktop);
return;
} else {
fail(rsp, "");
@ -733,7 +733,7 @@ void cmd_desktop(char **args, int num, FILE *rsp)
}
if (changed) {
arrange(trg.monitor, trg.desktop);
arrange(ref.monitor, ref.desktop);
}
}
@ -745,11 +745,11 @@ void cmd_monitor(char **args, int num, FILE *rsp)
}
coordinates_t ref = {mon, NULL, NULL};
coordinates_t trg = ref;
if ((*args)[0] != OPT_CHR) {
int ret;
if ((ret = monitor_from_desc(*args, &ref, &trg)) == SELECTOR_OK) {
coordinates_t tmp = ref;
if ((ret = monitor_from_desc(*args, &tmp, &ref)) == SELECTOR_OK) {
num--, args++;
} else {
handle_failure(ret, "monitor", *args, rsp);
@ -759,11 +759,11 @@ void cmd_monitor(char **args, int num, FILE *rsp)
while (num > 0) {
if (streq("-f", *args) || streq("--focus", *args)) {
coordinates_t dst = trg;
coordinates_t dst = ref;
if (num > 1 && *(args + 1)[0] != OPT_CHR) {
num--, args++;
int ret;
if ((ret = monitor_from_desc(*args, &trg, &dst)) != SELECTOR_OK) {
if ((ret = monitor_from_desc(*args, &ref, &dst)) != SELECTOR_OK) {
handle_failure(ret, "monitor -f", *args, rsp);
fail(rsp, "");
return;
@ -776,24 +776,24 @@ void cmd_monitor(char **args, int num, FILE *rsp)
fail(rsp, "monitor %s: Not enough arguments.\n", *(args - 1));
return;
}
desktop_t *d = trg.monitor->desk_head;
desktop_t *d = ref.monitor->desk_head;
while (num > 0 && d != NULL) {
rename_desktop(trg.monitor, d, *args);
rename_desktop(ref.monitor, d, *args);
d = d->next;
num--, args++;
}
put_status(SBSC_MASK_REPORT);
while (num > 0) {
add_desktop(trg.monitor, make_desktop(*args, XCB_NONE));
add_desktop(ref.monitor, make_desktop(*args, XCB_NONE));
num--, args++;
}
while (d != NULL) {
desktop_t *next = d->next;
if (d == mon->desk) {
focus_node(trg.monitor, d->prev, d->prev->focus);
focus_node(ref.monitor, d->prev, d->prev->focus);
}
merge_desktops(trg.monitor, d, mon, mon->desk);
remove_desktop(trg.monitor, d);
merge_desktops(ref.monitor, d, mon, mon->desk);
remove_desktop(ref.monitor, d);
d = next;
}
} else if (streq("-a", *args) || streq("--add-desktops", *args)) {
@ -803,7 +803,7 @@ void cmd_monitor(char **args, int num, FILE *rsp)
return;
}
while (num > 0) {
add_desktop(trg.monitor, make_desktop(*args, XCB_NONE));
add_desktop(ref.monitor, make_desktop(*args, XCB_NONE));
num--, args++;
}
} else if (streq("-r", *args) || streq("--remove", *args)) {
@ -815,7 +815,7 @@ void cmd_monitor(char **args, int num, FILE *rsp)
fail(rsp, "");
return;
}
remove_monitor(trg.monitor);
remove_monitor(ref.monitor);
return;
} else if (streq("-o", *args) || streq("--order-desktops", *args)) {
num--, args++;
@ -823,12 +823,12 @@ void cmd_monitor(char **args, int num, FILE *rsp)
fail(rsp, "monitor %s: Not enough arguments.\n", *(args - 1));
return;
}
desktop_t *d = trg.monitor->desk_head;
desktop_t *d = ref.monitor->desk_head;
while (d != NULL && num > 0) {
desktop_t *next = d->next;
coordinates_t dst;
if (locate_desktop(*args, &dst) && dst.monitor == trg.monitor) {
swap_desktops(trg.monitor, d, dst.monitor, dst.desktop);
if (locate_desktop(*args, &dst) && dst.monitor == ref.monitor) {
swap_desktops(ref.monitor, d, dst.monitor, dst.desktop);
if (next == dst.desktop) {
next = d;
}
@ -844,7 +844,7 @@ void cmd_monitor(char **args, int num, FILE *rsp)
}
xcb_rectangle_t r;
if (parse_rectangle(*args, &r)) {
update_root(trg.monitor, &r);
update_root(ref.monitor, &r);
} else {
fail(rsp, "monitor %s: Invalid argument: '%s'.\n", *(args - 1), *args);
return;
@ -855,7 +855,7 @@ void cmd_monitor(char **args, int num, FILE *rsp)
fail(rsp, "monitor %s: Not enough arguments.\n", *(args - 1));
return;
}
rename_monitor(trg.monitor, *args);
rename_monitor(ref.monitor, *args);
} else if (streq("-s", *args) || streq("--swap", *args)) {
num--, args++;
if (num < 1) {
@ -864,8 +864,8 @@ void cmd_monitor(char **args, int num, FILE *rsp)
}
coordinates_t dst;
int ret;
if ((ret = monitor_from_desc(*args, &trg, &dst)) == SELECTOR_OK) {
if (!swap_monitors(trg.monitor, dst.monitor)) {
if ((ret = monitor_from_desc(*args, &ref, &dst)) == SELECTOR_OK) {
if (!swap_monitors(ref.monitor, dst.monitor)) {
fail(rsp, "");
return;
}
@ -901,10 +901,37 @@ void cmd_query(char **args, int num, FILE *rsp)
dom = DOMAIN_TREE, d++;
} else if (streq("-M", *args) || streq("--monitors", *args)) {
dom = DOMAIN_MONITOR, d++;
if (num > 1 && *(args + 1)[0] != OPT_CHR) {
num--, args++;
int ret;
coordinates_t tmp = ref;
if ((ret = monitor_from_desc(*args, &tmp, &ref)) != SELECTOR_OK) {
handle_failure(ret, "query -M", *args, rsp);
break;
}
}
} else if (streq("-D", *args) || streq("--desktops", *args)) {
dom = DOMAIN_DESKTOP, d++;
if (num > 1 && *(args + 1)[0] != OPT_CHR) {
num--, args++;
int ret;
coordinates_t tmp = ref;
if ((ret = desktop_from_desc(*args, &tmp, &ref)) != SELECTOR_OK) {
handle_failure(ret, "query -D", *args, rsp);
break;
}
}
} else if (streq("-N", *args) || streq("--nodes", *args)) {
dom = DOMAIN_NODE, d++;
if (num > 1 && *(args + 1)[0] != OPT_CHR) {
num--, args++;
int ret;
coordinates_t tmp = ref;
if ((ret = node_from_desc(*args, &tmp, &ref)) != SELECTOR_OK) {
handle_failure(ret, "query -N", *args, rsp);
break;
}
}
} else if (streq("-m", *args) || streq("--monitor", *args)) {
if (num > 1 && *(args + 1)[0] != OPT_CHR) {
num--, args++;
@ -999,15 +1026,15 @@ void cmd_query(char **args, int num, FILE *rsp)
}
if (dom == DOMAIN_NODE) {
if (query_node_ids(trg, node_sel, rsp) < 1) {
if (query_node_ids(&ref, &trg, node_sel, rsp) < 1) {
fail(rsp, "");
}
} else if (dom == DOMAIN_DESKTOP) {
if (query_desktop_ids(trg, desktop_sel, rsp) < 1) {
if (query_desktop_ids(&ref, &trg, desktop_sel, rsp) < 1) {
fail(rsp, "");
}
} else if (dom == DOMAIN_MONITOR) {
if (query_monitor_ids(trg, monitor_sel, rsp) < 1) {
if (query_monitor_ids(&ref, &trg, monitor_sel, rsp) < 1) {
fail(rsp, "");
}
} else {

View file

@ -447,6 +447,8 @@ bool parse_node_modifiers(char *desc, node_select_t *sel)
GET_MOD(locked)
GET_MOD(urgent)
GET_MOD(same_class)
GET_MOD(descendant_of)
GET_MOD(ancestor_of)
GET_MOD(below)
GET_MOD(normal)
GET_MOD(above)

66
query.c
View file

@ -212,54 +212,52 @@ void query_stack(FILE *rsp)
fprintf(rsp, "]");
}
int query_node_ids(coordinates_t loc, node_select_t *sel, FILE *rsp)
int query_node_ids(coordinates_t *ref, coordinates_t *trg, node_select_t *sel, FILE *rsp)
{
int count = 0;
for (monitor_t *m = mon_head; m != NULL; m = m->next) {
if (loc.monitor != NULL && m != loc.monitor) {
if (trg->monitor != NULL && m != trg->monitor) {
continue;
}
for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
if (loc.desktop != NULL && d != loc.desktop) {
if (trg->desktop != NULL && d != trg->desktop) {
continue;
}
count += query_node_ids_in(d->root, d, m, loc, sel, rsp);
count += query_node_ids_in(d->root, d, m, ref, trg, sel, rsp);
}
}
return count;
}
int query_node_ids_in(node_t *n, desktop_t *d, monitor_t *m, coordinates_t loc, node_select_t *sel, FILE *rsp)
int query_node_ids_in(node_t *n, desktop_t *d, monitor_t *m, coordinates_t *ref, coordinates_t *trg, node_select_t *sel, FILE *rsp)
{
int count = 0;
if (n == NULL) {
return 0;
} else {
coordinates_t ref = {mon, mon->desk, mon->desk->focus};
coordinates_t trg = {m, d, n};
if ((loc.node == NULL || n == loc.node) &&
(sel == NULL || node_matches(&trg, &ref, *sel))) {
coordinates_t loc = {m, d, n};
if ((trg->node == NULL || n == trg->node) &&
(sel == NULL || node_matches(&loc, ref, *sel))) {
fprintf(rsp, "0x%08X\n", n->id);
count++;
}
count += query_node_ids_in(n->first_child, d, m, loc, sel, rsp);
count += query_node_ids_in(n->second_child, d, m, loc, sel, rsp);
count += query_node_ids_in(n->first_child, d, m, ref, trg, sel, rsp);
count += query_node_ids_in(n->second_child, d, m, ref, trg, sel, rsp);
}
return count;
}
int query_desktop_ids(coordinates_t loc, desktop_select_t *sel, FILE *rsp)
int query_desktop_ids(coordinates_t *ref, coordinates_t *trg, desktop_select_t *sel, FILE *rsp)
{
int count = 0;
for (monitor_t *m = mon_head; m != NULL; m = m->next) {
if (loc.monitor != NULL && m != loc.monitor) {
if (trg->monitor != NULL && m != trg->monitor) {
continue;
}
for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
coordinates_t ref = {mon, mon->desk, NULL};
coordinates_t trg = {m, d, NULL};
if ((loc.desktop != NULL && d != loc.desktop) ||
(sel != NULL && !desktop_matches(&trg, &ref, *sel))) {
coordinates_t loc = {m, d, NULL};
if ((trg->desktop != NULL && d != trg->desktop) ||
(sel != NULL && !desktop_matches(&loc, ref, *sel))) {
continue;
}
fprintf(rsp, "0x%08X\n", d->id);
@ -269,14 +267,13 @@ int query_desktop_ids(coordinates_t loc, desktop_select_t *sel, FILE *rsp)
return count;
}
int query_monitor_ids(coordinates_t loc, monitor_select_t *sel, FILE *rsp)
int query_monitor_ids(coordinates_t *ref, coordinates_t *trg, monitor_select_t *sel, FILE *rsp)
{
int count = 0;
for (monitor_t *m = mon_head; m != NULL; m = m->next) {
coordinates_t ref = {mon, NULL, NULL};
coordinates_t trg = {m, NULL, NULL};
if ((loc.monitor != NULL && m != loc.monitor) ||
(sel != NULL && !monitor_matches(&trg, &ref, *sel))) {
coordinates_t loc = {m, NULL, NULL};
if ((trg->monitor != NULL && m != trg->monitor) ||
(sel != NULL && !monitor_matches(&loc, ref, *sel))) {
continue;
}
fprintf(rsp, "0x%08X\n", m->id);
@ -351,6 +348,8 @@ node_select_t make_node_select(void)
.locked = OPTION_NONE,
.urgent = OPTION_NONE,
.same_class = OPTION_NONE,
.descendant_of = OPTION_NONE,
.ancestor_of = OPTION_NONE,
.below = OPTION_NONE,
.normal = OPTION_NONE,
.above = OPTION_NONE
@ -390,8 +389,6 @@ int node_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
return SELECTOR_BAD_MODIFIERS;
}
dst->monitor = ref->monitor;
dst->desktop = ref->desktop;
dst->node = NULL;
direction_t dir;
@ -406,7 +403,7 @@ int node_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
} else if (streq("last", desc)) {
history_find_node(HISTORY_OLDER, ref, dst, sel);
} else if (streq("biggest", desc)) {
dst->node = find_biggest(ref->monitor, ref->desktop, ref->node, sel);
find_biggest(ref, dst, sel);
} else if (streq("pointed", desc)) {
xcb_window_t win;
query_pointer(&win, NULL);
@ -418,12 +415,11 @@ int node_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
} else if (streq("focused", desc)) {
coordinates_t loc = {mon, mon->desk, mon->desk->focus};
if (node_matches(&loc, ref, sel)) {
dst->monitor = mon;
dst->desktop = mon->desk;
dst->node = mon->desk->focus;
*dst = loc;
}
} else if (*desc == '@') {
desc++;
*dst = *ref;
if (colon != NULL) {
*colon = '\0';
int ret;
@ -836,6 +832,20 @@ bool node_matches(coordinates_t *loc, coordinates_t *ref, node_select_t sel)
return false;
}
if (sel.descendant_of != OPTION_NONE &&
!is_descendant(loc->node, ref->node)
? sel.descendant_of == OPTION_TRUE
: sel.descendant_of == OPTION_FALSE) {
return false;
}
if (sel.ancestor_of != OPTION_NONE &&
!is_descendant(ref->node, loc->node)
? sel.ancestor_of == OPTION_TRUE
: sel.ancestor_of == OPTION_FALSE) {
return false;
}
#define WSTATE(p, e) \
if (sel.p != OPTION_NONE && \
loc->node->client->state != e \

View file

@ -52,10 +52,10 @@ void query_padding(padding_t p, FILE *rsp);
void query_history(FILE *rsp);
void query_coordinates(coordinates_t *loc, FILE *rsp);
void query_stack(FILE *rsp);
int query_node_ids(coordinates_t loc, node_select_t *sel, FILE *rsp);
int query_node_ids_in(node_t *n, desktop_t *d, monitor_t *m, coordinates_t loc, node_select_t *sel, FILE *rsp);
int query_desktop_ids(coordinates_t loc, desktop_select_t *sel, FILE *rsp);
int query_monitor_ids(coordinates_t loc, monitor_select_t *sel, FILE *rsp);
int query_node_ids(coordinates_t *ref, coordinates_t *trg, node_select_t *sel, FILE *rsp);
int query_node_ids_in(node_t *n, desktop_t *d, monitor_t *m, coordinates_t *ref, coordinates_t *trg, node_select_t *sel, FILE *rsp);
int query_desktop_ids(coordinates_t *ref, coordinates_t *trg, desktop_select_t *sel, FILE *rsp);
int query_monitor_ids(coordinates_t *ref, coordinates_t *trg, monitor_select_t *sel, FILE *rsp);
void print_modifier_mask(uint16_t m, FILE *rsp);
void print_pointer_action(pointer_action_t a, FILE *rsp);
node_select_t make_node_select(void);

32
tree.c
View file

@ -968,29 +968,25 @@ int tiled_count(node_t *n)
return cnt;
}
node_t *find_biggest(monitor_t *m, desktop_t *d, node_t *n, node_select_t sel)
void find_biggest(coordinates_t *ref, coordinates_t *dst, node_select_t sel)
{
if (d == NULL) {
return NULL;
}
node_t *b = NULL;
unsigned int b_area = 0;
coordinates_t ref = {m, d, n};
for (node_t *f = first_extrema(d->root); f != NULL; f = next_leaf(f, d->root)) {
coordinates_t loc = {m, d, f};
if (f->client == NULL || f->vacant || !node_matches(&loc, &ref, sel)) {
continue;
}
unsigned int f_area = node_area(d, f);
if (f_area > b_area) {
b = f;
b_area = f_area;
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 *f = first_extrema(d->root); f != NULL; f = next_leaf(f, d->root)) {
coordinates_t loc = {m, d, f};
if (f->client == NULL || f->vacant || !node_matches(&loc, ref, sel)) {
continue;
}
unsigned int f_area = node_area(d, f);
if (f_area > b_area) {
*dst = loc;
b_area = f_area;
}
}
}
}
return b;
}
void rotate_tree(node_t *n, int deg)

2
tree.h
View file

@ -66,7 +66,7 @@ node_t *find_by_id_in(node_t *r, uint32_t id);
void find_nearest_neighbor(coordinates_t *ref, coordinates_t *dst, direction_t dir, node_select_t sel);
unsigned int node_area(desktop_t *d, node_t *n);
int tiled_count(node_t *n);
node_t *find_biggest(monitor_t *m, desktop_t *d, node_t *n, node_select_t sel);
void find_biggest(coordinates_t *ref, coordinates_t *dst, node_select_t sel);
void rotate_tree(node_t *n, int deg);
void rotate_brother(node_t *n);
void unrotate_tree(node_t *n, int rot);

View file

@ -154,6 +154,8 @@ typedef struct {
option_bool_t locked;
option_bool_t urgent;
option_bool_t same_class;
option_bool_t descendant_of;
option_bool_t ancestor_of;
option_bool_t below;
option_bool_t normal;
option_bool_t above;