Make following optional

Fixes #758.
This commit is contained in:
Bastien Dejean 2018-01-14 22:32:11 +01:00
parent 0ba0ca3426
commit cba737e778
15 changed files with 218 additions and 118 deletions

View file

@ -2,12 +2,12 @@
.\" Title: bspwm
.\" Author: [see the "Author" section]
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
.\" Date: 09/29/2017
.\" Date: 01/14/2018
.\" Manual: Bspwm Manual
.\" Source: Bspwm 0.9.3-30-gd953f6f
.\" Source: Bspwm 0.9.3-42-g0ba0ca3
.\" Language: English
.\"
.TH "BSPWM" "1" "09/29/2017" "Bspwm 0\&.9\&.3\-30\-gd953f6f" "Bspwm Manual"
.TH "BSPWM" "1" "01/14/2018" "Bspwm 0\&.9\&.3\-42\-g0ba0ca3" "Bspwm Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@ -570,24 +570,32 @@ Focus the selected or given node\&.
Activate the selected or given node\&.
.RE
.PP
\fB\-d\fR, \fB\-\-to\-desktop\fR \fIDESKTOP_SEL\fR
\fB\-d\fR, \fB\-\-to\-desktop\fR \fIDESKTOP_SEL\fR [\fB\-\-follow\fR]
.RS 4
Send the selected node to the given desktop\&.
Send the selected node to the given desktop\&. If
\fB\-\-follow\fR
is passed, the focused node will stay focused\&.
.RE
.PP
\fB\-m\fR, \fB\-\-to\-monitor\fR \fIMONITOR_SEL\fR
\fB\-m\fR, \fB\-\-to\-monitor\fR \fIMONITOR_SEL\fR [\fB\-\-follow\fR]
.RS 4
Send the selected node to the given monitor\&.
Send the selected node to the given monitor\&. If
\fB\-\-follow\fR
is passed, the focused node will stay focused\&.
.RE
.PP
\fB\-n\fR, \fB\-\-to\-node\fR \fINODE_SEL\fR
\fB\-n\fR, \fB\-\-to\-node\fR \fINODE_SEL\fR [\fB\-\-follow\fR]
.RS 4
Transplant the selected node to the given node\&.
Send the selected node on the given node\&. If
\fB\-\-follow\fR
is passed, the focused node will stay focused\&.
.RE
.PP
\fB\-s\fR, \fB\-\-swap\fR \fINODE_SEL\fR
\fB\-s\fR, \fB\-\-swap\fR \fINODE_SEL\fR [\fB\-\-follow\fR]
.RS 4
Swap the selected node with the given node\&.
Swap the selected node with the given node\&. If
\fB\-\-follow\fR
is passed, the focused node will stay focused\&.
.RE
.PP
\fB\-p\fR, \fB\-\-presel\-dir\fR [~]\fIDIR\fR|cancel
@ -721,9 +729,18 @@ Focus the selected or given desktop\&.
Activate the selected or given desktop\&.
.RE
.PP
\fB\-m\fR, \fB\-\-to\-monitor\fR \fIMONITOR_SEL\fR
\fB\-m\fR, \fB\-\-to\-monitor\fR \fIMONITOR_SEL\fR [\fB\-\-follow\fR]
.RS 4
Send the selected desktop to the given monitor\&.
Send the selected desktop to the given monitor\&. If
\fB\-\-follow\fR
is passed, the focused desktop will stay focused\&.
.RE
.PP
\fB\-s\fR, \fB\-\-swap\fR \fIDESKTOP_SEL\fR [\fB\-\-follow\fR]
.RS 4
Swap the selected desktop with the given desktop\&. If
\fB\-\-follow\fR
is passed, the focused desktop will stay focused\&.
.RE
.PP
\fB\-l\fR, \fB\-\-layout\fR \fICYCLE_DIR\fR|monocle|tiled
@ -736,11 +753,6 @@ Set or cycle the layout of the selected desktop\&.
Rename the selected desktop\&.
.RE
.PP
\fB\-s\fR, \fB\-\-swap\fR \fIDESKTOP_SEL\fR
.RS 4
Swap the selected desktop with the given desktop\&.
.RE
.PP
\fB\-b\fR, \fB\-\-bubble\fR \fICYCLE_DIR\fR
.RS 4
Bubble the selected desktop in the given direction\&.

