Merge remote-tracking branch 'stebalien/apply-modifiers-to-everything'

This commit is contained in:
Bastien Dejean 2013-07-13 22:57:09 +02:00
commit e865e656ec
3 changed files with 91 additions and 48 deletions

39
query.c
View file

@ -150,17 +150,22 @@ bool node_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
direction_t dir;
cycle_dir_t cyc;
if (parse_direction(desc, &dir)) {
dst->node = nearest_neighbor(dst->desktop, ref->node, dir);
dst->node = nearest_neighbor(dst->desktop, ref->node, dir, sel);
} else if (parse_cycle_direction(desc, &cyc)) {
dst->node = closest_node(ref->desktop, ref->node, cyc, sel);
} else if (streq("last", desc)) {
dst->node = history_get(ref->desktop->history, 1);
int i = 1;
do {
dst->node = history_get(ref->desktop->history, i++);
} while (dst->node != NULL && (dst->node == ref->node || !node_matches(ref->node, dst->node, sel)));
} else if (streq("biggest", desc)) {
dst->node = find_biggest(ref->desktop);
dst->node = find_biggest(ref->desktop, ref->node, sel);
} else if (streq("focused", desc)) {
dst->monitor = mon;
dst->desktop = mon->desk;
dst->node = mon->desk->focus;
if (node_matches(ref->node, dst->node, sel)) {
dst->monitor = mon;
dst->desktop = mon->desk;
dst->node = mon->desk->focus;
}
} else {
long int wid;
if (parse_window_id(desc, &wid))
@ -192,11 +197,15 @@ bool desktop_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
dst->monitor = ref->monitor;
dst->desktop = closest_desktop(ref->monitor, ref->desktop, cyc, sel);
} else if (streq("last", desc)) {
dst->monitor = mon;
dst->desktop = mon->last_desk;
if (desktop_matches(mon->last_desk, sel)) {
dst->monitor = mon;
dst->desktop = mon->last_desk;
}
} else if (streq("focused", desc)) {
dst->monitor = mon;
dst->desktop = mon->desk;
if (desktop_matches(mon->desk, sel)) {
dst->monitor = mon;
dst->desktop = mon->desk;
}
} else {
locate_desktop(desc, dst);
}
@ -224,13 +233,17 @@ bool monitor_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
direction_t dir;
cycle_dir_t cyc;
if (parse_direction(desc, &dir)) {
dst->monitor = nearest_monitor(ref->monitor, dir);
dst->monitor = nearest_monitor(ref->monitor, dir, sel);
} else if (parse_cycle_direction(desc, &cyc)) {
dst->monitor = closest_monitor(ref->monitor, cyc, sel);
} else if (streq("last", desc)) {
dst->monitor = last_mon;
if (desktop_matches(last_mon->desk, sel)) {
dst->monitor = last_mon;
}
} else if (streq("focused", desc)) {
dst->monitor = mon;
if (desktop_matches(mon->desk, sel)) {
dst->monitor = mon;
}
} else {
locate_monitor(desc, dst);
}

88
tree.c
View file

@ -39,6 +39,43 @@ bool is_second_child(node_t *n)
return (n != NULL && n->parent != NULL && n->parent->second_child == n);
}
/**
* Check if the specified node matches the selection criteria.
*
* Arguments:
* node_t *c - the active node
* node_t *t - the node to test
* client_sel_t sel - the selection criteria
*
* Returns true if the node matches.
**/
bool node_matches(node_t *c, node_t *t, client_select_t sel)
{
if (sel.type != CLIENT_TYPE_ALL &&
is_tiled(t->client)
? sel.type == CLIENT_TYPE_FLOATING
: sel.type == CLIENT_TYPE_TILED
) return false;
if (sel.class != CLIENT_CLASS_ALL &&
streq(c->client->class_name, t->client->class_name)
? sel.class == CLIENT_CLASS_DIFFER
: sel.class == CLIENT_CLASS_EQUAL
) return false;
return true;
}
bool desktop_matches(desktop_t *t, desktop_select_t sel) {
if (sel != DESKTOP_ALL &&
t->root == NULL
? sel == DESKTOP_OCCUPIED
: sel == DESKTOP_FREE
) return false;
return true;
}
void change_split_ratio(node_t *n, value_change_t chg)
{
n->split_ratio = pow(n->split_ratio,
@ -165,7 +202,7 @@ node_t *find_fence(node_t *n, direction_t dir)
}
node_t *nearest_neighbor(desktop_t *d, node_t *n, direction_t dir)
node_t *nearest_neighbor(desktop_t *d, node_t *n, direction_t dir, client_select_t sel)
{
if (n == NULL || n->client->fullscreen
|| (d->layout == LAYOUT_MONOCLE && is_tiled(n->client)))
@ -173,13 +210,13 @@ node_t *nearest_neighbor(desktop_t *d, node_t *n, direction_t dir)
node_t *nearest = NULL;
if (history_aware_focus)
nearest = nearest_from_history(d->history, n, dir);
nearest = nearest_from_history(d->history, n, dir, sel);
if (nearest == NULL)
nearest = nearest_from_distance(d, n, dir);
nearest = nearest_from_distance(d, n, dir, sel);
return nearest;
}
node_t *nearest_from_history(focus_history_t *f, node_t *n, direction_t dir)
node_t *nearest_from_history(focus_history_t *f, node_t *n, direction_t dir, client_select_t sel)
{
if (n == NULL || !is_tiled(n->client))
return NULL;
@ -198,6 +235,9 @@ node_t *nearest_from_history(focus_history_t *f, node_t *n, direction_t dir)
for (node_t *a = first_extrema(target); a != NULL; a = next_leaf(a, target)) {
if (a->vacant || !is_adjacent(n, a, dir) || a == n)
continue;
if (!node_matches(n, a, sel))
continue;
int rank = history_rank(f, a);
if (rank >= 0 && rank < min_rank) {
nearest = a;
@ -208,7 +248,7 @@ node_t *nearest_from_history(focus_history_t *f, node_t *n, direction_t dir)
return nearest;
}
node_t *nearest_from_distance(desktop_t *d, node_t *n, direction_t dir)
node_t *nearest_from_distance(desktop_t *d, node_t *n, direction_t dir, client_select_t sel)
{
if (n == NULL)
return NULL;
@ -236,10 +276,11 @@ node_t *nearest_from_distance(desktop_t *d, node_t *n, direction_t dir)
double ds = DBL_MAX;
for (node_t *a = first_extrema(target); a != NULL; a = next_leaf(a, target)) {
if (is_tiled(a->client) != is_tiled(n->client)
|| (is_tiled(a->client) && !is_adjacent(n, a, dir))
|| a == n)
continue;
if (a == n) continue;
if (!node_matches(n, a, sel)) continue;
if (is_tiled(a->client) != is_tiled(n->client)) continue;
if (is_tiled(a->client) && !is_adjacent(n, a, dir)) continue;
get_side_handle(a->client, dir2, &pt2);
double ds2 = distance(pt, pt2);
if (ds2 < ds) {
@ -277,7 +318,7 @@ int tiled_area(node_t *n)
return rect.width * rect.height;
}
node_t *find_biggest(desktop_t *d)
node_t *find_biggest(desktop_t *d, node_t *c, client_select_t sel)
{
if (d == NULL)
return NULL;
@ -286,7 +327,7 @@ node_t *find_biggest(desktop_t *d)
int r_area = tiled_area(r);
for (node_t *f = first_extrema(d->root); f != NULL; f = next_leaf(f, d->root)) {
if (!is_tiled(f->client))
if (!is_tiled(f->client) || !node_matches(c, f, sel))
continue;
int f_area = tiled_area(f);
if (r == NULL) {
@ -854,7 +895,7 @@ void select_monitor(monitor_t *m)
put_status();
}
monitor_t *nearest_monitor(monitor_t *m, direction_t dir)
monitor_t *nearest_monitor(monitor_t *m, direction_t dir, desktop_select_t sel)
{
int dmin = INT_MAX;
monitor_t *nearest = NULL;
@ -862,6 +903,8 @@ monitor_t *nearest_monitor(monitor_t *m, direction_t dir)
for (monitor_t *f = mon_head; f != NULL; f = f->next) {
if (f == m)
continue;
if (desktop_matches(f->desk, sel))
continue;
xcb_rectangle_t r = f->rectangle;
if ((dir == DIR_LEFT && r.x < rect.x) ||
(dir == DIR_RIGHT && r.x >= (rect.x + rect.width)) ||
@ -904,11 +947,8 @@ monitor_t *closest_monitor(monitor_t *m, cycle_dir_t dir, desktop_select_t sel)
f = (dir == CYCLE_PREV ? mon_tail : mon_head);
while (f != m) {
if (sel == DESKTOP_ALL
|| (sel == DESKTOP_FREE && f->desk->root == NULL)
|| (sel == DESKTOP_OCCUPIED && f->desk->root != NULL)) {
if (desktop_matches(f->desk, sel))
return f;
}
f = (dir == CYCLE_PREV ? m->prev : m->next);
if (f == NULL)
f = (dir == CYCLE_PREV ? mon_tail : mon_head);
@ -924,11 +964,8 @@ desktop_t *closest_desktop(monitor_t *m, desktop_t *d, cycle_dir_t dir, desktop_
f = (dir == CYCLE_PREV ? m->desk_tail : m->desk_head);
while (f != d) {
if (sel == DESKTOP_ALL
|| (sel == DESKTOP_FREE && f->root == NULL)
|| (sel == DESKTOP_OCCUPIED && f->root != NULL)) {
if (desktop_matches(f, sel))
return f;
}
f = (dir == CYCLE_PREV ? f->prev : f->next);
if (f == NULL)
f = (dir == CYCLE_PREV ? m->desk_tail : m->desk_head);
@ -947,17 +984,8 @@ node_t *closest_node(desktop_t *d, node_t *n, cycle_dir_t dir, client_select_t s
f = (dir == CYCLE_PREV ? second_extrema(d->root) : first_extrema(d->root));
while (f != n) {
bool tiled = is_tiled(f->client);
if ((sel.type == CLIENT_TYPE_ALL
|| (tiled && sel.type == CLIENT_TYPE_TILED)
|| (!tiled && sel.type == CLIENT_TYPE_FLOATING)) &&
(sel.class == CLIENT_CLASS_ALL
|| (sel.class == CLIENT_CLASS_EQUAL
&& streq(f->client->class_name, n->client->class_name))
|| (sel.class == CLIENT_CLASS_DIFFER
&& !streq(f->client->class_name, n->client->class_name)))) {
if (node_matches(n, f, sel))
return f;
}
f = (dir == CYCLE_PREV ? prev_leaf(f, d->root) : next_leaf(f, d->root));
if (f == NULL)
f = (dir == CYCLE_PREV ? second_extrema(d->root) : first_extrema(d->root));

12
tree.h
View file

@ -3,6 +3,8 @@
#define GROWTH_FACTOR 1.1
bool node_matches(node_t *, node_t *, client_select_t);
bool desktop_matches(desktop_t *, desktop_select_t);
void arrange(monitor_t *, desktop_t *);
void apply_layout(monitor_t *, desktop_t *, node_t *, xcb_rectangle_t, xcb_rectangle_t);
void focus_node(monitor_t *, desktop_t *, node_t *);
@ -13,10 +15,10 @@ void swap_nodes(node_t *, node_t *);
void pseudo_focus(desktop_t *, node_t *);
void update_current(void);
node_t *find_fence(node_t *, direction_t);
node_t *nearest_neighbor(desktop_t *, node_t *, direction_t);
node_t *nearest_from_distance(desktop_t *, node_t *, direction_t);
node_t *nearest_from_history(focus_history_t *, node_t *, direction_t);
node_t *find_biggest(desktop_t *);
node_t *nearest_neighbor(desktop_t *, node_t *, direction_t, client_select_t);
node_t *nearest_from_distance(desktop_t *, node_t *, direction_t, client_select_t);
node_t *nearest_from_history(focus_history_t *, node_t *, direction_t, client_select_t);
node_t *find_biggest(desktop_t *, node_t *, client_select_t);
bool is_leaf(node_t *);
bool is_tiled(client_t *);
bool is_floating(client_t *);
@ -45,7 +47,7 @@ void transfer_node(monitor_t *, desktop_t *, monitor_t *, desktop_t *, node_t *)
void transplant_node(monitor_t *, desktop_t *, node_t *, node_t *);
void select_monitor(monitor_t *);
void select_desktop(monitor_t *, desktop_t *);
monitor_t *nearest_monitor(monitor_t *, direction_t);
monitor_t *nearest_monitor(monitor_t *, direction_t, desktop_select_t);
node_t *closest_node(desktop_t *, node_t *, cycle_dir_t, client_select_t);
desktop_t *closest_desktop(monitor_t *, desktop_t *, cycle_dir_t, desktop_select_t);
monitor_t *closest_monitor(monitor_t *, cycle_dir_t, desktop_select_t);