Remove tags

Tags should generalize desktops.

To accomplish this, the main node attributes: (type, ratio) would have
to become a dictionary: ((tf1, (type1, ratio1)), (tf2, (type2, ratio2),
...). (`tf<n>` being a tag field.).
This commit is contained in:
Bastien Dejean 2013-10-19 10:56:34 +02:00
parent 6daf058c5d
commit 08e1c85ce0
19 changed files with 50 additions and 643 deletions

View file

@ -13,7 +13,7 @@ BASHCPL = $(PREFIX)/share/bash-completion/completions
ZSHCPL = $(PREFIX)/share/zsh/site-functions ZSHCPL = $(PREFIX)/share/zsh/site-functions
WM_SRC = bspwm.c helpers.c settings.c monitor.c desktop.c tree.c stack.c history.c \ WM_SRC = bspwm.c helpers.c settings.c monitor.c desktop.c tree.c stack.c history.c \
events.c pointer.c window.c messages.c query.c restore.c rule.c tag.c ewmh.c events.c pointer.c window.c messages.c query.c restore.c rule.c ewmh.c
WM_OBJ = $(WM_SRC:.c=.o) WM_OBJ = $(WM_SRC:.c=.o)
CL_SRC = bspc.c helpers.c CL_SRC = bspc.c helpers.c
CL_OBJ = $(CL_SRC:.c=.o) CL_OBJ = $(CL_SRC:.c=.o)

View file

@ -1,18 +1,17 @@
bspc.o: bspc.c common.h helpers.h bspc.o: bspc.c common.h helpers.h
bspwm.o: bspwm.c bspwm.h common.h desktop.h events.h ewmh.h helpers.h history.h messages.h monitor.h rule.h settings.h stack.h tag.h tree.h types.h window.h bspwm.o: bspwm.c bspwm.h common.h desktop.h events.h ewmh.h helpers.h history.h messages.h monitor.h rule.h settings.h stack.h tree.h types.h window.h
desktop.o: desktop.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h tree.h types.h window.h desktop.o: desktop.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h tree.h types.h window.h
events.o: events.c bspwm.h events.h ewmh.h helpers.h monitor.h query.h settings.h tree.h types.h window.h events.o: events.c bspwm.h events.h ewmh.h helpers.h monitor.h query.h settings.h tree.h types.h window.h
ewmh.o: ewmh.c bspwm.h ewmh.h helpers.h settings.h tree.h types.h ewmh.o: ewmh.c bspwm.h ewmh.h helpers.h settings.h tree.h types.h
helpers.o: helpers.c bspwm.h helpers.h types.h helpers.o: helpers.c bspwm.h helpers.h types.h
history.o: history.c bspwm.h helpers.h query.h tree.h types.h history.o: history.c bspwm.h helpers.h query.h tree.h types.h
messages.o: messages.c bspwm.h desktop.h ewmh.h helpers.h history.h messages.h monitor.h pointer.h query.h restore.h rule.h settings.h tag.h tree.h types.h window.h messages.o: messages.c bspwm.h desktop.h ewmh.h helpers.h history.h messages.h monitor.h pointer.h query.h restore.h rule.h settings.h tree.h types.h window.h
monitor.o: monitor.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h settings.h tree.h types.h window.h monitor.o: monitor.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h settings.h tree.h types.h window.h
pointer.o: pointer.c bspwm.h helpers.h pointer.h query.h settings.h stack.h tree.h types.h window.h pointer.o: pointer.c bspwm.h helpers.h pointer.h query.h settings.h stack.h tree.h types.h window.h
query.o: query.c bspwm.h desktop.h helpers.h history.h messages.h monitor.h query.h tree.h types.h query.o: query.c bspwm.h desktop.h helpers.h history.h messages.h monitor.h query.h tree.h types.h
restore.o: restore.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h restore.h settings.h stack.h tree.h types.h window.h restore.o: restore.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h restore.h settings.h stack.h tree.h types.h window.h
rule.o: rule.c bspwm.h ewmh.h helpers.h messages.h query.h rule.h tag.h types.h window.h rule.o: rule.c bspwm.h ewmh.h helpers.h messages.h query.h rule.h types.h window.h
settings.o: settings.c bspwm.h helpers.h settings.h types.h settings.o: settings.c bspwm.h helpers.h settings.h types.h
stack.o: stack.c bspwm.h helpers.h stack.h types.h window.h stack.o: stack.c bspwm.h helpers.h stack.h types.h window.h
tag.o: tag.c bspwm.h helpers.h history.h tag.h tree.h types.h window.h tree.o: tree.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h settings.h stack.h tree.h types.h window.h
tree.o: tree.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h settings.h stack.h tag.h tree.h types.h window.h window.o: window.c bspwm.h ewmh.h helpers.h monitor.h query.h rule.h settings.h stack.h tree.h types.h window.h
window.o: window.c bspwm.h ewmh.h helpers.h monitor.h query.h rule.h settings.h stack.h tag.h tree.h types.h window.h

View file

@ -45,7 +45,6 @@
#include "window.h" #include "window.h"
#include "history.h" #include "history.h"
#include "stack.h" #include "stack.h"
#include "tag.h"
#include "rule.h" #include "rule.h"
#include "ewmh.h" #include "ewmh.h"
#include "bspwm.h" #include "bspwm.h"
@ -197,7 +196,6 @@ void init(void)
rule_head = rule_tail = NULL; rule_head = rule_tail = NULL;
history_head = history_tail = history_needle = NULL; history_head = history_tail = history_needle = NULL;
stack_head = stack_tail = NULL; stack_head = stack_tail = NULL;
init_tags();
status_fifo = NULL; status_fifo = NULL;
last_motion_time = last_motion_x = last_motion_y = 0; last_motion_time = last_motion_x = last_motion_y = 0;
visible = auto_raise = sticky_still = record_history = true; visible = auto_raise = sticky_still = record_history = true;
@ -301,8 +299,6 @@ void cleanup(void)
remove_rule(rule_head); remove_rule(rule_head);
while (stack_head != NULL) while (stack_head != NULL)
remove_stack(stack_head); remove_stack(stack_head);
while (num_tags > 0)
remove_tag_by_index(num_tags - 1);
empty_history(); empty_history();
free(frozen_pointer); free(frozen_pointer);
} }
@ -325,11 +321,8 @@ void put_status(void)
fprintf(status_fifo, "%c%s:", c, d->name); fprintf(status_fifo, "%c%s:", c, d->name);
} }
} }
if (mon != NULL && mon->desk != NULL) { if (mon != NULL && mon->desk != NULL)
for (int i = 0; i < num_tags; i++)
fprintf(status_fifo, "%c%s:", (tags[i]->mask & mon->desk->tags_field) != 0 ? 'T' : 't', tags[i]->name);
fprintf(status_fifo, "L%s", (mon->desk->layout == LAYOUT_TILED ? "tiled" : "monocle")); fprintf(status_fifo, "L%s", (mon->desk->layout == LAYOUT_TILED ? "tiled" : "monocle"));
}
fprintf(status_fifo, "\n"); fprintf(status_fifo, "\n");
fflush(status_fifo); fflush(status_fifo);
} }

