Implement private windows

This commit is contained in:
Bastien Dejean 2013-10-12 21:16:51 +02:00
parent 9cbde46493
commit 7334277454
16 changed files with 175 additions and 27 deletions

View file

@ -1,7 +1,7 @@
_bspc() {
local commands='window desktop monitor query pointer rule restore control config quit'
local settings='focused_border_color active_border_color normal_border_color presel_border_color focused_locked_border_color active_locked_border_color normal_locked_border_color focused_sticky_border_color normal_sticky_border_color urgent_border_color focused_frame_opacity active_frame_opacity normal_frame_opacity border_width window_gap top_padding right_padding bottom_padding left_padding split_ratio growth_factor borderless_monocle gapless_monocle focus_follows_pointer pointer_follows_monitor apply_floating_atom auto_alternate auto_cancel history_aware_focus honor_ewmh_focus'
local settings='focused_border_color active_border_color normal_border_color presel_border_color focused_locked_border_color active_locked_border_color normal_locked_border_color focused_sticky_border_color normal_sticky_border_color focused_private_border_color active_private_border_color normal_private_border_color urgent_border_color focused_frame_opacity active_frame_opacity normal_frame_opacity border_width window_gap top_padding right_padding bottom_padding left_padding split_ratio growth_factor borderless_monocle gapless_monocle focus_follows_pointer pointer_follows_monitor apply_floating_atom auto_alternate auto_cancel history_aware_focus honor_ewmh_focus'
COMPREPLY=()

View file

@ -3,7 +3,7 @@
_bspc() {
local -a commands settings
commands=('window' 'desktop' 'monitor' 'query' 'pointer' 'rule' 'restore' 'control' 'config' 'quit')
settings=('focused_border_color' 'active_border_color' 'normal_border_color' 'presel_border_color' 'focused_locked_border_color' 'active_locked_border_color' 'normal_locked_border_color' 'focused_sticky_border_color' 'normal_sticky_border_color' 'urgent_border_color' 'focused_frame_opacity' 'active_frame_opacity' 'normal_frame_opacity' 'border_width' 'window_gap' 'top_padding' 'right_padding' 'bottom_padding' 'left_padding' 'split_ratio' 'growth_factor' 'borderless_monocle' 'gapless_monocle' 'focus_follows_pointer' 'pointer_follows_monitor' 'apply_floating_atom' 'auto_alternate' 'auto_cancel' 'history_aware_focus' 'honor_ewmh_focus')
settings=('focused_border_color' 'active_border_color' 'normal_border_color' 'presel_border_color' 'focused_locked_border_color' 'active_locked_border_color' 'normal_locked_border_color' 'focused_sticky_border_color' 'normal_sticky_border_color' 'focused_private_border_color' 'active_private_border_color' 'normal_private_border_color' 'urgent_border_color' 'focused_frame_opacity' 'active_frame_opacity' 'normal_frame_opacity' 'border_width' 'window_gap' 'top_padding' 'right_padding' 'bottom_padding' 'left_padding' 'split_ratio' 'growth_factor' 'borderless_monocle' 'gapless_monocle' 'focus_follows_pointer' 'pointer_follows_monitor' 'apply_floating_atom' 'auto_alternate' 'auto_cancel' 'history_aware_focus' 'honor_ewmh_focus')
if (( CURRENT == 2 )) ; then
_values 'command' "$commands[@]"
elif (( CURRENT == 3 )) ; then

View file

@ -2,12 +2,12 @@
.\" Title: bspwm
.\" Author: [see the "Author" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
.\" Date: 10/11/2013
.\" Date: 10/12/2013
.\" Manual: Bspwm Manual
.\" Source: Bspwm 0.8.5
.\" Language: English
.\"
.TH "BSPWM" "1" "10/11/2013" "Bspwm 0\&.8\&.5" "Bspwm Manual"
.TH "BSPWM" "1" "10/12/2013" "Bspwm 0\&.8\&.5" "Bspwm Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@ -518,7 +518,7 @@ Set the splitting ratio (or pull, or push) the edge located in the given directi
Rotate the tree holding the edge located in the given direction in relation to the selected window\&.
.RE
.PP
\fB\-t\fR, \fB\-\-toggle\fR floating|fullscreen|locked|sticky|visible[=on|off]
\fB\-t\fR, \fB\-\-toggle\fR floating|fullscreen|locked|sticky|private|visible[=on|off]
.RS 4
Set or toggle the given state for the selected window\&.
.RE
@ -914,7 +914,7 @@ rule \fIOPTIONS\fR
\fBOptions\fR
.RS 4
.PP
\fB\-a\fR, \fB\-\-add\fR <class_name>|<instance_name> [\-d \fIDESKTOP_SEL\fR [\-\-follow]] [\-\-tags <name>|^<n>[,\&...]][\-\-floating] [\-\-fullscreen] [\-\-locked] [\-\-sticky] [\-\-focus] [\-\-frame] [\-\-unmanage] [\-\-one\-shot]
\fB\-a\fR, \fB\-\-add\fR <class_name>|<instance_name> [\-d \fIDESKTOP_SEL\fR [\-\-follow]] [\-\-tags <name>|^<n>[,\&...]][\-\-floating] [\-\-fullscreen] [\-\-locked] [\-\-sticky] [\-\-focus] [\-\-frame] [\-\-private] [\-\-unmanage] [\-\-one\-shot]
.RS 4
Create a new rule\&.
.RE
@ -1018,6 +1018,21 @@ Color of the border of a focused sticky window of an unfocused monitor\&.
Color of the border of an unfocused sticky window\&.
.RE
.PP
\fIfocused_private_border_color\fR
.RS 4
Color of the border of a focused private window of a focused monitor\&.
.RE
.PP
\fIactive_private_border_color\fR
.RS 4
Color of the border of a focused private window of an unfocused monitor\&.
.RE
.PP
\fInormal_private_border_color\fR
.RS 4
Color of the border of an unfocused private window\&.
.RE
.PP
\fIurgent_border_color\fR
.RS 4
Color of the border of an urgent window\&.

View file

@ -334,7 +334,7 @@ Options
*-R*, *--rotate* 'DIR' '90|270|180'::
Rotate the tree holding the edge located in the given direction in relation to the selected window.
*-t*, *--toggle* floating|fullscreen|locked|sticky|visible[=on|off]::
*-t*, *--toggle* floating|fullscreen|locked|sticky|private|visible[=on|off]::
Set or toggle the given state for the selected window.
*-c*, *--close*::
@ -550,7 +550,7 @@ rule 'OPTIONS'
Options
^^^^^^^
*-a*, *--add* <class_name>|<instance_name> [-d 'DESKTOP_SEL' [--follow]] [--tags <name>|^<n>[,...]][--floating] [--fullscreen] [--locked] [--sticky] [--focus] [--frame] [--unmanage] [--one-shot]::
*-a*, *--add* <class_name>|<instance_name> [-d 'DESKTOP_SEL' [--follow]] [--tags <name>|^<n>[,...]][--floating] [--fullscreen] [--locked] [--sticky] [--focus] [--frame] [--private] [--unmanage] [--one-shot]::
Create a new rule.
*-r*, *--remove* <name>|^<n>|tail|head...::
@ -616,6 +616,15 @@ Global Settings
'normal_sticky_border_color'::
Color of the border of an unfocused sticky window.
'focused_private_border_color'::
Color of the border of a focused private window of a focused monitor.
'active_private_border_color'::
Color of the border of a focused private window of an unfocused monitor.
'normal_private_border_color'::
Color of the border of an unfocused private window.
'urgent_border_color'::
Color of the border of an urgent window.

View file

@ -214,6 +214,8 @@ bool cmd_window(char **args, int num)
set_locked(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->client->locked));
} else if (streq("sticky", key)) {
set_sticky(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->client->sticky));
} else if (streq("private", key)) {
set_private(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->client->private));
} else if (streq("visible", key)) {
set_presence(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !is_visible(trg.desktop, trg.node)));
}
@ -770,6 +772,8 @@ bool cmd_rule(char **args, int num, char *rsp)
rule->effect.focus = true;
} else if (streq("--frame", *args)) {
rule->effect.frame = true;
} else if (streq("--private", *args)) {
rule->effect.private = true;
} else if (streq("--unmanage", *args)) {
rule->effect.unmanage = true;
} else if (streq("--one-shot", *args)) {
@ -1029,6 +1033,9 @@ bool set_setting(coordinates_t loc, char *name, char *value)
SETCOLOR(focused_sticky_border_color)
SETCOLOR(active_sticky_border_color)
SETCOLOR(normal_sticky_border_color)
SETCOLOR(focused_private_border_color)
SETCOLOR(active_private_border_color)
SETCOLOR(normal_private_border_color)
SETCOLOR(urgent_border_color)
#undef SETCOLOR
} else if (streq("focus_follows_pointer", name)) {

View file

@ -90,7 +90,7 @@ void query_tree(desktop_t *d, node_t *n, char *rsp, unsigned int depth)
if (is_leaf(n)) {
client_t *c = n->client;
snprintf(line, sizeof(line), "%c %s 0x%X %u %u %ux%u%+i%+i %c %c%c%c%c%c%c%c%c", (n->birth_rotation == 90 ? 'a' : (n->birth_rotation == 270 ? 'c' : 'm')), c->class_name, c->window, c->tags_field, c->border_width, c->floating_rectangle.width, c->floating_rectangle.height, c->floating_rectangle.x, c->floating_rectangle.y, (n->split_dir == DIR_UP ? 'U' : (n->split_dir == DIR_RIGHT ? 'R' : (n->split_dir == DIR_DOWN ? 'D' : 'L'))), (c->floating ? 'f' : '-'), (c->transient ? 't' : '-'), (c->fullscreen ? 'F' : '-'), (c->urgent ? 'u' : '-'), (c->locked ? 'l' : '-'), (c->sticky ? 's' : '-'), (c->frame ? 'e' : '-'), (n->split_mode ? 'p' : '-'));
snprintf(line, sizeof(line), "%c %s 0x%X %u %u %ux%u%+i%+i %c %c%c%c%c%c%c%c%c%c", (n->birth_rotation == 90 ? 'a' : (n->birth_rotation == 270 ? 'c' : 'm')), c->class_name, c->window, c->tags_field, c->border_width, c->floating_rectangle.width, c->floating_rectangle.height, c->floating_rectangle.x, c->floating_rectangle.y, (n->split_dir == DIR_UP ? 'U' : (n->split_dir == DIR_RIGHT ? 'R' : (n->split_dir == DIR_DOWN ? 'D' : 'L'))), (c->floating ? 'f' : '-'), (c->transient ? 't' : '-'), (c->fullscreen ? 'F' : '-'), (c->urgent ? 'u' : '-'), (c->locked ? 'l' : '-'), (c->sticky ? 's' : '-'), (c->frame ? 'e' : '-'), (c->private ? 'i' : '-'), (n->split_mode ? 'p' : '-'));
} else {
snprintf(line, sizeof(line), "%c %c %.2f", (n->split_type == TYPE_HORIZONTAL ? 'H' : 'V'), (n->birth_rotation == 90 ? 'a' : (n->birth_rotation == 270 ? 'c' : 'm')), n->split_ratio);
}

View file

@ -137,8 +137,8 @@ void restore_tree(char *file_path)
} else {
client_t *c = make_client(XCB_NONE);
num_clients++;
char floating, transient, fullscreen, urgent, locked, sticky, frame, sd, sm, end = 0;
sscanf(line + level, "%c %s %X %u %u %hux%hu%hi%hi %c %c%c%c%c%c%c%c%c %c", &br, c->class_name, &c->window, &c->tags_field, &c->border_width, &c->floating_rectangle.width, &c->floating_rectangle.height, &c->floating_rectangle.x, &c->floating_rectangle.y, &sd, &floating, &transient, &fullscreen, &urgent, &locked, &sticky, &frame, &sm, &end);
char floating, transient, fullscreen, urgent, locked, sticky, frame, private, sd, sm, end = 0;
sscanf(line + level, "%c %s %X %u %u %hux%hu%hi%hi %c %c%c%c%c%c%c%c%c%c %c", &br, c->class_name, &c->window, &c->tags_field, &c->border_width, &c->floating_rectangle.width, &c->floating_rectangle.height, &c->floating_rectangle.x, &c->floating_rectangle.y, &sd, &floating, &transient, &fullscreen, &urgent, &locked, &sticky, &frame, &private, &sm, &end);
c->floating = (floating == '-' ? false : true);
c->transient = (transient == '-' ? false : true);
c->fullscreen = (fullscreen == '-' ? false : true);
@ -146,6 +146,7 @@ void restore_tree(char *file_path)
c->locked = (locked == '-' ? false : true);
c->sticky = (sticky == '-' ? false : true);
c->frame = (frame == '-' ? false : true);
c->private = (private == '-' ? false : true);
n->split_mode = (sm == '-' ? MODE_AUTOMATIC : MODE_MANUAL);
if (sd == 'U')
n->split_dir = DIR_UP;
@ -182,6 +183,8 @@ void restore_tree(char *file_path)
n->vacant = true;
update_vacant_state(n->parent);
}
if (n->client->private)
update_privacy_level(n, true);
}
ewmh_update_current_desktop();
}

7
rule.c
View file

@ -42,6 +42,7 @@ rule_t *make_rule(void)
r->effect.follow = false;
r->effect.focus = false;
r->effect.frame = false;
r->effect.private = false;
r->effect.unmanage = false;
r->one_shot = false;
r->effect.desc[0] = '\0';
@ -115,7 +116,7 @@ bool is_match(rule_t *r, xcb_window_t win)
return false;
}
void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, unsigned int *tags_field, bool *floating, bool *fullscreen, bool *locked, bool *sticky, bool *follow, bool *transient, bool *takes_focus, bool *frame, bool *manage)
void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, unsigned int *tags_field, bool *floating, bool *fullscreen, bool *locked, bool *sticky, bool *follow, bool *transient, bool *takes_focus, bool *frame, bool *private, bool *manage)
{
xcb_ewmh_get_atoms_reply_t win_type;
@ -183,6 +184,8 @@ void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, unsigned int *
*takes_focus = true;
if (efc.frame)
*frame = true;
if (efc.private)
*private = private;
if (efc.unmanage)
*manage = false;
if (efc.desc[0] != '\0') {
@ -243,6 +246,8 @@ void list_rules(char *pattern, char *rsp)
strncat(rsp, " --focus", REMLEN(rsp));
if (r->effect.frame)
strncat(rsp, " --frame", REMLEN(rsp));
if (r->effect.private)
strncat(rsp, " --private", REMLEN(rsp));
if (r->effect.unmanage)
strncat(rsp, " --unmanage", REMLEN(rsp));
if (r->one_shot)

2
rule.h
View file

@ -34,7 +34,7 @@ void remove_rule(rule_t *r);
void remove_rule_by_name(char *name);
bool remove_rule_by_index(int idx);
bool is_match(rule_t *r, xcb_window_t win);
void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, unsigned int *tags_field, bool *floating, bool *fullscreen, bool *locked, bool *sticky, bool *follow, bool *transient, bool *takes_focus, bool *frame, bool *manage);
void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, unsigned int *tags_field, bool *floating, bool *fullscreen, bool *locked, bool *sticky, bool *follow, bool *transient, bool *takes_focus, bool *frame, bool *private, bool *manage);
void list_rules(char *pattern, char *rsp);
#endif

View file

@ -56,6 +56,9 @@ void load_settings(void)
snprintf(focused_sticky_border_color, sizeof(focused_sticky_border_color), "%s", FOCUSED_STICKY_BORDER_COLOR);
snprintf(active_sticky_border_color, sizeof(active_sticky_border_color), "%s", ACTIVE_STICKY_BORDER_COLOR);
snprintf(normal_sticky_border_color, sizeof(normal_sticky_border_color), "%s", NORMAL_STICKY_BORDER_COLOR);
snprintf(focused_private_border_color, sizeof(focused_private_border_color), "%s", FOCUSED_PRIVATE_BORDER_COLOR);
snprintf(active_private_border_color, sizeof(active_private_border_color), "%s", ACTIVE_PRIVATE_BORDER_COLOR);
snprintf(normal_private_border_color, sizeof(normal_private_border_color), "%s", NORMAL_PRIVATE_BORDER_COLOR);
snprintf(urgent_border_color, sizeof(urgent_border_color), "%s", URGENT_BORDER_COLOR);
focused_frame_opacity = FOCUSED_FRAME_OPACITY;

View file

@ -31,17 +31,20 @@
#define CONFIG_NAME WM_NAME "rc"
#define CONFIG_HOME_ENV "XDG_CONFIG_HOME"
#define FOCUSED_BORDER_COLOR "#7E7F89"
#define ACTIVE_BORDER_COLOR "#545350"
#define NORMAL_BORDER_COLOR "#3F3E3B"
#define PRESEL_BORDER_COLOR "#E8E8F4"
#define FOCUSED_LOCKED_BORDER_COLOR "#C7B579"
#define ACTIVE_LOCKED_BORDER_COLOR "#545350"
#define NORMAL_LOCKED_BORDER_COLOR "#3F3E3B"
#define FOCUSED_STICKY_BORDER_COLOR "#E3A5DA"
#define ACTIVE_STICKY_BORDER_COLOR "#545350"
#define NORMAL_STICKY_BORDER_COLOR "#3F3E3B"
#define URGENT_BORDER_COLOR "#EFA29A"
#define FOCUSED_BORDER_COLOR "#7E7F89"
#define ACTIVE_BORDER_COLOR "#545350"
#define NORMAL_BORDER_COLOR "#3F3E3B"
#define PRESEL_BORDER_COLOR "#E8E8F4"
#define FOCUSED_LOCKED_BORDER_COLOR "#C7B579"
#define ACTIVE_LOCKED_BORDER_COLOR "#545350"
#define NORMAL_LOCKED_BORDER_COLOR "#3F3E3B"
#define FOCUSED_STICKY_BORDER_COLOR "#E3A5DA"
#define ACTIVE_STICKY_BORDER_COLOR "#545350"
#define NORMAL_STICKY_BORDER_COLOR "#3F3E3B"
#define FOCUSED_PRIVATE_BORDER_COLOR "#42CAD9"
#define ACTIVE_PRIVATE_BORDER_COLOR "#5C5955"
#define NORMAL_PRIVATE_BORDER_COLOR "#34322E"
#define URGENT_BORDER_COLOR "#EFA29A"
#define FOCUSED_FRAME_OPACITY 0.5
#define ACTIVE_FRAME_OPACITY 0.25
@ -70,6 +73,9 @@ char normal_locked_border_color[MAXLEN];
char focused_sticky_border_color[MAXLEN];
char active_sticky_border_color[MAXLEN];
char normal_sticky_border_color[MAXLEN];
char focused_private_border_color[MAXLEN];
char active_private_border_color[MAXLEN];
char normal_private_border_color[MAXLEN];
char urgent_border_color[MAXLEN];
double focused_frame_opacity;

