diff options
Diffstat (limited to 'desktop/bspwm/patches/bspwm-0.8.8_0ca5bf3.patch')
-rw-r--r-- | desktop/bspwm/patches/bspwm-0.8.8_0ca5bf3.patch | 4719 |
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=* --plus=+ --caret=^ --startsb=[ --endsb=] --backslash=\ --tilde=~ --apostrophe=' --backtick=` --litdd=-- -- --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, °)) { - 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, °)) { - 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); |