View file

@ -358,17 +358,17 @@ Commands
*-a*, *--activate* ['NODE_SEL']::
Activate the selected or given node.
*-d*, *--to-desktop* 'DESKTOP_SEL'::
Send the selected node to the given desktop.
*-d*, *--to-desktop* 'DESKTOP_SEL' [*--follow*]::
Send the selected node to the given desktop. If *--follow* is passed, the focused node will stay focused.
*-m*, *--to-monitor* 'MONITOR_SEL'::
Send the selected node to the given monitor.
*-m*, *--to-monitor* 'MONITOR_SEL' [*--follow*]::
Send the selected node to the given monitor. If *--follow* is passed, the focused node will stay focused.
*-n*, *--to-node* 'NODE_SEL'::
Transplant the selected node to the given node.
*-n*, *--to-node* 'NODE_SEL' [*--follow*]::
Send the selected node on the given node. If *--follow* is passed, the focused node will stay focused.
*-s*, *--swap* 'NODE_SEL'::
Swap the selected node with the given node.
*-s*, *--swap* 'NODE_SEL' [*--follow*]::
Swap the selected node with the given node. If *--follow* is passed, the focused node will stay focused.
*-p*, *--presel-dir* \[~]'DIR'|cancel::
Preselect the splitting area of the selected node (or cancel the preselection). If *~* is prepended to 'DIR' and the current preselection direction matches 'DIR', then the argument is interpreted as *cancel*. A node with a preselected area is said to be in "manual insertion mode".
@ -436,8 +436,11 @@ COMMANDS
*-a*, *--activate* ['DESKTOP_SEL']::
Activate the selected or given desktop.
*-m*, *--to-monitor* 'MONITOR_SEL'::
Send the selected desktop to the given monitor.
*-m*, *--to-monitor* 'MONITOR_SEL' [*--follow*]::
Send the selected desktop to the given monitor. If *--follow* is passed, the focused desktop will stay focused.
*-s*, *--swap* 'DESKTOP_SEL' [*--follow*]::
Swap the selected desktop with the given desktop. If *--follow* is passed, the focused desktop will stay focused.
*-l*, *--layout* 'CYCLE_DIR'|monocle|tiled::
Set or cycle the layout of the selected desktop.
@ -445,9 +448,6 @@ COMMANDS
*-n*, *--rename* <new_name>::
Rename the selected desktop.
*-s*, *--swap* 'DESKTOP_SEL'::
Swap the selected desktop with the given desktop.
*-b*, *--bubble* 'CYCLE_DIR'::
Bubble the selected desktop in the given direction.

View file

@ -151,7 +151,7 @@ void handle_presel_feedbacks(monitor_t *m, desktop_t *d)
}
}
bool transfer_desktop(monitor_t *ms, monitor_t *md, desktop_t *d)
bool transfer_desktop(monitor_t *ms, monitor_t *md, desktop_t *d, bool follow)
{
if (ms == NULL || md == NULL || d == NULL || ms == md) {
return false;
@ -162,7 +162,7 @@ bool transfer_desktop(monitor_t *ms, monitor_t *md, desktop_t *d)
unlink_desktop(ms, d);
if (md->desk != NULL) {
if ((!follow || !d_was_active || !ms_was_focused) && md->desk != NULL) {
hide_desktop(d);
}
@ -170,11 +170,19 @@ bool transfer_desktop(monitor_t *ms, monitor_t *md, desktop_t *d)
history_transfer_desktop(md, d);
if (d_was_active) {
if (activate_desktop(ms, NULL)) {
activate_node(ms, ms->desk, NULL);
}
if (ms_was_focused) {
focus_node(md, d, d->focus);
if (follow) {
if (activate_desktop(ms, NULL)) {
activate_node(ms, ms->desk, NULL);
}
if (ms_was_focused) {
focus_node(md, d, d->focus);
}
} else {
if (ms_was_focused) {
focus_node(ms, ms->desk, NULL);
} else if (activate_desktop(ms, NULL)) {
activate_node(ms, ms->desk, NULL);
}
}
}
@ -187,8 +195,12 @@ bool transfer_desktop(monitor_t *ms, monitor_t *md, desktop_t *d)
adapt_geometry(&ms->rectangle, &md->rectangle, d->root);
arrange(md, d);
if (md->desk == d && mon != md) {
activate_node(md, d, d->focus);
if ((!follow || !d_was_active || !ms_was_focused) && md->desk == d) {
if (md == mon) {
focus_node(md, d, d->focus);
} else {
activate_node(md, d, d->focus);
}
}
ewmh_update_wm_desktops();
@ -332,10 +344,10 @@ void merge_desktops(monitor_t *ms, desktop_t *ds, monitor_t *md, desktop_t *dd)
if (ds == NULL || dd == NULL || ds == dd) {
return;
}
transfer_node(ms, ds, ds->root, md, dd, dd->focus);
transfer_node(ms, ds, ds->root, md, dd, dd->focus, false);
}
bool swap_desktops(monitor_t *m1, desktop_t *d1, monitor_t *m2, desktop_t *d2)
bool swap_desktops(monitor_t *m1, desktop_t *d1, monitor_t *m2, desktop_t *d2, bool follow)
{
if (d1 == NULL || d2 == NULL || d1 == d2 ||
(m1->desk == d1 && m1->sticky_count > 0) ||
@ -419,23 +431,41 @@ bool swap_desktops(monitor_t *m1, desktop_t *d1, monitor_t *m2, desktop_t *d2)
}
if (d1_was_active && !d2_was_active) {
hide_desktop(d1);
if ((!follow && m1 != m2) || !d1_was_focused) {
hide_desktop(d1);
}
show_desktop(d2);
} else if (!d1_was_active && d2_was_active) {
show_desktop(d1);
hide_desktop(d2);
if ((!follow && m1 != m2) || !d2_was_focused) {
hide_desktop(d2);
}
}
if (d1_was_focused) {
focus_node(m2, d1, d1->focus);
} else if (d1 == m2->desk) {
activate_node(m2, d1, d1->focus);
}
if (follow || m1 == m2) {
if (d1_was_focused) {
focus_node(m2, d1, d1->focus);
} else if (d1_was_active) {
activate_node(m2, d1, d1->focus);
}
if (d2_was_focused) {
focus_node(m1, d2, d2->focus);
} else if (d2 == m1->desk) {
activate_node(m1, d2, d2->focus);
if (d2_was_focused) {
focus_node(m1, d2, d2->focus);
} else if (d2_was_active) {
activate_node(m1, d2, d2->focus);
}
} else {
if (d1_was_focused) {
focus_node(m1, d2, d2->focus);
} else if (d1_was_active) {
activate_node(m1, d2, d2->focus);
}
if (d2_was_focused) {
focus_node(m2, d1, d1->focus);
} else if (d2_was_active) {
activate_node(m2, d1, d1->focus);
}
}
ewmh_update_wm_desktops();

View file

@ -32,7 +32,7 @@ bool activate_desktop(monitor_t *m, desktop_t *d);
bool find_closest_desktop(coordinates_t *ref, coordinates_t *dst, cycle_dir_t dir, desktop_select_t sel);
bool set_layout(monitor_t *m, desktop_t *d, layout_t l);
void handle_presel_feedbacks(monitor_t *m, desktop_t *d);
bool transfer_desktop(monitor_t *ms, monitor_t *md, desktop_t *d);
bool transfer_desktop(monitor_t *ms, monitor_t *md, desktop_t *d, bool follow);
desktop_t *make_desktop(const char *name, uint32_t id);
void rename_desktop(monitor_t *m, desktop_t *d, const char *name);
void insert_desktop(monitor_t *m, desktop_t *d);
@ -41,7 +41,7 @@ desktop_t *find_desktop_in(uint32_t id, monitor_t *m);
void unlink_desktop(monitor_t *m, desktop_t *d);
void remove_desktop(monitor_t *m, desktop_t *d);
void merge_desktops(monitor_t *ms, desktop_t *ds, monitor_t *md, desktop_t *dd);
bool swap_desktops(monitor_t *m1, desktop_t *d1, monitor_t *m2, desktop_t *d2);
bool swap_desktops(monitor_t *m1, desktop_t *d1, monitor_t *m2, desktop_t *d2, bool follow);
void show_desktop(desktop_t *d);
void hide_desktop(desktop_t *d);
bool is_urgent(desktop_t *d);

View file

@ -171,7 +171,7 @@ void configure_request(xcb_generic_event_t *evt)
monitor_t *m = monitor_from_client(c);
if (m != loc.monitor) {
transfer_node(loc.monitor, loc.desktop, loc.node, m, m->desk, m->desk->focus);
transfer_node(loc.monitor, loc.desktop, loc.node, m, m->desk, m->desk->focus, false);
}
} else {
if (c->state == STATE_PSEUDO_TILED) {
@ -315,7 +315,7 @@ void client_message(xcb_generic_event_t *evt)
} else if (e->type == ewmh->_NET_WM_DESKTOP) {
coordinates_t dloc;
if (ewmh_locate_desktop(e->data.data32[0], &dloc)) {
transfer_node(loc.monitor, loc.desktop, loc.node, dloc.monitor, dloc.desktop, dloc.desktop->focus);
transfer_node(loc.monitor, loc.desktop, loc.node, dloc.monitor, dloc.desktop, dloc.desktop->focus, false);
}
} else if (e->type == ewmh->_NET_CLOSE_WINDOW) {
close_node(loc.node);

View file

@ -176,7 +176,12 @@ void cmd_node(char **args, int num, FILE *rsp)
coordinates_t dst;
int ret;
if ((ret = desktop_from_desc(*args, &ref, &dst)) == SELECTOR_OK) {
if (transfer_node(trg.monitor, trg.desktop, trg.node, dst.monitor, dst.desktop, dst.desktop->focus)) {
bool follow = false;
if (num > 1 && streq("--follow", *(args+1))) {
follow = true;
num--, args++;
}
if (transfer_node(trg.monitor, trg.desktop, trg.node, dst.monitor, dst.desktop, dst.desktop->focus, follow)) {
trg.monitor = dst.monitor;
trg.desktop = dst.desktop;
} else {
@ -196,7 +201,12 @@ void cmd_node(char **args, int num, FILE *rsp)
coordinates_t dst;
int ret;
if ((ret = monitor_from_desc(*args, &ref, &dst)) == SELECTOR_OK) {
if (transfer_node(trg.monitor, trg.desktop, trg.node, dst.monitor, dst.monitor->desk, dst.monitor->desk->focus)) {
bool follow = false;
if (num > 1 && streq("--follow", *(args+1))) {
follow = true;
num--, args++;
}
if (transfer_node(trg.monitor, trg.desktop, trg.node, dst.monitor, dst.monitor->desk, dst.monitor->desk->focus, follow)) {
trg.monitor = dst.monitor;
trg.desktop = dst.monitor->desk;
} else {
@ -216,7 +226,12 @@ void cmd_node(char **args, int num, FILE *rsp)
coordinates_t dst;
int ret;
if ((ret = node_from_desc(*args, &ref, &dst)) == SELECTOR_OK) {
if (transfer_node(trg.monitor, trg.desktop, trg.node, dst.monitor, dst.desktop, dst.node)) {
bool follow = false;
if (num > 1 && streq("--follow", *(args+1))) {
follow = true;
num--, args++;
}
if (transfer_node(trg.monitor, trg.desktop, trg.node, dst.monitor, dst.desktop, dst.node, follow)) {
trg.monitor = dst.monitor;
trg.desktop = dst.desktop;
} else {
@ -236,7 +251,12 @@ void cmd_node(char **args, int num, FILE *rsp)
coordinates_t dst;
int ret;
if ((ret = node_from_desc(*args, &ref, &dst)) == SELECTOR_OK) {
if (swap_nodes(trg.monitor, trg.desktop, trg.node, dst.monitor, dst.desktop, dst.node)) {
bool follow = false;
if (num > 1 && streq("--follow", *(args+1))) {
follow = true;
num--, args++;
}
if (swap_nodes(trg.monitor, trg.desktop, trg.node, dst.monitor, dst.desktop, dst.node, follow)) {
trg.monitor = dst.monitor;
trg.desktop = dst.desktop;
} else {
@ -641,7 +661,12 @@ void cmd_desktop(char **args, int num, FILE *rsp)
coordinates_t dst;
int ret;
if ((ret = monitor_from_desc(*args, &ref, &dst)) == SELECTOR_OK) {
if (transfer_desktop(trg.monitor, dst.monitor, trg.desktop)) {
bool follow = false;
if (num > 1 && streq("--follow", *(args+1))) {
follow = true;
num--, args++;
}
if (transfer_desktop(trg.monitor, dst.monitor, trg.desktop, follow)) {
trg.monitor = dst.monitor;
} else {
fail(rsp, "");
@ -660,7 +685,12 @@ void cmd_desktop(char **args, int num, FILE *rsp)
coordinates_t dst;
int ret;
if ((ret = desktop_from_desc(*args, &ref, &dst)) == SELECTOR_OK) {
if (swap_desktops(trg.monitor, trg.desktop, dst.monitor, dst.desktop)) {
bool follow = false;
if (num > 1 && streq("--follow", *(args+1))) {
follow = true;
num--, args++;
}
if (swap_desktops(trg.monitor, trg.desktop, dst.monitor, dst.desktop, follow)) {
trg.monitor = dst.monitor;
} else {
fail(rsp, "");
@ -682,18 +712,18 @@ void cmd_desktop(char **args, int num, FILE *rsp)
if (cyc == CYCLE_PREV) {
if (d->prev == NULL) {
while (d->next != NULL) {
swap_desktops(trg.monitor, d, trg.monitor, d->next);
swap_desktops(trg.monitor, d, trg.monitor, d->next, false);
}
} else {
swap_desktops(trg.monitor, d, trg.monitor, d->prev);
swap_desktops(trg.monitor, d, trg.monitor, d->prev, false);
}
} else {
if (d->next == NULL) {
while (d->prev != NULL) {
swap_desktops(trg.monitor, d, trg.monitor, d->prev);
swap_desktops(trg.monitor, d, trg.monitor, d->prev, false);
}
} else {
swap_desktops(trg.monitor, d, trg.monitor, d->next);
swap_desktops(trg.monitor, d, trg.monitor, d->next, false);
}
}
} else {
@ -869,7 +899,7 @@ void cmd_monitor(char **args, int num, FILE *rsp)
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);
swap_desktops(trg.monitor, d, dst.monitor, dst.desktop, false);
if (next == dst.desktop) {
next = d;
}

View file

@ -306,7 +306,7 @@ void merge_monitors(monitor_t *ms, monitor_t *md)
desktop_t *d = ms->desk_head;
while (d != NULL) {
desktop_t *next = d->next;
transfer_desktop(ms, md, d);
transfer_desktop(ms, md, d, false);
d = next;
}
}

View file

@ -69,14 +69,17 @@ void load_settings(void)
gapless_monocle = GAPLESS_MONOCLE;
paddingless_monocle = PADDINGLESS_MONOCLE;
single_monocle = SINGLE_MONOCLE;
focus_follows_pointer = FOCUS_FOLLOWS_POINTER;
pointer_follows_focus = POINTER_FOLLOWS_FOCUS;
pointer_follows_monitor = POINTER_FOLLOWS_MONITOR;
ignore_ewmh_focus = IGNORE_EWMH_FOCUS;
center_pseudo_tiled = CENTER_PSEUDO_TILED;
click_to_focus = CLICK_TO_FOCUS;
swallow_first_click = SWALLOW_FIRST_CLICK;
ignore_ewmh_focus = IGNORE_EWMH_FOCUS;
center_pseudo_tiled = CENTER_PSEUDO_TILED;
honor_size_hints = HONOR_SIZE_HINTS;
remove_disabled_monitors = REMOVE_DISABLED_MONITORS;
remove_unplugged_monitors = REMOVE_UNPLUGGED_MONITORS;
merge_overlapping_monitors = MERGE_OVERLAPPING_MONITORS;

View file

@ -46,14 +46,17 @@
#define GAPLESS_MONOCLE false
#define PADDINGLESS_MONOCLE false
#define SINGLE_MONOCLE false
#define FOCUS_FOLLOWS_POINTER false
#define POINTER_FOLLOWS_FOCUS false
#define POINTER_FOLLOWS_MONITOR false
#define IGNORE_EWMH_FOCUS false
#define CENTER_PSEUDO_TILED true
#define CLICK_TO_FOCUS -1
#define SWALLOW_FIRST_CLICK false
#define IGNORE_EWMH_FOCUS false
#define CENTER_PSEUDO_TILED true
#define HONOR_SIZE_HINTS false
#define REMOVE_DISABLED_MONITORS false
#define REMOVE_UNPLUGGED_MONITORS false
#define MERGE_OVERLAPPING_MONITORS false
@ -81,14 +84,17 @@ bool borderless_monocle;
bool gapless_monocle;
bool paddingless_monocle;
bool single_monocle;
bool focus_follows_pointer;
bool pointer_follows_focus;
bool pointer_follows_monitor;
bool ignore_ewmh_focus;
bool center_pseudo_tiled;
int8_t click_to_focus;
bool swallow_first_click;
bool ignore_ewmh_focus;
bool center_pseudo_tiled;
bool honor_size_hints;
bool remove_disabled_monitors;
bool remove_unplugged_monitors;
bool merge_overlapping_monitors;

View file

@ -483,7 +483,7 @@ void transfer_sticky_nodes(monitor_t *m, desktop_t *ds, desktop_t *dd, node_t *n
if (n == NULL) {
return;
} else if (n->sticky) {
transfer_node(m, ds, n, m, dd, dd->focus);
transfer_node(m, ds, n, m, dd, dd->focus, false);
} else {
/* we need references to the children because n might be freed after
* the first recursive call */
@ -1251,7 +1251,7 @@ void free_node(node_t *n)
free_node(second_child);
}
bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop_t *d2, node_t *n2)
bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop_t *d2, node_t *n2, bool follow)
{
if (n1 == NULL || n2 == NULL || n1 == n2 || is_descendant(n1, n2) || is_descendant(n2, n1) ||
(d1 != d2 && ((m1->sticky_count > 0 && sticky_count(n1) > 0) ||
@ -1323,20 +1323,28 @@ bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop
history_swap_nodes(m1, d1, n1, m2, d2, n2);
if (m1->desk != d1 && m2->desk == d2) {
show_node(d2, n1);
hide_node(d2, n2);
} else if (m1->desk == d1 && m2->desk != d2) {
hide_node(d1, n1);
show_node(d1, n2);
}
bool d1_was_focused = (d1 == mon->desk);
bool d2_was_focused = (d2 == mon->desk);
if (m1->desk != d1 && m2->desk == d2) {
show_node(d2, n1);
if (!follow || !d2_was_focused || !n2_held_focus) {
hide_node(d2, n2);
}
} else if (m1->desk == d1 && m2->desk != d2) {
if (!follow || !d1_was_focused || !n1_held_focus) {
hide_node(d1, n1);
}
show_node(d1, n2);
}
if (n1_held_focus) {
if (d1_was_focused) {
focus_node(m2, d2, last_d1_focus);
if (follow) {
focus_node(m2, d2, last_d1_focus);
} else {
focus_node(m1, d1, d1->focus);
}
} else {
activate_node(m1, d1, d1->focus);
}
@ -1346,7 +1354,11 @@ bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop
if (n2_held_focus) {
if (d2_was_focused) {
focus_node(m1, d1, last_d2_focus);
if (follow) {
focus_node(m1, d1, last_d2_focus);
} else {
focus_node(m2, d2, d2->focus);
}
} else {
activate_node(m2, d2, d2->focus);
}
@ -1367,7 +1379,7 @@ bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop
return true;
}
bool transfer_node(monitor_t *ms, desktop_t *ds, node_t *ns, monitor_t *md, desktop_t *dd, node_t *nd)
bool transfer_node(monitor_t *ms, desktop_t *ds, node_t *ns, monitor_t *md, desktop_t *dd, node_t *nd, bool follow)
{
if (ns == NULL || ns == nd || is_child(ns, nd) || is_descendant(nd, ns)) {
return false;
@ -1382,8 +1394,9 @@ bool transfer_node(monitor_t *ms, desktop_t *ds, node_t *ns, monitor_t *md, desk
bool held_focus = is_descendant(ds->focus, ns);
/* avoid ending up with a dangling pointer (because of unlink_node) */
node_t *last_ds_focus = is_child(ns, ds->focus) ? NULL : ds->focus;
bool ds_was_focused = (ds == mon->desk);
if (held_focus && ds == mon->desk) {
if (held_focus && ds_was_focused) {
clear_input_focus();
}
@ -1410,7 +1423,7 @@ bool transfer_node(monitor_t *ms, desktop_t *ds, node_t *ns, monitor_t *md, desk
if (ds == dd) {
if (held_focus) {
if (ds == mon->desk) {
if (ds_was_focused) {
focus_node(ms, ds, last_ds_focus);
} else {
activate_node(ms, ds, last_ds_focus);
@ -1420,19 +1433,29 @@ bool transfer_node(monitor_t *ms, desktop_t *ds, node_t *ns, monitor_t *md, desk
}
} else {
if (held_focus) {
if (ds == mon->desk) {
focus_node(md, dd, last_ds_focus);
}
activate_node(ms, ds, ds->focus);
}
if (dd->focus == ns) {
if (dd == mon->desk) {
focus_node(md, dd, held_focus ? last_ds_focus : ns);
if (follow) {
if (ds_was_focused) {
focus_node(md, dd, last_ds_focus);
}
activate_node(ms, ds, ds->focus);
} else {
activate_node(md, dd, held_focus ? last_ds_focus : ns);
if (ds_was_focused) {
focus_node(ms, ds, ds->focus);
} else {
activate_node(ms, ds, ds->focus);
}
}
}
if (!held_focus || !follow || !ds_was_focused) {
if (dd->focus == ns) {
if (dd == mon->desk) {
focus_node(md, dd, held_focus ? last_ds_focus : ns);
} else {
activate_node(md, dd, held_focus ? last_ds_focus : ns);
}
} else {
draw_border(ns, is_descendant(ns, dd->focus), (md == mon));
}
} else {
draw_border(ns, is_descendant(ns, dd->focus), (md == mon));
}
}
@ -1495,7 +1518,7 @@ void circulate_leaves(monitor_t *m, desktop_t *d, node_t *n, circulate_dir_t dir
e = prev_leaf(e, n);
}
for (node_t *s = e, *f = prev_tiled_leaf(s, n); f != NULL; s = prev_tiled_leaf(f, n), f = prev_tiled_leaf(s, n)) {
swap_nodes(m, d, f, m, d, s);
swap_nodes(m, d, f, m, d, s, false);
}
} else {
node_t *e = first_extrema(n);
@ -1503,7 +1526,7 @@ void circulate_leaves(monitor_t *m, desktop_t *d, node_t *n, circulate_dir_t dir
e = next_leaf(e, n);
}
for (node_t *f = e, *s = next_tiled_leaf(f, n); s != NULL; f = next_tiled_leaf(s, n), s = next_tiled_leaf(f, n)) {
swap_nodes(m, d, f, m, d, s);
swap_nodes(m, d, f, m, d, s, false);
}
}
if (p != NULL) {
@ -1838,7 +1861,7 @@ void set_sticky(monitor_t *m, desktop_t *d, node_t *n, bool value)
}
if (d != m->desk) {
transfer_node(m, d, n, m, m->desk, m->desk->focus);
transfer_node(m, d, n, m, m->desk, m->desk->focus, false);
}
n->sticky = value;

View file

@ -83,8 +83,8 @@ void close_node(node_t *n);
void kill_node(monitor_t *m, desktop_t *d, node_t *n);
void remove_node(monitor_t *m, desktop_t *d, node_t *n);
void free_node(node_t *n);
bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop_t *d2, node_t *n2);
bool transfer_node(monitor_t *ms, desktop_t *ds, node_t *ns, monitor_t *md, desktop_t *dd, node_t *nd);
bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop_t *d2, node_t *n2, bool follow);
bool transfer_node(monitor_t *ms, desktop_t *ds, node_t *ns, monitor_t *md, desktop_t *dd, node_t *nd, bool follow);
bool find_closest_node(coordinates_t *ref, coordinates_t *dst, cycle_dir_t dir, node_select_t sel);
void circulate_leaves(monitor_t *m, desktop_t *d, node_t *n, circulate_dir_t dir);
void set_vacant(monitor_t *m, desktop_t *d, node_t *n, bool value);

View file

@ -487,7 +487,7 @@ bool move_client(coordinates_t *loc, int dx, int dy)
coordinates_t dst;
bool is_managed = (pwin != XCB_NONE && locate_window(pwin, &dst));
if (is_managed && dst.monitor == loc->monitor && IS_TILED(dst.node->client)) {
swap_nodes(loc->monitor, loc->desktop, n, loc->monitor, loc->desktop, dst.node);
swap_nodes(loc->monitor, loc->desktop, n, loc->monitor, loc->desktop, dst.node, false);
return true;
} else {
if (is_managed && dst.monitor == loc->monitor) {
@ -518,13 +518,9 @@ bool move_client(coordinates_t *loc, int dx, int dy)
return true;
}
bool focused = (n == mon->desk->focus);
transfer_node(loc->monitor, loc->desktop, n, pm, pm->desk, pm->desk->focus);
transfer_node(loc->monitor, loc->desktop, n, pm, pm->desk, pm->desk->focus, true);
loc->monitor = pm;
loc->desktop = pm->desk;
if (focused) {
focus_node(pm, pm->desk, n);
}
return true;
}

View file

@ -19,9 +19,9 @@ bspc desktop "TEST-SWAP-A:^1" -s "TEST-SWAP-B:^1"
[ "$(bspc query -N -m 'TEST-SWAP-A')" = "$nodes_b" ] || fail "Wrong nodes in first monitor"
[ "$(bspc query -N -m 'TEST-SWAP-B')" = "$nodes_a" ] || fail "Wrong nodes in second monitor"
window remove 2
bspc monitor -f "TEST-SWAP-B"
window remove 3
bspc monitor -f "TEST-SWAP-A"
window remove 2
bspc monitor "TEST-SWAP-A" -r
bspc monitor "TEST-SWAP-B" -r

View file

@ -17,10 +17,10 @@ bspc node @/2 -s @test-swap-b:/1
[ "$(bspc query -N -n @test-swap-b:)" = "$next_focus_b" ] || fail "Invalid focus after swap."
window remove 2
bspc desktop -f "test-swap-b"
window remove 1 2
window remove 4
bspc desktop -f "test-swap-a"
window remove 2
bspc desktop "test-swap-a" -r
bspc desktop "test-swap-b" -r

View file

@ -16,10 +16,10 @@ bspc node @/2 -d "test-transfer-b"
[ "$next_focus_a" = "$(bspc query -N -n @test-transfer-a:)" ] || fail "Invalid focus after transfer from source."
[ "$next_focus_b" = "$(bspc query -N -n @test-transfer-b:)" ] || fail "Invalid focus after transfer in destination."
window remove
bspc desktop -f "test-transfer-b"
window remove 1 2
window remove 2
bspc desktop -f "test-transfer-a"
window remove
bspc desktop "test-transfer-a" -r
bspc desktop "test-transfer-b" -r