75
tree.c
View file

@ -147,6 +147,28 @@ void insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f)
f = p;
p = f->parent;
}
if (((f->client != NULL && f->client->private) || (p != NULL && p->privacy_level > 0))
&& f->split_mode == MODE_AUTOMATIC) {
node_t *closest = NULL;
node_t *public = NULL;
closest_public(d, f, &closest, &public);
if (public != NULL) {
f = public;
p = f->parent;
} else {
if (closest != NULL) {
f = closest;
p = f->parent;
}
f->split_mode = MODE_MANUAL;
xcb_rectangle_t rect = f->client->tiled_rectangle;
f->split_dir = (rect.width >= rect.height ? DIR_LEFT : DIR_UP);
if (f->client->private) {
get_opposite(f->split_dir, &f->split_dir);
update_privacy_level(f, false);
}
}
}
n->parent = c;
c->birth_rotation = f->birth_rotation;
switch (f->split_mode) {
@ -229,7 +251,11 @@ void insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f)
}
if (f->vacant)
update_vacant_state(p);
if (f->client != NULL && f->client->private)
update_privacy_level(f, true);
}
if (n->client->private)
update_privacy_level(n, true);
if (d->focus == NULL && is_visible(d, n))
d->focus = n;
if (n->client->sticky)
@ -326,6 +352,7 @@ node_t *make_node(void)
n->split_mode = MODE_AUTOMATIC;
n->split_type = TYPE_VERTICAL;
n->birth_rotation = 0;
n->privacy_level = 0;
n->client = NULL;
n->vacant = false;
return n;
@ -338,7 +365,7 @@ client_t *make_client(xcb_window_t win)
c->border_width = BORDER_WIDTH;
c->window = win;
c->floating = c->transient = c->fullscreen = c->locked = c->sticky = c->urgent = false;
c->frame = c->icccm_focus = false;
c->frame = c->private = c->icccm_focus = false;
xcb_icccm_get_wm_protocols_reply_t protocols;
if (xcb_icccm_get_wm_protocols_reply(dpy, xcb_icccm_get_wm_protocols(dpy, win, ewmh->WM_PROTOCOLS), &protocols, NULL) == 1) {
if (has_proto(WM_TAKE_FOCUS, &protocols))
@ -441,6 +468,33 @@ node_t *closest_visible(desktop_t *d, node_t *n)
return NULL;
}
void closest_public(desktop_t *d, node_t *n, node_t **closest, node_t **public)
{
if (n == NULL)
return;
node_t *prev = prev_leaf(n, d->root);
node_t *next = next_leaf(n, d->root);
while (prev != NULL || next != NULL) {
#define TESTLOOP(n) \
if (n != NULL) { \
if (is_visible(d, n) && is_tiled(n->client)) { \
if (n->privacy_level == 0) { \
if (n->parent == NULL || n->parent->privacy_level == 0) { \
*public = n; \
return; \
} else if (*closest == NULL) { \
*closest = n; \
} \
} \
} \
n = n##_leaf(n, d->root); \
}
TESTLOOP(prev)
TESTLOOP(next)
#undef TESTLOOP
}
}
node_t *first_extrema(node_t *n)
{
if (n == NULL)
@ -816,6 +870,9 @@ void unlink_node(monitor_t *m, desktop_t *d, node_t *n)
d->focus = closest_visible(d, n);
}
if (n->client->private)
update_privacy_level(n, false);
node_t *b;
node_t *g = p->parent;
@ -897,6 +954,8 @@ bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop
bool n2_first_child = is_first_child(n2);
int br1 = n1->birth_rotation;
int br2 = n2->birth_rotation;
int pl1 = n1->privacy_level;
int pl2 = n2->privacy_level;
if (pn1 != NULL) {
if (n1_first_child)
@ -916,12 +975,19 @@ bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop
n2->parent = pn1;
n1->birth_rotation = br2;
n2->birth_rotation = br1;
n1->privacy_level = pl2;
n2->privacy_level = pl1;
if (n1->vacant != n2->vacant) {
update_vacant_state(n1->parent);
update_vacant_state(n2->parent);
}
if (n1->client->private != n2->client->private) {
n1->client->private = !n1->client->private;
n2->client->private = !n2->client->private;
}
if (d1 != d2) {
if (d1->root == n1)
d1->root = n2;
@ -1071,3 +1137,10 @@ void update_vacant_state(node_t *n)
p = p->parent;
}
}
void update_privacy_level(node_t *n, bool value)
{
int v = (value ? 1 : -1);
for (node_t *p = n; p != NULL; p = p->parent)
p->privacy_level += v;
}