View file

@ -120,7 +120,6 @@ desktop_t *make_desktop(const char *name)
d->root = d->focus = NULL; d->root = d->focus = NULL;
d->window_gap = WINDOW_GAP; d->window_gap = WINDOW_GAP;
d->border_width = BORDER_WIDTH; d->border_width = BORDER_WIDTH;
d->tags_field = 1;
return d; return d;
} }
@ -280,8 +279,7 @@ void show_desktop(desktop_t *d)
if (!visible) if (!visible)
return; return;
for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
if (is_visible(d, n)) window_show(n->client->window);
window_show(n->client->window);
} }
void hide_desktop(desktop_t *d) void hide_desktop(desktop_t *d)
@ -289,8 +287,7 @@ void hide_desktop(desktop_t *d)
if (!visible) if (!visible)
return; return;
for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
if (is_visible(d, n)) window_hide(n->client->window);
window_hide(n->client->window);
} }
bool is_urgent(desktop_t *d) bool is_urgent(desktop_t *d)

View file

@ -2,12 +2,12 @@
.\" Title: bspwm .\" Title: bspwm
.\" Author: [see the "Author" section] .\" Author: [see the "Author" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/> .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
.\" Date: 10/12/2013 .\" Date: 10/19/2013
.\" Manual: Bspwm Manual .\" Manual: Bspwm Manual
.\" Source: Bspwm 0.8.5 .\" Source: Bspwm 0.8.5
.\" Language: English .\" Language: English
.\" .\"
.TH "BSPWM" "1" "10/12/2013" "Bspwm 0\&.8\&.5" "Bspwm Manual" .TH "BSPWM" "1" "10/19/2013" "Bspwm 0\&.8\&.5" "Bspwm Manual"
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
.\" * Define some portability stuff .\" * 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\&. Rotate the tree holding the edge located in the given direction in relation to the selected window\&.
.RE .RE
.PP .PP
\fB\-t\fR, \fB\-\-toggle\fR floating|fullscreen|locked|sticky|private|visible[=on|off] \fB\-t\fR, \fB\-\-toggle\fR floating|fullscreen|locked|sticky|private[=on|off]
.RS 4 .RS 4
Set or toggle the given state for the selected window\&. Set or toggle the given state for the selected window\&.
.RE .RE
@ -660,75 +660,6 @@ Rename, add or remove desktops depending on whether the number of given names is
Swap the selected monitor with the given monitor\&. Swap the selected monitor with the given monitor\&.
.RE .RE
.RE .RE
.SS "Tag"
.sp
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
.ps +1
\fBGeneral Syntax\fR
.RS 4
.sp
tag \fIOPTIONS\fR
.RE
.sp
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
.ps +1
\fBOptions\fR
.RS 4
.PP
\fB\-l\fR, \fB\-\-list\fR
.RS 4
List the tags\&.
.RE
.PP
\fB\-a\fR, \fB\-\-add\fR <name>\&...
.RS 4
Create tags with the given names\&.
.RE
.PP
\fB\-r\fR, \fB\-\-remove\fR <name>|^<n>\&...
.RS 4
Remove tags with the given names or indexes\&.
.RE
.PP
\fB\-e\fR, \fB\-\-enumerate\-tags\fR <name>\&...
.RS 4
Rename, add or remove tags depending on whether the number of given names is equal, superior or inferior to the number of existing tags\&.
.RE
.PP
\fB\-d\fR, \fB\-\-desktop\fR \fIDESKTOP_SEL\fR
.RS 4
Select the given desktop as target for the
\fB\-s\fR
and
\fB\-t\fR
options\&.
.RE
.PP
\fB\-w\fR, \fB\-\-window\fR \fIWINDOW_SEL\fR
.RS 4
Select the given window as target for the
\fB\-s\fR
and
\fB\-t\fR
options\&.
.RE
.PP
\fB\-s\fR, \fB\-\-set\-tags\fR (<name>|^<n>\&...)|all
.RS 4
Set the tags of the selected object\&.
.RE
.PP
\fB\-t\fR, \fB\-\-toggle\-tags\fR (<name>|^<n>)[=on|off]\&...
.RS 4
Toggle the tags of the selected object\&.
.RE
.RE
.SS "Query" .SS "Query"
.sp .sp
.it 1 an-trap .it 1 an-trap
@ -914,7 +845,7 @@ rule \fIOPTIONS\fR
\fBOptions\fR \fBOptions\fR
.RS 4 .RS 4
.PP .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] [\-\-private] [\-\-unmanage] [\-\-one\-shot] \fB\-a\fR, \fB\-\-add\fR <class_name>|<instance_name> [\-d \fIDESKTOP_SEL\fR [\-\-follow]] [\-\-floating] [\-\-fullscreen] [\-\-locked] [\-\-sticky] [\-\-focus] [\-\-frame] [\-\-private] [\-\-unmanage] [\-\-one\-shot]
.RS 4 .RS 4
Create a new rule\&. Create a new rule\&.
.RE .RE
@ -1186,16 +1117,6 @@ Urgent unfocused desktop\&.
.RS 4 .RS 4
Layout of the focused desktop of the focused monitor\&. Layout of the focused desktop of the focused monitor\&.
.RE .RE
.PP
\fIT<tag_name>\fR
.RS 4
Selected tag of the focused desktop of the focused monitor\&.
.RE
.PP
\fIt<tag_name>\fR
.RS 4
Non\-selected tag of the focused desktop of the focused monitor\&.
.RE
.SH "ENVIRONMENT VARIABLES" .SH "ENVIRONMENT VARIABLES"
.PP .PP
\fIBSPWM_SOCKET\fR \fIBSPWM_SOCKET\fR

View file

@ -334,7 +334,7 @@ Options
*-R*, *--rotate* 'DIR' '90|270|180':: *-R*, *--rotate* 'DIR' '90|270|180'::
Rotate the tree holding the edge located in the given direction in relation to the selected window. Rotate the tree holding the edge located in the given direction in relation to the selected window.
*-t*, *--toggle* floating|fullscreen|locked|sticky|private|visible[=on|off]:: *-t*, *--toggle* floating|fullscreen|locked|sticky|private[=on|off]::
Set or toggle the given state for the selected window. Set or toggle the given state for the selected window.
*-c*, *--close*:: *-c*, *--close*::
@ -414,40 +414,6 @@ Options
*-s*, *--swap* 'MONITOR_SEL':: *-s*, *--swap* 'MONITOR_SEL'::
Swap the selected monitor with the given monitor. Swap the selected monitor with the given monitor.
Tag
~~~
General Syntax
^^^^^^^^^^^^^^
tag 'OPTIONS'
Options
^^^^^^^
*-l*, *--list*::
List the tags.
*-a*, *--add* <name>...::
Create tags with the given names.
*-r*, *--remove* <name>|^<n>...::
Remove tags with the given names or indexes.
*-e*, *--enumerate-tags* <name>...::
Rename, add or remove tags depending on whether the number of given names is equal, superior or inferior to the number of existing tags.
*-d*, *--desktop* 'DESKTOP_SEL'::
Select the given desktop as target for the *-s* and *-t* options.
*-w*, *--window* 'WINDOW_SEL'::
Select the given window as target for the *-s* and *-t* options.
*-s*, *--set-tags* (<name>|^<n>...)|all::
Set the tags of the selected object.
*-t*, *--toggle-tags* (<name>|^<n>)[=on|off]...::
Toggle the tags of the selected object.
Query Query
~~~~~ ~~~~~
@ -550,7 +516,7 @@ rule 'OPTIONS'
Options Options
^^^^^^^ ^^^^^^^
*-a*, *--add* <class_name>|<instance_name> [-d 'DESKTOP_SEL' [--follow]] [--tags <name>|^<n>[,...]][--floating] [--fullscreen] [--locked] [--sticky] [--focus] [--frame] [--private] [--unmanage] [--one-shot]:: *-a*, *--add* <class_name>|<instance_name> [-d 'DESKTOP_SEL' [--follow]] [--floating] [--fullscreen] [--locked] [--sticky] [--focus] [--frame] [--private] [--unmanage] [--one-shot]::
Create a new rule. Create a new rule.
*-r*, *--remove* <name>|^<n>|tail|head...:: *-r*, *--remove* <name>|^<n>|tail|head...::
@ -725,12 +691,6 @@ Each item as the form '<type><value>' where '<type>' is the first character of t
'L(tiled|monocle)':: 'L(tiled|monocle)'::
Layout of the focused desktop of the focused monitor. Layout of the focused desktop of the focused monitor.
'T<tag_name>'::
Selected tag of the focused desktop of the focused monitor.
't<tag_name>'::
Non-selected tag of the focused desktop of the focused monitor.
Environment Variables Environment Variables
--------------------- ---------------------

View file

