mirror of
https://github.com/vale981/bspwm
synced 2025-03-04 17:31:39 -05:00
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:
parent
758f5e6392
commit
a0b9199df5
11 changed files with 70 additions and 39 deletions
|
@ -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
|
||||
|
|
1
bspwm.c
1
bspwm.c
|
@ -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,
|
||||
|
|
|
@ -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=()
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
5
rules.c
5
rules.c
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
8
tree.c
|
@ -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);
|
||||
|
||||
|
|
80
window.c
80
window.c
|
@ -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)
|
||||
|
|
4
window.h
4
window.h
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue