summaryrefslogtreecommitdiffstats
path: root/desktop/bspwm/patches/bspwm-0.8.8_0ca5bf3.patch
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/bspwm/patches/bspwm-0.8.8_0ca5bf3.patch')
-rw-r--r--desktop/bspwm/patches/bspwm-0.8.8_0ca5bf3.patch4719
1 files changed, 0 insertions, 4719 deletions
diff --git a/desktop/bspwm/patches/bspwm-0.8.8_0ca5bf3.patch b/desktop/bspwm/patches/bspwm-0.8.8_0ca5bf3.patch
deleted file mode 100644
index 3e7dec1736..0000000000
--- a/desktop/bspwm/patches/bspwm-0.8.8_0ca5bf3.patch
+++ /dev/null
@@ -1,4719 +0,0 @@
-diff --git a/LICENSE b/LICENSE
-index b6ffa88..1f93c08 100644
---- a/LICENSE
-+++ b/LICENSE
-@@ -1,4 +1,4 @@
--Copyright (c) 2012-2013, Bastien Dejean
-+Copyright (c) 2012-2014, Bastien Dejean
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
-diff --git a/Sourcedeps b/Sourcedeps
-index 9b36a69..f757d4e 100644
---- a/Sourcedeps
-+++ b/Sourcedeps
-@@ -11,7 +11,7 @@ helpers.o: helpers.c bspwm.h types.h helpers.h
- history.o: history.c bspwm.h types.h helpers.h query.h
- messages.o: messages.c bspwm.h types.h helpers.h desktop.h ewmh.h \
- history.h monitor.h pointer.h query.h rule.h restore.h settings.h tree.h \
-- window.h messages.h
-+ window.h common.h subscribe.h messages.h
- monitor.o: monitor.c bspwm.h types.h helpers.h desktop.h ewmh.h history.h \
- query.h settings.h tree.h window.h monitor.h
- pointer.o: pointer.c bspwm.h types.h helpers.h query.h settings.h stack.h \
-@@ -29,4 +29,4 @@ subscribe.o: subscribe.c bspwm.h types.h helpers.h tree.h settings.h \
- tree.o: tree.c bspwm.h types.h helpers.h desktop.h ewmh.h history.h \
- monitor.h query.h settings.h stack.h window.h tree.h
- window.o: window.c bspwm.h types.h helpers.h ewmh.h monitor.h query.h \
-- rule.h settings.h stack.h tree.h window.h
-+ rule.h settings.h stack.h tree.h messages.h window.h
-diff --git a/bspc.c b/bspc.c
-index 1617afc..3903eaf 100644
---- a/bspc.c
-+++ b/bspc.c
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #include <stdlib.h>
-@@ -66,10 +70,15 @@ int main(int argc, char *argv[])
- if (send(fd, msg, msg_len, 0) == -1)
- err("Failed to send the data.\n");
-
-- int ret = EXIT_SUCCESS, nb;
-+ int ret = 0, nb;
- while ((nb = recv(fd, rsp, sizeof(rsp), 0)) > 0) {
-- if (nb == 1 && rsp[0] == MESSAGE_FAILURE) {
-- ret = EXIT_FAILURE;
-+ if (nb == 1 && rsp[0] < MSG_LENGTH) {
-+ ret = rsp[0];
-+ if (ret == MSG_UNKNOWN) {
-+ warn("Unknown command.\n");
-+ } else if (ret == MSG_SYNTAX) {
-+ warn("Invalid syntax.\n");
-+ }
- } else {
- int end = MIN(nb, (int) sizeof(rsp) - 1);
- rsp[end--] = '\0';
-diff --git a/bspwm.c b/bspwm.c
-index 95049ae..b3d91c2 100644
---- a/bspwm.c
-+++ b/bspwm.c
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #include <stdio.h>
-@@ -57,9 +61,7 @@ int main(int argc, char *argv[])
- config_path[0] = '\0';
- int sock_fd, cli_fd, dpy_fd, max_fd, n;
- struct sockaddr_un sock_address;
-- size_t rsp_len = 0;
- char msg[BUFSIZ] = {0};
-- char rsp[BUFSIZ] = {0};
- xcb_generic_event_t *event;
- char opt;
-
-@@ -155,19 +157,21 @@ int main(int argc, char *argv[])
- cli_fd = accept(sock_fd, NULL, 0);
- if (cli_fd > 0 && (n = recv(cli_fd, msg, sizeof(msg), 0)) > 0) {
- msg[n] = '\0';
-- if (handle_message(msg, n, rsp)) {
-- rsp_len = strlen(rsp);
-+ FILE *rsp = fdopen(cli_fd, "w");
-+ if (rsp != NULL) {
-+ int ret = handle_message(msg, n, rsp);
-+ if (ret == MSG_SUBSCRIBE) {
-+ add_subscriber(rsp);
- } else {
-- rsp[0] = MESSAGE_FAILURE;
-- rsp_len = 1;
-+ if (ret != MSG_SUCCESS)
-+ fprintf(rsp, "%c", ret);
-+ fflush(rsp);
-+ fclose(rsp);
- }
-- if (rsp_len == 1 && rsp[0] == MESSAGE_SUBSCRIBE) {
-- add_subscriber(cli_fd);
- } else {
-- send(cli_fd, rsp, rsp_len, 0);
-+ warn("Can't open the client socket as file.\n");
- close(cli_fd);
- }
-- rsp[0] = '\0';
- }
- }
-
-@@ -339,7 +343,8 @@ void put_status(void)
- subscriber_list_t *sb = subscribe_head;
- while (sb != NULL) {
- subscriber_list_t *next = sb->next;
-- feed_subscriber(sb);
-+ if (print_status(sb->stream) != 0)
-+ remove_subscriber(sb);
- sb = next;
- }
- }
-diff --git a/bspwm.h b/bspwm.h
-index 6732933..274d6ea 100644
---- a/bspwm.h
-+++ b/bspwm.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_BSPWM_H
-diff --git a/common.h b/common.h
-index 2b29ba0..bb565dd 100644
---- a/common.h
-+++ b/common.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_COMMON_H
-@@ -27,6 +31,14 @@
-
- #define SOCKET_PATH_TPL "/tmp/bspwm%s-socket"
- #define SOCKET_ENV_VAR "BSPWM_SOCKET"
--#define MESSAGE_FAILURE '\x18'
-+
-+enum {
-+ MSG_SUCCESS,
-+ MSG_FAILURE,
-+ MSG_SYNTAX,
-+ MSG_UNKNOWN,
-+ MSG_SUBSCRIBE,
-+ MSG_LENGTH
-+};
-
- #endif
-diff --git a/desktop.c b/desktop.c
-index 5b6a4fd..fcc9770 100644
---- a/desktop.c
-+++ b/desktop.c
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #include <stdlib.h>
-diff --git a/desktop.h b/desktop.h
-index 5931cd2..812dc1c 100644
---- a/desktop.h
-+++ b/desktop.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_DESKTOP_H
-diff --git a/doc/CONTRIBUTING.md b/doc/CONTRIBUTING.md
-index 8151d22..8f5534c 100644
---- a/doc/CONTRIBUTING.md
-+++ b/doc/CONTRIBUTING.md
-@@ -4,14 +4,10 @@ You must be comfortable with [C][1], [XCB][2] and [Git][3].
-
- ## Coding Style
-
--I follow the [Linux Coding Style][4] with the following exceptions:
--- One *Tab* equals 4 spaces.
--- Always use `typedef ...` for structures.
-+I follow the [Linux Coding Style][4].
-
- ## Browsing the Code
-
--The first files you might want to look at are `types.h`, `bspwm.c` and `events.c`.
--
- If you use `vim`:
- - Hitting *K* will lead you to the manual page of the function under the cursor (works with most `xcb_*` functions), sometimes you'll have to explicitly specify the section of the manual you're interested in with *3K* (e.g.: `open`).
- - Install `ctags` and run `ctags *.{c,h}` in the directory holding the source. Then, hitting *Ctrl-]* will lead you to the definition of the function/variable/structure under the cursor (to go back: *Ctrl-T*).
-@@ -24,11 +20,11 @@ To produce debug executables, issue:
- make debug
- ```
-
--If you use `systemd`, X might be started on the same virtual terminal as `bspwm` and you won't see its output, hence use something like `startx -- vt08` to start X (you can switch to the virtual terminal number *n* with *Ctrl-Alt-Fn*).
-+If you use `systemd`, X might be started on the same virtual terminal as `bspwm` and you won't see its output, hence use something like `startx -- vt08` to start X (you can switch to the virtual terminal number *<n>* with *Ctrl-Alt-F<n>*).
-
- The debug messages are generated by the `PRINTF` and `PUTS` macros: feel free to use them.
-
--If you want to use [`gdb`][5], switch to a free virtual terminal, e.g. *Ctrl-Alt-F2* and issue:
-+If you want to use [`gdb`][5], switch to a free virtual terminal and issue:
-
- ```
- gdb bspwm $(pgrep -x bspwm)
-diff --git a/doc/TODO.md b/doc/TODO.md
-index 4757461..3785005 100644
---- a/doc/TODO.md
-+++ b/doc/TODO.md
-@@ -1,5 +1,5 @@
--- Desktops as nodes?
-+- Set more attributes in `make_client` (instead of doing it in `apply_rules`) and don't pass `XCB_NONE` as argument.
-+- Internal nodes selectors/actions: labels?
- - Invisible state.
- - Restore built-in pointer grabbing?
--- `FILE *` instead of `char *` for writing the server response?
- - Use BSD `sys/{queue/tree}.h` for {list,tree} structures?
-diff --git a/doc/asciidoc.conf b/doc/asciidoc.conf
-deleted file mode 100644
-index 68d4d6d..0000000
---- a/doc/asciidoc.conf
-+++ /dev/null
-@@ -1,39 +0,0 @@
--#
--# Borrowed from pacman
--#
--
--[macros]
--(?su)[\\]?(?P<name>linkman):(?P<target>\S*?)\[(?P<attrlist>.*?)\]=
--
--[attributes]
--asterisk=&#42;
--plus=&#43;
--caret=&#94;
--startsb=&#91;
--endsb=&#93;
--backslash=&#92;
--tilde=&#126;
--apostrophe=&#39;
--backtick=&#96;
--litdd=&#45;&#45;
--
--ifdef::backend-docbook[]
--[linkman-inlinemacro]
--{0%{target}}
--{0#<citerefentry>}
--{0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>}
--{0#</citerefentry>}
--endif::backend-docbook[]
--
--ifdef::backend-docbook[]
--ifndef::docbook-xsl-172[]
--# "unbreak" docbook-xsl v1.68 for manpages. v1.69 works with or without this.
--# v1.72 breaks with this because it replaces dots not in roff requests.
--[listingblock]
--<example><title>{title}</title>
--<literallayout>
--|
--</literallayout>
--{title#}</example>
--endif::docbook-xsl-172[]
--endif::backend-docbook[]
-diff --git a/doc/bspwm.1 b/doc/bspwm.1
-index 0248bd5..b6e42ec 100644
---- a/doc/bspwm.1
-+++ b/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: 01/03/2014
-+.\" Date: 02/17/2014
- .\" Manual: Bspwm Manual
- .\" Source: Bspwm 0.8.8
- .\" Language: English
- .\"
--.TH "BSPWM" "1" "01/03/2014" "Bspwm 0\&.8\&.8" "Bspwm Manual"
-+.TH "BSPWM" "1" "02/17/2014" "Bspwm 0\&.8\&.8" "Bspwm Manual"
- .\" -----------------------------------------------------------------
- .\" * Define some portability stuff
- .\" -----------------------------------------------------------------
-@@ -167,7 +167,7 @@ Select a window\&.
- .\}
- .nf
- WINDOW_SEL := <window_id>
-- | (DIR|CYCLE_DIR|biggest|last|focused|older|newer)[\&.floating|\&.tiled][\&.like|\&.unlike][\&.manual][\&.urgent][\&.local]
-+ | (DIR|CYCLE_DIR|biggest|last|focused|older|newer)[\&.floating|\&.tiled][\&.like|\&.unlike][\&.manual|\&.automatic][\&.urgent][\&.local]
- .fi
- .if n \{\
- .RE
-@@ -247,8 +247,12 @@ Only consider windows that have a different class than the current window\&.
- .PP
- manual
- .RS 4
--Only consider windows in manual splitting mode (see
--\fB\-\-presel\fR)\&.
-+Only consider windows in manual splitting mode\&.
-+.RE
-+.PP
-+automatic
-+.RS 4
-+Only consider windows in automatic splitting mode\&.
- .RE
- .PP
- local
-@@ -270,8 +274,8 @@ Select a desktop\&.
- .\}
- .nf
- DESKTOP_SEL := <desktop_name>
-- | ^<n>
-- | (CYCLE_DIR|last|focused[:MONITOR_SEL]|older|newer)[\&.occupied|\&.free][\&.urgent][\&.local]
-+ | [MONITOR_SEL:]^<n>
-+ | (CYCLE_DIR|last|[MONITOR_SEL:]focused|older|newer)[\&.occupied|\&.free][\&.urgent][\&.local]
- .fi
- .if n \{\
- .RE
-@@ -620,6 +624,11 @@ Flip the tree of the selected desktop\&.
- Rotate the tree of the selected desktop\&.
- .RE
- .PP
-+\fB\-E\fR, \fB\-\-equalize\fR
-+.RS 4
-+Reset the split ratios of the tree of the selected desktop\&.
-+.RE
-+.PP
- \fB\-B\fR, \fB\-\-balance\fR
- .RS 4
- Adjust the split ratios of the tree of the selected desktop so that all windows occupy the same area\&.
-@@ -821,7 +830,12 @@ Enable or disable the recording of window focus history\&.
- .PP
- \fB\-\-subscribe\fR
- .RS 4
--Continuously print status informations on standard output\&.
-+Continuously print status informations\&.
-+.RE
-+.PP
-+\fB\-\-get\-status\fR
-+.RS 4
-+Print the current status informations\&.
- .RE
- .RE
- .SS "Pointer"
-@@ -881,7 +895,7 @@ rule \fIOPTIONS\fR
- \fBOptions\fR
- .RS 4
- .PP
--\fB\-a\fR, \fB\-\-add\fR <class_name>|<instance_name>|* [\fB\-o\fR|\fB\-\-one\-shot\fR] [desktop=DESKTOP_SEL|monitor=MONITOR_SEL] [(floating|fullscreen|pseudo_tiled|locked|sticky|private|center|lower|follow|manage|focus)=(true|false)]
-+\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)=(true|false)] [split_dir=DIR]
- .RS 4
- Create a new rule\&.
- .RE
-@@ -906,7 +920,7 @@ List the rules\&.
- \fBGeneral Syntax\fR
- .RS 4
- .PP
--config [\-m \fIMONITOR_SEL\fR|\-d \fIDESKTOP_SEL\fR] <key> [<value>]
-+config [\-m \fIMONITOR_SEL\fR|\-d \fIDESKTOP_SEL\fR|\-w \fIWINDOW_SEL\fR] <key> [<value>]
- .RS 4
- Get or set the value of <key>\&.
- .RE
-@@ -926,6 +940,24 @@ quit [<status>]
- Quit with an optional exit status\&.
- .RE
- .RE
-+.SH "EXIT CODES"
-+.sp
-+If the server can\(cqt handle a message, \fBbspc\fR will return with one of the following exit codes:
-+.PP
-+1
-+.RS 4
-+Failure\&.
-+.RE
-+.PP
-+2
-+.RS 4
-+Syntax error\&.
-+.RE
-+.PP
-+3
-+.RS 4
-+Unknown command\&.
-+.RE
- .SH "SETTINGS"
- .sp
- Colors are either X color names or \fI#RRGGBB\fR, booleans are \fItrue\fR or \fIfalse\fR\&.
-@@ -1076,7 +1108,7 @@ atom of each window according to its floating state\&.
- .PP
- \fIignore_ewmh_focus\fR
- .RS 4
--Ignore EWMH requests to focus a window\&.
-+Ignore EWMH focus requests coming from applications\&.
- .RE
- .PP
- \fIremove_disabled_monitor\fR
-@@ -1089,16 +1121,17 @@ Consider disabled monitors as disconnected\&.
- .RS 4
- Padding space added at the sides of the monitor or desktop\&.
- .RE
--.SS "Desktop Settings"
-+.SS "Desktop and Window Settings"
- .PP
--\fIwindow_gap\fR
-+\fIborder_width\fR
- .RS 4
--Size of the gap that separates windows\&.
-+Window border width\&.
- .RE
-+.SS "Desktop Settings"
- .PP
--\fIborder_width\fR
-+\fIwindow_gap\fR
- .RS 4
--Window border width\&.
-+Size of the gap that separates windows\&.
- .RE
- .SH "STATUS FORMAT"
- .sp
-diff --git a/doc/bspwm.1.txt b/doc/bspwm.1.txt
-index 278d089..3cad790 100644
---- a/doc/bspwm.1.txt
-+++ b/doc/bspwm.1.txt
-@@ -134,15 +134,14 @@ Select a window.
-
- ----
- WINDOW_SEL := <window_id>
-- | (DIR|CYCLE_DIR|biggest|last|focused|older|newer)[.floating|.tiled][.like|.unlike][.manual][.urgent][.local]
-+ | (DIR|CYCLE_DIR|biggest|last|focused|older|newer)[.floating|.tiled][.like|.unlike][.manual|.automatic][.urgent][.local]
- ----
-
- Primary Selectors
- ^^^^^^^^^^^^^^^^^
-
- 'DIR'::
-- Selects the window in the given (spacial) direction relative to the active
-- window.
-+ Selects the window in the given (spacial) direction relative to the active window.
-
- 'CYCLE_DIR'::
- Selects the window in the given (cyclic) direction.
-@@ -178,7 +177,10 @@ unlike::
- Only consider windows that have a different class than the current window.
-
- manual::
-- Only consider windows in manual splitting mode (see *--presel*).
-+ Only consider windows in manual splitting mode.
-+
-+automatic::
-+ Only consider windows in automatic splitting mode.
-
- local::
- Only consider windows of the current desktop.
-@@ -193,8 +195,8 @@ Select a desktop.
-
- ----
- DESKTOP_SEL := <desktop_name>
-- | ^<n>
-- | (CYCLE_DIR|last|focused[:MONITOR_SEL]|older|newer)[.occupied|.free][.urgent][.local]
-+ | [MONITOR_SEL:]^<n>
-+ | (CYCLE_DIR|last|[MONITOR_SEL:]focused|older|newer)[.occupied|.free][.urgent][.local]
- ----
-
- Primary Selectors
-@@ -395,6 +397,9 @@ Options
- *-R*, *--rotate* '90|270|180'::
- Rotate the tree of the selected desktop.
-
-+*-E*, *--equalize*::
-+ Reset the split ratios of the tree of the selected desktop.
-+
- *-B*, *--balance*::
- Adjust the split ratios of the tree of the selected desktop so that all windows occupy the same area.
-
-@@ -508,7 +513,10 @@ Options
- Enable or disable the recording of window focus history.
-
- *--subscribe*::
-- Continuously print status informations on standard output.
-+ Continuously print status informations.
-+
-+*--get-status*::
-+ Print the current status informations.
-
- Pointer
- ~~~~~~~
-@@ -541,7 +549,7 @@ rule 'OPTIONS'
- Options
- ^^^^^^^
-
--*-a*, *--add* <class_name>|<instance_name>|* [*-o*|*--one-shot*] [desktop=DESKTOP_SEL|monitor=MONITOR_SEL] [(floating|fullscreen|pseudo_tiled|locked|sticky|private|center|lower|follow|manage|focus)=(true|false)]::
-+*-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)=(true|false)] [split_dir=DIR]::
- Create a new rule.
-
- *-r*, *--remove* ^<n>|head|tail|<class_name>|<instance_name>|*...::
-@@ -556,7 +564,7 @@ Config
- General Syntax
- ^^^^^^^^^^^^^^
-
--config [-m 'MONITOR_SEL'|-d 'DESKTOP_SEL'] <key> [<value>]::
-+config [-m 'MONITOR_SEL'|-d 'DESKTOP_SEL'|-w 'WINDOW_SEL'] <key> [<value>]::
- Get or set the value of <key>.
-
- Quit
-@@ -568,6 +576,19 @@ General Syntax
- quit [<status>]::
- Quit with an optional exit status.
-
-+Exit Codes
-+----------
-+
-+If the server can't handle a message, *bspc* will return with one of the following exit codes:
-+
-+1::
-+ Failure.
-+2::
-+ Syntax error.
-+3::
-+ Unknown command.
-+
-+
- Settings
- --------
- Colors are either http://en.wikipedia.org/wiki/X11_color_names[X color names] or '#RRGGBB', booleans are 'true' or 'false'.
-@@ -653,7 +674,7 @@ Global Settings
- Set the value of the '_BSPWM_FLOATING_WINDOW' atom of each window according to its floating state.
-
- 'ignore_ewmh_focus'::
-- Ignore EWMH requests to focus a window.
-+ Ignore EWMH focus requests coming from applications.
-
- 'remove_disabled_monitor'::
- Consider disabled monitors as disconnected.
-@@ -667,15 +688,18 @@ Monitor and Desktop Settings
- 'left_padding'::
- Padding space added at the sides of the monitor or desktop.
-
-+Desktop and Window Settings
-+~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+
-+'border_width'::
-+ Window border width.
-+
- Desktop Settings
- ~~~~~~~~~~~~~~~~
-
- 'window_gap'::
- Size of the gap that separates windows.
-
--'border_width'::
-- Window border width.
--
-
- Status Format
- -------------
-diff --git a/events.c b/events.c
-index b41a9a7..559030d 100644
---- a/events.c
-+++ b/events.c
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #include <stdlib.h>
-@@ -87,26 +91,38 @@ void configure_request(xcb_generic_event_t *evt)
-
- coordinates_t loc;
- bool is_managed = locate_window(e->window, &loc);
-+ client_t *c = (is_managed ? loc.node->client : NULL);
-+ int w = 0, h = 0;
-
-- if (is_managed && !is_floating(loc.node->client)) {
-+ if (is_managed && !is_floating(c)) {
- if (e->value_mask & XCB_CONFIG_WINDOW_X)
-- loc.node->client->floating_rectangle.x = e->x;
-+ c->floating_rectangle.x = e->x;
- if (e->value_mask & XCB_CONFIG_WINDOW_Y)
-- loc.node->client->floating_rectangle.y = e->y;
-+ c->floating_rectangle.y = e->y;
- if (e->value_mask & XCB_CONFIG_WINDOW_WIDTH)
-- loc.node->client->floating_rectangle.width = e->width;
-+ w = e->width;
- if (e->value_mask & XCB_CONFIG_WINDOW_HEIGHT)
-- loc.node->client->floating_rectangle.height = e->height;
-+ h = e->height;
-+
-+ if (w != 0) {
-+ restrain_floating_width(c, &w);
-+ c->floating_rectangle.width = w;
-+ }
-+
-+ if (h != 0) {
-+ restrain_floating_height(c, &h);
-+ c->floating_rectangle.height = h;
-+ }
-
- xcb_configure_notify_event_t evt;
- xcb_rectangle_t rect;
-- xcb_window_t win = loc.node->client->window;
-- unsigned int bw = loc.node->client->border_width;
-+ xcb_window_t win = c->window;
-+ unsigned int bw = c->border_width;
-
-- if (loc.node->client->fullscreen)
-+ if (c->fullscreen)
- rect = loc.monitor->rectangle;
- else
-- rect = loc.node->client->tiled_rectangle;
-+ rect = c->tiled_rectangle;
-
- evt.response_type = XCB_CONFIGURE_NOTIFY;
- evt.event = win;
-@@ -121,7 +137,7 @@ void configure_request(xcb_generic_event_t *evt)
-
- xcb_send_event(dpy, false, win, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char *) &evt);
-
-- if (loc.node->client->pseudo_tiled)
-+ if (c->pseudo_tiled)
- arrange(loc.monitor, loc.desktop);
- } else {
- uint16_t mask = 0;
-@@ -132,28 +148,34 @@ void configure_request(xcb_generic_event_t *evt)
- mask |= XCB_CONFIG_WINDOW_X;
- values[i++] = e->x;
- if (is_managed)
-- loc.node->client->floating_rectangle.x = e->x;
-+ c->floating_rectangle.x = e->x;
- }
-
- if (e->value_mask & XCB_CONFIG_WINDOW_Y) {
- mask |= XCB_CONFIG_WINDOW_Y;
- values[i++] = e->y;
- if (is_managed)
-- loc.node->client->floating_rectangle.y = e->y;
-+ c->floating_rectangle.y = e->y;
- }
-
- if (e->value_mask & XCB_CONFIG_WINDOW_WIDTH) {
- mask |= XCB_CONFIG_WINDOW_WIDTH;
-- values[i++] = e->width;
-- if (is_managed)
-- loc.node->client->floating_rectangle.width = e->width;
-+ w = e->width;
-+ if (is_managed) {
-+ restrain_floating_width(c, &w);
-+ c->floating_rectangle.width = w;
-+ }
-+ values[i++] = w;
- }
-
- if (e->value_mask & XCB_CONFIG_WINDOW_HEIGHT) {
- mask |= XCB_CONFIG_WINDOW_HEIGHT;
-- values[i++] = e->height;
-- if (is_managed)
-- loc.node->client->floating_rectangle.height = e->height;
-+ h = e->height;
-+ if (is_managed) {
-+ restrain_floating_height(c, &h);
-+ c->floating_rectangle.height = h;
-+ }
-+ values[i++] = h;
- }
-
- if (!is_managed && e->value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) {
-@@ -175,7 +197,7 @@ void configure_request(xcb_generic_event_t *evt)
- }
-
- if (is_managed)
-- translate_client(monitor_from_client(loc.node->client), loc.monitor, loc.node->client);
-+ translate_client(monitor_from_client(c), loc.monitor, c);
- }
-
- void destroy_notify(xcb_generic_event_t *evt)
-@@ -199,17 +221,38 @@ void unmap_notify(xcb_generic_event_t *evt)
- void property_notify(xcb_generic_event_t *evt)
- {
- xcb_property_notify_event_t *e = (xcb_property_notify_event_t *) evt;
-- xcb_icccm_wm_hints_t hints;
-
- /* PRINTF("property notify %X\n", e->window); */
-
-- if (e->atom != XCB_ATOM_WM_HINTS)
-+ if (e->atom != XCB_ATOM_WM_HINTS && e->atom != XCB_ATOM_WM_NORMAL_HINTS)
- return;
-
- coordinates_t loc;
-- if (locate_window(e->window, &loc)
-- && xcb_icccm_get_wm_hints_reply(dpy, xcb_icccm_get_wm_hints(dpy, e->window), &hints, NULL) == 1)
-+ if (!locate_window(e->window, &loc))
-+ return;
-+
-+ if (e->atom == XCB_ATOM_WM_HINTS) {
-+ xcb_icccm_wm_hints_t hints;
-+ if (xcb_icccm_get_wm_hints_reply(dpy, xcb_icccm_get_wm_hints(dpy, e->window), &hints, NULL) == 1 &&
-+ (hints.flags & XCB_ICCCM_WM_HINT_X_URGENCY))
- set_urgency(loc.monitor, loc.desktop, loc.node, xcb_icccm_wm_hints_get_urgency(&hints));
-+ } else if (e->atom == XCB_ATOM_WM_NORMAL_HINTS) {
-+ client_t *c = loc.node->client;
-+ xcb_size_hints_t size_hints;
-+ if (xcb_icccm_get_wm_normal_hints_reply(dpy, xcb_icccm_get_wm_normal_hints(dpy, e->window), &size_hints, NULL) == 1 &&
-+ (size_hints.flags & (XCB_ICCCM_SIZE_HINT_P_MIN_SIZE | XCB_ICCCM_SIZE_HINT_P_MAX_SIZE))) {
-+ c->min_width = size_hints.min_width;
-+ c->max_width = size_hints.max_width;
-+ c->min_height = size_hints.min_height;
-+ c->max_height = size_hints.max_height;
-+ int w = c->floating_rectangle.width;
-+ int h = c->floating_rectangle.height;
-+ restrain_floating_size(c, &w, &h);
-+ c->floating_rectangle.width = w;
-+ c->floating_rectangle.height = h;
-+ arrange(loc.monitor, loc.desktop);
-+ }
-+ }
- }
-
- void client_message(xcb_generic_event_t *evt)
-@@ -233,7 +276,8 @@ void client_message(xcb_generic_event_t *evt)
- handle_state(loc.monitor, loc.desktop, loc.node, e->data.data32[1], e->data.data32[0]);
- handle_state(loc.monitor, loc.desktop, loc.node, e->data.data32[2], e->data.data32[0]);
- } else if (e->type == ewmh->_NET_ACTIVE_WINDOW) {
-- if (ignore_ewmh_focus || loc.node == mon->desk->focus)
-+ if ((ignore_ewmh_focus && e->data.data32[0] == XCB_EWMH_CLIENT_SOURCE_TYPE_NORMAL) ||
-+ loc.node == mon->desk->focus)
- return;
- if (loc.desktop->focus->client->fullscreen && loc.desktop->focus != loc.node) {
- set_fullscreen(loc.desktop->focus, false);
-@@ -255,16 +299,16 @@ void focus_in(xcb_generic_event_t *evt)
-
- /* PRINTF("focus in %X %d %d\n", e->event, e->mode, e->detail); */
-
-- if (e->mode == XCB_NOTIFY_MODE_GRAB
-- || e->mode == XCB_NOTIFY_MODE_UNGRAB)
-+ if (e->mode == XCB_NOTIFY_MODE_GRAB ||
-+ e->mode == XCB_NOTIFY_MODE_UNGRAB)
- return;
- /* prevent focus stealing */
- if ((e->detail == XCB_NOTIFY_DETAIL_ANCESTOR ||
- e->detail == XCB_NOTIFY_DETAIL_INFERIOR ||
- e->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL ||
- e->detail == XCB_NOTIFY_DETAIL_NONLINEAR) &&
-- (mon->desk->focus == NULL
-- || mon->desk->focus->client->window != e->event))
-+ (mon->desk->focus == NULL ||
-+ mon->desk->focus->client->window != e->event))
- update_input_focus();
- }
-
-@@ -275,8 +319,9 @@ void enter_notify(xcb_generic_event_t *evt)
-
- PRINTF("enter notify %X %d %d\n", win, e->mode, e->detail);
-
-- if (e->mode != XCB_NOTIFY_MODE_NORMAL
-- || (mon->desk->focus != NULL && mon->desk->focus->client->window == win))
-+ if (e->mode != XCB_NOTIFY_MODE_NORMAL ||
-+ (mon->desk->focus != NULL &&
-+ mon->desk->focus->client->window == win))
- return;
-
- enable_motion_recorder();
-diff --git a/events.h b/events.h
-index 7812dad..1d718da 100644
---- a/events.h
-+++ b/events.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_EVENTS_H
-diff --git a/ewmh.c b/ewmh.c
-index 25d86d3..f7d1466 100644
---- a/ewmh.c
-+++ b/ewmh.c
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #include <string.h>
-diff --git a/ewmh.h b/ewmh.h
-index b41c4ee..9a757e6 100644
---- a/ewmh.h
-+++ b/ewmh.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_EWMH_H
-diff --git a/examples/panel/panel_bar b/examples/panel/panel_bar
-index 7cbd2fa..bee3ec7 100755
---- a/examples/panel/panel_bar
-+++ b/examples/panel/panel_bar
-@@ -6,11 +6,11 @@ while read -r line ; do
- case $line in
- S*)
- # clock output
-- sys_infos="\\br\\f6${line#?}"
-+ sys_infos="\\br\\f7${line#?}"
- ;;
- T*)
- # xtitle output
-- title="\\br\\f7${line#?}"
-+ title="\\br\\f4${line#?}"
- ;;
- W*)
- # bspwm internal state
-@@ -48,7 +48,7 @@ while read -r line ; do
- L*)
- # layout
- layout=$(printf "%s" "${name}" | sed 's/\(.\).*/\U\1/')
-- wm_infos="$wm_infos \\br\\f6$layout"
-+ wm_infos="$wm_infos \\br\\f2$layout"
- ;;
- esac
- shift
-diff --git a/examples/panel/panel_dzen2 b/examples/panel/panel_dzen2
-index ac5cf94..adf1df1 100755
---- a/examples/panel/panel_dzen2
-+++ b/examples/panel/panel_dzen2
-@@ -7,17 +7,13 @@ font_size=11
-
- . panel_colors
-
--adaptive_centering=0
- screen_width=$(sres -W)
- NORMIFS=$IFS
- FIELDIFS=':'
- PADDING=' '
-
--while getopts 'af:s:' opt ; do
-+while getopts 'f:s:' opt ; do
- case "$opt" in
-- a)
-- adaptive_centering=1
-- ;;
- f)
- font_family=$OPTARG
- ;;
-@@ -68,8 +64,8 @@ while read -r line ; do
- ;;
- o*)
- # occupied desktop
-- FG=$COLOR_OCUPPIED_FG
-- BG=$COLOR_OCUPPIED_BG
-+ FG=$COLOR_OCCUPIED_FG
-+ BG=$COLOR_OCCUPIED_BG
- ;;
- f*)
- # free desktop
-@@ -103,12 +99,14 @@ while read -r line ; do
- right_indent=$((screen_width - right_width))
- available_center=$((screen_width - (left_width + right_width)))
- if [ $available_center -lt $center_width ] ; then
-- center_indent=$((left_indent + left_width))
-+ center_indent=$left_width
- else
-- if [ $adaptive_centering -eq 1 ] ; then
-+ max_left_right_width=$left_width
-+ [ $left_width -lt $right_width ] && max_left_right_width=$right_width
-+ if [ $((2 * max_left_right_width + center_width)) -gt $screen_width ] ; then
- center_indent=$((left_width + (available_center - center_width) / 2))
- else
-- center_indent=$(( (screen_width - center_width) / 2 ))
-+ center_indent=$(((screen_width - center_width) / 2))
- fi
- fi
- printf "%s\n" "^pa($center_indent)$title^pa($left_indent)$wm_infos^pa($right_indent)$sys_infos"
-diff --git a/helpers.c b/helpers.c
-index ccc197a..2e2f23f 100644
---- a/helpers.c
-+++ b/helpers.c
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #include <stdlib.h>
-@@ -83,9 +87,3 @@ double distance(xcb_point_t a, xcb_point_t b)
- {
- return hypot(a.x - b.x, a.y - b.y);
- }
--
--void center_rectangle(xcb_rectangle_t *src, xcb_rectangle_t dst)
--{
-- src->x = dst.x + (dst.width - src->width) / 2;
-- src->y = dst.y + (dst.height - src->height) / 2;
--}
-diff --git a/helpers.h b/helpers.h
-index 81821ad..9a88676 100644
---- a/helpers.h
-+++ b/helpers.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_HELPERS_H
-@@ -44,7 +48,6 @@
- #define SMALEN 32
- #define INIT_CAP 8
-
--#define REMLEN(x) (BUFSIZ - strlen(x) - 1)
- #define streq(s1, s2) (strcmp((s1), (s2)) == 0)
-
- #ifdef DEBUG
-@@ -59,6 +62,5 @@ void warn(char *fmt, ...);
- void err(char *fmt, ...);
- bool get_color(char *col, xcb_window_t win, uint32_t *pxl);
- double distance(xcb_point_t a, xcb_point_t b);
--void center_rectangle(xcb_rectangle_t *src, xcb_rectangle_t dst);
-
- #endif
-diff --git a/history.c b/history.c
-index 4f6882c..7440a08 100644
---- a/history.c
-+++ b/history.c
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #include <stdlib.h>
-@@ -103,8 +107,8 @@ void history_remove(desktop_t *d, node_t *n)
- history_t *c = b->prev;
- if (a != NULL) {
- /* remove duplicate entries */
-- while (c != NULL && ((a->loc.node != NULL && a->loc.node == c->loc.node)
-- || (a->loc.node == NULL && a->loc.desktop == c->loc.desktop))) {
-+ while (c != NULL && ((a->loc.node != NULL && a->loc.node == c->loc.node) ||
-+ (a->loc.node == NULL && a->loc.desktop == c->loc.desktop))) {
- history_t *d = c->prev;
- if (history_head == c)
- history_head = history_tail;
-@@ -173,10 +177,10 @@ bool history_find_node(history_dir_t hdi, coordinates_t *ref, coordinates_t *dst
-
- history_t *h;
- for (h = history_needle; h != NULL; h = (hdi == HISTORY_OLDER ? h->prev : h->next)) {
-- if (!h->latest
-- || h->loc.node == NULL
-- || h->loc.node == ref->node
-- || !node_matches(&h->loc, ref, sel))
-+ if (!h->latest ||
-+ h->loc.node == NULL ||
-+ h->loc.node == ref->node ||
-+ !node_matches(&h->loc, ref, sel))
- continue;
- if (!record_history)
- history_needle = h;
-@@ -193,9 +197,9 @@ bool history_find_desktop(history_dir_t hdi, coordinates_t *ref, coordinates_t *
-
- history_t *h;
- for (h = history_needle; h != NULL; h = (hdi == HISTORY_OLDER ? h->prev : h->next)) {
-- if (!h->latest
-- || h->loc.desktop == ref->desktop
-- || !desktop_matches(&h->loc, ref, sel))
-+ if (!h->latest ||
-+ h->loc.desktop == ref->desktop ||
-+ !desktop_matches(&h->loc, ref, sel))
- continue;
- if (!record_history)
- history_needle = h;
-@@ -212,9 +216,9 @@ bool history_find_monitor(history_dir_t hdi, coordinates_t *ref, coordinates_t *
-
- 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))
-+ if (!h->latest ||
-+ h->loc.monitor == ref->monitor ||
-+ !desktop_matches(&h->loc, ref, sel))
- continue;
- if (!record_history)
- history_needle = h;
-diff --git a/history.h b/history.h
-index b57b94f..7b55516 100644
---- a/history.h
-+++ b/history.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_HISTORY_H
-diff --git a/messages.c b/messages.c
-index 2eb5cd8..af98cc0 100644
---- a/messages.c
-+++ b/messages.c
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #include <errno.h>
-@@ -38,15 +42,17 @@
- #include "settings.h"
- #include "tree.h"
- #include "window.h"
-+#include "common.h"
-+#include "subscribe.h"
- #include "messages.h"
-
--bool handle_message(char *msg, int msg_len, char *rsp)
-+int handle_message(char *msg, int msg_len, FILE *rsp)
- {
- int cap = INIT_CAP;
- int num = 0;
- char **args = malloc(cap * sizeof(char *));
- if (args == NULL)
-- return false;
-+ return MSG_FAILURE;
-
- for (int i = 0, j = 0; i < msg_len; i++) {
- if (msg[i] == 0) {
-@@ -58,7 +64,7 @@ bool handle_message(char *msg, int msg_len, char *rsp)
- char **new = realloc(args, cap * sizeof(char *));
- if (new == NULL) {
- free(args);
-- return false;
-+ return MSG_FAILURE;
- } else {
- args = new;
- }
-@@ -67,16 +73,16 @@ bool handle_message(char *msg, int msg_len, char *rsp)
-
- if (num < 1) {
- free(args);
-- return false;
-+ return MSG_SYNTAX;
- }
-
- char **args_orig = args;
-- bool ret = process_message(args, num, rsp);
-+ int ret = process_message(args, num, rsp);
- free(args_orig);
- return ret;
- }
-
--bool process_message(char **args, int num, char *rsp)
-+int process_message(char **args, int num, FILE *rsp)
- {
- if (streq("window", *args)) {
- return cmd_window(++args, --num);
-@@ -100,13 +106,13 @@ bool process_message(char **args, int num, char *rsp)
- return cmd_quit(++args, --num);
- }
-
-- return false;
-+ return MSG_UNKNOWN;
- }
-
--bool cmd_window(char **args, int num)
-+int cmd_window(char **args, int num)
- {
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
-
- coordinates_t ref = {mon, mon->desk, mon->desk->focus};
- coordinates_t trg = ref;
-@@ -115,11 +121,11 @@ bool cmd_window(char **args, int num)
- if (node_from_desc(*args, &ref, &trg))
- num--, args++;
- else
-- return false;
-+ return MSG_FAILURE;
- }
-
- if (trg.node == NULL)
-- return false;
-+ return MSG_FAILURE;
-
- bool dirty = false;
-
-@@ -129,7 +135,7 @@ bool cmd_window(char **args, int num)
- if (num > 1 && *(args + 1)[0] != OPT_CHR) {
- num--, args++;
- if (!node_from_desc(*args, &trg, &dst))
-- return false;
-+ return MSG_FAILURE;
- }
- focus_node(dst.monitor, dst.desktop, dst.node);
- } else if (streq("-d", *args) || streq("--to-desktop", *args)) {
-@@ -141,12 +147,12 @@ bool cmd_window(char **args, int num)
- trg.desktop = dst.desktop;
- }
- } else {
-- return false;
-+ return MSG_FAILURE;
- }
- } else if (streq("-m", *args) || streq("--to-monitor", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- coordinates_t dst;
- if (monitor_from_desc(*args, &trg, &dst)) {
- if (transfer_node(trg.monitor, trg.desktop, trg.node, dst.monitor, dst.monitor->desk, dst.monitor->desk->focus)) {
-@@ -154,12 +160,12 @@ bool cmd_window(char **args, int num)
- trg.desktop = dst.monitor->desk;
- }
- } else {
-- return false;
-+ return MSG_FAILURE;
- }
- } else if (streq("-w", *args) || streq("--to-window", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- coordinates_t dst;
- if (node_from_desc(*args, &trg, &dst)) {
- if (transfer_node(trg.monitor, trg.desktop, trg.node, dst.monitor, dst.desktop, dst.node)) {
-@@ -167,12 +173,12 @@ bool cmd_window(char **args, int num)
- trg.desktop = dst.desktop;
- }
- } else {
-- return false;
-+ return MSG_FAILURE;
- }
- } else if (streq("-s", *args) || streq("--swap", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- coordinates_t dst;
- if (node_from_desc(*args, &trg, &dst)) {
- if (swap_nodes(trg.monitor, trg.desktop, trg.node, dst.monitor, dst.desktop, dst.node)) {
-@@ -183,12 +189,12 @@ bool cmd_window(char **args, int num)
- dirty = true;
- }
- } else {
-- return false;
-+ return MSG_FAILURE;
- }
- } else if (streq("-t", *args) || streq("--toggle", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- char *key = strtok(*args, EQL_TOK);
- char *val = strtok(NULL, EQL_TOK);
- alter_state_t a;
-@@ -199,7 +205,7 @@ bool cmd_window(char **args, int num)
- if (parse_bool(val, &b))
- a = ALTER_SET;
- else
-- return false;
-+ return MSG_FAILURE;
- }
- if (streq("fullscreen", key)) {
- set_fullscreen(trg.node, (a == ALTER_SET ? b : !trg.node->client->fullscreen));
-@@ -217,13 +223,15 @@ bool cmd_window(char **args, int num)
- } else if (streq("private", key)) {
- set_private(trg.monitor, trg.desktop, trg.node, (a == ALTER_SET ? b : !trg.node->client->private));
- } else {
-- return false;
-+ return MSG_FAILURE;
- }
- } else if (streq("-p", *args) || streq("--presel", *args)) {
- num--, args++;
-- if (num < 1 || !is_tiled(trg.node->client)
-- || trg.desktop->layout != LAYOUT_TILED)
-- return false;
-+ if (num < 1)
-+ return MSG_SYNTAX;
-+ if (!is_tiled(trg.node->client) ||
-+ trg.desktop->layout != LAYOUT_TILED)
-+ return MSG_FAILURE;
- if (streq("cancel", *args)) {
- reset_mode(&trg);
- } else {
-@@ -233,11 +241,11 @@ bool cmd_window(char **args, int num)
- if (num > 1 && *(args + 1)[0] != OPT_CHR) {
- num--, args++;
- if (sscanf(*args, "%lf", &rat) != 1 || rat <= 0 || rat >= 1)
-- return false;
-+ return MSG_FAILURE;
- }
-- if (auto_cancel && trg.node->split_mode == MODE_MANUAL
-- && dir == trg.node->split_dir
-- && rat == trg.node->split_ratio) {
-+ if (auto_cancel && trg.node->split_mode == MODE_MANUAL &&
-+ dir == trg.node->split_dir &&
-+ rat == trg.node->split_ratio) {
- reset_mode(&trg);
- } else {
- trg.node->split_mode = MODE_MANUAL;
-@@ -246,19 +254,19 @@ bool cmd_window(char **args, int num)
- }
- window_draw_border(trg.node, trg.desktop->focus == trg.node, mon == trg.monitor);
- } else {
-- return false;
-+ return MSG_FAILURE;
- }
- }
- } else if (streq("-e", *args) || streq("--edge", *args)) {
- num--, args++;
- if (num < 2)
-- return false;
-+ return MSG_SYNTAX;
- direction_t dir;
- if (!parse_direction(*args, &dir))
-- return false;
-+ return MSG_FAILURE;
- node_t *n = find_fence(trg.node, dir);
- if (n == NULL)
-- return false;
-+ return MSG_FAILURE;
- num--, args++;
- if ((*args)[0] == '+' || (*args)[0] == '-') {
- int pix;
-@@ -268,58 +276,58 @@ bool cmd_window(char **args, int num)
- if (rat > 0 && rat < 1)
- n->split_ratio = rat;
- else
-- return false;
-+ return MSG_FAILURE;
- } else {
-- return false;
-+ return MSG_FAILURE;
- }
- } else {
- double rat;
- if (sscanf(*args, "%lf", &rat) == 1 && rat > 0 && rat < 1)
- n->split_ratio = rat;
- else
-- return false;
-+ return MSG_FAILURE;
- }
- dirty = true;
- } else if (streq("-r", *args) || streq("--ratio", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- double rat;
- if (sscanf(*args, "%lf", &rat) == 1 && rat > 0 && rat < 1) {
- trg.node->split_ratio = rat;
- window_draw_border(trg.node, trg.desktop->focus == trg.node, mon == trg.monitor);
- } else {
-- return false;
-+ return MSG_FAILURE;
- }
- } else if (streq("-R", *args) || streq("--rotate", *args)) {
- num--, args++;
- if (num < 2)
-- return false;
-+ return MSG_SYNTAX;
- direction_t dir;
- if (!parse_direction(*args, &dir))
-- return false;
-+ return MSG_FAILURE;
- node_t *n = find_fence(trg.node, dir);
- if (n == NULL)
-- return false;
-+ return MSG_FAILURE;
- num--, args++;
- int deg;
- if (parse_degree(*args, &deg)) {
- rotate_tree(n, deg);
- dirty = true;
- } else {
-- return false;
-+ return MSG_FAILURE;
- }
- } else if (streq("-c", *args) || streq("--close", *args)) {
- if (num > 1)
-- return false;
-+ return MSG_SYNTAX;
- window_close(trg.node);
- } else if (streq("-k", *args) || streq("--kill", *args)) {
- if (num > 1)
-- return false;
-+ return MSG_SYNTAX;
- window_kill(trg.monitor, trg.desktop, trg.node);
- dirty = true;
- } else {
-- return false;
-+ return MSG_SYNTAX;
- }
-
- num--, args++;
-@@ -328,13 +336,13 @@ bool cmd_window(char **args, int num)
- if (dirty)
- arrange(trg.monitor, trg.desktop);
-
-- return true;
-+ return MSG_SUCCESS;
- }
-
--bool cmd_desktop(char **args, int num)
-+int cmd_desktop(char **args, int num)
- {
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
-
- coordinates_t ref = {mon, mon->desk, NULL};
- coordinates_t trg = ref;
-@@ -343,7 +351,7 @@ bool cmd_desktop(char **args, int num)
- if (desktop_from_desc(*args, &ref, &trg))
- num--, args++;
- else
-- return false;
-+ return MSG_FAILURE;
- }
-
- bool dirty = false;
-@@ -354,7 +362,7 @@ bool cmd_desktop(char **args, int num)
- if (num > 1 && *(args + 1)[0] != OPT_CHR) {
- num--, args++;
- if (!desktop_from_desc(*args, &trg, &dst))
-- return false;
-+ return MSG_FAILURE;
- }
- if (auto_alternate && dst.desktop == mon->desk) {
- desktop_select_t sel = {DESKTOP_STATUS_ALL, false, false};
-@@ -363,29 +371,31 @@ bool cmd_desktop(char **args, int num)
- focus_node(dst.monitor, dst.desktop, dst.desktop->focus);
- } else if (streq("-m", *args) || streq("--to-monitor", *args)) {
- num--, args++;
-- if (num < 1 || trg.monitor->desk_head == trg.monitor->desk_tail)
-- return false;
-+ if (num < 1)
-+ return MSG_SYNTAX;
-+ if (trg.monitor->desk_head == trg.monitor->desk_tail)
-+ return MSG_FAILURE;
- coordinates_t dst;
- if (monitor_from_desc(*args, &trg, &dst)) {
- transfer_desktop(trg.monitor, dst.monitor, trg.desktop);
- trg.monitor = dst.monitor;
- update_current();
- } else {
-- return false;
-+ return MSG_FAILURE;
- }
- } else if (streq("-s", *args) || streq("--swap", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- coordinates_t dst;
- if (desktop_from_desc(*args, &trg, &dst))
- swap_desktops(trg.monitor, trg.desktop, dst.monitor, dst.desktop);
- else
-- return false;
-+ return MSG_FAILURE;
- } else if (streq("-l", *args) || streq("--layout", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- layout_t lyt;
- cycle_dir_t cyc;
- if (parse_cycle_direction(*args, &cyc))
-@@ -393,66 +403,69 @@ bool cmd_desktop(char **args, int num)
- else if (parse_layout(*args, &lyt))
- change_layout(trg.monitor, trg.desktop, lyt);
- else
-- return false;
-+ return MSG_FAILURE;
- } else if (streq("-n", *args) || streq("--rename", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- snprintf(trg.desktop->name, sizeof(trg.desktop->name), "%s", *args);
- ewmh_update_desktop_names();
- put_status();
- } else if (streq("-r", *args) || streq("--remove", *args)) {
-- if (trg.desktop->root == NULL
-- && trg.monitor->desk_head != trg.monitor->desk_tail) {
-+ if (trg.desktop->root == NULL &&
-+ trg.monitor->desk_head != trg.monitor->desk_tail) {
- remove_desktop(trg.monitor, trg.desktop);
- show_desktop(trg.monitor->desk);
- update_current();
-- return true;
-+ return MSG_SUCCESS;
- } else {
-- return false;
-+ return MSG_FAILURE;
- }
- } else if (streq("-c", *args) || streq("--cancel-presel", *args)) {
- reset_mode(&trg);
- } else if (streq("-F", *args) || streq("--flip", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- flip_t flp;
- if (parse_flip(*args, &flp)) {
- flip_tree(trg.desktop->root, flp);
- dirty = true;
- } else {
-- return false;
-+ return MSG_FAILURE;
- }
- } else if (streq("-R", *args) || streq("--rotate", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- int deg;
- if (parse_degree(*args, &deg)) {
- rotate_tree(trg.desktop->root, deg);
- dirty = true;
- } else {
-- return false;
-+ return MSG_FAILURE;
- }
-+ } else if (streq("-E", *args) || streq("--equalize", *args)) {
-+ equalize_tree(trg.desktop->root);
-+ dirty = true;
- } else if (streq("-B", *args) || streq("--balance", *args)) {
- balance_tree(trg.desktop->root);
- dirty = true;
- } else if (streq("-C", *args) || streq("--circulate", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- circulate_dir_t cir;
- if (parse_circulate_direction(*args, &cir)) {
- circulate_leaves(trg.monitor, trg.desktop, cir);
- dirty = true;
- } else {
-- return false;
-+ return MSG_FAILURE;
- }
- } else if (streq("-t", *args) || streq("--toggle", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- char *key = strtok(*args, EQL_TOK);
- char *val = strtok(NULL, EQL_TOK);
- alter_state_t a;
-@@ -463,14 +476,14 @@ bool cmd_desktop(char **args, int num)
- if (parse_bool(val, &b))
- a = ALTER_SET;
- else
-- return false;
-+ return MSG_FAILURE;
- }
- if (streq("floating", key))
- trg.desktop->floating = (a == ALTER_SET ? b : !trg.desktop->floating);
- else
-- return false;
-+ return MSG_FAILURE;
- } else {
-- return false;
-+ return MSG_SYNTAX;
- }
- num--, args++;
- }
-@@ -478,13 +491,13 @@ bool cmd_desktop(char **args, int num)
- if (dirty)
- arrange(trg.monitor, trg.desktop);
-
-- return true;
-+ return MSG_SUCCESS;
- }
-
--bool cmd_monitor(char **args, int num)
-+int cmd_monitor(char **args, int num)
- {
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
-
- coordinates_t ref = {mon, NULL, NULL};
- coordinates_t trg = ref;
-@@ -493,7 +506,7 @@ bool cmd_monitor(char **args, int num)
- if (monitor_from_desc(*args, &ref, &trg))
- num--, args++;
- else
-- return false;
-+ return MSG_FAILURE;
- }
-
- while (num > 0) {
-@@ -502,7 +515,7 @@ bool cmd_monitor(char **args, int num)
- if (num > 1 && *(args + 1)[0] != OPT_CHR) {
- num--, args++;
- if (!monitor_from_desc(*args, &trg, &dst))
-- return false;
-+ return MSG_FAILURE;
- }
- if (auto_alternate && dst.monitor == mon) {
- desktop_select_t sel = {DESKTOP_STATUS_ALL, false, false};
-@@ -512,7 +525,7 @@ bool cmd_monitor(char **args, int num)
- } else if (streq("-d", *args) || streq("--reset-desktops", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- desktop_t *d = trg.monitor->desk_head;
- while (num > 0 && d != NULL) {
- snprintf(d->name, sizeof(d->name), "%s", *args);
-@@ -535,7 +548,7 @@ bool cmd_monitor(char **args, int num)
- } else if (streq("-a", *args) || streq("--add-desktops", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- while (num > 0) {
- add_desktop(trg.monitor, make_desktop(*args));
- num--, args++;
-@@ -543,7 +556,7 @@ bool cmd_monitor(char **args, int num)
- } else if (streq("-r", *args) || streq("--remove-desktops", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- while (num > 0) {
- coordinates_t dst;
- if (locate_desktop(*args, &dst) && dst.monitor->desk_head != dst.monitor->desk_tail && dst.desktop->root == NULL) {
-@@ -555,7 +568,7 @@ bool cmd_monitor(char **args, int num)
- } else if (streq("-o", *args) || streq("--order-desktops", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- desktop_t *d = trg.monitor->desk_head;
- while (d != NULL && num > 0) {
- desktop_t *next = d->next;
-@@ -571,28 +584,28 @@ bool cmd_monitor(char **args, int num)
- } else if (streq("-n", *args) || streq("--rename", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- snprintf(trg.monitor->name, sizeof(trg.monitor->name), "%s", *args);
- put_status();
- } else if (streq("-s", *args) || streq("--swap", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- coordinates_t dst;
- if (monitor_from_desc(*args, &trg, &dst))
- swap_monitors(trg.monitor, dst.monitor);
- else
-- return false;
-+ return MSG_FAILURE;
- } else {
-- return false;
-+ return MSG_SYNTAX;
- }
- num--, args++;
- }
-
-- return true;
-+ return MSG_SUCCESS;
- }
-
--bool cmd_query(char **args, int num, char *rsp)
-+int cmd_query(char **args, int num, FILE *rsp)
- {
- coordinates_t ref = {mon, mon->desk, mon->desk->focus};
- coordinates_t trg = {NULL, NULL, NULL};
-@@ -617,7 +630,7 @@ bool cmd_query(char **args, int num, char *rsp)
- if (num > 1 && *(args + 1)[0] != OPT_CHR) {
- num--, args++;
- if (!monitor_from_desc(*args, &ref, &trg))
-- return false;
-+ return MSG_FAILURE;
- }
- t++;
- } else if (streq("-d", *args) || streq("--desktop", *args)) {
-@@ -626,7 +639,7 @@ bool cmd_query(char **args, int num, char *rsp)
- if (num > 1 && *(args + 1)[0] != OPT_CHR) {
- num--, args++;
- if (!desktop_from_desc(*args, &ref, &trg))
-- return false;
-+ return MSG_FAILURE;
- }
- t++;
- } else if (streq("-w", *args) || streq("--window", *args)) {
-@@ -634,17 +647,17 @@ bool cmd_query(char **args, int num, char *rsp)
- if (num > 1 && *(args + 1)[0] != OPT_CHR) {
- num--, args++;
- if (!node_from_desc(*args, &ref, &trg))
-- return false;
-+ return MSG_FAILURE;
- }
- t++;
- } else {
-- return false;
-+ return MSG_SYNTAX;
- }
- num--, args++;
- }
-
- if (d != 1 || t > 1)
-- return false;
-+ return MSG_SYNTAX;
-
- if (dom == DOMAIN_HISTORY)
- query_history(trg, rsp);
-@@ -655,18 +668,18 @@ bool cmd_query(char **args, int num, char *rsp)
- else
- query_monitors(trg, dom, rsp);
-
-- return true;
-+ return MSG_SUCCESS;
- }
-
--bool cmd_rule(char **args, int num, char *rsp)
-+int cmd_rule(char **args, int num, FILE *rsp)
- {
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- while (num > 0) {
- if (streq("-a", *args) || streq("--add", *args)) {
- num--, args++;
- if (num < 2)
-- return false;
-+ return MSG_SYNTAX;
- rule_t *rule = make_rule();
- snprintf(rule->cause, sizeof(rule->cause), "%s", *args);
- num--, args++;
-@@ -687,7 +700,7 @@ bool cmd_rule(char **args, int num, char *rsp)
- } else if (streq("-r", *args) || streq("--remove", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- int idx;
- while (num > 0) {
- if (parse_index(*args, &idx))
-@@ -704,129 +717,135 @@ bool cmd_rule(char **args, int num, char *rsp)
- num--, args++;
- list_rules(num > 0 ? *args : NULL, rsp);
- } else {
-- return false;
-+ return MSG_SYNTAX;
- }
- num--, args++;
- }
-
-- return true;
-+ return MSG_SUCCESS;
- }
-
--bool cmd_pointer(char **args, int num)
-+int cmd_pointer(char **args, int num)
- {
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- while (num > 0) {
- if (streq("-t", *args) || streq("--track", *args)) {
- num--, args++;
- if (num < 2)
-- return false;
-+ return MSG_SYNTAX;
- int x, y;
- if (sscanf(*args, "%i", &x) == 1 && sscanf(*(args + 1), "%i", &y) == 1)
- track_pointer(x, y);
- else
-- return false;
-+ return MSG_FAILURE;
- } else if (streq("-g", *args) || streq("--grab", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- pointer_action_t pac;
- if (parse_pointer_action(*args, &pac))
- grab_pointer(pac);
- else
-- return false;
-+ return MSG_FAILURE;
- } else if (streq("-u", *args) || streq("--ungrab", *args)) {
- ungrab_pointer();
- } else {
-- return false;
-+ return MSG_SYNTAX;
- }
- num--, args++;
- }
-
-- return true;
-+ return MSG_SUCCESS;
- }
-
--bool cmd_restore(char **args, int num)
-+int cmd_restore(char **args, int num)
- {
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- while (num > 0) {
- if (streq("-T", *args) || streq("--tree", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- restore_tree(*args);
- } else if (streq("-H", *args) || streq("--history", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- restore_history(*args);
- } else if (streq("-S", *args) || streq("--stack", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- restore_stack(*args);
- } else {
-- return false;
-+ return MSG_SYNTAX;
- }
- num--, args++;
- }
-
-- return true;
-+ return MSG_SUCCESS;
- }
-
--bool cmd_control(char **args, int num, char *rsp)
-+int cmd_control(char **args, int num, FILE *rsp)
- {
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- while (num > 0) {
- if (streq("--adopt-orphans", *args)) {
- adopt_orphans();
-- } else if (streq("--put-status", *args)) {
-- put_status();
- } else if (streq("--toggle-visibility", *args)) {
- toggle_visibility();
- } else if (streq("--subscribe", *args)) {
-- snprintf(rsp, BUFSIZ, "%c", MESSAGE_SUBSCRIBE);
-+ return MSG_SUBSCRIBE;
-+ } else if (streq("--get-status", *args)) {
-+ print_status(rsp);
- } else if (streq("--record-history", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- bool b;
- if (parse_bool(*args, &b))
- record_history = b;
- else
-- return false;
-+ return MSG_SYNTAX;
- } else {
-- return false;
-+ return MSG_SYNTAX;
- }
- num--, args++;
- }
-
-- return true;
-+ return MSG_SUCCESS;
- }
-
--bool cmd_config(char **args, int num, char *rsp)
-+int cmd_config(char **args, int num, FILE *rsp)
- {
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
- coordinates_t ref = {mon, mon->desk, mon->desk->focus};
- coordinates_t trg = {NULL, NULL, NULL};
- if ((*args)[0] == OPT_CHR) {
-- if (streq("-d", *args) || streq("--desktop", *args)) {
-+ if (streq("-m", *args) || streq("--monitor", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-+ return MSG_SYNTAX;
-+ if (!monitor_from_desc(*args, &ref, &trg))
-+ return MSG_FAILURE;
-+ } else if (streq("-d", *args) || streq("--desktop", *args)) {
-+ num--, args++;
-+ if (num < 1)
-+ return MSG_SYNTAX;
- if (!desktop_from_desc(*args, &ref, &trg))
-- return false;
-- } else if (streq("-m", *args) || streq("--monitor", *args)) {
-+ return MSG_FAILURE;
-+ } else if (streq("-w", *args) || streq("--window", *args)) {
- num--, args++;
- if (num < 1)
-- return false;
-- if (!monitor_from_desc(*args, &ref, &trg))
-- return false;
-+ return MSG_SYNTAX;
-+ if (!node_from_desc(*args, &ref, &trg))
-+ return MSG_FAILURE;
- } else {
-- return false;
-+ return MSG_SYNTAX;
- }
- num--, args++;
- }
-@@ -835,21 +854,23 @@ bool cmd_config(char **args, int num, char *rsp)
- else if (num == 1)
- return get_setting(trg, *args, rsp);
- else
-- return false;
-+ return MSG_SYNTAX;
- }
-
--bool cmd_quit(char **args, int num)
-+int cmd_quit(char **args, int num)
- {
- if (num > 0 && sscanf(*args, "%i", &exit_status) != 1)
-- return false;
-+ return MSG_FAILURE;
- running = false;
-- return true;
-+ return MSG_SUCCESS;
- }
-
--bool set_setting(coordinates_t loc, char *name, char *value)
-+int set_setting(coordinates_t loc, char *name, char *value)
- {
--#define DESKSET(k, v) \
-- if (loc.desktop != NULL) \
-+#define DESKWINSET(k, v) \
-+ if (loc.node != NULL) \
-+ loc.node->client->k = v; \
-+ else if (loc.desktop != NULL) \
- loc.desktop->k = v; \
- else if (loc.monitor != NULL) \
- for (desktop_t *d = loc.monitor->desk_head; d != NULL; d = d->next) \
-@@ -861,12 +882,23 @@ bool set_setting(coordinates_t loc, char *name, char *value)
- if (streq("border_width", name)) {
- unsigned int bw;
- if (sscanf(value, "%u", &bw) != 1)
-- return false;
-- DESKSET(border_width, bw)
-+ return MSG_FAILURE;
-+ DESKWINSET(border_width, bw)
-+#undef DESKWINSET
-+#define DESKSET(k, v) \
-+ if (loc.desktop != NULL) \
-+ loc.desktop->k = v; \
-+ else if (loc.monitor != NULL) \
-+ for (desktop_t *d = loc.monitor->desk_head; d != NULL; d = d->next) \
-+ d->k = v; \
-+ else \
-+ for (monitor_t *m = mon_head; m != NULL; m = m->next) \
-+ for (desktop_t *d = m->desk_head; d != NULL; d = d->next) \
-+ d->k = v;
- } else if (streq("window_gap", name)) {
- int wg;
- if (sscanf(value, "%i", &wg) != 1)
-- return false;
-+ return MSG_FAILURE;
- DESKSET(window_gap, wg)
- #undef DESKSET
- #define MONDESKSET(k, v) \
-@@ -880,22 +912,22 @@ bool set_setting(coordinates_t loc, char *name, char *value)
- } else if (streq("top_padding", name)) {
- int tp;
- if (sscanf(value, "%i", &tp) != 1)
-- return false;
-+ return MSG_FAILURE;
- MONDESKSET(top_padding, tp)
- } else if (streq("right_padding", name)) {
- int rp;
- if (sscanf(value, "%i", &rp) != 1)
-- return false;
-+ return MSG_FAILURE;
- MONDESKSET(right_padding, rp)
- } else if (streq("bottom_padding", name)) {
- int bp;
- if (sscanf(value, "%i", &bp) != 1)
-- return false;
-+ return MSG_FAILURE;
- MONDESKSET(bottom_padding, bp)
- } else if (streq("left_padding", name)) {
- int lp;
- if (sscanf(value, "%i", &lp) != 1)
-- return false;
-+ return MSG_FAILURE;
- MONDESKSET(left_padding, lp)
- #undef MONDESKSET
- #define SETSTR(s) \
-@@ -909,8 +941,8 @@ bool set_setting(coordinates_t loc, char *name, char *value)
- if (sscanf(value, "%lf", &r) == 1 && r > 0 && r < 1)
- split_ratio = r;
- else
-- return false;
-- return true;
-+ return MSG_FAILURE;
-+ return MSG_SUCCESS;
- #define SETCOLOR(s) \
- } else if (streq(#s, name)) { \
- snprintf(s, sizeof(s), "%s", value);
-@@ -948,14 +980,14 @@ bool set_setting(coordinates_t loc, char *name, char *value)
- window_hide(m->root);
- disable_motion_recorder();
- }
-- return true;
-+ return MSG_SUCCESS;
- } else {
-- return false;
-+ return MSG_FAILURE;
- }
- #define SETBOOL(s) \
- } else if (streq(#s, name)) { \
- if (!parse_bool(value, &s)) \
-- return false;
-+ return MSG_FAILURE;
- SETBOOL(borderless_monocle)
- SETBOOL(gapless_monocle)
- SETBOOL(pointer_follows_monitor)
-@@ -967,42 +999,44 @@ bool set_setting(coordinates_t loc, char *name, char *value)
- SETBOOL(remove_disabled_monitor)
- #undef SETBOOL
- } else {
-- return false;
-+ return MSG_FAILURE;
- }
-
- for (monitor_t *m = mon_head; m != NULL; m = m->next)
- for (desktop_t *d = m->desk_head; d != NULL; d = d->next)
- arrange(m, d);
-
-- return true;
-+ return MSG_SUCCESS;
- }
-
--bool get_setting(coordinates_t loc, char *name, char* rsp)
-+int get_setting(coordinates_t loc, char *name, FILE* rsp)
- {
- if (streq("split_ratio", name))
-- snprintf(rsp, BUFSIZ, "%lf", split_ratio);
-+ fprintf(rsp, "%lf", split_ratio);
- else if (streq("window_gap", name))
- if (loc.desktop == NULL)
-- return false;
-+ return MSG_FAILURE;
- else
-- snprintf(rsp, BUFSIZ, "%i", loc.desktop->window_gap);
-+ fprintf(rsp, "%i", loc.desktop->window_gap);
- else if (streq("border_width", name))
-- if (loc.desktop == NULL)
-- return false;
-+ if (loc.node != NULL)
-+ fprintf(rsp, "%u", loc.node->client->border_width);
-+ else if (loc.desktop != NULL)
-+ fprintf(rsp, "%u", loc.desktop->border_width);
- else
-- snprintf(rsp, BUFSIZ, "%u", loc.desktop->border_width);
-+ return MSG_FAILURE;
- else if (streq("external_rules_command", name))
-- snprintf(rsp, BUFSIZ, "%s", external_rules_command);
-+ fprintf(rsp, "%s", external_rules_command);
- else if (streq("status_prefix", name))
-- snprintf(rsp, BUFSIZ, "%s", status_prefix);
-+ fprintf(rsp, "%s", status_prefix);
- #define MONDESKGET(k) \
- else if (streq(#k, name)) \
- if (loc.desktop != NULL) \
-- snprintf(rsp, BUFSIZ, "%i", loc.desktop->k); \
-+ fprintf(rsp, "%i", loc.desktop->k); \
- else if (loc.monitor != NULL) \
-- snprintf(rsp, BUFSIZ, "%i", loc.monitor->k); \
-+ fprintf(rsp, "%i", loc.monitor->k); \
- else \
-- return false;
-+ return MSG_FAILURE;
- MONDESKGET(top_padding)
- MONDESKGET(right_padding)
- MONDESKGET(bottom_padding)
-@@ -1010,7 +1044,7 @@ bool get_setting(coordinates_t loc, char *name, char* rsp)
- #undef DESKGET
- #define GETCOLOR(s) \
- else if (streq(#s, name)) \
-- snprintf(rsp, BUFSIZ, "%s", s);
-+ fprintf(rsp, "%s", s);
- GETCOLOR(focused_border_color)
- GETCOLOR(active_border_color)
- GETCOLOR(normal_border_color)
-@@ -1025,7 +1059,7 @@ bool get_setting(coordinates_t loc, char *name, char* rsp)
- #undef GETCOLOR
- #define GETBOOL(s) \
- else if (streq(#s, name)) \
-- snprintf(rsp, BUFSIZ, "%s", BOOLSTR(s));
-+ fprintf(rsp, "%s", BOOLSTR(s));
- GETBOOL(borderless_monocle)
- GETBOOL(gapless_monocle)
- GETBOOL(focus_follows_pointer)
-@@ -1038,8 +1072,8 @@ bool get_setting(coordinates_t loc, char *name, char* rsp)
- GETBOOL(remove_disabled_monitor)
- #undef GETBOOL
- else
-- return false;
-- return true;
-+ return MSG_FAILURE;
-+ return MSG_SUCCESS;
- }
-
- bool parse_bool(char *value, bool *b)
-diff --git a/messages.h b/messages.h
-index 46a27f4..aa0e447 100644
---- a/messages.h
-+++ b/messages.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_MESSAGES_H
-@@ -31,22 +35,20 @@
- #define CAT_CHR '.'
- #define EQL_TOK "="
-
--#define MESSAGE_SUBSCRIBE '\x01'
--
--bool handle_message(char *msg, int msg_len, char *rsp);
--bool process_message(char **args, int num, char *rsp);
--bool cmd_window(char **args, int num);
--bool cmd_desktop(char **args, int num);
--bool cmd_monitor(char **args, int num);
--bool cmd_query(char **args, int num, char *rsp);
--bool cmd_rule(char **args, int num, char *rsp);
--bool cmd_pointer(char **args, int num);
--bool cmd_restore(char **args, int num);
--bool cmd_control(char **args, int num, char *rsp);
--bool cmd_config(char **args, int num, char *rsp);
--bool cmd_quit(char **args, int num);
--bool set_setting(coordinates_t loc, char *name, char *value);
--bool get_setting(coordinates_t loc, char *name, char* rsp);
-+int handle_message(char *msg, int msg_len, FILE *rsp);
-+int process_message(char **args, int num, FILE *rsp);
-+int cmd_window(char **args, int num);
-+int cmd_desktop(char **args, int num);
-+int cmd_monitor(char **args, int num);
-+int cmd_query(char **args, int num, FILE *rsp);
-+int cmd_rule(char **args, int num, FILE *rsp);
-+int cmd_pointer(char **args, int num);
-+int cmd_restore(char **args, int num);
-+int cmd_control(char **args, int num, FILE *rsp);
-+int cmd_config(char **args, int num, FILE *rsp);
-+int cmd_quit(char **args, int num);
-+int set_setting(coordinates_t loc, char *name, char *value);
-+int get_setting(coordinates_t loc, char *name, FILE* rsp);
- bool parse_bool(char *value, bool *b);
- bool parse_layout(char *s, layout_t *l);
- bool parse_direction(char *s, direction_t *d);
-diff --git a/monitor.c b/monitor.c
-index ea8e8c1..10c4dac 100644
---- a/monitor.c
-+++ b/monitor.c
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #include <limits.h>
-@@ -393,8 +397,9 @@ bool import_monitors(void)
- monitor_t *next = m->next;
- if (m->wired) {
- for (monitor_t *mb = mon_head; mb != NULL; mb = mb->next)
-- if (mb != m && mb->wired && (m->desk == NULL || mb->desk == NULL)
-- && contains(mb->rectangle, m->rectangle)) {
-+ if (mb != m && mb->wired &&
-+ (m->desk == NULL || mb->desk == NULL) &&
-+ contains(mb->rectangle, m->rectangle)) {
- if (mm == m)
- mm = mb;
- merge_monitors(m, mb);
-@@ -421,6 +426,9 @@ bool import_monitors(void)
- if (m->desk == NULL && (running || pri_mon == NULL || m != pri_mon))
- add_desktop(m, make_desktop(NULL));
-
-+ if (!running && pri_mon != NULL && mon_head != pri_mon)
-+ swap_monitors(mon_head, pri_mon);
-+
- free(sres);
- update_motion_recorder();
- return (num_monitors > 0);
-diff --git a/monitor.h b/monitor.h
-index 3c5bc9f..1d290c0 100644
---- a/monitor.h
-+++ b/monitor.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_MONITOR_H
-diff --git a/pointer.c b/pointer.c
-index c06922e..4527c30 100644
---- a/pointer.c
-+++ b/pointer.c
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #include "bspwm.h"
-@@ -173,8 +177,7 @@ void track_pointer(int root_x, int root_y)
- if (frozen_pointer->action == ACTION_NONE)
- return;
-
-- int16_t delta_x, delta_y, x = 0, y = 0, w = 1, h = 1;
-- uint16_t width, height;
-+ int delta_x, delta_y, x = 0, y = 0, w = 1, h = 1;
-
- pointer_action_t pac = frozen_pointer->action;
- monitor_t *m = frozen_pointer->monitor;
-@@ -311,15 +314,27 @@ void track_pointer(int root_x, int root_y)
- break;
- }
- }
-- width = MAX(1, w);
-- height = MAX(1, h);
-+
-+ int oldw = w, oldh = h;
-+ restrain_floating_size(c, &w, &h);
-+
- if (c->pseudo_tiled) {
-- c->floating_rectangle.width = width;
-- c->floating_rectangle.height = height;
-+ c->floating_rectangle.width = w;
-+ c->floating_rectangle.height = h;
- arrange(m, d);
- } else {
-- c->floating_rectangle = (xcb_rectangle_t) {x, y, width, height};
-- window_move_resize(win, x, y, width, height);
-+ if (oldw == w) {
-+ c->floating_rectangle.x = x;
-+ c->floating_rectangle.width = w;
-+ }
-+ if (oldh == h) {
-+ c->floating_rectangle.y = y;
-+ c->floating_rectangle.height = h;
-+ }
-+ window_move_resize(win, c->floating_rectangle.x,
-+ c->floating_rectangle.y,
-+ c->floating_rectangle.width,
-+ c->floating_rectangle.height);
- }
- }
- break;
-diff --git a/pointer.h b/pointer.h
-index 534c66e..e156dfa 100644
---- a/pointer.h
-+++ b/pointer.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_POINTER_H
-diff --git a/query.c b/query.c
-index 13c3910..2f61882 100644
---- a/query.c
-+++ b/query.c
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #include <stdio.h>
-@@ -33,82 +37,78 @@
- #include "tree.h"
- #include "query.h"
-
--void query_monitors(coordinates_t loc, domain_t dom, char *rsp)
-+void query_monitors(coordinates_t loc, domain_t dom, FILE *rsp)
- {
-- char line[MAXLEN];
- for (monitor_t *m = mon_head; m != NULL; m = m->next) {
- if (loc.monitor != NULL && m != loc.monitor)
- continue;
- if (dom != DOMAIN_DESKTOP) {
- if (dom == DOMAIN_MONITOR) {
-- snprintf(line, sizeof(line), "%s\n", m->name);
-- strncat(rsp, line, REMLEN(rsp));
-+ fprintf(rsp, "%s\n", m->name);
- continue;
- } else {
-- snprintf(line, sizeof(line), "%s %ux%u%+i%+i %i,%i,%i,%i", m->name, m->rectangle.width, m->rectangle.height, m->rectangle.x, m->rectangle.y, m->top_padding, m->right_padding, m->bottom_padding, m->left_padding);
-- strncat(rsp, line, REMLEN(rsp));
-- if (m == mon)
-- strncat(rsp, " *", REMLEN(rsp));
-- strncat(rsp, "\n", REMLEN(rsp));
-+ fprintf(rsp, "%s %ux%u%+i%+i %i,%i,%i,%i%s\n", m->name,
-+ m->rectangle.width,m->rectangle.height, m->rectangle.x, m->rectangle.y,
-+ m->top_padding, m->right_padding, m->bottom_padding, m->left_padding,
-+ (m == mon ? " *" : ""));
- }
- }
- query_desktops(m, dom, loc, (dom == DOMAIN_DESKTOP ? 0 : 1), rsp);
- }
- }
-
--void query_desktops(monitor_t *m, domain_t dom, coordinates_t loc, unsigned int depth, char *rsp)
-+void query_desktops(monitor_t *m, domain_t dom, coordinates_t loc, unsigned int depth, FILE *rsp)
- {
-- char line[MAXLEN];
- for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
- if (loc.desktop != NULL && d != loc.desktop)
- continue;
- for (unsigned int i = 0; i < depth; i++)
-- strncat(rsp, " ", REMLEN(rsp));
-+ fprintf(rsp, "\t");
- if (dom == DOMAIN_DESKTOP) {
-- snprintf(line, sizeof(line), "%s\n", d->name);
-- strncat(rsp, line, REMLEN(rsp));
-+ fprintf(rsp, "%s\n", d->name);
- continue;
- } else {
-- snprintf(line, sizeof(line), "%s %u %i %i,%i,%i,%i %c %c", 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' : '-'));
-- strncat(rsp, line, REMLEN(rsp));
-- if (d == m->desk)
-- strncat(rsp, " *", REMLEN(rsp));
-- strncat(rsp, "\n", REMLEN(rsp));
-+ fprintf(rsp, "%s %u %i %i,%i,%i,%i %c %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 == m->desk ? " *" : ""));
- }
- query_tree(d, d->root, rsp, depth + 1);
- }
- }
-
--void query_tree(desktop_t *d, node_t *n, char *rsp, unsigned int depth)
-+void query_tree(desktop_t *d, node_t *n, FILE *rsp, unsigned int depth)
- {
- if (n == NULL)
- return;
-
-- char line[MAXLEN];
--
- for (unsigned int i = 0; i < depth; i++)
-- strncat(rsp, " ", REMLEN(rsp));
-+ fprintf(rsp, "\t");
-
- if (is_leaf(n)) {
- client_t *c = n->client;
-- snprintf(line, sizeof(line), "%c %s 0x%X %u %ux%u%+i%+i %c %c%c%c%c%c%c%c%c", (n->birth_rotation == 90 ? 'a' : (n->birth_rotation == 270 ? 'c' : 'm')), c->class_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' : '-'));
-+ fprintf(rsp, "%c %s %s 0x%X %u %ux%u%+i%+i %c %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' : '-'),
-+ (n == d->focus ? " *" : ""));
- } else {
-- snprintf(line, sizeof(line), "%c %c %lf", (n->split_type == TYPE_HORIZONTAL ? 'H' : 'V'), (n->birth_rotation == 90 ? 'a' : (n->birth_rotation == 270 ? 'c' : 'm')), n->split_ratio);
-+ fprintf(rsp, "%c %c %lf\n", (n->split_type == TYPE_HORIZONTAL ? 'H' : 'V'),
-+ (n->birth_rotation == 90 ? 'a' : (n->birth_rotation == 270 ? 'c' : 'm')), n->split_ratio);
- }
-
-- strncat(rsp, line, REMLEN(rsp));
--
-- if (n == d->focus)
-- strncat(rsp, " *", REMLEN(rsp));
-- strncat(rsp, "\n", REMLEN(rsp));
--
- query_tree(d, n->first_child, rsp, depth + 1);
- query_tree(d, n->second_child, rsp, depth + 1);
- }
-
--void query_history(coordinates_t loc, char *rsp)
-+void query_history(coordinates_t loc, FILE *rsp)
- {
-- char line[MAXLEN];
- for (history_t *h = history_head; h != NULL; h = h->next) {
- if ((loc.monitor != NULL && h->loc.monitor != loc.monitor)
- || (loc.desktop != NULL && h->loc.desktop != loc.desktop))
-@@ -116,26 +116,18 @@ void query_history(coordinates_t loc, char *rsp)
- xcb_window_t win = XCB_NONE;
- if (h->loc.node != NULL)
- win = h->loc.node->client->window;
-- snprintf(line, sizeof(line), "%s %s 0x%X", h->loc.monitor->name, h->loc.desktop->name, win);
-- strncat(rsp, line, REMLEN(rsp));
-- strncat(rsp, "\n", REMLEN(rsp));
-+ fprintf(rsp, "%s %s 0x%X\n", h->loc.monitor->name, h->loc.desktop->name, win);
- }
- }
-
--void query_stack(char *rsp)
-+void query_stack(FILE *rsp)
- {
-- char line[MAXLEN];
-- for (stacking_list_t *s = stack_head; s != NULL; s = s->next) {
-- snprintf(line, sizeof(line), "0x%X", s->node->client->window);
-- strncat(rsp, line, REMLEN(rsp));
-- strncat(rsp, "\n", REMLEN(rsp));
-- }
-+ for (stacking_list_t *s = stack_head; s != NULL; s = s->next)
-+ fprintf(rsp, "0x%X\n", s->node->client->window);
- }
-
--void query_windows(coordinates_t loc, char *rsp)
-+void query_windows(coordinates_t loc, FILE *rsp)
- {
-- char line[MAXLEN];
--
- for (monitor_t *m = mon_head; m != NULL; m = m->next) {
- if (loc.monitor != NULL && m != loc.monitor)
- continue;
-@@ -145,8 +137,7 @@ void query_windows(coordinates_t loc, char *rsp)
- for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) {
- if (loc.node != NULL && n != loc.node)
- continue;
-- snprintf(line, sizeof(line), "0x%X\n", n->client->window);
-- strncat(rsp, line, REMLEN(rsp));
-+ fprintf(rsp, "0x%X\n", n->client->window);
- }
- }
- }
-@@ -154,7 +145,7 @@ void query_windows(coordinates_t loc, char *rsp)
-
- bool node_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
- {
-- client_select_t sel = {CLIENT_TYPE_ALL, CLIENT_CLASS_ALL, false, false, false};
-+ client_select_t sel = {CLIENT_TYPE_ALL, CLIENT_CLASS_ALL, CLIENT_MODE_ALL, false, false};
- char *tok;
- while ((tok = strrchr(desc, CAT_CHR)) != NULL) {
- tok[0] = '\0';
-@@ -167,10 +158,12 @@ bool node_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
- sel.class = CLIENT_CLASS_EQUAL;
- } else if (streq("unlike", tok)) {
- sel.class = CLIENT_CLASS_DIFFER;
-+ } else if (streq("manual", tok)) {
-+ sel.mode = CLIENT_MODE_MANUAL;
-+ } else if (streq("automatic", tok)) {
-+ sel.mode = CLIENT_MODE_AUTOMATIC;
- } else if (streq("urgent", tok)) {
- sel.urgent = true;
-- } else if (streq("manual", tok)) {
-- sel.manual = true;
- } else if (streq("local", tok)) {
- sel.local = true;
- }
-@@ -185,6 +178,14 @@ bool node_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
- history_dir_t hdi;
- if (parse_direction(desc, &dir)) {
- dst->node = nearest_neighbor(ref->monitor, ref->desktop, ref->node, dir, sel);
-+ if (dst->node == NULL && num_monitors > 1) {
-+ monitor_t *m = nearest_monitor(ref->monitor, dir, (desktop_select_t) {DESKTOP_STATUS_ALL, false, false});
-+ if (m != NULL) {
-+ dst->monitor = m;
-+ dst->desktop = m->desk;
-+ dst->node = m->desk->focus;
-+ }
-+ }
- } else if (parse_cycle_direction(desc, &cyc)) {
- dst->node = closest_node(ref->monitor, ref->desktop, ref->node, cyc, sel);
- } else if (parse_history_direction(desc, &hdi)) {
-@@ -246,13 +247,17 @@ bool desktop_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
- dst->monitor = mon;
- dst->desktop = mon->desk;
- }
-- } else if ((colon = index(desc, ':')) != NULL) {
-+ } else if ((colon = strchr(desc, ':')) != NULL) {
- *colon = '\0';
-- if (streq("focused", desc))
-- if (monitor_from_desc(colon + 1, ref, dst))
-+ if (monitor_from_desc(desc, ref, dst)) {
-+ if (streq("focused", colon + 1)) {
- dst->desktop = dst->monitor->desk;
-+ } else if (parse_index(colon + 1, &idx)) {
-+ desktop_from_index(idx, dst, dst->monitor);
-+ }
-+ }
- } else if (parse_index(desc, &idx)) {
-- desktop_from_index(idx, dst);
-+ desktop_from_index(idx, dst, NULL);
- } else {
- locate_desktop(desc, dst);
- }
-@@ -343,9 +348,11 @@ bool locate_monitor(char *name, coordinates_t *loc)
- return false;
- }
-
--bool desktop_from_index(int i, coordinates_t *loc)
-+bool desktop_from_index(int i, coordinates_t *loc, monitor_t *mm)
- {
-- for (monitor_t *m = mon_head; m != NULL; m = m->next)
-+ for (monitor_t *m = mon_head; m != NULL; m = m->next) {
-+ if (mm != NULL && m != mm)
-+ continue;
- for (desktop_t *d = m->desk_head; d != NULL; d = d->next, i--)
- if (i == 1) {
- loc->monitor = m;
-@@ -353,6 +360,7 @@ bool desktop_from_index(int i, coordinates_t *loc)
- loc->node = NULL;
- return true;
- }
-+ }
- return false;
- }
-
-@@ -370,6 +378,9 @@ bool monitor_from_index(int i, coordinates_t *loc)
-
- bool node_matches(coordinates_t *loc, coordinates_t *ref, client_select_t sel)
- {
-+ if (ref->node == NULL || loc->node == NULL)
-+ return false;
-+
- if (sel.type != CLIENT_TYPE_ALL &&
- is_tiled(loc->node->client)
- ? sel.type == CLIENT_TYPE_FLOATING
-@@ -382,7 +393,10 @@ bool node_matches(coordinates_t *loc, coordinates_t *ref, client_select_t sel)
- : sel.class == CLIENT_CLASS_EQUAL)
- return false;
-
-- if (sel.manual && loc->node->split_mode != MODE_MANUAL)
-+ if (sel.mode != CLIENT_MODE_ALL &&
-+ loc->node->split_mode == MODE_MANUAL
-+ ? sel.mode == CLIENT_MODE_AUTOMATIC
-+ : sel.mode == CLIENT_MODE_MANUAL)
- return false;
-
- if (sel.local && loc->desktop != ref->desktop)
-diff --git a/query.h b/query.h
-index bb2db30..8cd2ee7 100644
---- a/query.h
-+++ b/query.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_QUERY_H
-@@ -34,19 +38,19 @@ typedef enum {
- DOMAIN_STACK
- } domain_t;
-
--void query_monitors(coordinates_t loc, domain_t dom, char *rsp);
--void query_desktops(monitor_t *m, domain_t dom, coordinates_t loc, unsigned int depth, char *rsp);
--void query_tree(desktop_t *d, node_t *n, char *rsp, unsigned int depth);
--void query_history(coordinates_t loc, char *rsp);
--void query_stack(char *rsp);
--void query_windows(coordinates_t loc, char *rsp);
-+void query_monitors(coordinates_t loc, domain_t dom, FILE *rsp);
-+void query_desktops(monitor_t *m, domain_t dom, coordinates_t loc, unsigned int depth, FILE *rsp);
-+void query_tree(desktop_t *d, node_t *n, FILE *rsp, unsigned int depth);
-+void query_history(coordinates_t loc, FILE *rsp);
-+void query_stack(FILE *rsp);
-+void query_windows(coordinates_t loc, FILE *rsp);
- 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);
- bool locate_window(xcb_window_t win, coordinates_t *loc);
- bool locate_desktop(char *name, coordinates_t *loc);
- bool locate_monitor(char *name, coordinates_t *loc);
--bool desktop_from_index(int i, coordinates_t *loc);
-+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);
-diff --git a/restore.c b/restore.c
-index f136156..24ae84d 100644
---- a/restore.c
-+++ b/restore.c
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #include <ctype.h>
-@@ -68,7 +72,8 @@ void restore_tree(char *file_path)
- unsigned int w, h;
- char end = 0;
- name[0] = '\0';
-- sscanf(line + level, "%s %ux%u%i%i %i,%i,%i,%i %c", name, &w, &h, &x, &y, &top, &right, &bottom, &left, &end);
-+ sscanf(line + level, "%s %ux%u%i%i %i,%i,%i,%i %c", name, &w, &h, &x, &y,
-+ &top, &right, &bottom, &left, &end);
- m = find_monitor(name);
- if (m == NULL)
- continue;
-@@ -79,7 +84,7 @@ void restore_tree(char *file_path)
- m->left_padding = left;
- if (end != 0)
- mon = m;
-- } else if (level == 2) {
-+ } else if (level == 1) {
- if (m == NULL)
- continue;
- int wg, top, right, bottom, left;
-@@ -87,7 +92,8 @@ void restore_tree(char *file_path)
- char floating, layout = 0, end = 0;
- name[0] = '\0';
- loc.desktop = NULL;
-- sscanf(line + level, "%s %u %i %i,%i,%i,%i %c %c %c", name, &bw, &wg, &top, &right, &bottom, &left, &layout, &floating, &end);
-+ sscanf(line + level, "%s %u %i %i,%i,%i,%i %c %c %c", name,
-+ &bw, &wg, &top, &right, &bottom, &left, &layout, &floating, &end);
- locate_desktop(name, &loc);
- d = loc.desktop;
- if (d == NULL)
-@@ -109,7 +115,7 @@ void restore_tree(char *file_path)
- if (m == NULL || d == NULL)
- continue;
- node_t *birth = make_node();
-- if (level == 4) {
-+ if (level == 2) {
- empty_desktop(d);
- d->root = birth;
- } else if (n != NULL) {
-@@ -135,10 +141,15 @@ void restore_tree(char *file_path)
- else if (st == 'V')
- n->split_type = TYPE_VERTICAL;
- } else {
-- client_t *c = make_client(XCB_NONE);
-+ client_t *c = make_client(XCB_NONE, d->border_width);
- num_clients++;
- char floating, pseudo_tiled, fullscreen, urgent, locked, sticky, private, sd, sm, end = 0;
-- sscanf(line + level, "%c %s %X %u %hux%hu%hi%hi %c %c%c%c%c%c%c%c%c %c", &br, c->class_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, &end);
-+ sscanf(line + level, "%c %s %s %X %u %hux%hu%hi%hi %c %c%c%c%c%c%c%c%c %c", &br,
-+ 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, &end);
- c->floating = (floating == '-' ? false : true);
- c->pseudo_tiled = (pseudo_tiled == '-' ? false : true);
- c->fullscreen = (fullscreen == '-' ? false : true);
-diff --git a/restore.h b/restore.h
-index 7f0ae21..7debd57 100644
---- a/restore.h
-+++ b/restore.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_RESTORE_H
-diff --git a/rule.c b/rule.c
-index e886343..b669cb6 100644
---- a/rule.c
-+++ b/rule.c
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #include <stdio.h>
-@@ -148,12 +152,15 @@ void apply_rules(xcb_window_t win, rule_consequence_t *csq)
- if (xcb_ewmh_get_wm_window_type_reply(ewmh, xcb_ewmh_get_wm_window_type(ewmh, win), &win_type, NULL) == 1) {
- for (unsigned int i = 0; i < win_type.atoms_len; i++) {
- xcb_atom_t a = win_type.atoms[i];
-- if (a == ewmh->_NET_WM_WINDOW_TYPE_TOOLBAR
-- || a == ewmh->_NET_WM_WINDOW_TYPE_UTILITY) {
-+ if (a == ewmh->_NET_WM_WINDOW_TYPE_TOOLBAR ||
-+ a == ewmh->_NET_WM_WINDOW_TYPE_UTILITY) {
- csq->focus = false;
- } else if (a == ewmh->_NET_WM_WINDOW_TYPE_DIALOG) {
- csq->floating = 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->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)
- window_lower(win);
-@@ -177,10 +184,14 @@ void apply_rules(xcb_window_t win, rule_consequence_t *csq)
-
- xcb_size_hints_t size_hints;
- 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)
-+ 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;
-+ csq->min_width = size_hints.min_width;
-+ csq->max_width = size_hints.max_width;
-+ csq->min_height = size_hints.min_height;
-+ csq->max_height = size_hints.max_height;
- }
-
- xcb_window_t transient_for = XCB_NONE;
-@@ -198,9 +209,9 @@ void apply_rules(xcb_window_t win, rule_consequence_t *csq)
- rule_t *rule = rule_head;
- while (rule != NULL) {
- rule_t *next = rule->next;
-- if (streq(rule->cause, MATCH_ANY)
-- || streq(rule->cause, csq->class_name)
-- || streq(rule->cause, csq->instance_name)) {
-+ if (streq(rule->cause, MATCH_ANY) ||
-+ streq(rule->cause, csq->class_name) ||
-+ streq(rule->cause, csq->instance_name)) {
- char effect[MAXLEN];
- snprintf(effect, sizeof(effect), "%s", rule->effect);
- char *key = strtok(effect, CSQ_BLK);
-@@ -265,10 +276,14 @@ void parse_rule_consequence(int fd, rule_consequence_t *csq)
- void parse_key_value(char *key, char *value, rule_consequence_t *csq)
- {
- bool v;
-- if (streq("desktop", key)) {
-- snprintf(csq->desktop_desc, sizeof(csq->desktop_desc), "%s", value);
-- } else if (streq("monitor", key)) {
-+ if (streq("monitor", key)) {
- snprintf(csq->monitor_desc, sizeof(csq->monitor_desc), "%s", value);
-+ } else if (streq("desktop", key)) {
-+ snprintf(csq->desktop_desc, sizeof(csq->desktop_desc), "%s", value);
-+ } else if (streq("window", key)) {
-+ 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 (parse_bool(value, &v)) {
- if (streq("floating", key))
- csq->floating = v;
-@@ -281,7 +296,6 @@ void parse_key_value(char *key, char *value, rule_consequence_t *csq)
- SETCSQ(sticky)
- SETCSQ(private)
- SETCSQ(center)
-- SETCSQ(lower)
- SETCSQ(follow)
- SETCSQ(manage)
- SETCSQ(focus)
-@@ -289,13 +303,11 @@ void parse_key_value(char *key, char *value, rule_consequence_t *csq)
- }
- }
-
--void list_rules(char *pattern, char *rsp)
-+void list_rules(char *pattern, FILE *rsp)
- {
-- char line[MAXLEN];
- for (rule_t *r = rule_head; r != NULL; r = r->next) {
- if (pattern != NULL && !streq(pattern, r->cause))
- continue;
-- snprintf(line, sizeof(line), "%s => %s\n", r->cause, r->effect);
-- strncat(rsp, line, REMLEN(rsp));
-+ fprintf(rsp, "%s => %s\n", r->cause, r->effect);
- }
- }
-diff --git a/rule.h b/rule.h
-index 6467aaf..f57301d 100644
---- a/rule.h
-+++ b/rule.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_RULE_H
-@@ -41,6 +45,6 @@ void apply_rules(xcb_window_t win, rule_consequence_t *csq);
- bool schedule_rules(xcb_window_t win, rule_consequence_t *csq);
- void parse_rule_consequence(int fd, rule_consequence_t *csq);
- void parse_key_value(char *key, char *value, rule_consequence_t *csq);
--void list_rules(char *pattern, char *rsp);
-+void list_rules(char *pattern, FILE *rsp);
-
- #endif
-diff --git a/settings.c b/settings.c
-index 997ef93..4b0ed4e 100644
---- a/settings.c
-+++ b/settings.c
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #include <unistd.h>
-diff --git a/settings.h b/settings.h
-index 372347e..06195f9 100644
---- a/settings.h
-+++ b/settings.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_SETTINGS_H
-diff --git a/stack.c b/stack.c
-index 3c4f6be..7351bd1 100644
---- a/stack.c
-+++ b/stack.c
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #include <stdlib.h>
-@@ -41,6 +45,8 @@ void stack_insert_after(stacking_list_t *a, node_t *n)
- if (a == NULL) {
- stack_head = stack_tail = s;
- } else {
-+ if (a->node == n)
-+ return;
- remove_stack_node(n);
- stacking_list_t *b = a->next;
- if (b != NULL)
-@@ -59,6 +65,8 @@ void stack_insert_before(stacking_list_t *a, node_t *n)
- if (a == NULL) {
- stack_head = stack_tail = s;
- } else {
-+ if (a->node == n)
-+ return;
- remove_stack_node(n);
- stacking_list_t *b = a->prev;
- if (b != NULL)
-@@ -113,8 +121,14 @@ void stack(node_t *n, stack_flavor_t f)
- return;
- stacking_list_t *latest_tiled = NULL;
- stacking_list_t *oldest_floating = NULL;
-+ stacking_list_t *oldest_fullscreen = NULL;
- for (stacking_list_t *s = (f == STACK_ABOVE ? stack_tail : stack_head); s != NULL; s = (f == STACK_ABOVE ? s->prev : s->next)) {
- if (s->node != n) {
-+ if (s->node->client->fullscreen) {
-+ if (oldest_fullscreen == NULL)
-+ oldest_fullscreen = s;
-+ continue;
-+ }
- if (s->node->client->floating == n->client->floating) {
- if (f == STACK_ABOVE) {
- stack_insert_after(s, n);
-@@ -131,18 +145,24 @@ void stack(node_t *n, stack_flavor_t f)
- }
- }
- }
-- if (latest_tiled == NULL && oldest_floating == NULL)
-+ if (latest_tiled == NULL && oldest_floating == NULL && oldest_fullscreen == NULL)
- return;
- if (n->client->floating) {
-- if (latest_tiled == NULL)
-- return;
-+ if (latest_tiled != NULL) {
- window_above(n->client->window, latest_tiled->node->client->window);
- stack_insert_after(latest_tiled, n);
-+ } else if (oldest_fullscreen != NULL) {
-+ window_below(n->client->window, oldest_fullscreen->node->client->window);
-+ stack_insert_before(oldest_fullscreen, n);
-+ }
- } else {
-- if (oldest_floating == NULL)
-- return;
-+ if (oldest_floating != NULL) {
- window_below(n->client->window, oldest_floating->node->client->window);
- stack_insert_before(oldest_floating, n);
-+ } else if (oldest_fullscreen != NULL) {
-+ window_below(n->client->window, oldest_fullscreen->node->client->window);
-+ stack_insert_before(oldest_fullscreen, n);
-+ }
- }
- }
- }
-diff --git a/stack.h b/stack.h
-index 259a201..83f767f 100644
---- a/stack.h
-+++ b/stack.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_STACK_H
-diff --git a/subscribe.c b/subscribe.c
-index d876052..104c873 100644
---- a/subscribe.c
-+++ b/subscribe.c
-@@ -1,3 +1,31 @@
-+/* Copyright (c) 2012-2014, Bastien Dejean
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ *
-+ * 1. Redistributions of source code must retain the above copyright notice, this
-+ * list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
-+ */
-+
- #include <stdlib.h>
- #include <unistd.h>
- #include <ctype.h>
-@@ -6,18 +34,11 @@
- #include "settings.h"
- #include "subscribe.h"
-
--subscriber_list_t *make_subscriber_list(int fd)
-+subscriber_list_t *make_subscriber_list(FILE *stream)
- {
- subscriber_list_t *sb = malloc(sizeof(subscriber_list_t));
- sb->prev = sb->next = NULL;
-- sb->fd = fd;
-- sb->stream = fdopen(fd, "w");
-- if (sb->stream == NULL) {
-- warn("Can't open subscriber %i\n", fd);
-- close(fd);
-- free(sb);
-- return NULL;
-- }
-+ sb->stream = stream;
- return sb;
- }
-
-@@ -39,11 +60,9 @@ void remove_subscriber(subscriber_list_t *sb)
- free(sb);
- }
-
--void add_subscriber(int fd)
-+void add_subscriber(FILE *stream)
- {
-- subscriber_list_t *sb = make_subscriber_list(fd);
-- if (sb == NULL)
-- return;
-+ subscriber_list_t *sb = make_subscriber_list(stream);
- if (subscribe_head == NULL) {
- subscribe_head = subscribe_tail = sb;
- } else {
-@@ -51,28 +70,26 @@ void add_subscriber(int fd)
- sb->prev = subscribe_tail;
- subscribe_tail = sb;
- }
-- feed_subscriber(sb);
-+ print_status(sb->stream);
- }
-
--void feed_subscriber(subscriber_list_t *sb)
-+int print_status(FILE *stream)
- {
-- fprintf(sb->stream, "%s", status_prefix);
-+ fprintf(stream, "%s", status_prefix);
- bool urgent = false;
- for (monitor_t *m = mon_head; m != NULL; m = m->next) {
-- fprintf(sb->stream, "%c%s:", (mon == m ? 'M' : 'm'), m->name);
-+ fprintf(stream, "%c%s:", (mon == m ? 'M' : 'm'), m->name);
- for (desktop_t *d = m->desk_head; d != NULL; d = d->next, urgent = false) {
- for (node_t *n = first_extrema(d->root); n != NULL && !urgent; n = next_leaf(n, d->root))
- urgent |= n->client->urgent;
- char c = (urgent ? 'u' : (d->root == NULL ? 'f' : 'o'));
- if (m->desk == d)
- c = toupper(c);
-- fprintf(sb->stream, "%c%s:", c, d->name);
-+ fprintf(stream, "%c%s:", c, d->name);
- }
- }
- if (mon != NULL && mon->desk != NULL)
-- fprintf(sb->stream, "L%s", (mon->desk->layout == LAYOUT_TILED ? "tiled" : "monocle"));
-- fprintf(sb->stream, "%s", "\n");
-- int ret = fflush(sb->stream);
-- if (ret != 0)
-- remove_subscriber(sb);
-+ fprintf(stream, "L%s", (mon->desk->layout == LAYOUT_TILED ? "tiled" : "monocle"));
-+ fprintf(stream, "%s", "\n");
-+ return fflush(stream);
- }
-diff --git a/subscribe.h b/subscribe.h
-index e5ce7de..31bb8c4 100644
---- a/subscribe.h
-+++ b/subscribe.h
-@@ -1,9 +1,37 @@
-+/* Copyright (c) 2012-2014, Bastien Dejean
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ *
-+ * 1. Redistributions of source code must retain the above copyright notice, this
-+ * list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
-+ */
-+
- #ifndef BSPWM_SUBSCRIBE_H
- #define BSPWM_SUBSCRIBE_H
-
--subscriber_list_t *make_subscriber_list(int fd);
-+subscriber_list_t *make_subscriber_list(FILE *stream);
- void remove_subscriber(subscriber_list_t *sb);
--void add_subscriber(int fd);
--void feed_subscriber(subscriber_list_t *sb);
-+void add_subscriber(FILE *stream);
-+int print_status(FILE *stream);
-
- #endif
-diff --git a/tree.c b/tree.c
-index b9c7950..0756547 100644
---- a/tree.c
-+++ b/tree.c
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #include <float.h>
-@@ -60,24 +64,28 @@ void apply_layout(monitor_t *m, desktop_t *d, node_t *n, xcb_rectangle_t rect, x
-
- if (is_leaf(n)) {
-
-- if ((borderless_monocle && is_tiled(n->client) && d->layout == LAYOUT_MONOCLE)
-- || n->client->fullscreen)
-- n->client->border_width = 0;
-+ unsigned int bw;
-+ if ((borderless_monocle && is_tiled(n->client) &&
-+ !n->client->pseudo_tiled &&
-+ d->layout == LAYOUT_MONOCLE) ||
-+ n->client->fullscreen)
-+ bw = 0;
- else
-- n->client->border_width = d->border_width;
-+ 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;
-- center_rectangle(&r, rect);
-+ r.x = rect.x - bw + (rect.width - wg - r.width) / 2;
-+ r.y = rect.y - bw + (rect.height - wg - r.height) / 2;
- } else {
- /* tiled clients */
- r = rect;
-- int wg = (gapless_monocle && d->layout == LAYOUT_MONOCLE ? 0 : d->window_gap);
-- int bleed = wg + 2 * n->client->border_width;
-+ int bleed = wg + 2 * bw;
- r.width = (bleed < r.width ? r.width - bleed : 1);
- r.height = (bleed < r.height ? r.height - bleed : 1);
- }
-@@ -92,7 +100,7 @@ void apply_layout(monitor_t *m, desktop_t *d, node_t *n, xcb_rectangle_t rect, x
- }
-
- window_move_resize(n->client->window, r.x, r.y, r.width, r.height);
-- window_border_width(n->client->window, n->client->border_width);
-+ window_border_width(n->client->window, bw);
- window_draw_border(n, d->focus == n, m == mon);
-
- } else {
-@@ -107,7 +115,7 @@ void apply_layout(monitor_t *m, desktop_t *d, node_t *n, xcb_rectangle_t rect, x
- fence = rect.width * n->split_ratio;
- first_rect = (xcb_rectangle_t) {rect.x, rect.y, fence, rect.height};
- second_rect = (xcb_rectangle_t) {rect.x + fence, rect.y, rect.width - fence, rect.height};
-- } else if (n->split_type == TYPE_HORIZONTAL) {
-+ } else {
- fence = rect.height * n->split_ratio;
- first_rect = (xcb_rectangle_t) {rect.x, rect.y, rect.width, fence};
- second_rect = (xcb_rectangle_t) {rect.x, rect.y + fence, rect.width, rect.height - fence};
-@@ -140,13 +148,14 @@ void insert_node(monitor_t *m, desktop_t *d, node_t *n, node_t *f)
- } else {
- node_t *c = make_node();
- node_t *p = f->parent;
-- if (p != NULL && f->split_mode == MODE_AUTOMATIC
-- && (p->first_child->vacant || p->second_child->vacant)) {
-+ if (p != NULL && f->split_mode == MODE_AUTOMATIC &&
-+ (p->first_child->vacant || p->second_child->vacant)) {
- f = p;
- p = f->parent;
- }
-- if (((f->client != NULL && f->client->private) || (p != NULL && p->privacy_level > 0))
-- && f->split_mode == MODE_AUTOMATIC) {
-+ if (((f->client != NULL && f->client->private) ||
-+ (p != NULL && p->privacy_level > 0)) &&
-+ f->split_mode == MODE_AUTOMATIC) {
- node_t *closest = NULL;
- node_t *public = NULL;
- closest_public(d, f, &closest, &public);
-@@ -292,10 +301,16 @@ void focus_node(monitor_t *m, desktop_t *d, node_t *n)
- n = d->focus;
- }
-
-- if (n != NULL && d->focus != NULL && n != d->focus && d->focus->client->fullscreen) {
-+ if (n != NULL) {
-+ if (d->focus != NULL && n != d->focus && d->focus->client->fullscreen) {
- set_fullscreen(d->focus, false);
- arrange(m, d);
- }
-+ if (n->client->urgent) {
-+ n->client->urgent = false;
-+ put_status();
-+ }
-+ }
-
- if (mon != m) {
- for (desktop_t *cd = mon->desk_head; cd != NULL; cd = cd->next)
-@@ -326,8 +341,6 @@ void focus_node(monitor_t *m, desktop_t *d, node_t *n)
-
- PRINTF("focus node %X\n", n->client->window);
-
-- n->client->urgent = false;
--
- history_add(m, d, n);
- set_input_focus(n);
-
-@@ -362,12 +375,13 @@ node_t *make_node(void)
- return n;
- }
-
--client_t *make_client(xcb_window_t win)
-+client_t *make_client(xcb_window_t win, unsigned int border_width)
- {
- client_t *c = malloc(sizeof(client_t));
-- snprintf(c->class_name, sizeof(c->class_name), "%s", MISSING_VALUE);
-- c->border_width = BORDER_WIDTH;
- c->window = win;
-+ 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;
-@@ -570,10 +584,10 @@ node_t *find_fence(node_t *n, direction_t dir)
- p = n->parent;
-
- while (p != NULL) {
-- if ((dir == DIR_UP && p->split_type == TYPE_HORIZONTAL && p->rectangle.y < n->rectangle.y)
-- || (dir == DIR_LEFT && p->split_type == TYPE_VERTICAL && p->rectangle.x < n->rectangle.x)
-- || (dir == DIR_DOWN && p->split_type == TYPE_HORIZONTAL && (p->rectangle.y + p->rectangle.height) > (n->rectangle.y + n->rectangle.height))
-- || (dir == DIR_RIGHT && p->split_type == TYPE_VERTICAL && (p->rectangle.x + p->rectangle.width) > (n->rectangle.x + n->rectangle.width)))
-+ if ((dir == DIR_UP && p->split_type == TYPE_HORIZONTAL && p->rectangle.y < n->rectangle.y) ||
-+ (dir == DIR_LEFT && p->split_type == TYPE_VERTICAL && p->rectangle.x < n->rectangle.x) ||
-+ (dir == DIR_DOWN && p->split_type == TYPE_HORIZONTAL && (p->rectangle.y + p->rectangle.height) > (n->rectangle.y + n->rectangle.height)) ||
-+ (dir == DIR_RIGHT && p->split_type == TYPE_VERTICAL && (p->rectangle.x + p->rectangle.width) > (n->rectangle.x + n->rectangle.width)))
- return p;
- p = p->parent;
- }
-@@ -583,8 +597,8 @@ node_t *find_fence(node_t *n, 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 && is_tiled(n->client)))
-+ if (n == NULL || n->client->fullscreen ||
-+ (d->layout == LAYOUT_MONOCLE && is_tiled(n->client)))
- return NULL;
-
- node_t *nearest = NULL;
-@@ -735,9 +749,9 @@ void rotate_tree(node_t *n, int deg)
-
- node_t *tmp;
-
-- if ((deg == 90 && n->split_type == TYPE_HORIZONTAL)
-- || (deg == 270 && n->split_type == TYPE_VERTICAL)
-- || deg == 180) {
-+ if ((deg == 90 && n->split_type == TYPE_HORIZONTAL) ||
-+ (deg == 270 && n->split_type == TYPE_VERTICAL) ||
-+ deg == 180) {
- tmp = n->first_child;
- n->first_child = n->second_child;
- n->second_child = tmp;
-@@ -779,8 +793,8 @@ void flip_tree(node_t *n, flip_t flp)
-
- node_t *tmp;
-
-- if ((flp == FLIP_HORIZONTAL && n->split_type == TYPE_HORIZONTAL)
-- || (flp == FLIP_VERTICAL && n->split_type == TYPE_VERTICAL)) {
-+ if ((flp == FLIP_HORIZONTAL && n->split_type == TYPE_HORIZONTAL) ||
-+ (flp == FLIP_VERTICAL && n->split_type == TYPE_VERTICAL)) {
- tmp = n->first_child;
- n->first_child = n->second_child;
- n->second_child = tmp;
-@@ -791,6 +805,17 @@ void flip_tree(node_t *n, flip_t flp)
- flip_tree(n->second_child, flp);
- }
-
-+void equalize_tree(node_t *n)
-+{
-+ if (n == NULL || n->vacant) {
-+ return;
-+ } else {
-+ n->split_ratio = split_ratio;
-+ equalize_tree(n->first_child);
-+ equalize_tree(n->second_child);
-+ }
-+}
-+
- int balance_tree(node_t *n)
- {
- if (n == NULL || n->vacant) {
-@@ -902,7 +927,8 @@ void destroy_tree(node_t *n)
-
- bool swap_nodes(monitor_t *m1, desktop_t *d1, node_t *n1, monitor_t *m2, desktop_t *d2, node_t *n2)
- {
-- if (n1 == NULL || n2 == NULL || n1 == n2 || (d1 != d2 && (n1->client->sticky || n2->client->sticky)))
-+ if (n1 == NULL || n2 == NULL ||n1 == n2 ||
-+ (d1 != d2 && (n1->client->sticky || n2->client->sticky)))
- return false;
-
- PRINTF("swap nodes %X %X\n", n1->client->window, n2->client->window);
-diff --git a/tree.h b/tree.h
-index 3a82a2e..3f0ee5d 100644
---- a/tree.h
-+++ b/tree.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_TREE_H
-@@ -32,7 +36,7 @@ void pseudo_focus(monitor_t *m, desktop_t *d, node_t *n);
- void focus_node(monitor_t *m, desktop_t *d, node_t *n);
- void update_current(void);
- node_t *make_node(void);
--client_t *make_client(xcb_window_t win);
-+client_t *make_client(xcb_window_t win, unsigned int border_width);
- bool is_leaf(node_t *n);
- bool is_tiled(client_t *c);
- bool is_floating(client_t *c);
-@@ -60,6 +64,7 @@ void rotate_brother(node_t *n);
- void unrotate_tree(node_t *n, int rot);
- void unrotate_brother(node_t *n);
- void flip_tree(node_t *n, flip_t flp);
-+void equalize_tree(node_t *n);
- int balance_tree(node_t *n);
- void unlink_node(monitor_t *m, desktop_t *d, node_t *n);
- void remove_node(monitor_t *m, desktop_t *d, node_t *n);
-diff --git a/types.h b/types.h
-index 6495f0a..6c57713 100644
---- a/types.h
-+++ b/types.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_TYPES_H
-@@ -56,11 +60,17 @@ typedef enum {
- CLIENT_CLASS_DIFFER
- } client_class_t;
-
-+typedef enum {
-+ CLIENT_MODE_ALL,
-+ CLIENT_MODE_AUTOMATIC,
-+ CLIENT_MODE_MANUAL
-+} client_mode_t;
-+
- typedef struct {
- client_type_t type;
- client_class_t class;
-+ client_mode_t mode;
- bool urgent;
-- bool manual;
- bool local;
- } client_select_t;
-
-@@ -143,7 +153,8 @@ typedef struct {
-
- typedef struct {
- xcb_window_t window;
-- char class_name[SMALEN];
-+ char class_name[3 * SMALEN / 2];
-+ char instance_name[3 * SMALEN / 2];
- unsigned int border_width;
- bool pseudo_tiled;
- bool floating;
-@@ -155,6 +166,10 @@ typedef struct {
- bool icccm_focus;
- xcb_rectangle_t floating_rectangle;
- xcb_rectangle_t tiled_rectangle;
-+ uint16_t min_width;
-+ uint16_t max_width;
-+ uint16_t min_height;
-+ uint16_t max_height;
- xcb_atom_t wm_state[MAX_STATE];
- int num_states;
- } client_t;
-@@ -250,10 +265,16 @@ struct rule_t {
- };
-
- typedef struct {
-- char class_name[SMALEN];
-- char instance_name[SMALEN];
-- char desktop_desc[MAXLEN];
-+ char class_name[3 * SMALEN / 2];
-+ char instance_name[3 * SMALEN / 2];
- char monitor_desc[MAXLEN];
-+ char desktop_desc[MAXLEN];
-+ char node_desc[MAXLEN];
-+ char split_dir[SMALEN];
-+ uint16_t min_width;
-+ uint16_t max_width;
-+ uint16_t min_height;
-+ uint16_t max_height;
- bool pseudo_tiled;
- bool floating;
- bool fullscreen;
-@@ -261,7 +282,6 @@ typedef struct {
- bool sticky;
- bool private;
- bool center;
-- bool lower;
- bool follow;
- bool manage;
- bool focus;
-diff --git a/window.c b/window.c
-index 4b1ed3f..ce69617 100644
---- a/window.c
-+++ b/window.c
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #include <stdlib.h>
-@@ -32,6 +36,7 @@
- #include "settings.h"
- #include "stack.h"
- #include "tree.h"
-+#include "messages.h"
- #include "window.h"
-
- void schedule_window(xcb_window_t win)
-@@ -65,12 +70,10 @@ void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
- {
- monitor_t *m = mon;
- desktop_t *d = mon->desk;
-+ node_t *f = mon->desk->focus;
-
- parse_rule_consequence(fd, csq);
-
-- if (csq->lower)
-- window_lower(win);
--
- if (!csq->manage) {
- disable_floating_atom(win);
- window_show(win);
-@@ -79,12 +82,21 @@ void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
-
- PRINTF("manage %X\n", win);
-
-- if (csq->desktop_desc[0] != '\0') {
-+ if (csq->node_desc[0] != '\0') {
-+ coordinates_t ref = {m, d, f};
-+ coordinates_t trg = {NULL, NULL, NULL};
-+ if (node_from_desc(csq->node_desc, &ref, &trg)) {
-+ m = trg.monitor;
-+ d = trg.desktop;
-+ f = trg.node;
-+ }
-+ } else if (csq->desktop_desc[0] != '\0') {
- coordinates_t ref = {m, d, NULL};
- coordinates_t trg = {NULL, NULL, NULL};
- if (desktop_from_desc(csq->desktop_desc, &ref, &trg)) {
- m = trg.monitor;
- d = trg.desktop;
-+ f = trg.desktop->focus;
- }
- } else if (csq->monitor_desc[0] != '\0') {
- coordinates_t ref = {m, NULL, NULL};
-@@ -92,16 +104,32 @@ void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
- if (monitor_from_desc(csq->monitor_desc, &ref, &trg)) {
- m = trg.monitor;
- d = trg.monitor->desk;
-+ f = trg.monitor->desk->focus;
- }
- }
-
- if (csq->sticky) {
- m = mon;
- d = mon->desk;
-+ f = mon->desk->focus;
-+ }
-+
-+ if (csq->split_dir[0] != '\0' && f != NULL) {
-+ direction_t dir;
-+ if (parse_direction(csq->split_dir, &dir)) {
-+ f->split_mode = MODE_MANUAL;
-+ f->split_dir = dir;
-+ }
- }
-
-- client_t *c = make_client(win);
-+ client_t *c = make_client(win, d->border_width);
- update_floating_rectangle(c);
-+ if (c->floating_rectangle.x == 0 && c->floating_rectangle.y == 0)
-+ csq->center = true;
-+ c->min_width = csq->min_width;
-+ c->max_width = csq->max_width;
-+ c->min_height = csq->min_height;
-+ c->max_height = csq->max_height;
- monitor_t *mm = monitor_from_client(c);
- embrace_client(mm, c);
- translate_client(mm, m, c);
-@@ -109,13 +137,14 @@ void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
- window_center(m, c);
-
- 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;
-
-- insert_node(m, d, n, d->focus);
-+ insert_node(m, d, n, f);
-
- disable_floating_atom(c->window);
- set_pseudo_tiled(n, csq->pseudo_tiled);
-@@ -165,6 +194,8 @@ void unmanage_window(xcb_window_t win)
- if (locate_window(win, &loc)) {
- PRINTF("unmanage %X\n", win);
- remove_node(loc.monitor, loc.desktop, loc.node);
-+ if (frozen_pointer->window == win)
-+ frozen_pointer->action = ACTION_NONE;
- arrange(loc.monitor, loc.desktop);
- } else {
- for (pending_rule_t *pr = pending_rule_head; pr != NULL; pr = pr->next) {
-@@ -266,8 +297,8 @@ pointer_state_t *make_pointer_state(void)
-
- bool contains(xcb_rectangle_t a, xcb_rectangle_t b)
- {
-- return (a.x <= b.x && (a.x + a.width) >= (b.x + b.width)
-- && a.y <= b.y && (a.y + a.height) >= (b.y + b.height));
-+ return (a.x <= b.x && (a.x + a.width) >= (b.x + b.width) &&
-+ a.y <= b.y && (a.y + a.height) >= (b.y + b.height));
- }
-
- xcb_rectangle_t get_rectangle(client_t *c)
-@@ -519,12 +550,35 @@ void update_floating_rectangle(client_t *c)
-
- if (geo != NULL)
- c->floating_rectangle = (xcb_rectangle_t) {geo->x, geo->y, geo->width, geo->height};
-- else
-- c->floating_rectangle = (xcb_rectangle_t) {0, 0, 32, 24};
-
- free(geo);
- }
-
-+void restrain_floating_width(client_t *c, int *width)
-+{
-+ if (*width < 1)
-+ *width = 1;
-+ if (c->min_width > 0 && *width < c->min_width)
-+ *width = c->min_width;
-+ else if (c->max_width > 0 && *width > c->max_width)
-+ *width = c->max_width;
-+}
-+
-+void restrain_floating_height(client_t *c, int *height)
-+{
-+ if (*height < 1)
-+ *height = 1;
-+ if (c->min_height > 0 && *height < c->min_height)
-+ *height = c->min_height;
-+ else if (c->max_height > 0 && *height > c->max_height)
-+ *height = c->max_height;
-+}
-+
-+void restrain_floating_size(client_t *c, int *width, int *height)
-+{
-+ restrain_floating_width(c, width);
-+ restrain_floating_height(c, height);
-+}
-
- void query_pointer(xcb_window_t *win, xcb_point_t *pt)
- {
-@@ -596,6 +650,8 @@ void window_center(monitor_t *m, client_t *c)
- r->y = a.y;
- else
- r->y = a.y + (a.height - r->height) / 2;
-+ r->x -= c->border_width;
-+ r->y -= c->border_width;
- }
-
- void window_stack(xcb_window_t w1, xcb_window_t w2, uint32_t mode)
-diff --git a/window.h b/window.h
-index 12bc117..9688ef3 100644
---- a/window.h
-+++ b/window.h
-@@ -1,25 +1,29 @@
--/* * Copyright (c) 2012-2013 Bastien Dejean
-+/* Copyright (c) 2012-2014, Bastien Dejean
- * All rights reserved.
- *
-- * Redistribution and use in source and binary forms, with or without modification,
-- * are permitted provided that the following conditions are met:
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
- *
-- * * Redistributions of source code must retain the above copyright notice, this
-+ * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
-- * * Redistributions in binary form must reproduce the above copyright notice,
-- * this list of conditions and the following disclaimer in the documentation and/or
-- * other materials provided with the distribution.
-+ * 2. Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
- *
-- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
-- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * The views and conclusions contained in the software and documentation are those
-+ * of the authors and should not be interpreted as representing official policies,
-+ * either expressed or implied, of the FreeBSD Project.
- */
-
- #ifndef BSPWM_WINDOW_H
-@@ -54,6 +58,9 @@ void enable_floating_atom(xcb_window_t win);
- void disable_floating_atom(xcb_window_t win);
- uint32_t get_border_color(client_t *c, bool focused_window, bool focused_monitor);
- void update_floating_rectangle(client_t *c);
-+void restrain_floating_width(client_t *c, int *width);
-+void restrain_floating_height(client_t *c, int *height);
-+void restrain_floating_size(client_t *c, int *width, int *height);
- void query_pointer(xcb_window_t *win, xcb_point_t *pt);
- bool window_focus(xcb_window_t win);
- void window_border_width(xcb_window_t win, uint32_t bw);