Stack in terms of relative actions

This rewrite is based on a TODO comment for the *stack_refresh*
function of *awesome*:
    It might be worth stopping to restack everyone and only stack `c'
    relatively to the first matching in the list.

And on the concept of relative stacking (via XDG_CONFIG_WINDOW_SIBLING).

Additionally the `adaptative_raise` setting was removed because it
became obsolete when the choice was made of not raising windows when
focusing via `focus_follows_pointer`.

Windows of type *desktop* are now supported (but not managed).
This commit is contained in:
Bastien Dejean 2013-09-12 16:26:01 +02:00
parent 758f5e6392
commit a0b9199df5
11 changed files with 70 additions and 39 deletions

View file

@ -6,7 +6,7 @@ helpers.o: helpers.c bspwm.h helpers.h types.h
messages.o: messages.c bspwm.h common.h events.h ewmh.h helpers.h messages.h query.h restore.h rules.h settings.h tree.h types.h window.h
query.o: query.c bspwm.h helpers.h messages.h query.h settings.h tree.h types.h
restore.o: restore.c bspwm.h ewmh.h helpers.h query.h restore.h settings.h tree.h types.h
rules.o: rules.c bspwm.h ewmh.h helpers.h query.h rules.h types.h
rules.o: rules.c bspwm.h ewmh.h helpers.h query.h rules.h types.h window.h
settings.o: settings.c bspwm.h common.h helpers.h settings.h types.h
tree.o: tree.c bspwm.h ewmh.h helpers.h settings.h tree.h types.h window.h
types.o: types.c bspwm.h ewmh.h helpers.h rules.h settings.h tree.h types.h window.h

View file

@ -208,6 +208,7 @@ void setup(void)
ewmh->_NET_WM_STATE_DEMANDS_ATTENTION,
ewmh->_NET_WM_WINDOW_TYPE,
ewmh->_NET_WM_WINDOW_TYPE_DOCK,
ewmh->_NET_WM_WINDOW_TYPE_DESKTOP,
ewmh->_NET_WM_WINDOW_TYPE_NOTIFICATION,
ewmh->_NET_WM_WINDOW_TYPE_DIALOG,
ewmh->_NET_WM_WINDOW_TYPE_UTILITY,

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 urgent_border_color border_width window_gap split_ratio borderless_monocle gapless_monocle focus_follows_pointer pointer_follows_monitor adaptative_raise apply_floating_atom auto_alternate auto_cancel history_aware_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 urgent_border_color border_width window_gap split_ratio borderless_monocle gapless_monocle focus_follows_pointer pointer_follows_monitor apply_floating_atom auto_alternate auto_cancel history_aware_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' 'urgent_border_color' 'border_width' 'window_gap' 'split_ratio' 'borderless_monocle' 'gapless_monocle' 'focus_follows_pointer' 'pointer_follows_monitor' 'adaptative_raise' 'apply_floating_atom' 'auto_alternate' 'auto_cancel' 'history_aware_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' 'urgent_border_color' 'border_width' 'window_gap' 'split_ratio' 'borderless_monocle' 'gapless_monocle' 'focus_follows_pointer' 'pointer_follows_monitor' 'apply_floating_atom' 'auto_alternate' 'auto_cancel' 'history_aware_focus')
if (( CURRENT == 2 )) ; then
_values 'command' "$commands[@]"
elif (( CURRENT == 3 )) ; then

View file

@ -778,7 +778,6 @@ bool set_setting(coordinates_t loc, char *name, char *value)
SETBOOL(borderless_monocle)
SETBOOL(gapless_monocle)
SETBOOL(pointer_follows_monitor)
SETBOOL(adaptative_raise)
SETBOOL(apply_floating_atom)
SETBOOL(auto_alternate)
SETBOOL(auto_cancel)
@ -825,7 +824,6 @@ bool get_setting(coordinates_t loc, char *name, char* rsp)
GETBOOL(gapless_monocle)
GETBOOL(focus_follows_pointer)
GETBOOL(pointer_follows_monitor)
GETBOOL(adaptative_raise)
GETBOOL(apply_floating_atom)
GETBOOL(auto_alternate)
GETBOOL(auto_cancel)

View file

@ -2,6 +2,7 @@
#include <string.h>
#include <xcb/xcb_icccm.h>
#include <xcb/xcb_ewmh.h>
#include "window.h"
#include "types.h"
#include "bspwm.h"
#include "ewmh.h"
@ -73,8 +74,10 @@ void handle_rules(xcb_window_t win, monitor_t **m, desktop_t **d, bool *floating
*takes_focus = false;
} else if (a == ewmh->_NET_WM_WINDOW_TYPE_DIALOG) {
*floating = true;
} else if (a == ewmh->_NET_WM_WINDOW_TYPE_DOCK || a == ewmh->_NET_WM_WINDOW_TYPE_NOTIFICATION) {
} else if (a == ewmh->_NET_WM_WINDOW_TYPE_DOCK || a == ewmh->_NET_WM_WINDOW_TYPE_DESKTOP || a == ewmh->_NET_WM_WINDOW_TYPE_NOTIFICATION) {
*manage = false;
if (a == ewmh->_NET_WM_WINDOW_TYPE_DESKTOP)
window_lower(win);
}
}
xcb_ewmh_get_atoms_reply_wipe(&win_type);

View file

@ -44,7 +44,6 @@ void load_settings(void)
gapless_monocle = GAPLESS_MONOCLE;
focus_follows_pointer = FOCUS_FOLLOWS_POINTER;
pointer_follows_monitor = POINTER_FOLLOWS_MONITOR;
adaptative_raise = ADAPTATIVE_RAISE;
apply_floating_atom = APPLY_FLOATING_ATOM;
auto_alternate = AUTO_ALTERNATE;
auto_cancel = AUTO_CANCEL;

View file

@ -26,7 +26,6 @@
#define POINTER_FOLLOWS_MONITOR false
#define AUTO_ALTERNATE false
#define AUTO_CANCEL false
#define ADAPTATIVE_RAISE false
#define APPLY_FLOATING_ATOM false
char focused_border_color[MAXLEN];
@ -45,7 +44,6 @@ bool borderless_monocle;
bool gapless_monocle;
bool focus_follows_pointer;
bool pointer_follows_monitor;
bool adaptative_raise;
bool apply_floating_atom;
bool auto_alternate;
bool auto_cancel;

8
tree.c
View file

@ -664,10 +664,11 @@ void insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f)
void pseudo_focus(desktop_t *d, node_t *n)
{
if (d->focus == n)
if (n == NULL || d->focus == n)
return;
d->focus = n;
history_add(d->history, n);
stack(d, n);
}
void focus_node(monitor_t *m, desktop_t *d, node_t *n)
@ -705,8 +706,6 @@ void focus_node(monitor_t *m, desktop_t *d, node_t *n)
n->client->urgent = false;
pseudo_focus(d, n);
stack(d, n);
set_input_focus(n);
if (focus_follows_pointer) {
@ -885,9 +884,6 @@ void transfer_node(monitor_t *ms, desktop_t *ds, monitor_t *md, desktop_t *dd, n
pseudo_focus(dd, n);
if (md->desk == dd)
stack(dd, n);
arrange(ms, ds);
arrange(md, dd);

View file

@ -28,14 +28,6 @@ bool contains(xcb_rectangle_t a, xcb_rectangle_t b)
&& a.y <= b.y && (a.y + a.height) >= (b.y + b.height));
}
bool might_cover(desktop_t *d, node_t *n)
{
for (node_t *f = first_extrema(d->root); f != NULL; f = next_leaf(f, d->root))
if (f != n && is_floating(f->client) && contains(n->client->floating_rectangle, f->client->floating_rectangle))
return true;
return false;
}
bool is_inside(monitor_t *m, xcb_point_t pt)
{
xcb_rectangle_t r = m->rectangle;
@ -140,17 +132,20 @@ void manage_window(monitor_t *m, desktop_t *d, xcb_window_t win)
if (fullscreen)
set_fullscreen(d, n, true);
if (is_tiled(c))
window_lower(c->window);
c->transient = transient;
bool give_focus = takes_focus && (d == mon->desk || follow);
bool give_focus = (takes_focus && (d == mon->desk || follow));
if (give_focus)
if (give_focus) {
focus_node(m, d, n);
else if (takes_focus)
} else if (takes_focus) {
pseudo_focus(d, n);
} else {
node_t *f = d->focus;
pseudo_focus(d, n);
if (f != NULL)
pseudo_focus(d, f);
}
xcb_rectangle_t *frect = &n->client->floating_rectangle;
if (frect->x == 0 && frect->y == 0)
@ -309,13 +304,13 @@ void set_fullscreen(desktop_t *d, node_t *n, bool value)
c->fullscreen = true;
xcb_atom_t values[] = {ewmh->_NET_WM_STATE_FULLSCREEN};
xcb_ewmh_set_wm_state(ewmh, c->window, LENGTH(values), values);
window_raise(c->window);
} else {
c->fullscreen = false;
xcb_atom_t values[] = {XCB_NONE};
xcb_ewmh_set_wm_state(ewmh, c->window, LENGTH(values), values);
stack(d, n);
}
stack(d, n);
}
void set_floating(desktop_t *d, node_t *n, bool value)
@ -329,6 +324,7 @@ void set_floating(desktop_t *d, node_t *n, bool value)
client_t *c = n->client;
c->floating = n->vacant = value;
update_vacant_state(n->parent);
if (value) {
enable_floating_atom(c->window);
unrotate_brother(n);
@ -336,6 +332,7 @@ void set_floating(desktop_t *d, node_t *n, bool value)
disable_floating_atom(c->window);
rotate_brother(n);
}
stack(d, n);
}
@ -425,7 +422,9 @@ void update_floating_rectangle(client_t *c)
void query_pointer(xcb_window_t *win, xcb_point_t *pt)
{
window_lower(motion_recorder);
xcb_query_pointer_reply_t *qpr = xcb_query_pointer_reply(dpy, xcb_query_pointer(dpy, root), NULL);
if (qpr != NULL) {
if (win != NULL)
*win = qpr->child;
@ -433,6 +432,7 @@ void query_pointer(xcb_window_t *win, xcb_point_t *pt)
*pt = (xcb_point_t) {qpr->root_x, qpr->root_y};
free(qpr);
}
window_raise(motion_recorder);
}
@ -476,19 +476,53 @@ void window_raise(xcb_window_t win)
xcb_configure_window(dpy, win, XCB_CONFIG_WINDOW_STACK_MODE, values);
}
void stack_tiled(desktop_t *d)
void window_stack(xcb_window_t w1, xcb_window_t w2, uint32_t mode)
{
for (node_list_t *a = d->history->head; a != NULL; a = a->next)
if (a->latest && is_tiled(a->node->client))
window_lower(a->node->client->window);
if (w2 == XCB_NONE)
return;
uint16_t mask = XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE;
uint32_t values[] = {w2, mode};
xcb_configure_window(dpy, w1, mask, values);
}
void window_above(xcb_window_t w1, xcb_window_t w2)
{
window_stack(w1, w2, XCB_STACK_MODE_ABOVE);
}
void window_below(xcb_window_t w1, xcb_window_t w2)
{
window_stack(w1, w2, XCB_STACK_MODE_BELOW);
}
void stack(desktop_t *d, node_t *n)
{
if (is_tiled(n->client))
stack_tiled(d);
else if (auto_raise && (!adaptative_raise || !might_cover(d, n)))
if (is_leaf(d->root))
return;
if (n->client->fullscreen) {
window_raise(n->client->window);
} else {
if (n->client->floating && !auto_raise)
return;
xcb_window_t latest_tiled = XCB_NONE;
xcb_window_t oldest_floating = XCB_NONE;
for (node_list_t *a = d->history->head; a != NULL; a = a->next) {
if (a->latest && a->node != n) {
if (a->node->client->floating == n->client->floating) {
window_above(n->client->window, a->node->client->window);
return;
} else if (latest_tiled == XCB_NONE && !a->node->client->floating) {
latest_tiled = a->node->client->window;
} else if (a->node->client->floating) {
oldest_floating = a->node->client->window;
}
}
}
if (n->client->floating)
window_above(n->client->window, latest_tiled);
else
window_below(n->client->window, oldest_floating);
}
}
void window_lower(xcb_window_t win)

View file

@ -9,7 +9,6 @@
void center(xcb_rectangle_t, xcb_rectangle_t *);
bool contains(xcb_rectangle_t, xcb_rectangle_t);
bool might_cover(desktop_t *, node_t *);
bool is_inside(monitor_t *, xcb_point_t);
xcb_rectangle_t get_rectangle(client_t *);
void get_side_handle(client_t *, direction_t, xcb_point_t *);
@ -36,6 +35,9 @@ void window_resize(xcb_window_t, uint16_t, uint16_t);
void window_move_resize(xcb_window_t, int16_t, int16_t, uint16_t, uint16_t);
void window_focus(xcb_window_t);
void window_raise(xcb_window_t);
void window_stack(xcb_window_t, xcb_window_t, uint32_t);
void window_above(xcb_window_t, xcb_window_t);
void window_below(xcb_window_t, xcb_window_t);
void stack_tiled(desktop_t *);
void stack(desktop_t *, node_t *);
void window_lower(xcb_window_t);