2
tree.h
View file

@ -43,6 +43,7 @@ void change_split_ratio(node_t *n, value_change_t chg);
void reset_mode(coordinates_t *loc);
node_t *brother_tree(node_t *n);
node_t *closest_visible(desktop_t *d, node_t *n);
void closest_public(desktop_t *d, node_t *n, node_t **closest, node_t **public);
node_t *first_extrema(node_t *n);
node_t *second_extrema(node_t *n);
node_t *next_leaf(node_t *n, node_t *r);
@ -72,5 +73,6 @@ bool transfer_node(monitor_t *ms, desktop_t *ds, node_t *ns, monitor_t *md, desk
node_t *closest_node(monitor_t *m, desktop_t *d, node_t *n, cycle_dir_t dir, client_select_t sel);
void circulate_leaves(monitor_t *m, desktop_t *d, circulate_dir_t dir);
void update_vacant_state(node_t *n);
void update_privacy_level(node_t *n, bool value);
#endif

View file

@ -162,6 +162,7 @@ typedef struct {
bool sticky;
bool urgent;
bool frame;
bool private;
bool icccm_focus;
xcb_rectangle_t floating_rectangle;
xcb_rectangle_t tiled_rectangle;
@ -179,6 +180,7 @@ struct node_t {
int birth_rotation;
xcb_rectangle_t rectangle;
bool vacant; /* vacant nodes only hold floating clients */
int privacy_level;
node_t *first_child;
node_t *second_child;
node_t *parent;
@ -251,6 +253,7 @@ typedef struct {
bool focus;
bool unmanage;
bool frame;
bool private;
char desc[MAXLEN];
char tags[MAXLEN];
} rule_effect_t;

View file

@ -49,9 +49,9 @@ void manage_window(monitor_t *m, desktop_t *d, xcb_window_t win)
if (override_redirect || locate_window(win, &loc))
return;
bool floating = false, fullscreen = false, locked = false, sticky = false, follow = false, transient = false, takes_focus = true, frame = false, manage = true;
bool floating = false, fullscreen = false, locked = false, sticky = false, follow = false, transient = false, takes_focus = true, frame = false, private = false, manage = true;
unsigned int tags_field = 0;
handle_rules(win, &m, &d, &tags_field, &floating, &fullscreen, &locked, &sticky, &follow, &transient, &takes_focus, &frame, &manage);
handle_rules(win, &m, &d, &tags_field, &floating, &fullscreen, &locked, &sticky, &follow, &transient, &takes_focus, &frame, &private, &manage);
if (!manage) {
disable_floating_atom(win);
@ -84,6 +84,7 @@ void manage_window(monitor_t *m, desktop_t *d, xcb_window_t win)
set_floating(n, floating);
set_locked(m, d, n, locked);
set_sticky(m, d, n, sticky);
set_private(m, d, n, private);
if (d->focus != NULL && d->focus->client->fullscreen)
set_fullscreen(d->focus, false);
@ -465,6 +466,20 @@ void set_sticky(monitor_t *m, desktop_t *d, node_t *n, bool value)
window_draw_border(n, d->focus == n, m == mon);
}
void set_private(monitor_t *m, desktop_t *d, node_t *n, bool value)
{
if (n == NULL || n->client->private == value)
return;
client_t *c = n->client;
PRINTF("set private %X: %s\n", c->window, BOOLSTR(value));
c->private = value;
update_privacy_level(n, value);
window_draw_border(n, d->focus == n, m == mon);
}
void set_urgency(monitor_t *m, desktop_t *d, node_t *n, bool value)
{
if (value && mon->desk->focus == n)
@ -503,6 +518,8 @@ uint32_t get_border_color(client_t *c, bool focused_window, bool focused_monitor
get_color(focused_locked_border_color, c->window, &pxl);
else if (c->sticky)
get_color(focused_sticky_border_color, c->window, &pxl);
else if (c->private)
get_color(focused_private_border_color, c->window, &pxl);
else
get_color(focused_border_color, c->window, &pxl);
} else if (focused_window) {
@ -512,6 +529,8 @@ uint32_t get_border_color(client_t *c, bool focused_window, bool focused_monitor
get_color(active_locked_border_color, c->window, &pxl);
else if (c->sticky)
get_color(active_sticky_border_color, c->window, &pxl);
else if (c->private)
get_color(active_private_border_color, c->window, &pxl);
else
get_color(active_border_color, c->window, &pxl);
} else {
@ -521,6 +540,8 @@ uint32_t get_border_color(client_t *c, bool focused_window, bool focused_monitor
get_color(normal_locked_border_color, c->window, &pxl);
else if (c->sticky)
get_color(normal_sticky_border_color, c->window, &pxl);
else if (c->private)
get_color(normal_private_border_color, c->window, &pxl);
else
get_color(normal_border_color, c->window, &pxl);
}

View file

@ -49,6 +49,7 @@ void set_fullscreen(node_t *n, bool value);
void set_floating(node_t *n, bool value);
void set_locked(monitor_t *m, desktop_t *d, node_t *n, bool value);
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_urgency(monitor_t *m, desktop_t *d, node_t *n, bool value);
void set_floating_atom(xcb_window_t win, uint32_t value);
void enable_floating_atom(xcb_window_t win);