@ -146,7 +146,7 @@ void empty_history(void)
node_t *history_get_node(desktop_t *d, node_t *n) node_t *history_get_node(desktop_t *d, node_t *n)
{ {
for (history_t *h = history_tail; h != NULL; h = h->prev) for (history_t *h = history_tail; h != NULL; h = h->prev)
if (h->latest && h->loc.node != NULL && h->loc.node != n && h->loc.desktop == d && is_visible(h->loc.desktop, h->loc.node)) if (h->latest && h->loc.node != NULL && h->loc.node != n && h->loc.desktop == d)
return h->loc.node; return h->loc.node;
return NULL; return NULL;
} }
@ -177,7 +177,6 @@ bool history_find_node(history_dir_t hdi, coordinates_t *ref, coordinates_t *dst
if (!h->latest if (!h->latest
|| h->loc.node == NULL || h->loc.node == NULL
|| h->loc.node == ref->node || h->loc.node == ref->node
|| !is_visible(h->loc.desktop, h->loc.node)
|| !node_matches(&h->loc, ref, sel)) || !node_matches(&h->loc, ref, sel))
continue; continue;
if (!record_history) if (!record_history)

View file

@ -31,7 +31,6 @@
#include "ewmh.h" #include "ewmh.h"
#include "history.h" #include "history.h"
#include "monitor.h" #include "monitor.h"
#include "tag.h"
#include "pointer.h" #include "pointer.h"
#include "query.h" #include "query.h"
#include "restore.h" #include "restore.h"
@ -87,8 +86,6 @@ bool process_message(char **args, int num, char *rsp)
return cmd_monitor(++args, --num); return cmd_monitor(++args, --num);
} else if (streq("query", *args)) { } else if (streq("query", *args)) {
return cmd_query(++args, --num, rsp); return cmd_query(++args, --num, rsp);
} else if (streq("tag", *args)) {
return cmd_tag(++args, --num, rsp);
} else if (streq("restore", *args)) { } else if (streq("restore", *args)) {
return cmd_restore(++args, --num); return cmd_restore(++args, --num);
} else if (streq("control", *args)) { } else if (streq("control", *args)) {
@ -216,8 +213,6 @@ bool cmd_window(char **args, int num)
set_sticky(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->client->sticky)); set_sticky(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->client->sticky));
} else if (streq("private", key)) { } else if (streq("private", key)) {
set_private(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->client->private)); 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)));
} }
} else if (streq("-p", *args) || streq("--presel", *args)) { } else if (streq("-p", *args) || streq("--presel", *args)) {
num--, args++; num--, args++;
@ -547,138 +542,6 @@ bool cmd_monitor(char **args, int num)
return true; return true;
} }
bool cmd_tag(char **args, int num, char *rsp)
{
if (num < 1)
return false;
coordinates_t ref = {mon, mon->desk, mon->desk->focus};
coordinates_t trg = {NULL, NULL, NULL};
while (num > 0) {
if (streq("-d", *args) || streq("--desktop", *args)) {
num--, args++;
if (num < 1)
return false;
if (!desktop_from_desc(*args, &ref, &trg))
return false;
} else if (streq("-w", *args) || streq("--window", *args)) {
num--, args++;
if (num < 1)
return false;
if (!node_from_desc(*args, &ref, &trg))
return false;
} else if (streq("-s", *args) || streq("--set-tags", *args)) {
num--, args++;
if (num < 1 || trg.desktop == NULL)
return false;
unsigned int tf = 0;
if (streq("all", *args))
tf = (1 << num_tags) - 1;
else
while (num > 0) {
tag_t *tag = NULL;
int idx;
if (parse_index(*args, &idx))
tag = get_tag_by_index(idx - 1);
else
tag = get_tag(*args);
if (tag != NULL)
tf |= tag->mask;
num--, args++;
}
if (trg.node == NULL)
tag_desktop(trg.monitor, trg.desktop, tf);
else
tag_node(trg.monitor, trg.desktop, trg.node, trg.desktop, tf);
return true;
} else if (streq("-t", *args) || streq("--toggle-tags", *args)) {
num--, args++;
if (num < 1 || trg.desktop == NULL)
return false;
unsigned int tf;
if (trg.node == NULL)
tf = trg.desktop->tags_field;
else
tf = trg.node->client->tags_field;
while (num > 0) {
char *key;
bool value;
alter_state_t alt;
if (parse_bool_declaration(*args, &key, &value, &alt)) {
tag_t *tag = NULL;
int idx;
if (parse_index(key, &idx))
tag = get_tag_by_index(idx - 1);
else
tag = get_tag(key);
if (tag != NULL) {
if (alt == ALTER_SET) {
if (value)
tf |= tag->mask;
else
tf &= ~tag->mask;
} else {
tf ^= tag->mask;
}
}
}
num--, args++;
}
if (trg.node == NULL)
tag_desktop(trg.monitor, trg.desktop, tf);
else
tag_node(trg.monitor, trg.desktop, trg.node, trg.desktop, tf);
return true;
} else if (streq("-e", *args) || streq("--enumerate-tags", *args)) {
num--, args++;
if (num < 1)
return false;
int i = 0;
while (i < num_tags && num > 0) {
snprintf(tags[i]->name, sizeof(tags[i]->name), "%s", *args);
tags[i]->mask = 1 << i;
i++, num--, args++;
}
while (i < num_tags) {
remove_tag_by_index(i);
}
while (num > 0) {
add_tag(*args);
num--, args++;
}
put_status();
} else if (streq("-a", *args) || streq("--add", *args)) {
num--, args++;
if (num < 1)
return false;
while (num > 0) {
add_tag(*args);
num--, args++;
}
} else if (streq("-r", *args) || streq("--remove", *args)) {
num--, args++;
if (num < 1)
return false;
int idx;
while (num > 0) {
if (parse_index(*args, &idx))
remove_tag_by_index(idx - 1);
else
remove_tag(*args);
num--, args++;
}
} else if (streq("-l", *args) || streq("--list", *args)) {
list_tags(rsp);
} else {
return false;
}
num--, args++;
}
return true;
}
bool cmd_query(char **args, int num, char *rsp) bool cmd_query(char **args, int num, char *rsp)
{ {
coordinates_t ref = {mon, mon->desk, mon->desk->focus}; coordinates_t ref = {mon, mon->desk, mon->desk->focus};
@ -778,13 +641,6 @@ bool cmd_rule(char **args, int num, char *rsp)
rule->effect.unmanage = true; rule->effect.unmanage = true;
} else if (streq("--one-shot", *args)) { } else if (streq("--one-shot", *args)) {
rule->one_shot = true; rule->one_shot = true;
} else if (streq("--tags", *args)) {
num--, args++;
if (num < 1) {
free(rule);
return false;
}
snprintf(rule->effect.tags, sizeof(rule->effect.tags), "%s", *args);
} else if (streq("-d", *args) || streq("--desktop", *args)) { } else if (streq("-d", *args) || streq("--desktop", *args)) {
num--, args++; num--, args++;
if (num < 1) { if (num < 1) {

View file

@ -36,7 +36,6 @@ bool process_message(char **args, int num, char *rsp);
bool cmd_window(char **args, int num); bool cmd_window(char **args, int num);
bool cmd_desktop(char **args, int num); bool cmd_desktop(char **args, int num);
bool cmd_monitor(char **args, int num); bool cmd_monitor(char **args, int num);
bool cmd_tag(char **args, int num, char *rsp);
bool cmd_query(char **args, int num, char *rsp); bool cmd_query(char **args, int num, char *rsp);
bool cmd_rule(char **args, int num, char *rsp); bool cmd_rule(char **args, int num, char *rsp);
bool cmd_pointer(char **args, int num); bool cmd_pointer(char **args, int num);

View file

@ -68,7 +68,7 @@ void query_desktops(monitor_t *m, domain_t dom, coordinates_t loc, unsigned int
strncat(rsp, line, REMLEN(rsp)); strncat(rsp, line, REMLEN(rsp));
continue; continue;
} else { } else {
snprintf(line, sizeof(line), "%s %u %i %u %c", d->name, d->border_width, d->window_gap, d->tags_field, (d->layout == LAYOUT_TILED ? 'T' : 'M')); snprintf(line, sizeof(line), "%s %u %i %c", d->name, d->border_width, d->window_gap, (d->layout == LAYOUT_TILED ? 'T' : 'M'));
strncat(rsp, line, REMLEN(rsp)); strncat(rsp, line, REMLEN(rsp));
if (d == m->desk) if (d == m->desk)
strncat(rsp, " *", REMLEN(rsp)); strncat(rsp, " *", REMLEN(rsp));
@ -90,7 +90,7 @@ void query_tree(desktop_t *d, node_t *n, char *rsp, unsigned int depth)
if (is_leaf(n)) { if (is_leaf(n)) {
client_t *c = n->client; 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%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' : '-')); snprintf(line, sizeof(line), "%c %s 0x%X %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->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 { } 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); 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

@ -85,18 +85,17 @@ void restore_tree(char *file_path)
if (m == NULL) if (m == NULL)
continue; continue;
int wg; int wg;
unsigned int tf, bw; unsigned int bw;
char layout = 0, end = 0; char layout = 0, end = 0;
name[0] = '\0'; name[0] = '\0';
loc.desktop = NULL; loc.desktop = NULL;
sscanf(line + level, "%s %u %i %u %c %c", name, &bw, &wg, &tf, &layout, &end); sscanf(line + level, "%s %u %i %c %c", name, &bw, &wg, &layout, &end);
locate_desktop(name, &loc); locate_desktop(name, &loc);
d = loc.desktop; d = loc.desktop;
if (d == NULL) if (d == NULL)
continue; continue;
d->border_width = bw; d->border_width = bw;
d->window_gap = wg; d->window_gap = wg;
d->tags_field = tf;
if (layout == 'M') if (layout == 'M')
d->layout = LAYOUT_MONOCLE; d->layout = LAYOUT_MONOCLE;
else if (layout == 'T') else if (layout == 'T')
@ -138,7 +137,7 @@ void restore_tree(char *file_path)
client_t *c = make_client(XCB_NONE); client_t *c = make_client(XCB_NONE);
num_clients++; num_clients++;
char floating, transient, fullscreen, urgent, locked, sticky, frame, private, sd, sm, end = 0; 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); sscanf(line + level, "%c %s %X %u %hux%hu%hi%hi %c %c%c%c%c%c%c%c%c%c %c", &br, c->class_name, &c->window, &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->floating = (floating == '-' ? false : true);
c->transient = (transient == '-' ? false : true); c->transient = (transient == '-' ? false : true);
c->fullscreen = (fullscreen == '-' ? false : true); c->fullscreen = (fullscreen == '-' ? false : true);
@ -179,7 +178,7 @@ void restore_tree(char *file_path)
for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) { for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) {
uint32_t values[] = {get_event_mask(n->client)}; uint32_t values[] = {get_event_mask(n->client)};
xcb_change_window_attributes(dpy, n->client->window, XCB_CW_EVENT_MASK, values); xcb_change_window_attributes(dpy, n->client->window, XCB_CW_EVENT_MASK, values);
if (n->client->floating || !is_visible(d, n)) { if (n->client->floating) {
n->vacant = true; n->vacant = true;
update_vacant_state(n->parent); update_vacant_state(n->parent);
} }

22
rule.c
View file

@ -29,7 +29,6 @@
#include "window.h" #include "window.h"
#include "messages.h" #include "messages.h"
#include "query.h" #include "query.h"
#include "tag.h"
#include "rule.h" #include "rule.h"
rule_t *make_rule(void) rule_t *make_rule(void)
@ -46,7 +45,6 @@ rule_t *make_rule(void)
r->effect.unmanage = false; r->effect.unmanage = false;
r->one_shot = false; r->one_shot = false;
r->effect.desc[0] = '\0'; r->effect.desc[0] = '\0';
r->effect.tags[0] = '\0';
r->prev = NULL; r->prev = NULL;
r->next = NULL; r->next = NULL;
return r; return r;
@ -116,7 +114,7 @@ bool is_match(rule_t *r, xcb_window_t win)
return false; 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 *private, bool *manage) void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, 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; xcb_ewmh_get_atoms_reply_t win_type;
@ -196,20 +194,6 @@ void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, unsigned int *
*d = loc.desktop; *d = loc.desktop;
} }
} }
if (efc.tags[0] != '\0') {
char *name = strtok(efc.tags, LST_SEP);
while (name != NULL) {
int idx;
tag_t *tag = NULL;
if (parse_index(name, &idx))
tag = get_tag_by_index(idx - 1);
else
tag = get_tag(name);
if (tag != NULL)
*tags_field |= tag->mask;
name = strtok(NULL, LST_SEP);
}
}
} }
rule_t *next = rule->next; rule_t *next = rule->next;
if (rule->one_shot) if (rule->one_shot)
@ -256,10 +240,6 @@ void list_rules(char *pattern, char *rsp)
snprintf(line, sizeof(line), " -d %s", r->effect.desc); snprintf(line, sizeof(line), " -d %s", r->effect.desc);
strncat(rsp, line, REMLEN(rsp)); strncat(rsp, line, REMLEN(rsp));
} }
if (r->effect.tags[0] != '\0') {
snprintf(line, sizeof(line), " --tags %s", r->effect.tags);
strncat(rsp, line, REMLEN(rsp));
}
strncat(rsp, "\n", REMLEN(rsp)); strncat(rsp, "\n", REMLEN(rsp));
} }
} }

