mirror of
https://github.com/vale981/bspwm
synced 2025-03-05 18:01:37 -05:00
Add *focused* modifier to desktops and monitors
This commit is contained in:
parent
512e9044e3
commit
d3166dd399
10 changed files with 115 additions and 48 deletions
18
doc/bspwm.1
18
doc/bspwm.1
|
@ -2,12 +2,12 @@
|
|||
.\" Title: bspwm
|
||||
.\" Author: [see the "Author" section]
|
||||
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
|
||||
.\" Date: 11/25/2015
|
||||
.\" Date: 11/26/2015
|
||||
.\" Manual: Bspwm Manual
|
||||
.\" Source: Bspwm 0.9
|
||||
.\" Language: English
|
||||
.\"
|
||||
.TH "BSPWM" "1" "11/25/2015" "Bspwm 0\&.9" "Bspwm Manual"
|
||||
.TH "BSPWM" "1" "11/26/2015" "Bspwm 0\&.9" "Bspwm Manual"
|
||||
.\" -----------------------------------------------------------------
|
||||
.\" * Define some portability stuff
|
||||
.\" -----------------------------------------------------------------
|
||||
|
@ -195,7 +195,7 @@ Select a desktop\&.
|
|||
.RS 4
|
||||
.\}
|
||||
.nf
|
||||
DESKTOP_SEL := (<desktop_name>|[MONITOR_SEL:](focused|^<n>)CYCLE_DIR|last|older|newer)[\&.[!]occupied][\&.[!]urgent][\&.[!]local]
|
||||
DESKTOP_SEL := (<desktop_name>|[MONITOR_SEL:](focused|^<n>)CYCLE_DIR|last|older|newer)[\&.[!]occupied][\&.[!]focused][\&.[!]urgent][\&.[!]local]
|
||||
.fi
|
||||
.if n \{\
|
||||
.RE
|
||||
|
@ -258,6 +258,11 @@ Selects the desktop newer than the focused desktop in the history\&.
|
|||
Only consider occupied or free desktops\&.
|
||||
.RE
|
||||
.PP
|
||||
[!]focused
|
||||
.RS 4
|
||||
Only consider focused or unfocused desktops\&.
|
||||
.RE
|
||||
.PP
|
||||
[!]urgent
|
||||
.RS 4
|
||||
Only consider urgent or non urgent desktops\&.
|
||||
|
@ -276,7 +281,7 @@ Select a monitor\&.
|
|||
.RS 4
|
||||
.\}
|
||||
.nf
|
||||
MONITOR_SEL := (<monitor_name>|^<n>|DIR|CYCLE_DIR|last|primary|focused|older|newer)[\&.[!]occupied]
|
||||
MONITOR_SEL := (<monitor_name>|^<n>|DIR|CYCLE_DIR|last|primary|focused|older|newer)[\&.[!]occupied][\&.[!]focused]
|
||||
.fi
|
||||
.if n \{\
|
||||
.RE
|
||||
|
@ -348,6 +353,11 @@ Selects the monitor newer than the focused monitor in the history\&.
|
|||
.RS 4
|
||||
Only consider monitors where the focused desktop is occupied or free\&.
|
||||
.RE
|
||||
.PP
|
||||
[!]focused
|
||||
.RS 4
|
||||
Only consider focused or unfocused monitors\&.
|
||||
.RE
|
||||
.RE
|
||||
.SH "WINDOW STATES"
|
||||
.PP
|
||||
|
|
|
@ -124,7 +124,7 @@ Desktop
|
|||
Select a desktop.
|
||||
|
||||
----
|
||||
DESKTOP_SEL := (<desktop_name>|[MONITOR_SEL:](focused|^<n>)CYCLE_DIR|last|older|newer)[.[!]occupied][.[!]urgent][.[!]local]
|
||||
DESKTOP_SEL := (<desktop_name>|[MONITOR_SEL:](focused|^<n>)CYCLE_DIR|last|older|newer)[.[!]occupied][.[!]focused][.[!]urgent][.[!]local]
|
||||
----
|
||||
|
||||
Primary Selectors
|
||||
|
@ -157,6 +157,9 @@ Modifiers
|
|||
[!]occupied::
|
||||
Only consider occupied or free desktops.
|
||||
|
||||
[!]focused::
|
||||
Only consider focused or unfocused desktops.
|
||||
|
||||
[!]urgent::
|
||||
Only consider urgent or non urgent desktops.
|
||||
|
||||
|
@ -169,7 +172,7 @@ Monitor
|
|||
Select a monitor.
|
||||
|
||||
----
|
||||
MONITOR_SEL := (<monitor_name>|^<n>|DIR|CYCLE_DIR|last|primary|focused|older|newer)[.[!]occupied]
|
||||
MONITOR_SEL := (<monitor_name>|^<n>|DIR|CYCLE_DIR|last|primary|focused|older|newer)[.[!]occupied][.[!]focused]
|
||||
----
|
||||
|
||||
Primary Selectors
|
||||
|
@ -208,6 +211,9 @@ Modifiers
|
|||
[!]occupied::
|
||||
Only consider monitors where the focused desktop is occupied or free.
|
||||
|
||||
[!]focused::
|
||||
Only consider focused or unfocused monitors.
|
||||
|
||||
|
||||
Window States
|
||||
-------------
|
||||
|
|
13
history.c
13
history.c
|
@ -205,22 +205,27 @@ bool history_find_desktop(history_dir_t hdi, coordinates_t *ref, coordinates_t *
|
|||
return false;
|
||||
}
|
||||
|
||||
bool history_find_monitor(history_dir_t hdi, coordinates_t *ref, coordinates_t *dst, desktop_select_t sel)
|
||||
bool history_find_monitor(history_dir_t hdi, coordinates_t *ref, coordinates_t *dst, monitor_select_t sel)
|
||||
{
|
||||
if (history_needle == NULL || record_history)
|
||||
if (history_needle == NULL || record_history) {
|
||||
history_needle = history_tail;
|
||||
}
|
||||
|
||||
history_t *h;
|
||||
|
||||
for (h = history_needle; h != NULL; h = (hdi == HISTORY_OLDER ? h->prev : h->next)) {
|
||||
if (!h->latest ||
|
||||
h->loc.monitor == ref->monitor ||
|
||||
!desktop_matches(&h->loc, ref, sel))
|
||||
!monitor_matches(&h->loc, ref, sel)) {
|
||||
continue;
|
||||
if (!record_history)
|
||||
}
|
||||
if (!record_history) {
|
||||
history_needle = h;
|
||||
}
|
||||
*dst = h->loc;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ desktop_t *history_get_desktop(monitor_t *m, desktop_t *d);
|
|||
monitor_t *history_get_monitor(monitor_t *m);
|
||||
bool history_find_node(history_dir_t hdi, coordinates_t *ref, coordinates_t *dst, client_select_t sel);
|
||||
bool history_find_desktop(history_dir_t hdi, coordinates_t *ref, coordinates_t *dst, desktop_select_t sel);
|
||||
bool history_find_monitor(history_dir_t hdi, coordinates_t *ref, coordinates_t *dst, desktop_select_t sel);
|
||||
bool history_find_monitor(history_dir_t hdi, coordinates_t *ref, coordinates_t *dst, monitor_select_t sel);
|
||||
int history_rank(desktop_t *d, node_t *n);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -544,7 +544,7 @@ int cmd_monitor(char **args, int num)
|
|||
return MSG_FAILURE;
|
||||
}
|
||||
if (auto_alternate && dst.monitor == mon) {
|
||||
desktop_select_t sel = make_desktop_select();
|
||||
monitor_select_t sel = make_monitor_select();
|
||||
history_find_monitor(HISTORY_OLDER, &trg, &dst, sel);
|
||||
}
|
||||
focus_node(dst.monitor, dst.monitor->desk, dst.monitor->desk->focus);
|
||||
|
|
24
monitor.c
24
monitor.c
|
@ -277,19 +277,23 @@ void swap_monitors(monitor_t *m1, monitor_t *m2)
|
|||
put_status(SBSC_MASK_REPORT);
|
||||
}
|
||||
|
||||
monitor_t *closest_monitor(monitor_t *m, cycle_dir_t dir, desktop_select_t sel)
|
||||
monitor_t *closest_monitor(monitor_t *m, cycle_dir_t dir, monitor_select_t sel)
|
||||
{
|
||||
monitor_t *f = (dir == CYCLE_PREV ? m->prev : m->next);
|
||||
if (f == NULL)
|
||||
|
||||
if (f == NULL) {
|
||||
f = (dir == CYCLE_PREV ? mon_tail : mon_head);
|
||||
}
|
||||
|
||||
while (f != m) {
|
||||
coordinates_t loc = {m, m->desk, NULL};
|
||||
if (desktop_matches(&loc, &loc, sel))
|
||||
coordinates_t loc = {m, NULL, NULL};
|
||||
if (monitor_matches(&loc, &loc, sel)) {
|
||||
return f;
|
||||
}
|
||||
f = (dir == CYCLE_PREV ? m->prev : m->next);
|
||||
if (f == NULL)
|
||||
if (f == NULL) {
|
||||
f = (dir == CYCLE_PREV ? mon_tail : mon_head);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -332,17 +336,19 @@ monitor_t *monitor_from_client(client_t *c)
|
|||
return nearest;
|
||||
}
|
||||
|
||||
monitor_t *nearest_monitor(monitor_t *m, direction_t dir, desktop_select_t sel)
|
||||
monitor_t *nearest_monitor(monitor_t *m, direction_t dir, monitor_select_t sel)
|
||||
{
|
||||
int dmin = INT_MAX;
|
||||
monitor_t *nearest = NULL;
|
||||
xcb_rectangle_t rect = m->rectangle;
|
||||
for (monitor_t *f = mon_head; f != NULL; f = f->next) {
|
||||
if (f == m)
|
||||
if (f == m) {
|
||||
continue;
|
||||
coordinates_t loc = {f, f->desk, NULL};
|
||||
if (!desktop_matches(&loc, &loc, sel))
|
||||
}
|
||||
coordinates_t loc = {f, NULL, NULL};
|
||||
if (!monitor_matches(&loc, &loc, 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)) ||
|
||||
|
|
|
@ -39,11 +39,11 @@ void add_monitor(monitor_t *m);
|
|||
void remove_monitor(monitor_t *m);
|
||||
void merge_monitors(monitor_t *ms, monitor_t *md);
|
||||
void swap_monitors(monitor_t *m1, monitor_t *m2);
|
||||
monitor_t *closest_monitor(monitor_t *m, cycle_dir_t dir, desktop_select_t sel);
|
||||
monitor_t *closest_monitor(monitor_t *m, cycle_dir_t dir, monitor_select_t sel);
|
||||
bool is_inside_monitor(monitor_t *m, xcb_point_t pt);
|
||||
monitor_t *monitor_from_point(xcb_point_t pt);
|
||||
monitor_t *monitor_from_client(client_t *c);
|
||||
monitor_t *nearest_monitor(monitor_t *m, direction_t dir, desktop_select_t sel);
|
||||
monitor_t *nearest_monitor(monitor_t *m, direction_t dir, monitor_select_t sel);
|
||||
bool update_monitors(void);
|
||||
|
||||
#endif
|
||||
|
|
82
query.c
82
query.c
|
@ -264,12 +264,28 @@ desktop_select_t make_desktop_select(void)
|
|||
{
|
||||
desktop_select_t sel = {
|
||||
.occupied = OPTION_NONE,
|
||||
.focused = OPTION_NONE,
|
||||
.urgent = OPTION_NONE,
|
||||
.local = OPTION_NONE
|
||||
};
|
||||
return sel;
|
||||
}
|
||||
|
||||
monitor_select_t make_monitor_select(void)
|
||||
{
|
||||
monitor_select_t sel = {
|
||||
.occupied = OPTION_NONE,
|
||||
.focused = OPTION_NONE
|
||||
};
|
||||
return sel;
|
||||
}
|
||||
|
||||
#define GET_MOD(k) \
|
||||
} else if (streq(#k, tok)) { \
|
||||
sel.k = OPTION_TRUE; \
|
||||
} else if (streq("!" #k, tok)) { \
|
||||
sel.k = OPTION_FALSE;
|
||||
|
||||
bool node_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
|
||||
{
|
||||
client_select_t sel = make_client_select();
|
||||
|
@ -277,11 +293,6 @@ bool node_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
|
|||
while ((tok = strrchr(desc, CAT_CHR)) != NULL) {
|
||||
tok[0] = '\0';
|
||||
tok++;
|
||||
#define GET_MOD(k) \
|
||||
} else if (streq(#k, tok)) { \
|
||||
sel.k = OPTION_TRUE; \
|
||||
} else if (streq("!" #k, tok)) { \
|
||||
sel.k = OPTION_FALSE;
|
||||
if (streq("tiled", tok)) {
|
||||
sel.tiled = OPTION_TRUE;
|
||||
} else if (streq("!tiled", tok)) {
|
||||
|
@ -302,7 +313,6 @@ bool node_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
|
|||
GET_MOD(above)
|
||||
}
|
||||
}
|
||||
#undef GET_MOD
|
||||
|
||||
dst->monitor = ref->monitor;
|
||||
dst->desktop = ref->desktop;
|
||||
|
@ -314,7 +324,7 @@ bool node_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
|
|||
if (parse_direction(desc, &dir)) {
|
||||
dst->node = nearest_neighbor(ref->monitor, ref->desktop, ref->node, dir, sel);
|
||||
if (dst->node == NULL && mon_head != mon_tail) {
|
||||
monitor_t *m = nearest_monitor(ref->monitor, dir, make_desktop_select());
|
||||
monitor_t *m = nearest_monitor(ref->monitor, dir, make_monitor_select());
|
||||
if (m != NULL) {
|
||||
coordinates_t loc = {m, m->desk, m->desk->focus};
|
||||
if (node_matches(&loc, ref, sel)) {
|
||||
|
@ -360,14 +370,9 @@ bool desktop_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
|
|||
sel.occupied = OPTION_TRUE;
|
||||
} else if (streq("!occupied", tok)) {
|
||||
sel.occupied = OPTION_FALSE;
|
||||
} else if (streq("urgent", tok)) {
|
||||
sel.urgent = OPTION_TRUE;
|
||||
} else if (streq("!urgent", tok)) {
|
||||
sel.urgent = OPTION_FALSE;
|
||||
} else if (streq("local", tok)) {
|
||||
sel.local = OPTION_TRUE;
|
||||
} else if (streq("!local", tok)) {
|
||||
sel.local = OPTION_FALSE;
|
||||
GET_MOD(focused)
|
||||
GET_MOD(urgent)
|
||||
GET_MOD(local)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -419,7 +424,7 @@ bool desktop_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
|
|||
|
||||
bool monitor_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
|
||||
{
|
||||
desktop_select_t sel = make_desktop_select();
|
||||
monitor_select_t sel = make_monitor_select();
|
||||
char *tok;
|
||||
while ((tok = strrchr(desc, CAT_CHR)) != NULL) {
|
||||
tok[0] = '\0';
|
||||
|
@ -428,6 +433,7 @@ bool monitor_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
|
|||
sel.occupied = OPTION_TRUE;
|
||||
} else if (streq("!occupied", tok)) {
|
||||
sel.occupied = OPTION_FALSE;
|
||||
GET_MOD(focused)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -447,31 +453,31 @@ bool monitor_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
|
|||
history_find_monitor(HISTORY_OLDER, ref, dst, sel);
|
||||
} else if (streq("primary", desc)) {
|
||||
if (pri_mon != NULL) {
|
||||
coordinates_t loc = {pri_mon, pri_mon->desk, NULL};
|
||||
if (desktop_matches(&loc, ref, sel)) {
|
||||
coordinates_t loc = {pri_mon, NULL, NULL};
|
||||
if (monitor_matches(&loc, ref, sel)) {
|
||||
dst->monitor = pri_mon;
|
||||
}
|
||||
}
|
||||
} else if (streq("focused", desc)) {
|
||||
coordinates_t loc = {mon, mon->desk, NULL};
|
||||
if (desktop_matches(&loc, ref, sel)) {
|
||||
coordinates_t loc = {mon, NULL, NULL};
|
||||
if (monitor_matches(&loc, ref, sel)) {
|
||||
dst->monitor = mon;
|
||||
}
|
||||
} else if (parse_index(desc, &idx)) {
|
||||
if (monitor_from_index(idx, dst)) {
|
||||
coordinates_t loc = {dst->monitor, dst->monitor->desk, NULL};
|
||||
return desktop_matches(&loc, ref, sel);
|
||||
monitor_matches(dst, ref, sel);
|
||||
}
|
||||
} else {
|
||||
if (locate_monitor(desc, dst)) {
|
||||
coordinates_t loc = {dst->monitor, dst->monitor->desk, NULL};
|
||||
return desktop_matches(&loc, ref, sel);
|
||||
return monitor_matches(dst, ref, sel);
|
||||
}
|
||||
}
|
||||
|
||||
return (dst->monitor != NULL);
|
||||
}
|
||||
|
||||
#undef GET_MOD
|
||||
|
||||
bool locate_window(xcb_window_t win, coordinates_t *loc)
|
||||
{
|
||||
for (monitor_t *m = mon_head; m != NULL; m = m->next)
|
||||
|
@ -625,7 +631,7 @@ bool node_matches(coordinates_t *loc, coordinates_t *ref, client_select_t sel)
|
|||
}
|
||||
|
||||
if (sel.focused != OPTION_NONE &&
|
||||
loc->node != loc->desktop->focus
|
||||
loc->node != mon->desk->focus
|
||||
? sel.focused == OPTION_TRUE
|
||||
: sel.focused == OPTION_FALSE) {
|
||||
return false;
|
||||
|
@ -643,6 +649,13 @@ bool desktop_matches(coordinates_t *loc, coordinates_t *ref, desktop_select_t se
|
|||
return false;
|
||||
}
|
||||
|
||||
if (sel.focused != OPTION_NONE &&
|
||||
mon->desk != loc->desktop
|
||||
? sel.focused == OPTION_TRUE
|
||||
: sel.focused == OPTION_FALSE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sel.urgent != OPTION_NONE &&
|
||||
!is_urgent(loc->desktop)
|
||||
? sel.urgent == OPTION_TRUE
|
||||
|
@ -659,3 +672,22 @@ bool desktop_matches(coordinates_t *loc, coordinates_t *ref, desktop_select_t se
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool monitor_matches(coordinates_t *loc, __attribute__((unused)) coordinates_t *ref, monitor_select_t sel)
|
||||
{
|
||||
if (sel.occupied != OPTION_NONE &&
|
||||
loc->monitor->desk->root == NULL
|
||||
? sel.occupied == OPTION_TRUE
|
||||
: sel.occupied == OPTION_FALSE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sel.focused != OPTION_NONE &&
|
||||
mon != loc->monitor
|
||||
? sel.focused == OPTION_TRUE
|
||||
: sel.focused == OPTION_FALSE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
2
query.h
2
query.h
|
@ -47,6 +47,7 @@ void query_windows(coordinates_t loc, FILE *rsp);
|
|||
void query_names(domain_t dom, coordinates_t loc, FILE *rsp);
|
||||
client_select_t make_client_select(void);
|
||||
desktop_select_t make_desktop_select(void);
|
||||
monitor_select_t make_monitor_select(void);
|
||||
bool node_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst);
|
||||
bool desktop_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst);
|
||||
bool monitor_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst);
|
||||
|
@ -57,5 +58,6 @@ bool desktop_from_index(int i, coordinates_t *loc, monitor_t *mm);
|
|||
bool monitor_from_index(int i, coordinates_t *loc);
|
||||
bool node_matches(coordinates_t *loc, coordinates_t *ref, client_select_t sel);
|
||||
bool desktop_matches(coordinates_t *loc, coordinates_t *ref, desktop_select_t sel);
|
||||
bool monitor_matches(coordinates_t *loc, __attribute__((unused)) coordinates_t *ref, monitor_select_t sel);
|
||||
|
||||
#endif
|
||||
|
|
6
types.h
6
types.h
|
@ -146,10 +146,16 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
option_bool_t occupied;
|
||||
option_bool_t focused;
|
||||
option_bool_t urgent;
|
||||
option_bool_t local;
|
||||
} desktop_select_t;
|
||||
|
||||
typedef struct {
|
||||
option_bool_t occupied;
|
||||
option_bool_t focused;
|
||||
} monitor_select_t;
|
||||
|
||||
typedef struct {
|
||||
xcb_window_t window;
|
||||
char class_name[3 * SMALEN / 2];
|
||||
|
|
Loading…
Add table
Reference in a new issue