bspc.o: bspc.c common.h helpers.h
bspwm.o: bspwm.c bspwm.h common.h desktop.h events.h ewmh.h helpers.h history.h messages.h monitor.h rule.h settings.h stack.h subscribe.h types.h window.h
-desktop.o: desktop.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h settings.h tree.h types.h window.h
+desktop.o: desktop.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h settings.h subscribe.h tree.h types.h window.h
events.o: events.c bspwm.h events.h ewmh.h helpers.h monitor.h query.h settings.h tree.h types.h window.h
ewmh.o: ewmh.c bspwm.h ewmh.h helpers.h settings.h tree.h types.h
helpers.o: helpers.c bspwm.h helpers.h types.h
history.o: history.c bspwm.h helpers.h query.h types.h
messages.o: messages.c bspwm.h common.h desktop.h ewmh.h helpers.h history.h messages.h monitor.h pointer.h query.h restore.h rule.h settings.h subscribe.h tree.h types.h window.h
-monitor.o: monitor.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h settings.h tree.h types.h window.h
+monitor.o: monitor.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h settings.h subscribe.h tree.h types.h window.h
pointer.o: pointer.c bspwm.h helpers.h monitor.h pointer.h query.h settings.h stack.h tree.h types.h window.h
-query.o: query.c bspwm.h desktop.h helpers.h history.h messages.h monitor.h query.h tree.h types.h
+query.o: query.c bspwm.h desktop.h helpers.h history.h messages.h monitor.h query.h subscribe.h tree.h types.h
restore.o: restore.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h restore.h settings.h stack.h tree.h types.h
-rule.o: rule.c bspwm.h ewmh.h helpers.h messages.h rule.h settings.h types.h window.h
+rule.o: rule.c bspwm.h ewmh.h helpers.h messages.h rule.h settings.h subscribe.h types.h window.h
settings.o: settings.c bspwm.h helpers.h settings.h types.h
stack.o: stack.c bspwm.h helpers.h stack.h types.h window.h
subscribe.o: subscribe.c bspwm.h helpers.h settings.h subscribe.h tree.h types.h
-tree.o: tree.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h settings.h stack.h tree.h types.h window.h
-window.o: window.c bspwm.h ewmh.h helpers.h messages.h monitor.h query.h rule.h settings.h stack.h tree.h types.h window.h
+tree.o: tree.c bspwm.h desktop.h ewmh.h helpers.h history.h monitor.h query.h settings.h stack.h subscribe.h tree.h types.h window.h
+window.o: window.c bspwm.h ewmh.h helpers.h messages.h monitor.h query.h rule.h settings.h stack.h subscribe.h tree.h types.h window.h
put_status(SBSC_MASK_DESKTOP_LAYOUT, "desktop_layout %s %s %s\n", m->name, d->name, l==LAYOUT_TILED?"tiled":"monocle");
d->layout = l;
arrange(m, d);
- if (d == m->desk)
+ if (d == m->desk) {
put_status(SBSC_MASK_REPORT);
+ }
}
void transfer_desktop(monitor_t *ms, monitor_t *md, desktop_t *d)
insert_desktop(md, d);
if (d == dd) {
- if (ms->desk != NULL)
+ if (ms->desk != NULL) {
show_desktop(ms->desk);
- if (md->desk != d)
+ }
+ if (md->desk != d) {
hide_desktop(d);
+ }
}
- for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root))
+ for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) {
translate_client(ms, md, n->client);
+ }
arrange(md, d);
- if (d != dd && md->desk == d)
+ if (d != dd && md->desk == d) {
show_desktop(d);
+ }
history_transfer_desktop(md, d);
d->top_padding = d->right_padding = d->bottom_padding = d->left_padding = 0;
d->window_gap = window_gap;
d->border_width = border_width;
- d->floating = false;
}
void insert_desktop(monitor_t *m, desktop_t *d)
.\" Title: bspwm
.\" Author: [see the "Author" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 10/27/2015
+.\" Date: 11/05/2015
.\" Manual: Bspwm Manual
.\" Source: Bspwm 0.9
.\" Language: English
.\"
-.TH "BSPWM" "1" "10/27/2015" "Bspwm 0\&.9" "Bspwm Manual"
+.TH "BSPWM" "1" "11/05/2015" "Bspwm 0\&.9" "Bspwm Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\}
.nf
WINDOW_SEL := <window_id>
- | (DIR|CYCLE_DIR|biggest|last|focused|older|newer)[\&.floating|\&.tiled][\&.like|\&.unlike][\&.manual|\&.automatic][\&.urgent|\&.nonurgent][\&.local|\&.foreign][\&.focused|\&.unfocused][\&.below|\&.normal|\&.above][\&.fullscreen|\&.nonfullscreen][\&.sticky|\&.nonsticky][\&.public|\&.private][\&.locked|\&.unlocked][\&.pseudotiled|\&.nonpseudotiled]
+ | (DIR|CYCLE_DIR|biggest|last|focused|older|newer)[\&.manual|\&.automatic][\&.tiled|nontiled][\&.pseudotiled|\&.nonpseudotiled][\&.floating|\&.nonfloating][\&.fullscreen|\&.nonfullscreen][\&.below|\&.normal|\&.above][\&.local|\&.foreign][\&.like|\&.unlike][\&.focused|\&.unfocused][\&.urgent|\&.nonurgent][\&.sticky|\&.nonsticky][\&.public|\&.private][\&.locked|\&.unlocked]
.fi
.if n \{\
.RE
\fBModifiers\fR
.RS 4
.PP
-floating
+tiled
.RS 4
-Only consider floating windows\&.
+Only consider tiled windows\&.
.RE
.PP
-tiled
+nontiled
.RS 4
Only consider tiled windows\&.
.RE
.PP
-like
+pseudotiled
.RS 4
-Only consider windows that have the same class as the current window\&.
+Only consider pseudo\-tiled windows\&.
.RE
.PP
-unlike
+nonpseudotiled
.RS 4
-Only consider windows that have a different class than the current window\&.
+Only consider non pseudo\-tiled windows\&.
.RE
.PP
-manual
+floating
.RS 4
-Only consider windows in manual splitting mode\&.
+Only consider floating windows\&.
.RE
.PP
-automatic
+nonfloating
.RS 4
-Only consider windows in automatic splitting mode\&.
+Only consider non floating windows\&.
.RE
.PP
-local
+fullscreen
.RS 4
-Only consider windows of the current desktop\&.
+Only consider fullscreen windows\&.
.RE
.PP
-foreign
+nonfullscreen
.RS 4
-Only consider windows outside of the current desktop\&.
+Only consider non fullscreen windows\&.
.RE
.PP
-private
+manual
.RS 4
-Only consider private windows\&.
+Only consider windows in manual splitting mode\&.
.RE
.PP
-public
+automatic
.RS 4
-Only consider non private windows\&.
+Only consider windows in automatic splitting mode\&.
.RE
.PP
-urgent
+focused
.RS 4
-Only consider urgent windows\&.
+Only consider focused windows\&.
.RE
.PP
-nonurgent
+unfocused
.RS 4
-Only consider non urgent windows\&.
+Only consider unfocused windows\&.
.RE
.PP
-pseudotiled
+below
.RS 4
-Only consider pseudo\-tiled windows\&.
+Only consider windows of the BELOW layer\&.
.RE
.PP
-nonpseudotiled
+normal
.RS 4
-Only consider non pseudo\-tiled windows\&.
+Only consider windows of the NORMAL layer\&.
.RE
.PP
-sticky
+above
.RS 4
-Only consider sticky windows\&.
+Only consider windows of the ABOVE layer\&.
.RE
.PP
-nonsticky
+like
.RS 4
-Only consider non sticky windows\&.
+Only consider windows that have the same class as the current window\&.
.RE
.PP
-locked
+unlike
.RS 4
-Only consider locked windows\&.
+Only consider windows that have a different class than the current window\&.
.RE
.PP
-unlocked
+local
.RS 4
-Only consider non locked windows\&.
+Only consider windows of the current desktop\&.
.RE
.PP
-nonfullscreen
+foreign
.RS 4
-Only consider non fullscreen windows\&.
+Only consider windows outside of the current desktop\&.
.RE
.PP
-fullscreen
+private
.RS 4
-Only consider fullscreen windows\&.
+Only consider private windows\&.
.RE
.PP
-nonfullscreen
+public
.RS 4
-Only consider non fullscreen windows\&.
+Only consider non private windows\&.
.RE
.PP
-focused
+urgent
.RS 4
-Only consider focused windows\&.
+Only consider urgent windows\&.
.RE
.PP
-unfocused
+nonurgent
.RS 4
-Only consider unfocused windows\&.
+Only consider non urgent windows\&.
.RE
.PP
-below
+sticky
.RS 4
-Only consider windows of the BELOW layer\&.
+Only consider sticky windows\&.
.RE
.PP
-normal
+nonsticky
.RS 4
-Only consider windows of the NORMAL layer\&.
+Only consider non sticky windows\&.
.RE
.PP
-above
+locked
.RS 4
-Only consider windows of the ABOVE layer\&.
+Only consider locked windows\&.
+.RE
+.PP
+unlocked
+.RS 4
+Only consider non locked windows\&.
.RE
.RE
.SS "Desktop"
.RE
.SH "WINDOW STATES"
.PP
-floating
+tiled
.RS 4
-Can be moved/resized freely\&. Although it doesn\(cqt occupy any tiling space, it is still part of the window tree\&.
+Its size and position are determined by the splitting type and ratio of each node of its path in the window tree\&.
.RE
.PP
pseudo_tiled
Has an unrestricted size while being centered in its tiling space\&.
.RE
.PP
+floating
+.RS 4
+Can be moved/resized freely\&. Although it doesn\(cqt occupy any tiling space, it is still part of the window tree\&.
+.RE
+.PP
fullscreen
.RS 4
-Fills its monitor rectangle and has no borders\&.
+Fills its monitor rectangle and has no borders\&. It is send in the ABOVE layer by default\&.
.RE
+.SH "WINDOW FLAGS"
.PP
locked
.RS 4
.PP
urgent
.RS 4
-Has its urgency hint set\&.
+Has its urgency hint set\&. This flag is set externally\&.
.RE
.SH "STACKING LAYERS"
.sp
There\(cqs three stacking layers: BELOW, NORMAL and ABOVE\&.
.sp
-In each layer, floating windows are stacked above tiled windows\&.
+In each layer, the window are orderered as follow: tiled & pseudo\-tiled < fullscreen < floating\&.
.SH "COMMANDS"
.SS "Window"
.sp
Rotate the tree holding the edge located in the given direction in relation to the selected window\&.
.RE
.PP
-\fB\-t\fR, \fB\-\-toggle\fR floating|fullscreen|pseudo_tiled|locked|sticky|private[=on|off]
+\fB\-t\fR, \fB\-\-state\fR tiled|pseudo_tiled|floating|fullscreen
+.RS 4
+Set the state of the selected window\&.
+.RE
+.PP
+\fB\-g\fR, \fB\-\-flag\fR locked|sticky|private[=on|off]
.RS 4
-Set or toggle the given state for the selected window\&.
+Set or toggle the given flag for the selected window\&.
.RE
.PP
\fB\-l\fR, \fB\-\-layer\fR below|normal|above
.RS 4
Circulate the leaves of the tree of the selected desktop\&.
.RE
-.PP
-\fB\-t\fR, \fB\-\-toggle\fR floating[=on|off]
-.RS 4
-Set or toggle the given state for the selected desktop\&.
-.RE
.RE
.SS "Monitor"
.sp
\fBOptions\fR
.RS 4
.PP
-\fB\-a\fR, \fB\-\-add\fR <class_name>|<instance_name>|* [\fB\-o\fR|\fB\-\-one\-shot\fR] [monitor=MONITOR_SEL|desktop=DESKTOP_SEL|window=WINDOW_SEL] [(floating|fullscreen|pseudo_tiled|locked|sticky|private|center|follow|manage|focus|border)=(on|off)] [layer=LAYER] [split_dir=DIR] [split_ratio=RATIO]
+\fB\-a\fR, \fB\-\-add\fR <class_name>|<instance_name>|* [\fB\-o\fR|\fB\-\-one\-shot\fR] [monitor=MONITOR_SEL|desktop=DESKTOP_SEL|window=WINDOW_SEL] [state=STATE] [layer=LAYER] [split_dir=DIR] [split_ratio=RATIO] [(locked|sticky|private|center|follow|manage|focus|border)=(on|off)]
.RS 4
Create a new rule\&.
.RE
----
WINDOW_SEL := <window_id>
- | (DIR|CYCLE_DIR|biggest|last|focused|older|newer)[.floating|.tiled][.like|.unlike][.manual|.automatic][.urgent|.nonurgent][.local|.foreign][.focused|.unfocused][.below|.normal|.above][.fullscreen|.nonfullscreen][.sticky|.nonsticky][.public|.private][.locked|.unlocked][.pseudotiled|.nonpseudotiled]
+ | (DIR|CYCLE_DIR|biggest|last|focused|older|newer)[.manual|.automatic][.tiled|nontiled][.pseudotiled|.nonpseudotiled][.floating|.nonfloating][.fullscreen|.nonfullscreen][.below|.normal|.above][.local|.foreign][.like|.unlike][.focused|.unfocused][.urgent|.nonurgent][.sticky|.nonsticky][.public|.private][.locked|.unlocked]
----
Primary Selectors
Modifiers
^^^^^^^^^
+tiled::
+ Only consider tiled windows.
+
+nontiled::
+ Only consider tiled windows.
+
+pseudotiled::
+ Only consider pseudo-tiled windows.
+
+nonpseudotiled::
+ Only consider non pseudo-tiled windows.
+
floating::
Only consider floating windows.
-tiled::
- Only consider tiled windows.
+nonfloating::
+ Only consider non floating windows.
-like::
- Only consider windows that have the same class as the current window.
+fullscreen::
+ Only consider fullscreen windows.
-unlike::
- Only consider windows that have a different class than the current window.
+nonfullscreen::
+ Only consider non fullscreen windows.
manual::
Only consider windows in manual splitting mode.
automatic::
Only consider windows in automatic splitting mode.
+focused::
+ Only consider focused windows.
+
+unfocused::
+ Only consider unfocused windows.
+
+below::
+ Only consider windows of the BELOW layer.
+
+normal::
+ Only consider windows of the NORMAL layer.
+
+above::
+ Only consider windows of the ABOVE layer.
+
+like::
+ Only consider windows that have the same class as the current window.
+
+unlike::
+ Only consider windows that have a different class than the current window.
+
local::
Only consider windows of the current desktop.
nonurgent::
Only consider non urgent windows.
-pseudotiled::
- Only consider pseudo-tiled windows.
-
-nonpseudotiled::
- Only consider non pseudo-tiled windows.
-
sticky::
Only consider sticky windows.
unlocked::
Only consider non locked windows.
-nonfullscreen::
- Only consider non fullscreen windows.
-
-fullscreen::
- Only consider fullscreen windows.
-
-nonfullscreen::
- Only consider non fullscreen windows.
-
-focused::
- Only consider focused windows.
-
-unfocused::
- Only consider unfocused windows.
-
-below::
- Only consider windows of the BELOW layer.
-
-normal::
- Only consider windows of the NORMAL layer.
-
-above::
- Only consider windows of the ABOVE layer.
-
Desktop
~~~~~~~
Window States
-------------
-floating::
- Can be moved/resized freely. Although it doesn't occupy any tiling space, it is still part of the window tree.
+tiled::
+ Its size and position are determined by the splitting type and ratio of each node of its path in the window tree.
pseudo_tiled::
Has an unrestricted size while being centered in its tiling space.
+floating::
+ Can be moved/resized freely. Although it doesn't occupy any tiling space, it is still part of the window tree.
+
fullscreen::
- Fills its monitor rectangle and has no borders.
+ Fills its monitor rectangle and has no borders. It is send in the ABOVE layer by default.
+
+
+Window Flags
+-------------
locked::
Ignores the *close* message.
Tries to keep the same tiling position/size.
urgent::
- Has its urgency hint set.
+ Has its urgency hint set. This flag is set externally.
Stacking Layers
There's three stacking layers: BELOW, NORMAL and ABOVE.
-In each layer, floating windows are stacked above tiled windows.
+In each layer, the window are orderered as follow: tiled & pseudo-tiled < fullscreen < floating.
Commands
*-R*, *--rotate* 'DIR' '90|270|180'::
Rotate the tree holding the edge located in the given direction in relation to the selected window.
-*-t*, *--toggle* floating|fullscreen|pseudo_tiled|locked|sticky|private[=on|off]::
- Set or toggle the given state for the selected window.
+*-t*, *--state* tiled|pseudo_tiled|floating|fullscreen::
+ Set the state of the selected window.
+
+*-g*, *--flag* locked|sticky|private[=on|off]::
+ Set or toggle the given flag for the selected window.
*-l*, *--layer* below|normal|above::
Set the stacking layer of the selected window.
*-C*, *--circulate* forward|backward::
Circulate the leaves of the tree of the selected desktop.
-*-t*, *--toggle* floating[=on|off]::
- Set or toggle the given state for the selected desktop.
-
Monitor
~~~~~~~
Options
^^^^^^^
-*-a*, *--add* <class_name>|<instance_name>|* [*-o*|*--one-shot*] [monitor=MONITOR_SEL|desktop=DESKTOP_SEL|window=WINDOW_SEL] [(floating|fullscreen|pseudo_tiled|locked|sticky|private|center|follow|manage|focus|border)=(on|off)] [layer=LAYER] [split_dir=DIR] [split_ratio=RATIO]::
+*-a*, *--add* <class_name>|<instance_name>|* [*-o*|*--one-shot*] [monitor=MONITOR_SEL|desktop=DESKTOP_SEL|window=WINDOW_SEL] [state=STATE] [layer=LAYER] [split_dir=DIR] [split_ratio=RATIO] [(locked|sticky|private|center|follow|manage|focus|border)=(on|off)]::
Create a new rule.
*-r*, *--remove* ^<n>|head|tail|<class_name>|<instance_name>|*...::
client_t *c = (is_managed ? loc.node->client : NULL);
int w = 0, h = 0;
- if (is_managed && !c->floating) {
+ if (is_managed && !IS_FLOATING(c)) {
if (e->value_mask & XCB_CONFIG_WINDOW_X)
c->floating_rectangle.x = e->x;
if (e->value_mask & XCB_CONFIG_WINDOW_Y)
}
xcb_configure_notify_event_t evt;
- xcb_rectangle_t rect;
xcb_window_t win = c->window;
unsigned int bw = c->border_width;
- if (c->fullscreen)
- rect = loc.monitor->rectangle;
- else
- rect = c->tiled_rectangle;
+ xcb_rectangle_t rect = get_rectangle(loc.monitor, c);
evt.response_type = XCB_CONFIGURE_NOTIFY;
evt.event = win;
xcb_send_event(dpy, false, win, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char *) &evt);
- if (c->pseudo_tiled)
+ if (c->state == STATE_PSEUDO_TILED) {
arrange(loc.monitor, loc.desktop);
+ }
} else {
uint16_t mask = 0;
uint32_t values[7];
xcb_configure_window(dpy, e->window, mask, values);
}
- if (is_managed)
+ if (is_managed) {
translate_client(monitor_from_client(c), loc.monitor, c);
+ }
}
void destroy_notify(xcb_generic_event_t *evt)
void handle_state(monitor_t *m, desktop_t *d, node_t *n, xcb_atom_t state, unsigned int action)
{
if (state == ewmh->_NET_WM_STATE_FULLSCREEN) {
- if (action == XCB_EWMH_WM_STATE_ADD)
- set_fullscreen(n, true);
- else if (action == XCB_EWMH_WM_STATE_REMOVE)
- set_fullscreen(n, false);
- else if (action == XCB_EWMH_WM_STATE_TOGGLE)
- set_fullscreen(n, !n->client->fullscreen);
+ if (action == XCB_EWMH_WM_STATE_ADD) {
+ set_state(m, d, n, STATE_FULLSCREEN);
+ } else if (action == XCB_EWMH_WM_STATE_REMOVE) {
+ set_state(m, d, n, n->client->last_state);
+ } else if (action == XCB_EWMH_WM_STATE_TOGGLE) {
+ set_state(m, d, n, IS_FULLSCREEN(n->client) ? n->client->last_state : STATE_FULLSCREEN);
+ }
arrange(m, d);
} else if (state == ewmh->_NET_WM_STATE_BELOW) {
- if (action == XCB_EWMH_WM_STATE_ADD)
- set_layer(n, LAYER_BELOW);
- else if (action == XCB_EWMH_WM_STATE_REMOVE)
- set_layer(n, LAYER_NORMAL);
- else if (action == XCB_EWMH_WM_STATE_TOGGLE)
- set_layer(n, n->client->layer == LAYER_BELOW ? LAYER_NORMAL : LAYER_BELOW);
+ if (action == XCB_EWMH_WM_STATE_ADD) {
+ set_layer(m, d, n, LAYER_BELOW);
+ } else if (action == XCB_EWMH_WM_STATE_REMOVE) {
+ set_layer(m, d, n, LAYER_NORMAL);
+ } else if (action == XCB_EWMH_WM_STATE_TOGGLE) {
+ set_layer(m, d, n, n->client->layer == LAYER_BELOW ? n->client->last_layer : LAYER_BELOW);
+ }
} else if (state == ewmh->_NET_WM_STATE_ABOVE) {
- if (action == XCB_EWMH_WM_STATE_ADD)
- set_layer(n, LAYER_ABOVE);
- else if (action == XCB_EWMH_WM_STATE_REMOVE)
- set_layer(n, LAYER_NORMAL);
- else if (action == XCB_EWMH_WM_STATE_TOGGLE)
- set_layer(n, n->client->layer == LAYER_ABOVE ? LAYER_NORMAL : LAYER_ABOVE);
+ if (action == XCB_EWMH_WM_STATE_ADD) {
+ set_layer(m, d, n, LAYER_ABOVE);
+ } else if (action == XCB_EWMH_WM_STATE_REMOVE) {
+ set_layer(m, d, n, n->client->last_layer);
+ } else if (action == XCB_EWMH_WM_STATE_TOGGLE) {
+ set_layer(m, d, n, n->client->layer == LAYER_ABOVE ? n->client->last_layer : LAYER_ABOVE);
+ }
} else if (state == ewmh->_NET_WM_STATE_STICKY) {
- if (action == XCB_EWMH_WM_STATE_ADD)
+ if (action == XCB_EWMH_WM_STATE_ADD) {
set_sticky(m, d, n, true);
- else if (action == XCB_EWMH_WM_STATE_REMOVE)
+ } else if (action == XCB_EWMH_WM_STATE_REMOVE) {
set_sticky(m, d, n, false);
- else if (action == XCB_EWMH_WM_STATE_TOGGLE)
+ } else if (action == XCB_EWMH_WM_STATE_TOGGLE) {
set_sticky(m, d, n, !n->client->sticky);
+ }
} else if (state == ewmh->_NET_WM_STATE_DEMANDS_ATTENTION) {
- if (action == XCB_EWMH_WM_STATE_ADD)
+ if (action == XCB_EWMH_WM_STATE_ADD) {
set_urgency(m, d, n, true);
- else if (action == XCB_EWMH_WM_STATE_REMOVE)
+ } else if (action == XCB_EWMH_WM_STATE_REMOVE) {
set_urgency(m, d, n, false);
- else if (action == XCB_EWMH_WM_STATE_TOGGLE)
+ } else if (action == XCB_EWMH_WM_STATE_TOGGLE) {
set_urgency(m, d, n, !n->client->urgent);
+ }
}
}
bspc monitor -d I II III IV V VI VII VIII IX X
-bspc rule -a Gimp desktop=^8 follow=on floating=on
+bspc rule -a Gimp desktop=^8 state=floating follow=on
bspc rule -a Chromium desktop=^2
-bspc rule -a mplayer2 floating=on
+bspc rule -a mplayer2 state=floating
bspc rule -a Kupfer.py focus=on
bspc rule -a Screenkey manage=off
super + w
bspc window -c
-super + t
+super + n
bspc desktop -l next
-super + b
- bspc desktop -B
-
-super + {s,f}
- bspc window -t {floating,fullscreen}
+super + {t,p,s,f}
+ bspc window -t {tiled,pseudo_tiled,floating,fullscreen}
super + {grave,Tab}
bspc {window,desktop} -f last
super + ctrl + {1-9}
bspc window -r 0.{1-9}
+super + {Left,Down,Up,Right}
+ xdo move {-x -20,-y +20,-y -20,-x +20}
+
super + {_,shift + }{1-9,0}
- bspc {desktop -f,window -d} ^{1-9,10}
+ bspc {desktop -f,window -d} '^{1-9,10}'
~button1
bspc pointer -g focus
#define BOOLSTR(A) ((A) ? "true" : "false")
#define ONOFFSTR(A) ((A) ? "on" : "off")
#define LAYERSTR(A) ((A) == LAYER_BELOW ? "below" : ((A) == LAYER_NORMAL ? "normal" : "above"))
+#define STATESTR(A) ((A) == STATE_TILED ? "tiled" : ((A) == STATE_FLOATING ? "floating" : ((A) == STATE_FULLSCREEN ? "fullscreen" : "pseudo_tiled")))
+#define IS_TILED(c) (c->state == STATE_TILED || c->state == STATE_PSEUDO_TILED)
+#define IS_FLOATING(c) (c->state == STATE_FLOATING)
+#define IS_FULLSCREEN(c) (c->state == STATE_FULLSCREEN)
#define XCB_CONFIG_WINDOW_X_Y XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y
#define XCB_CONFIG_WINDOW_WIDTH_HEIGHT XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT
} else {
return MSG_FAILURE;
}
- } else if (streq("-t", *args) || streq("--toggle", *args)) {
+ } else if (streq("-t", *args) || streq("--state", *args)) {
+ num--, args++;
+ if (num < 1)
+ return MSG_SYNTAX;
+ client_state_t cst;
+ if (parse_client_state(*args, &cst)) {
+ if (trg.node->client->state == cst) {
+ cst = trg.node->client->last_state;
+ }
+ set_state(trg.monitor, trg.desktop, trg.node, cst);
+ dirty = true;
+ } else {
+ return MSG_FAILURE;
+ }
+ } else if (streq("-g", *args) || streq("--flag", *args)) {
num--, args++;
if (num < 1)
return MSG_SYNTAX;
if (val == NULL) {
a = ALTER_TOGGLE;
} else {
- if (parse_bool(val, &b))
+ if (parse_bool(val, &b)) {
a = ALTER_SET;
- else
+ } else {
return MSG_FAILURE;
+ }
}
- if (streq("fullscreen", key)) {
- set_fullscreen(trg.node, (a == ALTER_SET ? b : !trg.node->client->fullscreen));
- dirty = true;
- } else if (streq("pseudo_tiled", key)) {
- set_pseudo_tiled(trg.node, (a == ALTER_SET ? b : !trg.node->client->pseudo_tiled));
- dirty = true;
- } else if (streq("floating", key)) {
- set_floating(trg.node, (a == ALTER_SET ? b : !trg.node->client->floating));
- dirty = true;
- } else if (streq("locked", key)) {
+ if (streq("locked", key)) {
set_locked(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->client->locked));
} else if (streq("sticky", key)) {
set_sticky(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->client->sticky));
num--, args++;
if (num < 1)
return MSG_SYNTAX;
- if (trg.node->client->floating ||
+ if (IS_FLOATING(trg.node->client) ||
trg.desktop->layout != LAYOUT_TILED)
return MSG_FAILURE;
if (streq("cancel", *args)) {
num--, args++;
if (num < 2)
return MSG_SYNTAX;
- if (trg.node->client->floating)
+ if (IS_FLOATING(trg.node->client))
return MSG_FAILURE;
direction_t dir;
if (!parse_direction(*args, &dir))
}
stack_layer_t lyr;
if (parse_stack_layer(*args, &lyr)) {
- set_layer(trg.node, lyr);
+ set_layer(trg.monitor, trg.desktop, trg.node, lyr);
} else {
return MSG_FAILURE;
}
} else {
return MSG_FAILURE;
}
- } else if (streq("-t", *args) || streq("--toggle", *args)) {
- num--, args++;
- if (num < 1)
- return MSG_SYNTAX;
- char *key = strtok(*args, EQL_TOK);
- char *val = strtok(NULL, EQL_TOK);
- alter_state_t a;
- bool b;
- if (val == NULL) {
- a = ALTER_TOGGLE;
- } else {
- if (parse_bool(val, &b))
- a = ALTER_SET;
- else
- return MSG_FAILURE;
- }
- if (streq("floating", key))
- trg.desktop->floating = (a == ALTER_SET ? b : !trg.desktop->floating);
- else
- return MSG_FAILURE;
- } else {
- return MSG_SYNTAX;
}
num--, args++;
}
*mask = SBSC_MASK_WINDOW_MOVE;
} else if (streq("window_state", s)) {
*mask = SBSC_MASK_WINDOW_STATE;
+ } else if (streq("window_flag", s)) {
+ *mask = SBSC_MASK_WINDOW_FLAG;
} else if (streq("window_layer", s)) {
*mask = SBSC_MASK_WINDOW_LAYER;
} else if (streq("desktop_add", s)) {
*mask = SBSC_MASK_DESKTOP_FOCUS;
} else if (streq("desktop_layout", s)) {
*mask = SBSC_MASK_DESKTOP_LAYOUT;
- } else if (streq("desktop_state", s)) {
- *mask = SBSC_MASK_DESKTOP_STATE;
} else if (streq("monitor_add", s)) {
*mask = SBSC_MASK_MONITOR_ADD;
} else if (streq("monitor_rename", s)) {
return false;
}
+bool parse_client_state(char *s, client_state_t *t)
+{
+ if (streq("tiled", s)) {
+ *t = STATE_TILED;
+ return true;
+ } else if (streq("pseudo_tiled", s)) {
+ *t = STATE_PSEUDO_TILED;
+ return true;
+ } else if (streq("floating", s)) {
+ *t = STATE_FLOATING;
+ return true;
+ } else if (streq("fullscreen", s)) {
+ *t = STATE_FULLSCREEN;
+ return true;
+ }
+ return false;
+}
+
bool parse_stack_layer(char *s, stack_layer_t *l)
{
if (streq("below", s)) {
bool parse_subscriber_mask(char *s, subscriber_mask_t *mask);
bool parse_bool(char *value, bool *b);
bool parse_layout(char *s, layout_t *l);
+bool parse_client_state(char *s, client_state_t *t);
bool parse_stack_layer(char *s, stack_layer_t *l);
bool parse_direction(char *s, direction_t *d);
bool parse_cycle_direction(char *s, cycle_dir_t *d);
PRINTF("remove monitor %s (0x%X)\n", m->name, m->id);
put_status(SBSC_MASK_MONITOR_REMOVE, "monitor_remove %s\n", m->name);
- while (m->desk_head != NULL)
+ while (m->desk_head != NULL) {
remove_desktop(m, m->desk_head);
+ }
+
monitor_t *prev = m->prev;
monitor_t *next = m->next;
monitor_t *last_mon = history_get_monitor(m);
- if (prev != NULL)
+
+ if (prev != NULL) {
prev->next = next;
- if (next != NULL)
+ }
+
+ if (next != NULL) {
next->prev = prev;
- if (mon_head == m)
+ }
+
+ if (mon_head == m) {
mon_head = next;
- if (mon_tail == m)
+ }
+
+ if (mon_tail == m) {
mon_tail = prev;
- if (pri_mon == m)
+ }
+
+ if (pri_mon == m) {
pri_mon = NULL;
+ }
+
if (mon == m) {
mon = (last_mon == NULL ? (prev == NULL ? next : prev) : last_mon);
- if (mon != NULL && mon->desk != NULL)
+ if (mon != NULL && mon->desk != NULL) {
update_current();
+ }
}
+
xcb_destroy_window(dpy, m->root);
free(m);
num_monitors--;
case ACTION_MOVE:
case ACTION_RESIZE_SIDE:
case ACTION_RESIZE_CORNER:
- if (c->floating) {
+ if (IS_FLOATING(c)) {
frozen_pointer->rectangle = c->floating_rectangle;
frozen_pointer->is_tiled = false;
- } else if (!c->floating) {
+ } else if (IS_TILED(c)) {
frozen_pointer->rectangle = c->tiled_rectangle;
- frozen_pointer->is_tiled = (pac == ACTION_MOVE || !c->pseudo_tiled);
+ frozen_pointer->is_tiled = (pac == ACTION_MOVE || c->state == STATE_PSEUDO_TILED);
} else {
frozen_pointer->action = ACTION_NONE;
return;
return;
coordinates_t loc;
bool is_managed = (pwin == XCB_NONE ? false : locate_window(pwin, &loc));
- if (is_managed && !loc.node->client->floating && loc.monitor == m) {
+ if (is_managed && !IS_FLOATING(loc.node->client) && loc.monitor == m) {
swap_nodes(m, d, n, m, d, loc.node);
arrange(m, d);
} else {
int oldw = w, oldh = h;
restrain_floating_size(c, &w, &h);
- if (c->pseudo_tiled) {
- c->floating_rectangle.width = w;
- c->floating_rectangle.height = h;
- arrange(m, d);
- } else {
+ if (c->state == STATE_FLOATING) {
if (oldw == w) {
c->floating_rectangle.x = x;
c->floating_rectangle.width = w;
c->floating_rectangle.y,
c->floating_rectangle.width,
c->floating_rectangle.height);
+ } else {
+ c->floating_rectangle.width = w;
+ c->floating_rectangle.height = h;
+ arrange(m, d);
}
}
break;
fprintf(rsp, "%s\n", d->name);
continue;
} else {
- fprintf(rsp, "%s %u %i %i,%i,%i,%i %c %c%s\n", d->name, d->border_width,
+ fprintf(rsp, "%s %u %i %i,%i,%i,%i %c%s\n", d->name, d->border_width,
d->window_gap,
d->top_padding, d->right_padding, d->bottom_padding, d->left_padding,
- (d->layout == LAYOUT_TILED ? 'T' : 'M'), (d->floating ? 'f' : '-'),
+ (d->layout == LAYOUT_TILED ? 'T' : 'M'),
(d == m->desk ? " *" : ""));
}
query_tree(d, d->root, rsp, depth + 1);
if (is_leaf(n)) {
client_t *c = n->client;
- fprintf(rsp, "%c %s %s 0x%X %u %ux%u%+i%+i %c %c%c%c%c%c%c%c%c%c%s\n",
+ fprintf(rsp, "%c %s %s 0x%X %u %ux%u%+i%+i %c%c %c%c %c%c%c%c%s\n",
(n->birth_rotation == 90 ? 'a' : (n->birth_rotation == 270 ? 'c' : 'm')),
c->class_name, c->instance_name, c->window, c->border_width,
c->floating_rectangle.width, c->floating_rectangle.height,
c->floating_rectangle.x, c->floating_rectangle.y,
(n->split_dir == DIR_UP ? 'U' : (n->split_dir == DIR_RIGHT ? 'R' : (n->split_dir == DIR_DOWN ? 'D' : 'L'))),
- (c->floating ? 'f' : '-'), (c->pseudo_tiled ? 'd' : '-'), (c->fullscreen ? 'F' : '-'),
- (c->urgent ? 'u' : '-'), (c->locked ? 'l' : '-'), (c->sticky ? 's' : '-'),
- (c->private ? 'i' : '-'), (n->split_mode ? 'p' : '-'),
- (c->layer == LAYER_BELOW ? 'b' : (c->layer == LAYER_ABOVE ? 'a' : '-')),
+ (n->split_mode == MODE_AUTOMATIC ? '-' : 'p'),
+ (c->state == STATE_TILED ? '-' : (c->state == STATE_FLOATING ? 'f' : (c->state == STATE_FULLSCREEN ? 'F' : 'p'))),
+ (c->layer == LAYER_NORMAL ? '-' : (c->layer == LAYER_ABOVE ? 'a' : 'b')),
+ (c->urgent ? 'u' : '-'), (c->locked ? 'l' : '-'), (c->sticky ? 's' : '-'), (c->private ? 'i' : '-'),
(n == d->focus ? " *" : ""));
} else {
fprintf(rsp, "%c %c %lf\n", (n->split_type == TYPE_HORIZONTAL ? 'H' : 'V'),
OPTION_NONE,
OPTION_NONE,
OPTION_NONE,
+ OPTION_NONE,
NULL
};
return sel;
while ((tok = strrchr(desc, CAT_CHR)) != NULL) {
tok[0] = '\0';
tok++;
- if (streq("floating", tok)) {
+ if (streq("tiled", tok)) {
+ sel.tiled = OPTION_TRUE;
+ } else if (streq("nontiled", tok)) {
+ sel.tiled = OPTION_FALSE;
+ } else if (streq("pseudotiled", tok)) {
+ sel.pseudo_tiled = OPTION_TRUE;
+ } else if (streq("nonpseudotiled", tok)) {
+ sel.pseudo_tiled = OPTION_FALSE;
+ } else if (streq("floating", tok)) {
sel.floating = OPTION_TRUE;
- } else if (streq("tiled", tok)) {
+ } else if (streq("nonfloating", tok)) {
sel.floating = OPTION_FALSE;
} else if (streq("like", tok)) {
sel.same_class = OPTION_TRUE;
sel.fullscreen = OPTION_TRUE;
} else if (streq("nonfullscreen", tok)) {
sel.fullscreen = OPTION_FALSE;
- } else if (streq("pseudotiled", tok)) {
- sel.pseudo_tiled = OPTION_TRUE;
- } else if (streq("nonpseudotiled", tok)) {
- sel.pseudo_tiled = OPTION_FALSE;
} else if (streq("urgent", tok)) {
sel.urgent = OPTION_TRUE;
} else if (streq("nonurgent", tok)) {
: sel.prop == OPTION_FALSE) { \
return false; \
}
- WSTATE(floating)
- WSTATE(fullscreen)
- WSTATE(pseudo_tiled)
WSTATE(locked)
WSTATE(sticky)
WSTATE(private)
WSTATE(urgent)
#undef MATCHSTATE
+ if (sel.tiled != OPTION_NONE &&
+ loc->node->client->state != STATE_TILED
+ ? sel.tiled == OPTION_TRUE
+ : sel.tiled == OPTION_FALSE) {
+ return false;
+ }
+
+ if (sel.pseudo_tiled != OPTION_NONE &&
+ loc->node->client->state != STATE_PSEUDO_TILED
+ ? sel.pseudo_tiled == OPTION_TRUE
+ : sel.pseudo_tiled == OPTION_FALSE) {
+ return false;
+ }
+
+ if (sel.floating != OPTION_NONE &&
+ loc->node->client->state != STATE_FLOATING
+ ? sel.floating == OPTION_TRUE
+ : sel.floating == OPTION_FALSE) {
+ return false;
+ }
+
+ if (sel.fullscreen != OPTION_NONE &&
+ loc->node->client->state != STATE_FULLSCREEN
+ ? sel.fullscreen == OPTION_TRUE
+ : sel.fullscreen == OPTION_FALSE) {
+ return false;
+ }
+
if (sel.same_class != OPTION_NONE && ref->node != NULL &&
streq(loc->node->client->class_name, ref->node->client->class_name)
? sel.same_class == OPTION_FALSE
return false;
}
- if (sel.local != OPTION_NONE && loc->desktop != ref->desktop
+ if (sel.local != OPTION_NONE &&
+ loc->desktop != ref->desktop
? sel.local == OPTION_TRUE
: sel.local == OPTION_FALSE) {
return false;
&bw, &wg, &top, &right, &bottom, &left, &layout, &floating, &end);
locate_desktop(name, &loc);
d = loc.desktop;
- if (d == NULL)
+ if (d == NULL) {
continue;
+ }
d->border_width = bw;
d->window_gap = wg;
d->top_padding = top;
d->right_padding = right;
d->bottom_padding = bottom;
d->left_padding = left;
- if (layout == 'M')
+ if (layout == 'M') {
d->layout = LAYOUT_MONOCLE;
- else if (layout == 'T')
+ } else if (layout == 'T') {
d->layout = LAYOUT_TILED;
- d->floating = (floating == '-' ? false : true);
- if (end != 0)
+ }
+ if (end != 0) {
m->desk = d;
+ }
} else {
if (m == NULL || d == NULL)
continue;
birth->parent = n;
}
n = birth;
- char br;
+ char birth_rotation;
if (isupper(line[level])) {
- char st;
- sscanf(line + level, "%c %c %lf", &st, &br, &n->split_ratio);
- if (st == 'H')
+ char split_type;
+ sscanf(line + level, "%c %c %lf", &split_type, &birth_rotation, &n->split_ratio);
+ if (split_type == 'H') {
n->split_type = TYPE_HORIZONTAL;
- else if (st == 'V')
+ } else if (split_type == 'V') {
n->split_type = TYPE_VERTICAL;
+ }
} else {
client_t *c = make_client(XCB_NONE, d->border_width);
num_clients++;
- char floating, pseudo_tiled, fullscreen, urgent, locked, sticky, private, sd, sm, sl, end = 0;
- sscanf(line + level, "%c %s %s %X %u %hux%hu%hi%hi %c %c%c%c%c%c%c%c%c%c %c", &br,
+ char urgent, locked, sticky, private, split_dir, split_mode, state, layer, end = 0;
+ sscanf(line + level, "%c %s %s %X %u %hux%hu%hi%hi %c%c %c%c %c%c%c%c %c", &birth_rotation,
c->class_name, c->instance_name, &c->window, &c->border_width,
&c->floating_rectangle.width, &c->floating_rectangle.height,
&c->floating_rectangle.x, &c->floating_rectangle.y,
- &sd, &floating, &pseudo_tiled, &fullscreen, &urgent,
- &locked, &sticky, &private, &sm, &sl, &end);
- c->floating = (floating == '-' ? false : true);
- c->pseudo_tiled = (pseudo_tiled == '-' ? false : true);
- c->fullscreen = (fullscreen == '-' ? false : true);
- c->urgent = (urgent == '-' ? false : true);
- c->locked = (locked == '-' ? false : true);
- c->sticky = (sticky == '-' ? false : true);
- c->private = (private == '-' ? false : true);
- n->split_mode = (sm == '-' ? MODE_AUTOMATIC : MODE_MANUAL);
- if (sd == 'U') {
+ &split_dir, &split_mode, &state, &layer,
+ &urgent, &locked, &sticky, &private, &end);
+ n->split_mode = (split_mode == '-' ? MODE_AUTOMATIC : MODE_MANUAL);
+ if (split_dir == 'U') {
n->split_dir = DIR_UP;
- } else if (sd == 'R') {
+ } else if (split_dir == 'R') {
n->split_dir = DIR_RIGHT;
- } else if (sd == 'D') {
+ } else if (split_dir == 'D') {
n->split_dir = DIR_DOWN;
- } else if (sd == 'L') {
+ } else if (split_dir == 'L') {
n->split_dir = DIR_LEFT;
}
- if (sl == 'b') {
+ if (state == 'f') {
+ c->state = STATE_FLOATING;
+ } else if (state == 'F') {
+ c->state = STATE_FULLSCREEN;
+ } else if (state == 'p') {
+ c->state = STATE_PSEUDO_TILED;
+ }
+ if (layer == 'b') {
c->layer = LAYER_BELOW;
- } else if (sl == 'a') {
+ } else if (layer == 'a') {
c->layer = LAYER_ABOVE;
}
+ c->urgent = (urgent == '-' ? false : true);
+ c->locked = (locked == '-' ? false : true);
+ c->sticky = (sticky == '-' ? false : true);
+ c->private = (private == '-' ? false : true);
n->client = c;
- if (end != 0)
+ if (end != 0) {
d->focus = n;
- if (c->sticky)
+ }
+ if (c->sticky) {
m->num_sticky++;
+ }
}
- if (br == 'a')
+ if (birth_rotation == 'a') {
n->birth_rotation = 90;
- else if (br == 'c')
+ } else if (birth_rotation == 'c') {
n->birth_rotation = 270;
- else if (br == 'm')
+ } else if (birth_rotation == 'm') {
n->birth_rotation = 0;
+ }
}
last_level = level;
}
fclose(snapshot);
- for (monitor_t *m = mon_head; m != NULL; m = m->next)
- for (desktop_t *d = m->desk_head; d != NULL; d = d->next)
+ for (monitor_t *m = mon_head; m != NULL; m = m->next) {
+ for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) {
uint32_t values[] = {CLIENT_EVENT_MASK | (focus_follows_pointer ? XCB_EVENT_MASK_ENTER_WINDOW : 0)};
xcb_change_window_attributes(dpy, n->client->window, XCB_CW_EVENT_MASK, values);
- if (n->client->floating) {
+ if (!IS_TILED(n->client)) {
n->vacant = true;
update_vacant_state(n->parent);
}
- if (n->client->private)
+ if (n->client->private) {
update_privacy_level(n, true);
+ }
}
+ }
+ }
+
ewmh_update_current_desktop();
}
rule_consequence_t *rc = calloc(1, sizeof(rule_consequence_t));
rc->manage = rc->focus = rc->border = true;
rc->layer = NULL;
+ rc->state = NULL;
return rc;
}
a == ewmh->_NET_WM_WINDOW_TYPE_UTILITY) {
csq->focus = false;
} else if (a == ewmh->_NET_WM_WINDOW_TYPE_DIALOG) {
- csq->floating = true;
+ if (csq->state == NULL) {
+ csq->state = malloc(sizeof(client_state_t));
+ }
+ *(csq->state) = STATE_FLOATING;
csq->center = true;
} else if (a == ewmh->_NET_WM_WINDOW_TYPE_DOCK ||
a == ewmh->_NET_WM_WINDOW_TYPE_DESKTOP ||
a == ewmh->_NET_WM_WINDOW_TYPE_NOTIFICATION) {
csq->manage = false;
- if (a == ewmh->_NET_WM_WINDOW_TYPE_DESKTOP)
+ if (a == ewmh->_NET_WM_WINDOW_TYPE_DESKTOP) {
window_lower(win);
+ }
}
}
xcb_ewmh_get_atoms_reply_wipe(&win_type);
for (unsigned int i = 0; i < win_state.atoms_len; i++) {
xcb_atom_t a = win_state.atoms[i];
if (a == ewmh->_NET_WM_STATE_FULLSCREEN) {
- csq->fullscreen = true;
+ if (csq->state == NULL) {
+ csq->state = malloc(sizeof(client_state_t));
+ }
+ *(csq->state) = STATE_FULLSCREEN;
} else if (a == ewmh->_NET_WM_STATE_BELOW) {
if (csq->layer == NULL) {
csq->layer = malloc(sizeof(stack_layer_t));
if (xcb_icccm_get_wm_normal_hints_reply(dpy, xcb_icccm_get_wm_normal_hints(dpy, win), &size_hints, NULL) == 1) {
if (size_hints.min_width > 0 && size_hints.min_height > 0 &&
size_hints.min_width == size_hints.max_width &&
- size_hints.min_height == size_hints.max_height)
- csq->floating = true;
+ size_hints.min_height == size_hints.max_height) {
+ if (csq->state == NULL) {
+ csq->state = malloc(sizeof(client_state_t));
+ }
+ *(csq->state) = STATE_FLOATING;
+ }
csq->min_width = size_hints.min_width;
csq->max_width = size_hints.max_width;
csq->min_height = size_hints.min_height;
xcb_window_t transient_for = XCB_NONE;
xcb_icccm_get_wm_transient_for_reply(dpy, xcb_icccm_get_wm_transient_for(dpy, win), &transient_for, NULL);
- if (transient_for != XCB_NONE)
- csq->floating = true;
+ if (transient_for != XCB_NONE) {
+ if (csq->state == NULL) {
+ csq->state = malloc(sizeof(client_state_t));
+ }
+ *(csq->state) = STATE_FLOATING;
+ }
xcb_icccm_get_wm_class_reply_t reply;
if (xcb_icccm_get_wm_class_reply(dpy, xcb_icccm_get_wm_class(dpy, win), &reply, NULL) == 1) {
key = strtok(NULL, CSQ_BLK);
value = strtok(NULL, CSQ_BLK);
}
- if (rule->one_shot)
+ if (rule->one_shot) {
remove_rule(rule);
+ }
}
rule = next;
}
bool schedule_rules(xcb_window_t win, rule_consequence_t *csq)
{
- if (external_rules_command[0] == '\0')
+ if (external_rules_command[0] == '\0') {
return false;
+ }
int fds[2];
- if (pipe(fds) == -1)
+ if (pipe(fds) == -1) {
return false;
+ }
pid_t pid = fork();
if (pid == 0) {
- if (dpy != NULL)
+ if (dpy != NULL) {
close(xcb_get_file_descriptor(dpy));
+ }
dup2(fds[1], 1);
close(fds[0]);
char wid[SMALEN];
snprintf(csq->node_desc, sizeof(csq->node_desc), "%s", value);
} else if (streq("split_dir", key)) {
snprintf(csq->split_dir, sizeof(csq->split_dir), "%s", value);
+ } else if (streq("state", key)) {
+ client_state_t cst;
+ if (parse_client_state(value, &cst)) {
+ if (csq->state == NULL) {
+ csq->state = malloc(sizeof(client_state_t));
+ }
+ *(csq->state) = cst;
+ }
} else if (streq("layer", key)) {
stack_layer_t lyr;
if (parse_stack_layer(value, &lyr)) {
csq->split_ratio = rat;
}
} else if (parse_bool(value, &v)) {
- if (streq("floating", key))
- csq->floating = v;
+ if (streq("locked", key))
+ csq->locked = true;
#define SETCSQ(name) \
else if (streq(#name, key)) \
csq->name = v;
- SETCSQ(pseudo_tiled)
- SETCSQ(fullscreen)
- SETCSQ(locked)
SETCSQ(sticky)
SETCSQ(private)
SETCSQ(center)
}
}
+int stack_level(client_t *c)
+{
+ int layer_level = (c->layer == LAYER_NORMAL ? 1 : (c->layer == LAYER_BELOW ? 0 : 2));
+ int state_level = (IS_TILED(c) ? 0 : (IS_FLOATING(c) ? 2 : 1));
+ return 3 * layer_level + state_level;
+}
+
int stack_cmp(client_t *c1, client_t *c2)
{
- if (c1->layer == c2->layer) {
- if (!c1->floating && c2->floating) {
- return -1;
- } else if (c1->floating && !c2->floating) {
- return 1;
- } else {
- return 0;
- }
- } else {
- if (c1->layer == LAYER_BELOW) {
- return -1;
- } else if (c1->layer == LAYER_ABOVE) {
- return 1;
- /* c1->layer == LAYER_NORMAL */
- } else {
- if (c2->layer == LAYER_ABOVE) {
- return -1;
- /* c2->layer == LAYER_BELOW */
- } else {
- return 1;
- }
- }
- }
+ return stack_level(c1) - stack_level(c2);
}
void stack(node_t *n)
if (stack_head == NULL) {
stack_insert_after(NULL, n);
} else {
- if (n->client->floating && !auto_raise)
+ if (IS_FLOATING(n->client) && !auto_raise) {
return;
+ }
stacking_list_t *s = stack_head;
while (s != NULL && stack_cmp(n->client, s->node->client) >= 0) {
s = s->next;
void stack_insert_before(stacking_list_t *a, node_t *n);
void remove_stack(stacking_list_t *s);
void remove_stack_node(node_t *n);
+int stack_level(client_t *c);
int stack_cmp(client_t *c1, client_t *c2);
void stack(node_t *n);
SBSC_MASK_DESKTOP_TRANSFER = 1 << 10,
SBSC_MASK_DESKTOP_FOCUS = 1 << 11,
SBSC_MASK_DESKTOP_LAYOUT = 1 << 12,
- SBSC_MASK_DESKTOP_STATE = 1 << 13,
- SBSC_MASK_WINDOW_MANAGE = 1 << 14,
- SBSC_MASK_WINDOW_UNMANAGE = 1 << 15,
- SBSC_MASK_WINDOW_SWAP = 1 << 16,
- SBSC_MASK_WINDOW_TRANSFER = 1 << 17,
- SBSC_MASK_WINDOW_FOCUS = 1 << 18,
- SBSC_MASK_WINDOW_RESIZE = 1 << 19,
- SBSC_MASK_WINDOW_MOVE = 1 << 20,
- SBSC_MASK_WINDOW_STATE = 1 << 21,
+ SBSC_MASK_WINDOW_MANAGE = 1 << 13,
+ SBSC_MASK_WINDOW_UNMANAGE = 1 << 14,
+ SBSC_MASK_WINDOW_SWAP = 1 << 15,
+ SBSC_MASK_WINDOW_TRANSFER = 1 << 16,
+ SBSC_MASK_WINDOW_FOCUS = 1 << 17,
+ SBSC_MASK_WINDOW_RESIZE = 1 << 18,
+ SBSC_MASK_WINDOW_MOVE = 1 << 19,
+ SBSC_MASK_WINDOW_STATE = 1 << 20,
+ SBSC_MASK_WINDOW_FLAG = 1 << 21,
SBSC_MASK_WINDOW_LAYER = 1 << 22,
SBSC_MASK_MONITOR = (1 << 6) - (1 << 1),
- SBSC_MASK_DESKTOP = (1 << 14) - (1 << 6),
- SBSC_MASK_WINDOW = (1 << 23) - (1 << 14),
+ SBSC_MASK_DESKTOP = (1 << 13) - (1 << 6),
+ SBSC_MASK_WINDOW = (1 << 23) - (1 << 13),
SBSC_MASK_ALL = (1 << 23) - 1
} subscriber_mask_t;
if (is_leaf(n)) {
unsigned int bw;
- if ((borderless_monocle && !n->client->floating &&
- !n->client->pseudo_tiled &&
- d->layout == LAYOUT_MONOCLE) ||
- n->client->fullscreen)
+ if ((borderless_monocle && n->client->state == STATE_TILED && d->layout == LAYOUT_MONOCLE)
+ || n->client->state == STATE_FULLSCREEN) {
bw = 0;
- else
+ } else {
bw = n->client->border_width;
+ }
xcb_rectangle_t r;
- if (!n->client->fullscreen) {
- if (!n->client->floating) {
- int wg = (gapless_monocle && d->layout == LAYOUT_MONOCLE ? 0 : d->window_gap);
- if (n->client->pseudo_tiled) {
- /* pseudo-tiled clients */
- r = n->client->floating_rectangle;
- if (center_pseudo_tiled) {
- r.x = rect.x - bw + (rect.width - wg - r.width) / 2;
- r.y = rect.y - bw + (rect.height - wg - r.height) / 2;
- } else {
- r.x = rect.x;
- r.y = rect.y;
- }
- } else {
- /* tiled clients */
- r = rect;
- int bleed = wg + 2 * bw;
- r.width = (bleed < r.width ? r.width - bleed : 1);
- r.height = (bleed < r.height ? r.height - bleed : 1);
- }
- n->client->tiled_rectangle = r;
+ client_state_t s = n->client->state;
+ if (s == STATE_TILED || s == STATE_PSEUDO_TILED) {
+ int wg = (gapless_monocle && d->layout == LAYOUT_MONOCLE ? 0 : d->window_gap);
+ /* tiled clients */
+ if (s == STATE_TILED) {
+ r = rect;
+ int bleed = wg + 2 * bw;
+ r.width = (bleed < r.width ? r.width - bleed : 1);
+ r.height = (bleed < r.height ? r.height - bleed : 1);
+ /* pseudo-tiled clients */
} else {
- /* floating clients */
r = n->client->floating_rectangle;
+ if (center_pseudo_tiled) {
+ r.x = rect.x - bw + (rect.width - wg - r.width) / 2;
+ r.y = rect.y - bw + (rect.height - wg - r.height) / 2;
+ } else {
+ r.x = rect.x;
+ r.y = rect.y;
+ }
}
+ /* floating clients */
+ } else if (s == STATE_FLOATING) {
+ r = n->client->floating_rectangle;
+ /* fullscreen clients */
} else {
- /* fullscreen clients */
r = m->rectangle;
}
c->second_child = n;
rot = 270;
}
- if (!n->client->floating)
+ if (IS_TILED(n->client)) {
rotate_tree(p, rot);
+ }
n->birth_rotation = rot;
}
break;
n->client->urgent = false;
put_status(SBSC_MASK_REPORT);
}
- if (d->focus != NULL && n != d->focus && d->focus->client->fullscreen && stack_cmp(n->client, d->focus->client) <= 0) {
- set_fullscreen(d->focus, false);
- arrange(m, d);
+ if (d->focus != NULL && n != d->focus && stack_cmp(n->client, d->focus->client) < 0) {
+ neutralize_obscuring_windows(m, d, n);
}
}
if (mon != m) {
- for (desktop_t *cd = mon->desk_head; cd != NULL; cd = cd->next)
+ for (desktop_t *cd = mon->desk_head; cd != NULL; cd = cd->next) {
window_draw_border(cd->focus, true, false);
- for (desktop_t *cd = m->desk_head; cd != NULL; cd = cd->next)
- if (cd != d)
+ }
+ for (desktop_t *cd = m->desk_head; cd != NULL; cd = cd->next) {
+ if (cd != d) {
window_draw_border(cd->focus, true, true);
- if (d->focus == n)
+ }
+ }
+ if (d->focus == n) {
window_draw_border(n, true, true);
+ }
}
if (d->focus != n) {
}
if (pointer_follows_focus) {
- center_pointer(get_rectangle(n->client));
+ center_pointer(get_rectangle(m, n->client));
}
ewmh_update_active_window();
{
client_t *c = malloc(sizeof(client_t));
c->window = win;
+ c->state = c->last_state = STATE_TILED;
c->layer = c->last_layer = LAYER_NORMAL;
snprintf(c->class_name, sizeof(c->class_name), "%s", MISSING_VALUE);
snprintf(c->instance_name, sizeof(c->instance_name), "%s", MISSING_VALUE);
c->border_width = border_width;
- c->pseudo_tiled = c->floating = c->fullscreen = false;
c->locked = c->sticky = c->urgent = c->private = c->icccm_focus = false;
xcb_icccm_get_wm_protocols_reply_t protocols;
if (xcb_icccm_get_wm_protocols_reply(dpy, xcb_icccm_get_wm_protocols(dpy, win, ewmh->WM_PROTOCOLS), &protocols, NULL) == 1) {
while (prev != NULL || next != NULL) {
#define TESTLOOP(n) \
if (n != NULL) { \
- if (!n->client->floating) { \
+ if (IS_TILED(n->client)) { \
if (n->privacy_level == 0) { \
if (n->parent == NULL || n->parent->privacy_level == 0) { \
*public = n; \
node_t *next_tiled_leaf(desktop_t *d, node_t *n, node_t *r)
{
node_t *next = next_leaf(n, r);
- if (next == NULL || !next->client->floating)
+ if (next == NULL || IS_TILED(next->client))
return next;
else
return next_tiled_leaf(d, next, r);
node_t *prev_tiled_leaf(desktop_t *d, node_t *n, node_t *r)
{
node_t *prev = prev_leaf(n, r);
- if (prev == NULL || !prev->client->floating)
+ if (prev == NULL || IS_TILED(prev->client))
return prev;
else
return prev_tiled_leaf(d, prev, r);
}
-/* bool is_adjacent(node_t *a, node_t *r) */
-/* { */
-/* node_t *f = r->parent; */
-/* node_t *p = a; */
-/* bool first_child = is_first_child(r); */
-/* while (p != r) { */
-/* if (p->parent->split_type == f->split_type && is_first_child(p) == first_child) */
-/* return false; */
-/* p = p->parent; */
-/* } */
-/* return true; */
-/* } */
-
/* Returns true if *b* is adjacent to *a* in the direction *dir* */
bool is_adjacent(node_t *a, node_t *b, direction_t dir)
{
node_t *nearest_neighbor(monitor_t *m, desktop_t *d, node_t *n, direction_t dir, client_select_t sel)
{
- if (n == NULL || n->client->fullscreen ||
- (d->layout == LAYOUT_MONOCLE && !n->client->floating))
+ if (n == NULL || IS_FULLSCREEN(n->client) ||
+ (d->layout == LAYOUT_MONOCLE && IS_TILED(n->client)))
return NULL;
node_t *nearest = NULL;
node_t *nearest_from_tree(monitor_t *m, desktop_t *d, node_t *n, direction_t dir, client_select_t sel)
{
- if (n == NULL)
+ if (n == NULL) {
return NULL;
+ }
node_t *fence = find_fence(n, dir);
node_t *nearest = NULL;
- if (dir == DIR_UP || dir == DIR_LEFT)
+ if (dir == DIR_UP || dir == DIR_LEFT) {
nearest = second_extrema(fence->first_child);
- else if (dir == DIR_DOWN || dir == DIR_RIGHT)
+ } else if (dir == DIR_DOWN || dir == DIR_RIGHT) {
nearest = first_extrema(fence->second_child);
+ }
coordinates_t ref = {m, d, n};
coordinates_t loc = {m, d, nearest};
- if (node_matches(&loc, &ref, sel))
+ if (node_matches(&loc, &ref, sel)) {
return nearest;
- else
+ } else {
return NULL;
+ }
}
node_t *nearest_from_history(monitor_t *m, desktop_t *d, node_t *n, direction_t dir, client_select_t sel)
{
- if (n == NULL || n->client->floating)
+ if (n == NULL || !IS_TILED(n->client)) {
return NULL;
+ }
node_t *target = find_fence(n, dir);
if (target == NULL)
node_t *target = NULL;
- if (!n->client->floating) {
+ if (IS_TILED(n->client)) {
target = find_fence(n, dir);
if (target == NULL)
return NULL;
coordinates_t loc = {m, d, a};
if (a == n ||
!node_matches(&loc, &ref, sel) ||
- !a->client->floating != !n->client->floating ||
- (!a->client->floating && !is_adjacent(n, a, dir)))
+ IS_TILED(a->client) != IS_TILED(n->client) ||
+ (IS_TILED(a->client) && !is_adjacent(n, a, dir)))
continue;
get_side_handle(a->client, dir2, &pt2);
{
int cnt = 0;
for (node_t *f = first_extrema(d->root); f != NULL; f = next_leaf(f, d->root)) {
- if (!f->client->floating) {
+ if (IS_TILED(f->client)) {
cnt++;
}
}
for (node_t *f = first_extrema(d->root); f != NULL; f = next_leaf(f, d->root)) {
coordinates_t loc = {m, d, f};
- if (f->client->floating || !node_matches(&loc, &ref, sel))
+ if (IS_FLOATING(f->client) || !node_matches(&loc, &ref, sel))
continue;
int f_area = tiled_area(f);
if (r == NULL) {
MODE_MANUAL
} split_mode_t;
+typedef enum {
+ STATE_TILED,
+ STATE_PSEUDO_TILED,
+ STATE_FLOATING,
+ STATE_FULLSCREEN
+} client_state_t;
+
typedef enum {
LAYER_BELOW,
LAYER_NORMAL,
} child_polarity_t;
typedef struct {
- option_bool_t floating;
+ option_bool_t tiled;
option_bool_t pseudo_tiled;
+ option_bool_t floating;
option_bool_t fullscreen;
option_bool_t locked;
option_bool_t sticky;
char class_name[3 * SMALEN / 2];
char instance_name[3 * SMALEN / 2];
unsigned int border_width;
- bool pseudo_tiled;
- bool floating;
- bool fullscreen;
bool locked; /* protects window from being closed */
bool sticky;
bool urgent;
bool private;
bool icccm_focus;
+ client_state_t state;
+ client_state_t last_state;
stack_layer_t layer;
stack_layer_t last_layer;
xcb_rectangle_t floating_rectangle;
int left_padding;
int window_gap;
unsigned int border_width;
- bool floating;
};
typedef struct monitor_t monitor_t;
char node_desc[MAXLEN];
char split_dir[SMALEN];
stack_layer_t *layer;
+ client_state_t *state;
double split_ratio;
uint16_t min_width;
uint16_t max_width;
uint16_t min_height;
uint16_t max_height;
- bool pseudo_tiled;
- bool floating;
- bool fullscreen;
bool locked;
bool sticky;
bool private;
parse_rule_consequence(fd, csq);
if (!csq->manage) {
+ free(csq->layer);
+ free(csq->state);
disable_floating_atom(win);
window_show(win);
return;
snprintf(c->class_name, sizeof(c->class_name), "%s", csq->class_name);
snprintf(c->instance_name, sizeof(c->instance_name), "%s", csq->instance_name);
- csq->floating = csq->floating || d->floating;
-
node_t *n = make_node();
n->client = c;
put_status(SBSC_MASK_WINDOW_MANAGE, "window_manage %s %s 0x%X 0x%X\n", m->name, d->name, f!=NULL?f->client->window:0, win);
insert_node(m, d, n, f);
- if (f != NULL && f->client != NULL && csq->floating) {
+ if (f != NULL && f->client != NULL && csq->state != NULL && *(csq->state) == STATE_FLOATING) {
c->layer = f->client->layer;
}
if (csq->layer != NULL) {
c->layer = *(csq->layer);
- free(csq->layer);
}
disable_floating_atom(c->window);
- set_pseudo_tiled(n, csq->pseudo_tiled);
- set_floating(n, csq->floating);
+ set_state(m, d, n, csq->state != NULL ? *(csq->state) : c->state);
set_locked(m, d, n, csq->locked);
set_sticky(m, d, n, csq->sticky);
set_private(m, d, n, csq->private);
- set_fullscreen(n, csq->fullscreen);
arrange(m, d);
bool give_focus = (csq->focus && (d == mon->desk || csq->follow));
- if (give_focus)
+ if (give_focus) {
focus_node(m, d, n);
- else if (csq->focus)
+ } else if (csq->focus) {
pseudo_focus(m, d, n);
- else
+ } else {
stack(n);
+ }
uint32_t values[] = {CLIENT_EVENT_MASK | (focus_follows_pointer ? XCB_EVENT_MASK_ENTER_WINDOW : 0)};
xcb_change_window_attributes(dpy, c->window, XCB_CW_EVENT_MASK, values);
}
/* the same function is already called in `focus_node` but has no effects on unmapped windows */
- if (give_focus)
+ if (give_focus) {
xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_POINTER_ROOT, win, XCB_CURRENT_TIME);
+ }
num_clients++;
ewmh_set_wm_desktop(n, d);
ewmh_update_client_list();
+ free(csq->layer);
+ free(csq->state);
}
void unmanage_window(xcb_window_t win)
uint32_t presel_border_color_pxl;
get_color(presel_border_color, win, &presel_border_color_pxl);
- xcb_rectangle_t actual_rectangle = get_rectangle(n->client);
+ xcb_rectangle_t actual_rectangle = get_rectangle(NULL, n->client);
uint16_t width = actual_rectangle.width;
uint16_t height = actual_rectangle.height;
a.y <= b.y && (a.y + a.height) >= (b.y + b.height));
}
-xcb_rectangle_t get_rectangle(client_t *c)
+xcb_rectangle_t get_rectangle(monitor_t *m, client_t *c)
{
- if (!c->floating)
- return c->tiled_rectangle;
- else
- return c->floating_rectangle;
+ switch (c->state) {
+ case STATE_TILED:
+ return c->tiled_rectangle;
+ break;
+ case STATE_PSEUDO_TILED:
+ case STATE_FLOATING:
+ return c->floating_rectangle;
+ break;
+ case STATE_FULLSCREEN:
+ return m->rectangle;
+ break;
+ }
}
void get_side_handle(client_t *c, direction_t dir, xcb_point_t *pt)
{
- xcb_rectangle_t rect = get_rectangle(c);
+ xcb_rectangle_t rect = get_rectangle(NULL, c);
+
switch (dir) {
case DIR_RIGHT:
pt->x = rect.x + rect.width;
remove_node(m, d, n);
}
-void set_fullscreen(node_t *n, bool value)
+void set_layer(monitor_t *m, desktop_t *d, node_t *n, stack_layer_t l)
{
- if (n == NULL || n->client->fullscreen == value)
+ if (n == NULL || n->client->layer == l) {
return;
+ }
client_t *c = n->client;
- PRINTF("fullscreen %X: %s\n", c->window, BOOLSTR(value));
- put_status(SBSC_MASK_WINDOW_STATE, "window_state fullscreen %s 0x%X\n", ONOFFSTR(value), c->window);
+ c->layer = l;
- c->fullscreen = value;
- if (value) {
- ewmh_wm_state_add(c, ewmh->_NET_WM_STATE_FULLSCREEN);
- c->last_layer = c->layer;
- c->layer = LAYER_ABOVE;
- } else {
- ewmh_wm_state_remove(c, ewmh->_NET_WM_STATE_FULLSCREEN);
- c->layer = c->last_layer;
+ put_status(SBSC_MASK_WINDOW_LAYER, "window_layer %s 0x%X\n", LAYERSTR(l), c->window);
+
+ if (d->focus == n) {
+ neutralize_obscuring_windows(m, d, n);
}
stack(n);
}
-void set_layer(node_t *n, stack_layer_t layer)
+void set_state(monitor_t *m, desktop_t *d, node_t *n, client_state_t s)
{
- if (n == NULL || n->client->layer == layer) {
+ if (n == NULL || n->client->state == s) {
return;
}
client_t *c = n->client;
- c->layer = layer;
- put_status(SBSC_MASK_WINDOW_LAYER, "window_layer %s 0x%X\n", LAYERSTR(layer), c->window);
+ c->last_state = c->state;
+ c->state = s;
- stack(n);
+ switch (c->last_state) {
+ case STATE_TILED:
+ case STATE_PSEUDO_TILED:
+ break;
+ case STATE_FLOATING:
+ set_floating(m, d, n, false);
+ break;
+ case STATE_FULLSCREEN:
+ set_fullscreen(m, d, n, false);
+ break;
+ }
+
+ put_status(SBSC_MASK_WINDOW_STATE, "window_state %s off 0x%X\n", STATESTR(c->last_state), c->window);
+
+ switch (c->state) {
+ case STATE_TILED:
+ case STATE_PSEUDO_TILED:
+ break;
+ case STATE_FLOATING:
+ set_floating(m, d, n, true);
+ break;
+ case STATE_FULLSCREEN:
+ set_fullscreen(m, d, n, true);
+ break;
+ }
+
+ put_status(SBSC_MASK_WINDOW_STATE, "window_state %s on 0x%X\n", STATESTR(c->state), c->window);
}
-void set_pseudo_tiled(node_t *n, bool value)
+void set_floating(monitor_t *m, desktop_t *d, node_t *n, bool value)
{
- if (n == NULL || n->client->pseudo_tiled == value)
+ if (n == NULL) {
return;
+ }
client_t *c = n->client;
- PRINTF("pseudo-tiled %X: %s\n", c->window, BOOLSTR(value));
- put_status(SBSC_MASK_WINDOW_STATE, "window_state pseudo_tiled %s 0x%X\n", ONOFFSTR(value), c->window);
+ n->split_mode = MODE_AUTOMATIC;
+ n->vacant = value;
+ update_vacant_state(n->parent);
- c->pseudo_tiled = value;
+ if (value) {
+ enable_floating_atom(c->window);
+ unrotate_brother(n);
+ } else {
+ disable_floating_atom(c->window);
+ rotate_brother(n);
+ if (d->focus == n) {
+ neutralize_obscuring_windows(m, d, n);
+ }
+ }
+
+ stack(n);
}
-void set_floating(node_t *n, bool value)
+void set_fullscreen(monitor_t *m, desktop_t *d, node_t *n, bool value)
{
- if (n == NULL || n->client->fullscreen || n->client->floating == value)
+ if (n == NULL) {
return;
+ }
client_t *c = n->client;
- PRINTF("floating %X: %s\n", c->window, BOOLSTR(value));
- put_status(SBSC_MASK_WINDOW_STATE, "window_state floating %s 0x%X\n", ONOFFSTR(value), c->window);
-
n->split_mode = MODE_AUTOMATIC;
- c->floating = n->vacant = value;
+ n->vacant = value;
update_vacant_state(n->parent);
if (value) {
- enable_floating_atom(c->window);
- unrotate_brother(n);
+ ewmh_wm_state_add(c, ewmh->_NET_WM_STATE_FULLSCREEN);
+ c->last_layer = c->layer;
+ c->layer = LAYER_ABOVE;
} else {
- disable_floating_atom(c->window);
- rotate_brother(n);
+ ewmh_wm_state_remove(c, ewmh->_NET_WM_STATE_FULLSCREEN);
+ c->layer = c->last_layer;
+ if (d->focus == n) {
+ neutralize_obscuring_windows(m, d, n);
+ }
}
stack(n);
}
+void neutralize_obscuring_windows(monitor_t *m, desktop_t *d, node_t *n)
+{
+ bool dirty = false;
+ for (node_t *a = first_extrema(d->root); a != NULL; a = next_leaf(a, d->root)) {
+ if (a != n) {
+ if (IS_FULLSCREEN(a->client) && stack_cmp(n->client, a->client) < 0) {
+ set_state(m, d, a, a->client->last_state);
+ dirty = true;
+ }
+ }
+ }
+ if (dirty) {
+ arrange(m, d);
+ }
+}
+
void set_locked(monitor_t *m, desktop_t *d, node_t *n, bool value)
{
if (n == NULL || n->client->locked == value)
client_t *c = n->client;
- PRINTF("set locked %X: %s\n", c->window, BOOLSTR(value));
- put_status(SBSC_MASK_WINDOW_STATE, "window_state locked %s 0x%X\n", ONOFFSTR(value), c->window);
+ put_status(SBSC_MASK_WINDOW_FLAG, "window_flag locked %s 0x%X\n", ONOFFSTR(value), c->window);
c->locked = value;
window_draw_border(n, d->focus == n, m == mon);
client_t *c = n->client;
- PRINTF("set sticky %X: %s\n", c->window, BOOLSTR(value));
- put_status(SBSC_MASK_WINDOW_STATE, "window_state sticky %s 0x%X\n", ONOFFSTR(value), c->window);
+ put_status(SBSC_MASK_WINDOW_FLAG, "window_flag sticky %s 0x%X\n", ONOFFSTR(value), c->window);
if (d != m->desk)
transfer_node(m, d, n, m, m->desk, m->desk->focus);
client_t *c = n->client;
- PRINTF("set private %X: %s\n", c->window, BOOLSTR(value));
- put_status(SBSC_MASK_WINDOW_STATE, "window_state private %s 0x%X\n", ONOFFSTR(value), c->window);
+ put_status(SBSC_MASK_WINDOW_FLAG, "window_flag private %s 0x%X\n", ONOFFSTR(value), c->window);
c->private = value;
update_privacy_level(n, value);
n->client->urgent = value;
window_draw_border(n, d->focus == n, m == mon);
- put_status(SBSC_MASK_WINDOW_STATE, "window_state urgent %s 0x%X\n", ONOFFSTR(value), n->client->window);
+ put_status(SBSC_MASK_WINDOW_FLAG, "window_flag urgent %s 0x%X\n", ONOFFSTR(value), n->client->window);
put_status(SBSC_MASK_REPORT);
}
void window_draw_border(node_t *n, bool focused_window, bool focused_monitor);
pointer_state_t *make_pointer_state(void);
bool contains(xcb_rectangle_t a, xcb_rectangle_t b);
-xcb_rectangle_t get_rectangle(client_t *c);
+xcb_rectangle_t get_rectangle(monitor_t *m, client_t *c);
void get_side_handle(client_t *c, direction_t dir, xcb_point_t *pt);
void adopt_orphans(void);
void window_close(node_t *n);
void window_kill(monitor_t *m, desktop_t *d, node_t *n);
-void set_fullscreen(node_t *n, bool value);
-void set_layer(node_t *n, stack_layer_t layer);
-void set_pseudo_tiled(node_t *n, bool value);
-void set_floating(node_t *n, bool value);
+void set_layer(monitor_t *m, desktop_t *d, node_t *n, stack_layer_t l);
+void set_state(monitor_t *m, desktop_t *d, node_t *n, client_state_t s);
+void set_floating(monitor_t *m, desktop_t *d, node_t *n, bool value);
+void set_fullscreen(monitor_t *m, desktop_t *d, node_t *n, bool value);
+void neutralize_obscuring_windows(monitor_t *m, desktop_t *d, node_t *n);
void set_locked(monitor_t *m, desktop_t *d, node_t *n, bool value);
void set_sticky(monitor_t *m, desktop_t *d, node_t *n, bool value);
void set_private(monitor_t *m, desktop_t *d, node_t *n, bool value);