2
rule.h
View file

@ -34,7 +34,7 @@ void remove_rule(rule_t *r);
void remove_rule_by_name(char *name); void remove_rule_by_name(char *name);
bool remove_rule_by_index(int idx); bool remove_rule_by_index(int idx);
bool is_match(rule_t *r, xcb_window_t win); 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 *private, bool *manage); void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, 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); void list_rules(char *pattern, char *rsp);
#endif #endif

191
tag.c
View file

@ -1,191 +0,0 @@
/* * Copyright (c) 2012-2013 Bastien Dejean
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "bspwm.h"
#include "window.h"
#include "history.h"
#include "tree.h"
#include "tag.h"
tag_t *make_tag(char *name, int idx)
{
tag_t *tag = malloc(sizeof(tag_t));
if (tag != NULL) {
snprintf(tag->name, sizeof(tag->name), "%s", name);
tag->mask = 1 << idx;
}
return tag;
}
bool add_tag(char *name)
{
if (num_tags >= MAXTAGS)
return false;
tag_t *tag = make_tag(name, num_tags);
if (tag == NULL)
return false;
tags[num_tags] = tag;
num_tags++;
return true;
}
bool remove_tag(char *name)
{
for (int i = 0; i < num_tags; i++)
if (streq(tags[i]->name, name))
return remove_tag_by_index(i);
return false;
}
bool remove_tag_by_index(int i)
{
if (i >= num_tags)
return false;
for (monitor_t *m = mon_head; m != NULL; m = m->next)
for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
tag_desktop(m, d, d->tags_field & ~tags[i]->mask);
for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
tag_node(m, d, n, d, n->client->tags_field & ~tags[i]->mask);
}
free(tags[i]);
for (int j = i; j < (num_tags - 1); j++)
tags[j] = tags[j + 1];
tags[num_tags - 1] = NULL;
num_tags--;
return true;
}
tag_t *get_tag(char *name)
{
for (int i = 0; i < num_tags; i++)
if (streq(tags[i]->name, name))
return tags[i];
return NULL;
}
tag_t *get_tag_by_index(int i)
{
if (i >= num_tags)
return NULL;
return tags[i];
}
void set_visibility(monitor_t *m, desktop_t *d, node_t *n, bool visible)
{
PRINTF("set visibilty %X: %s\n", n->client->window, BOOLSTR(visible));
if (!n->client->floating) {
n->vacant = !visible;
update_vacant_state(n->parent);
if (visible)
rotate_brother(n);
else
unrotate_brother(n);
}
if (visible) {
if (m->desk == d)
window_show(n->client->window);
if (d->focus == NULL) {
if (mon->desk == d)
focus_node(m, d, n);
else
pseudo_focus(d, n);
}
} else {
if (m->desk == d || n->client->sticky)
window_hide(n->client->window);
if (d->focus == n) {
node_t *f = history_get_node(d, n);
if (f == NULL)
f = closest_visible(d, n);
if (mon->desk == d)
focus_node(m, d, f);
else
pseudo_focus(d, f);
}
}
}
void set_presence(monitor_t *m, desktop_t *d, node_t *n, bool present)
{
if (is_visible(d, n) != present) {
if (present)
tag_node(m, d, n, d, n->client->tags_field | d->tags_field);
else
tag_node(m, d, n, d, n->client->tags_field & ~d->tags_field);
}
}
void tag_node(monitor_t *m, desktop_t *d, node_t *n, desktop_t *ds, unsigned int tags_field)
{
if (num_tags < 1)
return;
bool visible = is_visible(ds, n);
n->client->tags_field = tags_field;
if ((visible && (tags_field & d->tags_field) == 0)
|| (!visible && (tags_field & d->tags_field) != 0)) {
set_visibility(m, d, n, !visible);
arrange(m, d);
}
}
void tag_desktop(monitor_t *m, desktop_t *d, unsigned int tags_field)
{
if (num_tags < 1)
return;
bool dirty = false;
unsigned int old_tags_field = d->tags_field;
d->tags_field = tags_field;
for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) {
bool old_visible = (old_tags_field & n->client->tags_field) != 0;
bool visible = (tags_field & n->client->tags_field) != 0;
if (old_visible != visible) {
set_visibility(m, d, n, visible);
dirty = true;
}
}
if (dirty)
arrange(m, d);
if (d == mon->desk)
put_status();
}
void list_tags(char *rsp)
{
char line[MAXLEN];
for (int i = 0; i < num_tags; i++) {
snprintf(line, sizeof(line), "%s %u\n", tags[i]->name, tags[i]->mask);
strncat(rsp, line, REMLEN(rsp));
}
}
void init_tags(void)
{
num_tags = 0;
for (int i = 0; i < MAXTAGS; i++)
tags[i] = NULL;
add_tag(DEFAULT_TAG_NAME);
}

52
tag.h
View file

@ -1,52 +0,0 @@
/* * Copyright (c) 2012-2013 Bastien Dejean
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BSPWM_TAG_H
#define BSPWM_TAG_H
#define MAXTAGS 32
#define DEFAULT_TAG_NAME "*"
typedef struct {
char name[SMALEN];
unsigned int mask;
} tag_t;
tag_t *tags[MAXTAGS];
int num_tags;
tag_t *make_tag(char *name, int idx);
bool add_tag(char *name);
bool remove_tag(char *name);
bool remove_tag_by_index(int i);
tag_t *get_tag(char *name);
tag_t *get_tag_by_index(int i);
void set_visibility(monitor_t *m, desktop_t *d, node_t *n, bool visible);
void set_presence(monitor_t *m, desktop_t *d, node_t *n, bool present);
void tag_node(monitor_t *m, desktop_t *d, node_t *n, desktop_t *ds, unsigned int tags_field);
void tag_desktop(monitor_t *m, desktop_t *d, unsigned int tags_field);
void list_tags(char *rsp);
void init_tags(void);
#endif

67
tree.c
View file

@ -33,7 +33,6 @@
#include "query.h" #include "query.h"
#include "settings.h" #include "settings.h"
#include "stack.h" #include "stack.h"
#include "tag.h"
#include "window.h" #include "window.h"
#include "tree.h" #include "tree.h"
@ -256,7 +255,7 @@ void insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f)
} }
if (n->client->private) if (n->client->private)
update_privacy_level(n, true); update_privacy_level(n, true);
if (d->focus == NULL && is_visible(d, n)) if (d->focus == NULL)
d->focus = n; d->focus = n;
if (n->client->sticky) if (n->client->sticky)
m->num_sticky++; m->num_sticky++;
@ -285,7 +284,7 @@ void focus_node(monitor_t *m, desktop_t *d, node_t *n)
a = b; a = b;
} }
sticky_still = true; sticky_still = true;
if (n == NULL && d->focus != NULL && is_visible(d, d->focus)) if (n == NULL && d->focus != NULL)
n = d->focus; n = d->focus;
} }
@ -322,8 +321,6 @@ void focus_node(monitor_t *m, desktop_t *d, node_t *n)
n->client->urgent = false; n->client->urgent = false;
if (!is_visible(d, n))
tag_node(m, d, n, d, n->client->tags_field | d->tags_field);
history_add(m, d, n); history_add(m, d, n);
set_input_focus(n); set_input_focus(n);
@ -382,11 +379,6 @@ client_t *make_client(xcb_window_t win)
return c; return c;
} }
bool is_visible(desktop_t *d, node_t *n)
{
return (d->tags_field & n->client->tags_field) != 0;
}
bool is_leaf(node_t *n) bool is_leaf(node_t *n)
{ {
return (n != NULL && n->first_child == NULL && n->second_child == NULL); return (n != NULL && n->first_child == NULL && n->second_child == NULL);
@ -445,29 +437,6 @@ node_t *brother_tree(node_t *n)
return n->parent->first_child; return n->parent->first_child;
} }
node_t *closest_visible(desktop_t *d, node_t *n)
{
if (n == NULL)
return NULL;
node_t *prev = prev_leaf(n, d->root);
node_t *next = next_leaf(n, d->root);
while (prev != NULL || next != NULL) {
if (prev != NULL) {
if (is_visible(d, prev))
return prev;
else
prev = prev_leaf(prev, d->root);
}
if (next != NULL) {
if (is_visible(d, next))
return next;
else
next = next_leaf(next, d->root);
}
}
return NULL;
}
void closest_public(desktop_t *d, node_t *n, node_t **closest, node_t **public) void closest_public(desktop_t *d, node_t *n, node_t **closest, node_t **public)
{ {
if (n == NULL) if (n == NULL)
@ -477,7 +446,7 @@ void closest_public(desktop_t *d, node_t *n, node_t **closest, node_t **public)
while (prev != NULL || next != NULL) { while (prev != NULL || next != NULL) {
#define TESTLOOP(n) \ #define TESTLOOP(n) \
if (n != NULL) { \ if (n != NULL) { \
if (is_visible(d, n) && is_tiled(n->client)) { \ if (is_tiled(n->client)) { \
if (n->privacy_level == 0) { \ if (n->privacy_level == 0) { \
if (n->parent == NULL || n->parent->privacy_level == 0) { \ if (n->parent == NULL || n->parent->privacy_level == 0) { \
*public = n; \ *public = n; \
@ -539,22 +508,22 @@ node_t *prev_leaf(node_t *n, node_t *r)
return second_extrema(p->parent->first_child); return second_extrema(p->parent->first_child);
} }
node_t *next_visible_leaf(desktop_t *d, node_t *n, node_t *r) node_t *next_tiled_leaf(desktop_t *d, node_t *n, node_t *r)
{ {
node_t *next = next_leaf(n, r); node_t *next = next_leaf(n, r);
if (next == NULL || is_visible(d, next)) if (next == NULL || is_tiled(next->client))
return next; return next;
else else
return next_visible_leaf(d, next, r); return next_tiled_leaf(d, next, r);
} }
node_t *prev_visible_leaf(desktop_t *d, node_t *n, node_t *r) node_t *prev_tiled_leaf(desktop_t *d, node_t *n, node_t *r)
{ {
node_t *prev = prev_leaf(n, r); node_t *prev = prev_leaf(n, r);
if (prev == NULL || is_visible(d, prev)) if (prev == NULL || is_tiled(prev->client))
return prev; return prev;
else else
return prev_visible_leaf(d, prev, r); return prev_tiled_leaf(d, prev, r);
} }
/* bool is_adjacent(node_t *a, node_t *r) */ /* bool is_adjacent(node_t *a, node_t *r) */
@ -611,7 +580,6 @@ node_t *find_fence(node_t *n, direction_t dir)
return NULL; return NULL;
} }
node_t *nearest_neighbor(monitor_t *m, desktop_t *d, node_t *n, direction_t dir, client_select_t sel) node_t *nearest_neighbor(monitor_t *m, desktop_t *d, node_t *n, direction_t dir, client_select_t sel)
{ {
if (n == NULL || n->client->fullscreen if (n == NULL || n->client->fullscreen
@ -691,7 +659,6 @@ node_t *nearest_from_distance(monitor_t *m, desktop_t *d, node_t *n, direction_t
for (node_t *a = first_extrema(target); a != NULL; a = next_leaf(a, target)) { for (node_t *a = first_extrema(target); a != NULL; a = next_leaf(a, target)) {
coordinates_t loc = {m, d, a}; coordinates_t loc = {m, d, a};
if (a == n || if (a == n ||
!is_visible(d, a) ||
!node_matches(&loc, &ref, sel) || !node_matches(&loc, &ref, sel) ||
is_tiled(a->client) != is_tiled(n->client) || is_tiled(a->client) != is_tiled(n->client) ||
(is_tiled(a->client) && !is_adjacent(n, a, dir))) (is_tiled(a->client) && !is_adjacent(n, a, dir)))
@ -745,7 +712,7 @@ node_t *find_biggest(monitor_t *m, desktop_t *d, node_t *n, client_select_t sel)
for (node_t *f = first_extrema(d->root); f != NULL; f = next_leaf(f, d->root)) { for (node_t *f = first_extrema(d->root); f != NULL; f = next_leaf(f, d->root)) {
coordinates_t loc = {m, d, f}; coordinates_t loc = {m, d, f};
if (!is_visible(d, f) || !is_tiled(f->client) || !node_matches(&loc, &ref, sel)) if (!is_tiled(f->client) || !node_matches(&loc, &ref, sel))
continue; continue;
int f_area = tiled_area(f); int f_area = tiled_area(f);
if (r == NULL) { if (r == NULL) {
@ -867,7 +834,7 @@ void unlink_node(monitor_t *m, desktop_t *d, node_t *n)
if (n == d->focus) { if (n == d->focus) {
d->focus = history_get_node(d, n); d->focus = history_get_node(d, n);
if (d->focus == NULL) if (d->focus == NULL)
d->focus = closest_visible(d, n); d->focus = first_extrema(d->root);
} }
if (n->client->private) if (n->client->private)
@ -1015,9 +982,6 @@ bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop
window_show(n2->client->window); window_show(n2->client->window);
} }
tag_node(m1, d1, n2, d2, n2->client->tags_field);
tag_node(m2, d2, n1, d1, n1->client->tags_field);
update_input_focus(); update_input_focus();
} }
@ -1068,7 +1032,6 @@ bool transfer_node(monitor_t *ms, desktop_t *ds, node_t *ns, monitor_t *md, desk
update_input_focus(); update_input_focus();
} }
tag_node(md, dd, ns, ds, ns->client->tags_field);
arrange(ms, ds); arrange(ms, ds);
if (ds != dd) if (ds != dd)
arrange(md, dd); arrange(md, dd);
@ -1104,17 +1067,17 @@ void circulate_leaves(monitor_t *m, desktop_t *d, circulate_dir_t dir)
node_t *p = d->focus->parent; node_t *p = d->focus->parent;
bool focus_first_child = is_first_child(d->focus); bool focus_first_child = is_first_child(d->focus);
node_t *head, *tail; node_t *head, *tail;
for (head = first_extrema(d->root); head != NULL && !is_visible(d, head); head = next_leaf(head, d->root)) for (head = first_extrema(d->root); head != NULL; head = next_leaf(head, d->root))
; ;
for (tail = second_extrema(d->root); tail != NULL && !is_visible(d, tail); tail = prev_leaf(tail, d->root)) for (tail = second_extrema(d->root); tail != NULL; tail = prev_leaf(tail, d->root))
; ;
if (head == tail) if (head == tail)
return; return;
if (dir == CIRCULATE_FORWARD) if (dir == CIRCULATE_FORWARD)
for (node_t *s = tail, *f = prev_visible_leaf(d, s, d->root); f != NULL; s = prev_visible_leaf(d, f, d->root), f = prev_visible_leaf(d, s, d->root)) for (node_t *s = tail, *f = prev_tiled_leaf(d, s, d->root); f != NULL; s = prev_tiled_leaf(d, f, d->root), f = prev_tiled_leaf(d, s, d->root))
swap_nodes(m, d, f, m, d, s); swap_nodes(m, d, f, m, d, s);
else else
for (node_t *f = head, *s = next_visible_leaf(d, f, d->root); s != NULL; f = next_visible_leaf(d, s, d->root), s = next_visible_leaf(d, f, d->root)) for (node_t *f = head, *s = next_tiled_leaf(d, f, d->root); s != NULL; f = next_tiled_leaf(d, s, d->root), s = next_tiled_leaf(d, f, d->root))
swap_nodes(m, d, f, m, d, s); swap_nodes(m, d, f, m, d, s);
if (focus_first_child) if (focus_first_child)
focus_node(m, d, p->first_child); focus_node(m, d, p->first_child);

6
tree.h
View file

@ -33,7 +33,6 @@ void focus_node(monitor_t *m, desktop_t *d, node_t *n);
void update_current(void); void update_current(void);
node_t *make_node(void); node_t *make_node(void);
client_t *make_client(xcb_window_t win); client_t *make_client(xcb_window_t win);
bool is_visible(desktop_t *d, node_t *n);
bool is_leaf(node_t *n); bool is_leaf(node_t *n);
bool is_tiled(client_t *c); bool is_tiled(client_t *c);
bool is_floating(client_t *c); bool is_floating(client_t *c);
@ -42,14 +41,13 @@ bool is_second_child(node_t *n);
void change_split_ratio(node_t *n, value_change_t chg); void change_split_ratio(node_t *n, value_change_t chg);
void reset_mode(coordinates_t *loc); void reset_mode(coordinates_t *loc);
node_t *brother_tree(node_t *n); 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); void closest_public(desktop_t *d, node_t *n, node_t **closest, node_t **public);
node_t *first_extrema(node_t *n); node_t *first_extrema(node_t *n);
node_t *second_extrema(node_t *n); node_t *second_extrema(node_t *n);
node_t *next_leaf(node_t *n, node_t *r); node_t *next_leaf(node_t *n, node_t *r);
node_t *prev_leaf(node_t *n, node_t *r); node_t *prev_leaf(node_t *n, node_t *r);
node_t *next_visible_leaf(desktop_t *d, node_t *n, node_t *r); node_t *next_tiled_leaf(desktop_t *d, node_t *n, node_t *r);
node_t *prev_visible_leaf(desktop_t *d, node_t *n, node_t *r); node_t *prev_tiled_leaf(desktop_t *d, node_t *n, node_t *r);
bool is_adjacent(node_t *a, node_t *b, direction_t dir); bool is_adjacent(node_t *a, node_t *b, direction_t dir);
node_t *find_fence(node_t *n, direction_t dir); node_t *find_fence(node_t *n, direction_t dir);
node_t *nearest_neighbor(monitor_t *m, desktop_t *d, node_t *n, direction_t dir, client_select_t sel); node_t *nearest_neighbor(monitor_t *m, desktop_t *d, node_t *n, direction_t dir, client_select_t sel);

View file

@ -166,7 +166,6 @@ typedef struct {
bool icccm_focus; bool icccm_focus;
xcb_rectangle_t floating_rectangle; xcb_rectangle_t floating_rectangle;
xcb_rectangle_t tiled_rectangle; xcb_rectangle_t tiled_rectangle;
unsigned int tags_field;
xcb_atom_t wm_state[MAX_STATE]; xcb_atom_t wm_state[MAX_STATE];
int num_states; int num_states;
} client_t; } client_t;
@ -197,7 +196,6 @@ struct desktop_t {
desktop_t *next; desktop_t *next;
int window_gap; int window_gap;
unsigned int border_width; unsigned int border_width;
unsigned int tags_field;
}; };
typedef struct monitor_t monitor_t; typedef struct monitor_t monitor_t;
@ -255,7 +253,6 @@ typedef struct {
bool frame; bool frame;
bool private; bool private;
char desc[MAXLEN]; char desc[MAXLEN];
char tags[MAXLEN];
} rule_effect_t; } rule_effect_t;
typedef struct rule_t rule_t; typedef struct rule_t rule_t;

View file

@ -31,7 +31,6 @@
#include "rule.h" #include "rule.h"
#include "settings.h" #include "settings.h"
#include "stack.h" #include "stack.h"
#include "tag.h"
#include "tree.h" #include "tree.h"
#include "window.h" #include "window.h"
@ -50,8 +49,7 @@ void manage_window(monitor_t *m, desktop_t *d, xcb_window_t win)
return; return;
bool floating = false, fullscreen = false, locked = false, sticky = false, follow = false, transient = false, takes_focus = true, frame = false, private = 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, &floating, &fullscreen, &locked, &sticky, &follow, &transient, &takes_focus, &frame, &private, &manage);
handle_rules(win, &m, &d, &tags_field, &floating, &fullscreen, &locked, &sticky, &follow, &transient, &takes_focus, &frame, &private, &manage);
if (!manage) { if (!manage) {
disable_floating_atom(win); disable_floating_atom(win);
@ -63,7 +61,6 @@ void manage_window(monitor_t *m, desktop_t *d, xcb_window_t win)
client_t *c = make_client(win); client_t *c = make_client(win);
update_floating_rectangle(c); update_floating_rectangle(c);
c->tags_field = (tags_field == 0 ? d->tags_field : tags_field);
c->frame = frame; c->frame = frame;
xcb_icccm_get_wm_class_reply_t reply; xcb_icccm_get_wm_class_reply_t reply;
@ -92,9 +89,6 @@ void manage_window(monitor_t *m, desktop_t *d, xcb_window_t win)
set_fullscreen(n, fullscreen); set_fullscreen(n, fullscreen);
c->transient = transient; c->transient = transient;
if (!is_visible(d, n))
set_visibility(m, d, n, false);
xcb_rectangle_t *frect = &n->client->floating_rectangle; xcb_rectangle_t *frect = &n->client->floating_rectangle;
if (frect->x == 0 && frect->y == 0) if (frect->x == 0 && frect->y == 0)
center(m->rectangle, frect); center(m->rectangle, frect);
@ -104,21 +98,17 @@ void manage_window(monitor_t *m, desktop_t *d, xcb_window_t win)
bool give_focus = (takes_focus && (d == mon->desk || follow)); bool give_focus = (takes_focus && (d == mon->desk || follow));
if (is_visible(d, n)) { if (give_focus)
if (give_focus) focus_node(m, d, n);
focus_node(m, d, n); else if (takes_focus)
else if (takes_focus) pseudo_focus(d, n);
pseudo_focus(d, n); else
else stack(n);
stack(n);
} else {
stack_under(n);
}
uint32_t values[] = {get_event_mask(n->client)}; uint32_t values[] = {get_event_mask(n->client)};
xcb_change_window_attributes(dpy, c->window, XCB_CW_EVENT_MASK, values); xcb_change_window_attributes(dpy, c->window, XCB_CW_EVENT_MASK, values);
if (visible && is_visible(d, n)) { if (visible) {
if (d == m->desk) if (d == m->desk)
window_show(n->client->window); window_show(n->client->window);
else else
@ -677,8 +667,7 @@ void toggle_visibility(void)
clear_input_focus(); clear_input_focus();
for (monitor_t *m = mon_head; m != NULL; m = m->next) for (monitor_t *m = mon_head; m != NULL; m = m->next)
for (node_t *n = first_extrema(m->desk->root); n != NULL; n = next_leaf(n, m->desk->root)) for (node_t *n = first_extrema(m->desk->root); n != NULL; n = next_leaf(n, m->desk->root))
if (is_visible(m->desk, n)) window_set_visibility(n->client->window, visible);
window_set_visibility(n->client->window, visible);
if (visible) if (visible)
update_input_focus(); update_input_focus();
} }