mirror of
https://github.com/vale981/bspwm
synced 2025-03-06 10:11:43 -05:00
Merge remote-tracking branch 'stebalien/apply-modifiers-to-everything'
This commit is contained in:
commit
e865e656ec
3 changed files with 91 additions and 48 deletions
21
query.c
21
query.c
|
@ -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)) {
|
||||
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)) {
|
||||
if (desktop_matches(mon->last_desk, sel)) {
|
||||
dst->monitor = mon;
|
||||
dst->desktop = mon->last_desk;
|
||||
}
|
||||
} else if (streq("focused", desc)) {
|
||||
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)) {
|
||||
if (desktop_matches(last_mon->desk, sel)) {
|
||||
dst->monitor = last_mon;
|
||||
}
|
||||
} else if (streq("focused", desc)) {
|
||||
if (desktop_matches(mon->desk, sel)) {
|
||||
dst->monitor = mon;
|
||||
}
|
||||
} else {
|
||||
locate_monitor(desc, dst);
|
||||
}
|
||||
|
|
88
tree.c
88
tree.c
|
@ -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
12
tree.h
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue