Fixes #229.
ewmh->_NET_CLOSE_WINDOW,
ewmh->_NET_WM_DESKTOP,
ewmh->_NET_WM_STATE,
+ ewmh->_NET_WM_STATE_HIDDEN,
ewmh->_NET_WM_STATE_FULLSCREEN,
ewmh->_NET_WM_STATE_BELOW,
ewmh->_NET_WM_STATE_ABOVE,
-- Add support for showing/hiding nodes.
- Add zoom feature (view point distinct from root).
- Use BSD `sys/{queue/tree}.h` for {list,tree} structures?
.\" Title: bspwm
.\" Author: [see the "Author" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 04/14/2016
+.\" Date: 04/16/2016
.\" Manual: Bspwm Manual
-.\" Source: Bspwm 0.9.1-26-g789cb8a
+.\" Source: Bspwm 0.9.1-32-g828c93f
.\" Language: English
.\"
-.TH "BSPWM" "1" "04/14/2016" "Bspwm 0\&.9\&.1\-26\-g789cb8a" "Bspwm Manual"
+.TH "BSPWM" "1" "04/16/2016" "Bspwm 0\&.9\&.1\-32\-g828c93f" "Bspwm Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
STATE := tiled|pseudo_tiled|floating|fullscreen
-FLAG := urgent|sticky|private|locked
+FLAG := hidden|sticky|private|locked|urgent
LAYER := below|normal|above
Only consider windows that have or don\(cqt have the same class as the current window\&.
.RE
.PP
-[!](private|urgent|sticky|locked)
+[!](hidden|sticky|private|locked|urgent)
.RS 4
Only consider windows that have or don\(cqt have the given flag set\&.
.RE
.RE
.SH "NODE FLAGS"
.PP
-locked
+hidden
.RS 4
-Ignores the
-\fBnode \-\-close\fR
-message\&.
+Is hidden and doesn\(cqt occupy any tiling space\&.
.RE
.PP
sticky
Tries to keep the same tiling position/size\&.
.RE
.PP
+locked
+.RS 4
+Ignores the
+\fBnode \-\-close\fR
+message\&.
+.RE
+.PP
urgent
.RS 4
Has its urgency hint set\&. This flag is set externally\&.
is present and the current state matches the given state, then the argument is interpreted as the last state\&.
.RE
.PP
-\fB\-g\fR, \fB\-\-flag\fR locked|sticky|private[=on|off]
+\fB\-g\fR, \fB\-\-flag\fR hidden|sticky|private|locked[=on|off]
.RS 4
Set or toggle the given flag for the selected node\&.
.RE
\fBCommands\fR
.RS 4
.PP
-\fB\-a\fR, \fB\-\-add\fR (<class_name>|*)[:(<instance_name>|*)] [\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] [(locked|sticky|private|center|follow|manage|focus|border)=(on|off)]
+\fB\-a\fR, \fB\-\-add\fR (<class_name>|*)[:(<instance_name>|*)] [\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|center|follow|manage|focus|border)=(on|off)]
.RS 4
Create a new rule\&.
.RE
The state of a window changed\&.
.RE
.PP
-\fInode_flag <monitor_id> <desktop_id> <node_id> sticky|private|locked|urgent on|off\fR
+\fInode_flag <monitor_id> <desktop_id> <node_id> hidden|sticky|private|locked|urgent on|off\fR
.RS 4
One of the flags of a node changed\&.
.RE
STATE := tiled|pseudo_tiled|floating|fullscreen
-FLAG := urgent|sticky|private|locked
+FLAG := hidden|sticky|private|locked|urgent
LAYER := below|normal|above
[!]same_class::
Only consider windows that have or don't have the same class as the current window.
-[!](private|urgent|sticky|locked)::
+[!](hidden|sticky|private|locked|urgent)::
Only consider windows that have or don't have the given flag set.
[!](below|normal|above)::
Node Flags
----------
-locked::
- Ignores the *node --close* message.
+hidden::
+ Is hidden and doesn't occupy any tiling space.
sticky::
Stays in the focused desktop of its monitor.
private::
Tries to keep the same tiling position/size.
+locked::
+ Ignores the *node --close* message.
+
urgent::
Has its urgency hint set. This flag is set externally.
*-t*, *--state* [~](tiled|pseudo_tiled|floating|fullscreen)::
Set the state of the selected window. If *~* is present and the current state matches the given state, then the argument is interpreted as the last state.
-*-g*, *--flag* locked|sticky|private[=on|off]::
+*-g*, *--flag* hidden|sticky|private|locked[=on|off]::
Set or toggle the given flag for the selected node.
*-l*, *--layer* below|normal|above::
Commands
^^^^^^^^
-*-a*, *--add* (<class_name>|\*)[:(<instance_name>|\*)] [*-o*|*--one-shot*] [monitor=MONITOR_SEL|desktop=DESKTOP_SEL|node=NODE_SEL] [state=STATE] [layer=LAYER] [split_dir=DIR] [split_ratio=RATIO] [(locked|sticky|private|center|follow|manage|focus|border)=(on|off)]::
+*-a*, *--add* (<class_name>|\*)[:(<instance_name>|\*)] [*-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|center|follow|manage|focus|border)=(on|off)]::
Create a new rule.
*-r*, *--remove* ^<n>|head|tail|(<class_name>|\*)[:(<instance_name>|*)]...::
'node_state <monitor_id> <desktop_id> <node_id> tiled|pseudo_tiled|floating|fullscreen on|off'::
The state of a window changed.
-'node_flag <monitor_id> <desktop_id> <node_id> sticky|private|locked|urgent on|off'::
+'node_flag <monitor_id> <desktop_id> <node_id> hidden|sticky|private|locked|urgent on|off'::
One of the flags of a node changed.
'node_layer <monitor_id> <desktop_id> <node_id> below|normal|above'::
} else if (action == XCB_EWMH_WM_STATE_TOGGLE) {
set_layer(m, d, n, n->client->layer == LAYER_ABOVE ? n->client->last_layer : LAYER_ABOVE);
}
+ } else if (state == ewmh->_NET_WM_STATE_HIDDEN) {
+ if (action == XCB_EWMH_WM_STATE_ADD) {
+ set_hidden(m, d, n, true);
+ } else if (action == XCB_EWMH_WM_STATE_REMOVE) {
+ set_hidden(m, d, n, false);
+ } else if (action == XCB_EWMH_WM_STATE_TOGGLE) {
+ set_hidden(m, d, n, !n->hidden);
+ }
} else if (state == ewmh->_NET_WM_STATE_STICKY) {
if (action == XCB_EWMH_WM_STATE_ADD) {
set_sticky(m, d, n, true);
HANDLE_WM_STATE(SHADED)
HANDLE_WM_STATE(SKIP_TASKBAR)
HANDLE_WM_STATE(SKIP_PAGER)
- HANDLE_WM_STATE(HIDDEN)
}
#undef HANDLE_WM_STATE
}
node_t *history_last_node(desktop_t *d, node_t *n)
{
for (history_t *h = history_tail; h != NULL; h = h->prev) {
- if (h->latest && h->loc.node != NULL && !is_descendant(h->loc.node, n) && h->loc.desktop == d) {
+ if (h->latest && h->loc.node != NULL && !h->loc.node->hidden &&
+ !is_descendant(h->loc.node, n) && h->loc.desktop == d) {
return h->loc.node;
}
}
if (!h->latest ||
h->loc.node == NULL ||
h->loc.node == ref->node ||
+ h->loc.node->hidden ||
!node_matches(&h->loc, ref, sel)) {
continue;
}
break;
}
}
- if (streq("locked", key)) {
- set_locked(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->locked));
+ if (streq("hidden", key)) {
+ set_hidden(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->hidden));
+ changed = true;
} else if (streq("sticky", key)) {
set_sticky(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->sticky));
} else if (streq("private", key)) {
set_private(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->private));
+ } else if (streq("locked", key)) {
+ set_locked(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->locked));
} else {
fail(rsp, "node %s: Invalid key: '%s'.\n", *(args - 1), key);
break;
GET_MOD(pseudo_tiled)
GET_MOD(floating)
GET_MOD(fullscreen)
- GET_MOD(locked)
+ GET_MOD(hidden)
GET_MOD(sticky)
GET_MOD(private)
+ GET_MOD(locked)
GET_MOD(urgent)
GET_MOD(same_class)
GET_MOD(below)
fprintf(rsp, "\"splitRatio\":%lf,", n->split_ratio);
fprintf(rsp, "\"birthRotation\":%i,", n->birth_rotation);
fprintf(rsp, "\"vacant\":%s,", BOOL_STR(n->vacant));
+ fprintf(rsp, "\"hidden\":%s,", BOOL_STR(n->hidden));
fprintf(rsp, "\"sticky\":%s,", BOOL_STR(n->sticky));
fprintf(rsp, "\"private\":%s,", BOOL_STR(n->private));
fprintf(rsp, "\"locked\":%s,", BOOL_STR(n->locked));
fprintf(rsp, "\"layer\":\"%s\",", LAYER_STR(c->layer));
fprintf(rsp, "\"lastLayer\":\"%s\",", LAYER_STR(c->last_layer));
fprintf(rsp, "\"urgent\":%s,", BOOL_STR(c->urgent));
- fprintf(rsp, "\"visible\":%s,", BOOL_STR(c->visible));
+ fprintf(rsp, "\"shown\":%s,", BOOL_STR(c->shown));
fprintf(rsp, "\"tiledRectangle\":");
query_rectangle(c->tiled_rectangle, rsp);
fprintf(rsp,",");
(sel == NULL || node_matches(&trg, &ref, *sel))) {
fprintf(rsp, "0x%08X\n", n->id);
count++;
+ if (sel != NULL) {
+ return 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);
.pseudo_tiled = OPTION_NONE,
.floating = OPTION_NONE,
.fullscreen = OPTION_NONE,
- .locked = OPTION_NONE,
+ .hidden = OPTION_NONE,
.sticky = OPTION_NONE,
.private = OPTION_NONE,
+ .locked = OPTION_NONE,
.urgent = OPTION_NONE,
.same_class = OPTION_NONE,
.below = OPTION_NONE,
: sel.p == OPTION_FALSE) { \
return false; \
}
+ NFLAG(hidden)
NFLAG(sticky)
NFLAG(private)
NFLAG(locked)
RESTORE_DOUBLE(splitRatio, &n->split_ratio)
RESTORE_INT(birthRotation, &n->birth_rotation)
RESTORE_BOOL(vacant, &n->vacant)
+ RESTORE_BOOL(hidden, &n->hidden)
RESTORE_BOOL(sticky, &n->sticky)
RESTORE_BOOL(private, &n->private)
RESTORE_BOOL(locked, &n->locked)
RESTORE_ANY(lastLayer, &c->last_layer, parse_stack_layer)
RESTORE_UINT(borderWidth, &c->border_width)
RESTORE_BOOL(urgent, &c->urgent)
- RESTORE_BOOL(visible, &c->visible)
+ RESTORE_BOOL(shown, &c->shown)
} else if (keyeq("tiledRectangle", *t, json)) {
(*t)++;
restore_rectangle(&c->tiled_rectangle, t, json);
csq->split_ratio = rat;
}
} else if (parse_bool(value, &v)) {
- if (streq("locked", key))
- csq->locked = true;
+ if (streq("hidden", key))
+ csq->hidden = true;
#define SETCSQ(name) \
else if (streq(#name, key)) \
csq->name = v;
SETCSQ(sticky)
SETCSQ(private)
+ SETCSQ(locked)
SETCSQ(center)
SETCSQ(follow)
SETCSQ(manage)
}
cancel_presel(m, d, f);
}
- if (f->vacant) {
- propagate_vacant_state(m, d, f);
- }
}
- if (d->focus == NULL && !IS_RECEPTACLE(n)) {
+ propagate_flags_upward(m, d, n);
+
+ if (d->focus == NULL && is_focusable(n)) {
d->focus = n;
}
bool activate_node(monitor_t *m, desktop_t *d, node_t *n)
{
- if (d == mon->desk || IS_RECEPTACLE(n)) {
+ if (d == mon->desk || (n != NULL && !is_focusable(n))) {
return false;
}
bool focus_node(monitor_t *m, desktop_t *d, node_t *n)
{
- if (IS_RECEPTACLE(n)) {
+ if (n != NULL && !is_focusable(n)) {
return false;
}
if (n == NULL) {
return;
} else {
- if (n->presel != NULL) {
- window_hide(n->presel->feedback);
+ if (!n->hidden) {
+ if (n->presel != NULL) {
+ window_hide(n->presel->feedback);
+ }
+ if (n->client != NULL) {
+ window_hide(n->id);
+ }
}
if (n->client != NULL) {
- window_hide(n->id);
- n->client->visible = false;
+ n->client->shown = false;
}
hide_node(n->first_child);
hide_node(n->second_child);
if (n == NULL) {
return;
} else {
- if (n->client != NULL) {
- window_show(n->id);
- n->client->visible = true;
+ if (!n->hidden) {
+ if (n->client != NULL) {
+ window_show(n->id);
+ }
+ if (n->presel != NULL) {
+ window_show(n->presel->feedback);
+ }
}
- if (n->presel != NULL) {
- window_show(n->presel->feedback);
+ if (n->client != NULL) {
+ n->client->shown = true;
}
show_node(n->first_child);
show_node(n->second_child);
node_t *n = malloc(sizeof(node_t));
n->id = id;
n->parent = n->first_child = n->second_child = NULL;
- n->vacant = n->sticky = n->private = n->locked = false;
+ n->vacant = n->hidden = n->sticky = n->private = n->locked = false;
n->split_ratio = split_ratio;
n->split_type = TYPE_VERTICAL;
n->birth_rotation = 0;
client_t *make_client(void)
{
- client_t *c = calloc(1, sizeof(client_t));
+ client_t *c = malloc(sizeof(client_t));
c->state = c->last_state = STATE_TILED;
c->layer = c->last_layer = LAYER_NORMAL;
snprintf(c->class_name, sizeof(c->class_name), "%s", MISSING_VALUE);
snprintf(c->instance_name, sizeof(c->instance_name), "%s", MISSING_VALUE);
c->border_width = border_width;
+ c->wm_flags = 0;
c->icccm_props.input_hint = true;
+ c->icccm_props.take_focus = false;
+ c->size_hints.flags = 0;
return c;
}
xcb_icccm_get_wm_normal_hints_reply(dpy, xcb_icccm_get_wm_normal_hints(dpy, win), &c->size_hints, NULL);
}
+bool is_focusable(node_t *n)
+{
+ for (node_t *f = first_extrema(n); f != NULL; f = next_leaf(f, n)) {
+ if (f->client != NULL && !f->hidden) {
+ return true;
+ }
+ }
+ return false;
+}
+
bool is_leaf(node_t *n)
{
return (n != NULL && n->first_child == NULL && n->second_child == NULL);
node_t *first_focusable_leaf(node_t *n)
{
for (node_t *f = first_extrema(n); f != NULL; f = next_leaf(f, n)) {
- if (f->client != NULL) {
+ if (f->client != NULL && !f->hidden) {
return f;
}
}
node_t *next_tiled_leaf(node_t *n, node_t *r)
{
node_t *next = next_leaf(n, r);
- if (next == NULL || (next->client != NULL && IS_TILED(next->client))) {
+ if (next == NULL || (next->client != NULL && !next->vacant)) {
return next;
} else {
return next_tiled_leaf(next, r);
node_t *prev_tiled_leaf(node_t *n, node_t *r)
{
node_t *prev = prev_leaf(n, r);
- if (prev == NULL || (prev->client != NULL && IS_TILED(prev->client))) {
+ if (prev == NULL || (prev->client != NULL && !prev->vacant)) {
return prev;
} else {
return prev_tiled_leaf(prev, r);
coordinates_t loc = {m, d, a};
if (a == n ||
a->client == NULL ||
+ a->hidden ||
!node_matches(&loc, &ref, sel) ||
(n->client != NULL && (IS_TILED(a->client) != IS_TILED(n->client))) ||
(IS_TILED(a->client) && !is_adjacent(n, a, dir))) {
}
free(p);
- propagate_vacant_state(m, d, b);
+ propagate_flags_upward(m, d, b);
}
}
n1->birth_rotation = br2;
n2->birth_rotation = br1;
- if (n1->vacant != n2->vacant) {
- propagate_vacant_state(m2, d2, n1);
- propagate_vacant_state(m1, d1, n2);
- }
+ propagate_flags_upward(m2, d2, n1);
+ propagate_flags_upward(m1, d1, n2);
if (d1 != d2) {
if (d1->root == n1) {
coordinates_t ref = {m, d, n};
while (f != n) {
coordinates_t loc = {m, d, f};
- if (f->client != NULL && node_matches(&loc, &ref, sel)) {
+ if (f->client != NULL && !f->hidden && node_matches(&loc, &ref, sel)) {
return f;
}
f = (dir == CYCLE_PREV ? prev_leaf(f, d->root) : next_leaf(f, d->root));
}
}
-void set_vacant_state(monitor_t *m, desktop_t *d, node_t *n, bool value)
+void set_vacant(monitor_t *m, desktop_t *d, node_t *n, bool value)
+{
+ if (n->vacant == value) {
+ return;
+ }
+
+ propagate_vacant_downward(m, d, n, value);
+ propagate_vacant_upward(m, d, n);
+}
+
+void set_vacant_local(monitor_t *m, desktop_t *d, node_t *n, bool value)
{
n->vacant = value;
if (value) {
unrotate_brother(n);
+ cancel_presel(m, d, n);
} else {
rotate_brother(n);
}
+}
- if (value) {
- cancel_presel(m, d, n);
+void propagate_vacant_downward(monitor_t *m, desktop_t *d, node_t *n, bool value)
+{
+ if (n == NULL) {
+ return;
}
- propagate_vacant_state(m, d, n);
+ set_vacant_local(m, d, n, value);
+
+ propagate_vacant_downward(m, d, n->first_child, value);
+ propagate_vacant_downward(m, d, n->second_child, value);
}
-void propagate_vacant_state(monitor_t *m, desktop_t *d, node_t *n)
+void propagate_vacant_upward(monitor_t *m, desktop_t *d, node_t *n)
{
if (n == NULL) {
return;
node_t *p = n->parent;
- while (p != NULL) {
- p->vacant = (p->first_child->vacant && p->second_child->vacant);
- if (p->vacant) {
- cancel_presel(m, d, p);
- }
- p = p->parent;
+ if (p != NULL) {
+ set_vacant_local(m, d, p, (p->first_child->vacant && p->second_child->vacant));
}
+
+ propagate_vacant_upward(m, d, p);
}
bool set_layer(monitor_t *m, desktop_t *d, node_t *n, stack_layer_t l)
}
cancel_presel(m, d, n);
- set_vacant_state(m, d, n, value);
+ set_vacant(m, d, n, value);
if (!value && d->focus == n) {
neutralize_occluding_windows(m, d, n);
client_t *c = n->client;
cancel_presel(m, d, n);
- set_vacant_state(m, d, n, value);
+ set_vacant(m, d, n, value);
if (value) {
c->wm_flags |= WM_FLAG_FULLSCREEN;
}
}
-void set_locked(monitor_t *m, desktop_t *d, node_t *n, bool value)
+void propagate_flags_upward(monitor_t *m, desktop_t *d, node_t *n)
{
- if (n == NULL || n->locked == value) {
+ if (n == NULL) {
return;
}
- n->locked = value;
+ node_t *p = n->parent;
- put_status(SBSC_MASK_NODE_FLAG, "node_flag 0x%08X 0x%08X 0x%08X locked %s\n", m->id, d->id, n->id, ON_OFF_STR(value));
+ if (p != NULL) {
+ set_vacant_local(m, d, p, (p->first_child->vacant && p->second_child->vacant));
+ set_hidden_local(m, d, p, (p->first_child->hidden && p->second_child->hidden));
+ }
- if (n == m->desk->focus) {
- put_status(SBSC_MASK_REPORT);
+ propagate_flags_upward(m, d, p);
+}
+
+void set_hidden(monitor_t *m, desktop_t *d, node_t *n, bool value)
+{
+ if (n == NULL || n->hidden == value) {
+ return;
+ }
+
+ bool held_focus = is_descendant(d->focus, n);
+
+ propagate_hidden_downward(m, d, n, value);
+ propagate_hidden_upward(m, d, n);
+
+ put_status(SBSC_MASK_NODE_FLAG, "node_flag 0x%08X 0x%08X 0x%08X hidden %s\n", m->id, d->id, n->id, ON_OFF_STR(value));
+
+ if (held_focus || d->focus == NULL) {
+ if (d->focus != NULL) {
+ d->focus = NULL;
+ draw_border(n, false, (mon == m));
+ }
+ if (d == mon->desk) {
+ focus_node(m, d, d->focus);
+ } else {
+ activate_node(m, d, d->focus);
+ }
+ }
+}
+
+void set_hidden_local(monitor_t *m, desktop_t *d, node_t *n, bool value)
+{
+ n->hidden = value;
+ if (n->client != NULL) {
+ window_set_visibility(n->id, !value);
+ if (IS_TILED(n->client)) {
+ set_vacant(m, d, n, value);
+ }
+ if (value) {
+ n->client->wm_flags |= WM_FLAG_HIDDEN;
+ } else {
+ n->client->wm_flags &= ~WM_FLAG_HIDDEN;
+ }
}
}
+void propagate_hidden_downward(monitor_t *m, desktop_t *d, node_t *n, bool value)
+{
+ if (n == NULL) {
+ return;
+ }
+
+ set_hidden_local(m, d, n, value);
+
+ propagate_hidden_downward(m, d, n->first_child, value);
+ propagate_hidden_downward(m, d, n->second_child, value);
+}
+
+void propagate_hidden_upward(monitor_t *m, desktop_t *d, node_t *n)
+{
+ if (n == NULL) {
+ return;
+ }
+
+ node_t *p = n->parent;
+
+ if (p != NULL) {
+ set_hidden_local(m, d, p, p->first_child->hidden && p->second_child->hidden);
+ }
+
+ propagate_hidden_upward(m, d, p);
+}
+
void set_sticky(monitor_t *m, desktop_t *d, node_t *n, bool value)
{
if (n == NULL || n->sticky == value) {
}
}
+void set_locked(monitor_t *m, desktop_t *d, node_t *n, bool value)
+{
+ if (n == NULL || n->locked == value) {
+ return;
+ }
+
+ n->locked = value;
+
+ put_status(SBSC_MASK_NODE_FLAG, "node_flag 0x%08X 0x%08X 0x%08X locked %s\n", m->id, d->id, n->id, ON_OFF_STR(value));
+
+ if (n == m->desk->focus) {
+ put_status(SBSC_MASK_REPORT);
+ }
+}
+
void set_urgent(monitor_t *m, desktop_t *d, node_t *n, bool value)
{
if (value && mon->desk->focus == n) {
node_t *make_node(uint32_t id);
client_t *make_client(void);
void initialize_client(node_t *n);
+bool is_focusable(node_t *n);
bool is_leaf(node_t *n);
bool is_first_child(node_t *n);
bool is_second_child(node_t *n);
bool transfer_node(monitor_t *ms, desktop_t *ds, node_t *ns, monitor_t *md, desktop_t *dd, node_t *nd);
node_t *closest_node(monitor_t *m, desktop_t *d, node_t *n, 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_state(monitor_t *m, desktop_t *d, node_t *n, bool value);
-void propagate_vacant_state(monitor_t *m, desktop_t *d, node_t *n);
+void set_vacant(monitor_t *m, desktop_t *d, node_t *n, bool value);
+void set_vacant_local(monitor_t *m, desktop_t *d, node_t *n, bool value);
+void propagate_vacant_downward(monitor_t *m, desktop_t *d, node_t *n, bool value);
+void propagate_vacant_upward(monitor_t *m, desktop_t *d, node_t *n);
bool set_layer(monitor_t *m, desktop_t *d, node_t *n, stack_layer_t l);
bool set_state(monitor_t *m, desktop_t *d, node_t *n, client_state_t s);
void set_floating(monitor_t *m, desktop_t *d, node_t *n, bool value);
void set_fullscreen(monitor_t *m, desktop_t *d, node_t *n, bool value);
void neutralize_occluding_windows(monitor_t *m, desktop_t *d, node_t *n);
-void set_locked(monitor_t *m, desktop_t *d, node_t *n, bool value);
+void propagate_flags_upward(monitor_t *m, desktop_t *d, node_t *n);
+void set_hidden(monitor_t *m, desktop_t *d, node_t *n, bool value);
+void set_hidden_local(monitor_t *m, desktop_t *d, node_t *n, bool value);
+void propagate_hidden_downward(monitor_t *m, desktop_t *d, node_t *n, bool value);
+void propagate_hidden_upward(monitor_t *m, desktop_t *d, node_t *n);
void set_sticky(monitor_t *m, desktop_t *d, node_t *n, bool value);
void set_private(monitor_t *m, desktop_t *d, node_t *n, bool value);
+void set_locked(monitor_t *m, desktop_t *d, node_t *n, bool value);
void set_urgent(monitor_t *m, desktop_t *d, node_t *n, bool value);
bool contains(xcb_rectangle_t a, xcb_rectangle_t b);
xcb_rectangle_t get_rectangle(desktop_t *d, node_t *n);
option_bool_t pseudo_tiled;
option_bool_t floating;
option_bool_t fullscreen;
- option_bool_t locked;
+ option_bool_t hidden;
option_bool_t sticky;
option_bool_t private;
+ option_bool_t locked;
option_bool_t urgent;
option_bool_t same_class;
option_bool_t below;
char instance_name[3 * SMALEN / 2];
unsigned int border_width;
bool urgent;
- bool visible;
+ bool shown;
client_state_t state;
client_state_t last_state;
stack_layer_t layer;
presel_t *presel;
xcb_rectangle_t rectangle;
bool vacant;
+ bool hidden;
bool sticky;
bool private;
bool locked;
double split_ratio;
stack_layer_t *layer;
client_state_t *state;
- bool locked;
+ bool hidden;
bool sticky;
bool private;
+ bool locked;
bool center;
bool follow;
bool manage;
c->last_state = c->state;
}
- set_locked(m, d, n, csq->locked);
+ set_hidden(m, d, n, csq->hidden);
set_sticky(m, d, n, csq->sticky);
set_private(m, d, n, csq->private);
+ set_locked(m, d, n, csq->locked);
arrange(m, d);
- bool give_focus = (csq->focus && (d == mon->desk || csq->follow));
+ bool focused = false;
- if (give_focus) {
- focus_node(m, d, n);
- } else if (csq->focus) {
- activate_node(m, d, n);
+ if (!csq->hidden && csq->focus) {
+ if (d == mon->desk || csq->follow) {
+ focused = true;
+ focus_node(m, d, n);
+ } else {
+ activate_node(m, d, n);
+ }
} else {
stack(d, n, false);
}
}
/* the same function is already called in `focus_node` but has no effects on unmapped windows */
- if (give_focus) {
+ if (focused) {
xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_POINTER_ROOT, win, XCB_CURRENT_TIME);
}
*win = qpr->child;
xcb_point_t pt = {qpr->root_x, qpr->root_y};
for (stacking_list_t *s = stack_tail; s != NULL; s = s->prev) {
- if (!s->node->client->visible) {
+ if (!s->node->client->shown || s->node->hidden) {
continue;
}
xcb_rectangle_t rect = get_rectangle(NULL, s->node);