diff --git a/.clang-format b/.clang-format index 6b542c1..4a15e88 100644 --- a/.clang-format +++ b/.clang-format @@ -10,3 +10,4 @@ SpaceBeforeParens: ControlStatements SortIncludes: false ForEachMacros: [ TAILQ_FOREACH, TAILQ_FOREACH_REVERSE, SLIST_FOREACH, CIRCLEQ_FOREACH, CIRCLEQ_FOREACH_REVERSE, NODES_FOREACH, NODES_FOREACH_REVERSE, FOREACH_NONINTERNAL] +TypenameMacros: [ SLIST_HEAD, SLIST_ENTRY, LIST_HEAD, LIST_ENTRY, SIMPLEQ_HEAD, SIMPLEQ_ENTRY, TAILQ_HEAD, TAILQ_ENTRY, CIRCLEQ_HEAD, CIRCLEQ_ENTRY ] diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..6b8710a --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +.git diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..40fd839 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,41 @@ +# Contributing + +## i3status/i3lock bug reports and feature requests + +Note that bug reports and feature requests for related projects should be filed in the corresponding repositories for [i3status](https://github.com/i3/i3status) and [i3lock](https://github.com/i3/i3lock). + +## i3 bug reports and feature requests + +1. Read the [debugging instructions](https://i3wm.org/docs/debugging.html). +2. Make sure you include a link to your logfile in your report (section 3). +3. Make sure you include the i3 version number in your report (section 1). +4. Please be aware that we cannot support compatibility issues with + closed-source software, as digging into compatibility problems without + having access to the source code is too time-consuming. Additionally, + experience has shown that often, the software in question is responsible for + the issue. Please raise an issue with the software in question, not i3. +5. Please note that i3 does not support compositors (e.g. compton). If you + encountered the issue you are about to report while using a compositor, + please try reproducing it without a compositor. + +## Pull requests + +* Before sending a pull request for new features, please check with us that the + feature is something we want to see in i3 by opening an issue which has + ”feature request” or ”enhancement” in its title. +* Use the `next` branch for developing and sending your pull request. +* Use `clang-format` to format your code. +* Run the [testsuite](https://i3wm.org/docs/testsuite.html) +* If your changes should be reported on the next release's changelog, also + update the [RELEASE-notes-next](../RELEASE-notes-next) file in the root + folder. Example of changes that should be reported are bug fixes present in + the latest stable version of i3 and new enhancements. Example of changes that + should not be reported are minor code improvements, documentation, regression + and fixes for bugs that were introduced in the `next` branch. + +## Finding something to do + +* Find a [reproducible bug](https://github.com/i3/i3/issues?utf8=%E2%9C%93&q=is%3Aopen+label%3Areproducible+label%3Abug+) from the issue tracker. These issues have been reviewed and confirmed by a project contributor. +* Find an [accepted enhancement](https://github.com/i3/i3/issues?utf8=%E2%9C%93&q=is%3Aopen+label%3Aaccepted+label%3Aenhancement) from the issue tracker. These have been approved and are ok to start working on. + +There's an [overview of the codebase](https://i3wm.org/docs/hacking-howto.html) available to get you started. diff --git a/.github/GOVERNANCE.md b/.github/GOVERNANCE.md new file mode 100644 index 0000000..44e1334 --- /dev/null +++ b/.github/GOVERNANCE.md @@ -0,0 +1,30 @@ +# i3 project governance + +## Overview + +The i3 project uses a governance model commonly described as Benevolent +Dictator For Life (BDFL). This document outlines our understanding of what this +means. + +## Roles + +* user: anyone who interacts with the i3 project +* core contributor: a handful of people who have contributed significantly to + the project by any means (issue triage, support, documentation, code, etc.). + Core contributors are recognizable via GitHub’s “Member” badge. +* BDFL: a single individual who makes decisions when consensus cannot be + reached. i3’s current BDFL is [@stapelberg](https://github.com/stapelberg). + +## Decision making process + +In general, we try to reach consensus in discussions. In case consensus cannot +be reached, the BDFL makes a decision. + +For feature requests and code contributions specifically, the values with which +we consider them can be found on the bottom of https://i3wm.org/. These values +are not set in stone and are to be treated as guiding principles, not absolute +rules that must be followed in every case. + +## Contribution process + +Please see [CONTRIBUTING](CONTRIBUTING.md). diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..a6df0a9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,72 @@ +--- +name: Bug report +about: Create a report to help us improve +--- + + + +## I'm submitting a… + +
+[x] Bug
+[ ] Feature Request
+[ ] Documentation Request
+[ ] Other (Please describe in detail)
+
+ +## Current Behavior + + +## Expected Behavior + + +## Reproduction Instructions + + +## Environment + +Output of `i3 --moreversion 2>&-`: +
+i3 version: 
+
+ + +
Config file
+
+
+ + +
+Logfile URL:
+
+ + +
+- Linux Distribution & Version:
+- Are you using a compositor (e.g., xcompmgr or compton):
+
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..e1c169a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,47 @@ +--- +name: Feature request +about: Suggest an idea for this project +--- + + + +## I'm submitting a… + +
+[ ] Bug
+[x] Feature Request
+[ ] Documentation Request
+[ ] Other (Please describe in detail)
+
+ +## Current Behavior + + +## Desired Behavior + + +## Environment + +Output of `i3 --moreversion 2>&-`: +
+i3 version: 
+
+ + +
+- Linux Distribution & Version:
+- Are you using a compositor (e.g., xcompmgr or compton):
+
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..726b400 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,71 @@ + + +## I'm submitting a… + +
+[ ] Bug
+[ ] Feature Request
+[ ] Documentation Request
+[ ] Other (Please describe in detail)
+
+ +## Current Behavior + + +## Expected Behavior + + +## Reproduction Instructions + + +## Environment + +Output of `i3 --moreversion 2>&-`: +
+i3 version: 
+
+ + +
+
+ + +
+Logfile URL:
+
+ + +
+- Linux Distribution & Version:
+- Are you using a compositor (e.g., xcompmgr or compton):
+
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..51baa22 --- /dev/null +++ b/.gitignore @@ -0,0 +1,55 @@ +*.o +tags +include/GENERATED_*.h +include/all.h.pch +*~ +*.swp +*.gcda +*.gcno +*.dSYM +test.commands_parser +test.config_parser +testcases/MYMETA.json +testcases/MYMETA.yml +testcases/blib/ +testcases/pm_to_blib +AnyEvent-I3/Makefile +AnyEvent-I3/META.yml +AnyEvent-I3/MYMETA.json +AnyEvent-I3/MYMETA.yml +AnyEvent-I3/blib/ +AnyEvent-I3/inc/ +AnyEvent-I3/pm_to_blib +*.output +*.tab.* +*.yy.c +man/*.1 +man/*.xml +man/*.html +*.tar.bz2* +*.tar.xz* +i3 +i3-input/i3-input +i3-nagbar/i3-nagbar +i3-msg/i3-msg +i3-config-wizard/i3-config-wizard +i3-dump-log/i3-dump-log +libi3.a +docs/*.pdf +docs/*.html +!/docs/refcard.html +i3-command-parser.stamp +i3-config-parser.stamp +.clang_complete +compile_commands.json +/.ccls-cache +/.clangd +LAST_VERSION +build + +# We recommend building in a subdirectory called build. +# If you chose a different directory name, +# it is up to you to arrange for it to be ignored by git, +# e.g. by listing your directory in .git/info/exclude. +/build + diff --git a/.travis.yml b/.travis.yml index b56bf68..9935cb6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,9 +31,10 @@ script: - docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/check-safe-wrappers.sh - docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/check-formatting.sh - - docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 -e CC ${BASENAME} /bin/sh -c 'autoreconf -fi && mkdir -p build && cd build && (../configure || (cat config.log; false)) && make -j CFLAGS="-Wformat -Wformat-security -Wextra -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Werror -fno-common"' + - docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 -e CC ${BASENAME} /bin/sh -c 'rm -rf build; mkdir -p build && cd build && CFLAGS="-Wformat -Wformat-security -Wextra -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Werror -fno-common" meson .. -Ddocs=true -Dmans=true -Db_sanitize=address && ninja -v' - docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/check-spelling.pl - docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 -e CC ${BASENAME} ./travis/run-tests.sh + - docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 -e CC ${BASENAME} /bin/sh -c 'rm -rf distbuild; mkdir distbuild && cd distbuild && meson .. -Ddocs=true -Dmans=true && ninja -v dist' - ./travis/skip-pkg.sh || docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/debian-build.sh deb/debian-amd64/DIST - ./travis/skip-pkg.sh || docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME_UBUNTU} ./travis/debian-build.sh deb/ubuntu-amd64/DIST - ./travis/skip-pkg.sh || docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME_386} linux32 ./travis/debian-build.sh deb/debian-i386/DIST diff --git a/AnyEvent-I3/lib/AnyEvent/I3.pm b/AnyEvent-I3/lib/AnyEvent/I3.pm index ae9e5be..1f4e5bd 100644 --- a/AnyEvent-I3/lib/AnyEvent/I3.pm +++ b/AnyEvent-I3/lib/AnyEvent/I3.pm @@ -101,11 +101,13 @@ use constant TYPE_GET_CONFIG => 9; use constant TYPE_SEND_TICK => 10; use constant TYPE_SYNC => 11; +use constant TYPE_GET_BINDING_STATE => 12; our %EXPORT_TAGS = ( 'all' => [ qw(i3 TYPE_RUN_COMMAND TYPE_COMMAND TYPE_GET_WORKSPACES TYPE_SUBSCRIBE TYPE_GET_OUTPUTS TYPE_GET_TREE TYPE_GET_MARKS TYPE_GET_BAR_CONFIG TYPE_GET_VERSION - TYPE_GET_BINDING_MODES TYPE_GET_CONFIG TYPE_SEND_TICK TYPE_SYNC) + TYPE_GET_BINDING_MODES TYPE_GET_CONFIG TYPE_SEND_TICK TYPE_SYNC + TYPE_GET_BINDING_STATE) ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{all} } ); diff --git a/I3_VERSION b/I3_VERSION deleted file mode 100644 index 60f610c..0000000 --- a/I3_VERSION +++ /dev/null @@ -1 +0,0 @@ -4.18.1-non-git diff --git a/LICENSE b/LICENSE index 6354f06..1f0872c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,27 +1,26 @@ Copyright © 2009, Michael Stapelberg and contributors -All rights reserved. Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +modification, are permitted provided that the following conditions +are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. +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. +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. - * 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. - - * Neither the name of Michael Stapelberg nor the - names of contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY Michael Stapelberg ''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 Michael Stapelberg 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 +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 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. diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 1b9c092..0000000 --- a/Makefile.am +++ /dev/null @@ -1,644 +0,0 @@ -@CODE_COVERAGE_RULES@ - -echo-version: - @echo "@I3_VERSION@" - -bin_PROGRAMS = \ - i3 \ - i3bar/i3bar \ - i3-config-wizard/i3-config-wizard \ - i3-dump-log/i3-dump-log \ - i3-input/i3-input \ - i3-msg/i3-msg \ - i3-nagbar/i3-nagbar - -install-exec-hook: - $(LN_S) -f i3 $(DESTDIR)$(bindir)/i3-with-shmlog - -uninstall-hook: - rm -f $(DESTDIR)$(bindir)/i3-with-shmlog - -i3includedir=$(includedir)/i3 -i3include_HEADERS = \ - include/i3/ipc.h - -dist_bin_SCRIPTS = \ - i3-dmenu-desktop \ - i3-migrate-config-to-v4 \ - i3-save-tree \ - i3-sensible-editor \ - i3-sensible-pager \ - i3-sensible-terminal - -i3confdir = $(sysconfdir)/i3 -dist_i3conf_DATA = \ - etc/config \ - etc/config.keycodes - -I3STATUS_INSTALL_NAME = $(shell echo i3status | sed '@program_transform_name@') - -etc/config: etc/$(dirstamp) - $(AM_V_GEN) sed "s,status_command i3status,status_command $(I3STATUS_INSTALL_NAME),g" $(top_srcdir)/etc/config > etc/config - -etc/config.keycodes: etc/$(dirstamp) - $(AM_V_GEN) sed "s,status_command i3status,status_command $(I3STATUS_INSTALL_NAME),g" $(top_srcdir)/etc/config.keycodes > etc/config.keycodes - -applicationsdir = $(datarootdir)/applications -xsessionsdir = $(datarootdir)/xsessions -dist_applications_DATA = \ - share/applications/i3.desktop -dist_xsessions_DATA = \ - share/xsessions/i3.desktop \ - share/xsessions/i3-with-shmlog.desktop - -noinst_LIBRARIES = libi3.a - -check_PROGRAMS = \ - test.commands_parser \ - test.config_parser \ - test.inject_randr15 - -check_SCRIPTS = \ - testcases/complete-run.pl - -check_DATA = \ - anyevent-i3.stamp - -clean-check: - rm -rf testsuite-* latest i3-cfg-for-* _Inline -clean-local: clean-check - -TESTS = testcases/complete-run.pl - -EXTRA_DIST = \ - $(dist_docs_toc_DATA:.html=) \ - $(dist_docs_notoc_DATA:.html=) \ - AnyEvent-I3/Changes \ - AnyEvent-I3/MANIFEST \ - AnyEvent-I3/MANIFEST.SKIP \ - AnyEvent-I3/Makefile.PL \ - AnyEvent-I3/README \ - AnyEvent-I3/lib/AnyEvent/I3.pm \ - AnyEvent-I3/t/00-load.t \ - AnyEvent-I3/t/01-workspaces.t \ - AnyEvent-I3/t/02-sugar.t \ - AnyEvent-I3/t/boilerplate.t \ - AnyEvent-I3/t/manifest.t \ - AnyEvent-I3/t/pod-coverage.t \ - AnyEvent-I3/t/pod.t \ - contrib/dump-asy.pl \ - contrib/gtk-tree-watch.pl \ - contrib/i3-wsbar \ - contrib/per-workspace-layout.pl \ - contrib/trivial-bar-script.sh \ - docs/asciidoc-git.conf \ - docs/bigpicture.png \ - docs/i3-pod2html \ - docs/i3-sync.dia \ - docs/i3-sync.png \ - docs/i3-sync-working.dia \ - docs/i3-sync-working.png \ - docs/keyboard-layer1.png \ - docs/keyboard-layer2.png \ - docs/layout-saving-1.png \ - docs/logo-30.png \ - docs/modes.png \ - docs/refcard.html \ - docs/refcard_style.css \ - docs/single_terminal.png \ - docs/snapping.png \ - docs/tree-layout1.png \ - docs/tree-layout2.png \ - docs/tree-shot1.png \ - docs/tree-shot2.png \ - docs/tree-shot3.png \ - docs/tree-shot4.png \ - docs/two_columns.png \ - docs/two_terminals.png \ - docs/wsbar.dia \ - docs/wsbar.png \ - i3bar/LICENSE \ - libi3/README \ - $(asciidoc_MANS:.1=.man) \ - $(asciidoc_MANS:.1=.man) \ - man/asciidoc.conf.in \ - DEPENDS \ - I3_VERSION \ - LICENSE \ - PACKAGE-MAINTAINER \ - RELEASE-NOTES-4.18.1 \ - generate-command-parser.pl \ - parser-specs/commands.spec \ - parser-specs/config.spec \ - parser-specs/highlighting.vim \ - pseudo-doc.doxygen \ - testcases/complete-run.pl.in \ - testcases/i3-test.config \ - testcases/lib/i3test/Test.pm \ - testcases/lib/i3test/Util.pm \ - testcases/lib/i3test/XTEST.pm \ - testcases/lib/i3test.pm.in \ - testcases/lib/SocketActivation.pm \ - testcases/lib/StartXServer.pm \ - testcases/lib/StatusLine.pm \ - testcases/lib/TestWorker.pm \ - testcases/Makefile.PL \ - testcases/new-test \ - testcases/restart-state.golden \ - testcases/t \ - testcases/valgrind.supp - -# dirstamps contains directories which we want to be created in $(top_builddir) -# so that our custom rules can store files in them. -dirstamp = .dirstamp -dirstamps = \ - docs/$(dirstamp) \ - man/$(dirstamp) \ - parser/$(dirstamp) \ - etc/$(dirstamp) -DISTCLEANFILES = $(dirstamps) - -$(dirstamps): - @stamp='$@'; $(MKDIR_P) "$${stamp%/*}" - @: > $@ - -################################################################################ -# docs generation -################################################################################ - -docs_tocdir = ${docdir} -docs_notocdir = ${docdir} -docs_poddir = ${docdir} -if BUILD_DOCS -dist_docs_toc_DATA = \ - docs/hacking-howto.html \ - docs/userguide.html \ - docs/ipc.html \ - docs/multi-monitor.html \ - docs/wsbar.html \ - docs/testsuite.html \ - docs/i3bar-protocol.html \ - docs/layout-saving.html - -dist_docs_notoc_DATA = \ - docs/debugging.html - -dist_docs_pod_DATA = \ - docs/lib-i3test.html \ - docs/lib-i3test-test.html - -$(dist_docs_toc_DATA): docs/%.html: docs/% docs/$(dirstamp) - $(AM_V_GEN) @PATH_ASCIIDOC@ -a toc -n -o $@ $< - -$(dist_docs_notoc_DATA): docs/%.html: docs/% docs/$(dirstamp) - $(AM_V_GEN) @PATH_ASCIIDOC@ -n -o $@ $< - -docs/lib-i3test.html: testcases/lib/i3test.pm docs/$(dirstamp) - $(AM_V_GEN) $(top_srcdir)/docs/i3-pod2html $< $@ - -docs/lib-i3test-test.html: testcases/lib/i3test/Test.pm docs/$(dirstamp) - $(AM_V_GEN) $(top_srcdir)/docs/i3-pod2html $< $@ - -else -dist_docs_toc_DATA = -dist_docs_notoc_DATA = -dist_docs_pod_DATA = -endif - -################################################################################ -# manpage generation -################################################################################ - -if BUILD_MANS -dist_man1_MANS = \ - $(asciidoc_MANS) \ - $(pod_MANS) - -asciidoc_MANS = \ - man/i3.1 \ - man/i3bar.1 \ - man/i3-msg.1 \ - man/i3-input.1 \ - man/i3-nagbar.1 \ - man/i3-config-wizard.1 \ - man/i3-migrate-config-to-v4.1 \ - man/i3-sensible-editor.1 \ - man/i3-sensible-pager.1 \ - man/i3-sensible-terminal.1 \ - man/i3-dump-log.1 - -pod_MANS = \ - man/i3-dmenu-desktop.1 \ - man/i3-save-tree.1 - -$(asciidoc_MANS): man/%.1: man/%.xml man/$(dirstamp) - $(AM_V_GEN) out='$@'; @PATH_XMLTO@ man -o "$${out%/*}" $< - @stamp='$@'; $(MKDIR_P) "$${stamp%/*}" - -man/%.xml: man/%.man man/asciidoc.conf man/$(dirstamp) - $(AM_V_GEN) @PATH_ASCIIDOC@ -d manpage -b docbook -f $(top_builddir)/man/asciidoc.conf -o $@ $< - -$(pod_MANS): man/%.1: % man/$(dirstamp) - $(AM_V_GEN) @PATH_POD2MAN@ --utf8 $< > $@ -else -asciidoc_MANS = -endif - -AM_CPPFLAGS = \ - -DSYSCONFDIR="\"$(sysconfdir)\"" \ - -I$(top_builddir)/parser \ - -I$(top_srcdir)/include \ - @AX_EXTEND_SRCDIR_CPPFLAGS@ - -i3_CFLAGS = \ - $(AM_CFLAGS) \ - $(libi3_CFLAGS) \ - $(LIBSN_CFLAGS) \ - $(XCB_CFLAGS) \ - $(XCB_UTIL_CURSOR_CFLAGS) \ - $(XCB_UTIL_KEYSYM_CFLAGS) \ - $(XCB_UTIL_WM_CFLAGS) \ - $(XCB_UTIL_XRM_CFLAGS) \ - $(XKBCOMMON_CFLAGS) \ - $(YAJL_CFLAGS) \ - $(LIBPCRE_CFLAGS) \ - $(PTHREAD_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) - -i3_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - $(CODE_COVERAGE_CPPFLAGS) - -i3_LDADD = \ - $(libi3_LIBS) \ - $(LIBSN_LIBS) \ - $(XCB_LIBS) \ - $(XCB_UTIL_CURSOR_LIBS) \ - $(XCB_UTIL_KEYSYMS_LIBS) \ - $(XCB_UTIL_WM_LIBS) \ - $(XCB_UTIL_XRM_LIBS) \ - $(XKBCOMMON_LIBS) \ - $(YAJL_LIBS) \ - $(LIBPCRE_LIBS) \ - $(PANGOCAIRO_LIBS) \ - $(PTHREAD_LIBS) \ - $(CODE_COVERAGE_LDFLAGS) - -libi3_CFLAGS = \ - $(AM_CFLAGS) \ - $(GLIBGOBJECT_CFLAGS) \ - $(XCB_CFLAGS) \ - $(XCB_UTIL_CFLAGS) \ - $(XCB_UTIL_XRM_CFLAGS) \ - $(YAJL_CFLAGS) \ - $(PANGOCAIRO_CFLAGS) - -libi3_LIBS = \ - $(top_builddir)/libi3.a \ - $(GLIBGOBJECT_LIBS) \ - $(XCB_LIBS) \ - $(XCB_UTIL_LIBS) \ - $(XCB_UTIL_XRM_LIBS) \ - $(YAJL_LIBS) \ - $(PANGOCAIRO_LIBS) - -libi3_a_CFLAGS = \ - $(libi3_CFLAGS) - -libi3_a_SOURCES = \ - include/libi3.h \ - libi3/dpi.c \ - libi3/draw_util.c \ - libi3/fake_configure_notify.c \ - libi3/font.c \ - libi3/format_placeholders.c \ - libi3/g_utf8_make_valid.c \ - libi3/get_colorpixel.c \ - libi3/get_config_path.c \ - libi3/get_exe_path.c \ - libi3/get_mod_mask.c \ - libi3/get_process_filename.c \ - libi3/get_visualtype.c \ - libi3/ipc_connect.c \ - libi3/ipc_recv_message.c \ - libi3/ipc_send_message.c \ - libi3/is_debug_build.c \ - libi3/mkdirp.c \ - libi3/resolve_tilde.c \ - libi3/root_atom_contents.c \ - libi3/safewrappers.c \ - libi3/string.c \ - libi3/strndup.c \ - libi3/ucs2_conversion.c - -i3_dump_log_i3_dump_log_CFLAGS = \ - $(AM_CFLAGS) \ - $(PTHREAD_CFLAGS) \ - $(libi3_CFLAGS) - -i3_dump_log_i3_dump_log_LDADD = \ - $(PTHREAD_LIBS) \ - $(libi3_LIBS) - -i3_dump_log_i3_dump_log_SOURCES = \ - i3-dump-log/main.c - -i3_input_i3_input_CFLAGS = \ - $(AM_CFLAGS) \ - $(libi3_CFLAGS) - -i3_input_i3_input_LDADD = \ - $(libi3_LIBS) \ - $(XCB_UTIL_KEYSYMS_LIBS) - -i3_input_i3_input_SOURCES = \ - i3-input/i3-input.h \ - i3-input/keysym2ucs.c \ - i3-input/keysym2ucs.h \ - i3-input/main.c - -i3_msg_i3_msg_CFLAGS = \ - $(AM_CFLAGS) \ - $(libi3_CFLAGS) - -i3_msg_i3_msg_LDADD = \ - $(libi3_LIBS) - -i3_msg_i3_msg_SOURCES = \ - i3-msg/main.c - -i3_nagbar_i3_nagbar_CFLAGS = \ - $(AM_CFLAGS) \ - $(LIBSN_CFLAGS) \ - $(libi3_CFLAGS) - -i3_nagbar_i3_nagbar_LDADD = \ - $(libi3_LIBS) \ - $(LIBSN_LIBS) \ - $(XCB_UTIL_CURSOR_LIBS) - -i3_nagbar_i3_nagbar_SOURCES = \ - i3-nagbar/atoms.xmacro \ - i3-nagbar/i3-nagbar.h \ - i3-nagbar/main.c - -i3bar_i3bar_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir)/i3bar/include - -i3bar_i3bar_CFLAGS = \ - $(AM_CFLAGS) \ - $(libi3_CFLAGS) \ - $(XCB_CFLAGS) \ - $(XKBCOMMON_CFLAGS) \ - $(PANGOCAIRO_CFLAGS) \ - $(YAJL_CFLAGS) - -i3bar_i3bar_LDADD = \ - $(libi3_LIBS) \ - $(XCB_LIBS) \ - $(XCB_UTIL_CURSOR_LIBS) \ - $(XKBCOMMON_LIBS) \ - $(PANGOCAIRO_LIBS) \ - $(YAJL_LIBS) - -i3bar_i3bar_SOURCES = \ - i3bar/include/child.h \ - i3bar/include/common.h \ - i3bar/include/configuration.h \ - i3bar/include/ipc.h \ - i3bar/include/mode.h \ - i3bar/include/outputs.h \ - i3bar/include/parse_json_header.h \ - i3bar/include/trayclients.h \ - i3bar/include/util.h \ - i3bar/include/workspaces.h \ - i3bar/include/xcb_atoms.def \ - i3bar/include/xcb.h \ - i3bar/src/child.c \ - i3bar/src/config.c \ - i3bar/src/ipc.c \ - i3bar/src/main.c \ - i3bar/src/mode.c \ - i3bar/src/outputs.c \ - i3bar/src/parse_json_header.c \ - i3bar/src/workspaces.c \ - i3bar/src/xcb.c - -i3_config_wizard_i3_config_wizard_CFLAGS = \ - $(AM_CFLAGS) \ - $(libi3_CFLAGS) \ - $(LIBSN_CFLAGS) \ - $(XKBCOMMON_CFLAGS) - -i3_config_wizard_i3_config_wizard_LDADD = \ - $(libi3_LIBS) \ - $(LIBSN_LIBS) \ - $(XCB_UTIL_KEYSYMS_LIBS) \ - $(XKBCOMMON_LIBS) - -i3_config_wizard_i3_config_wizard_SOURCES = \ - i3-config-wizard/atoms.xmacro \ - i3-config-wizard/main.c \ - i3-config-wizard/xcb.h - -i3_config_wizard_i3_config_wizard_DEPENDENCIES = \ - $(config_parser_SOURCES) - -test_inject_randr15_CPPFLAGS = \ - $(AM_CPPFLAGS) - -test_inject_randr15_CFLAGS = \ - $(AM_CFLAGS) \ - $(i3_CFLAGS) - -test_inject_randr15_SOURCES = \ - testcases/inject_randr1.5.c - -test_inject_randr15_LDADD = \ - $(i3_LDADD) - -test_commands_parser_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -DTEST_PARSER - -test_commands_parser_CFLAGS = \ - $(AM_CFLAGS) \ - $(i3_CFLAGS) - -test_commands_parser_SOURCES = \ - src/commands_parser.c - -test_commands_parser_LDADD = \ - $(i3_LDADD) - -test_config_parser_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -DTEST_PARSER - -test_config_parser_CFLAGS = \ - $(AM_CFLAGS) \ - $(i3_CFLAGS) - -test_config_parser_SOURCES = \ - src/config_parser.c - -test_config_parser_LDADD = \ - $(i3_LDADD) - -command_parser_SOURCES = \ - parser/GENERATED_command_enums.h \ - parser/GENERATED_command_tokens.h \ - parser/GENERATED_command_call.h - -config_parser_SOURCES = \ - parser/GENERATED_config_enums.h \ - parser/GENERATED_config_tokens.h \ - parser/GENERATED_config_call.h - -i3_SOURCES = \ - $(command_parser_SOURCES) \ - $(config_parser_SOURCES) \ - include/all.h \ - include/assignments.h \ - include/atoms_NET_SUPPORTED.xmacro \ - include/atoms_rest.xmacro \ - include/atoms.xmacro \ - include/bindings.h \ - include/click.h \ - include/cmdparse.h \ - include/commands.h \ - include/commands_parser.h \ - include/config_directives.h \ - include/configuration.h \ - include/config_parser.h \ - include/con.h \ - include/data.h \ - include/display_version.h \ - include/drag.h \ - include/ewmh.h \ - include/fake_outputs.h \ - include/floating.h \ - include/handlers.h \ - include/i3.h \ - include/ipc.h \ - include/key_press.h \ - include/load_layout.h \ - include/log.h \ - include/main.h \ - include/manage.h \ - include/match.h \ - include/move.h \ - include/output.h \ - include/queue.h \ - include/randr.h \ - include/regex.h \ - include/render.h \ - include/resize.h \ - include/restore_layout.h \ - include/scratchpad.h \ - include/sd-daemon.h \ - include/shmlog.h \ - include/sighandler.h \ - include/startup.h \ - include/sync.h \ - include/tree.h \ - include/util.h \ - include/window.h \ - include/workspace.h \ - include/xcb.h \ - include/xcursor.h \ - include/x.h \ - include/xinerama.h \ - include/yajl_utils.h \ - src/assignments.c \ - src/bindings.c \ - src/click.c \ - src/commands.c \ - src/commands_parser.c \ - src/con.c \ - src/config.c \ - src/config_directives.c \ - src/config_parser.c \ - src/display_version.c \ - src/drag.c \ - src/ewmh.c \ - src/fake_outputs.c \ - src/floating.c \ - src/handlers.c \ - src/ipc.c \ - src/key_press.c \ - src/load_layout.c \ - src/log.c \ - src/main.c \ - src/manage.c \ - src/match.c \ - src/move.c \ - src/output.c \ - src/randr.c \ - src/regex.c \ - src/render.c \ - src/resize.c \ - src/restore_layout.c \ - src/scratchpad.c \ - src/sd-daemon.c \ - src/sighandler.c \ - src/startup.c \ - src/sync.c \ - src/tree.c \ - src/util.c \ - src/version.c \ - src/window.c \ - src/workspace.c \ - src/x.c \ - src/xcb.c \ - src/xcursor.c \ - src/xinerama.c - -################################################################################ -# parser generation -################################################################################ - -$(command_parser_SOURCES): %.h: i3-command-parser.stamp - -$(config_parser_SOURCES): %.h: i3-config-parser.stamp - -src/i3-commands_parser.$(OBJEXT): i3-command-parser.stamp - -src/i3-config_parser.$(OBJEXT): i3-config-parser.stamp - -i3-command-parser.stamp: parser/$(dirstamp) generate-command-parser.pl parser-specs/commands.spec - $(AM_V_GEN) $(top_srcdir)/generate-command-parser.pl --input=$(top_srcdir)/parser-specs/commands.spec --prefix=command - $(AM_V_at) mv GENERATED_command_* $(top_builddir)/parser - $(AM_V_at) touch $@ - -i3-config-parser.stamp: parser/$(dirstamp) generate-command-parser.pl parser-specs/config.spec - $(AM_V_GEN) $(top_srcdir)/generate-command-parser.pl --input=$(top_srcdir)/parser-specs/config.spec --prefix=config - $(AM_V_at) mv GENERATED_config_* $(top_builddir)/parser - $(AM_V_at) touch $@ - -################################################################################ -# AnyEvent-I3 build process -################################################################################ - -anyevent-i3.stamp: AnyEvent-I3/lib/AnyEvent/I3.pm - $(AM_V_BUILD) (cd $(top_srcdir)/AnyEvent-I3 && perl Makefile.PL && make) - $(AM_V_at) touch $@ - -CLEANFILES = \ - i3-command-parser.stamp \ - i3-config-parser.stamp \ - anyevent-i3.stamp - -################################################################################ -# Language Server support -################################################################################ - -# Recursively run make through https://github.com/rizsotto/Bear, -# which generates a compile_commands.json file in the source directory. -# This is useful for running e.g. the clangd or ccls language servers: -# https://clang.llvm.org/extra/clangd/ -# https://github.com/MaskRay/ccls/wiki -.PHONY: bear -bear: clean - bear -o $(top_srcdir)/compile_commands.json $(MAKE) $(MAKEFLAGS) diff --git a/PACKAGE-MAINTAINER b/PACKAGE-MAINTAINER index 953fac5..c5a7bea 100644 --- a/PACKAGE-MAINTAINER +++ b/PACKAGE-MAINTAINER @@ -21,12 +21,14 @@ If your distribution has a mechanism to get the preferred terminal, such as the x-terminal-emulator symlink in Debian, please use it in i3-sensible-terminal. -On debian, compilation and installing the manpages looks like this: +You can build i3 like you build any other software package which uses +https://mesonbuild.com/; see +https://mesonbuild.com/Quick-guide.html#compiling-a-meson-project +In case you’re unfamiliar: - autoreconf -fi - mkdir -p build && cd build - ../configure - make -j8 install + $ mkdir -p build && cd build + $ meson .. + $ ninja Please make sure that i3-migrate-config-to-v4 and i3-config-wizard are installed with i3. The Perl script is necessary to (automatically) convert v3 @@ -35,10 +37,8 @@ start of i3 (it will automatically exit if it finds a config file). If you have any questions, ideas, hints, problems or whatever, please do not -hesitate to contact me. I will help you out. Just drop me an E-Mail (find the -address at https://michael.stapelberg.de/Impressum/, scroll down to bottom), -contact me using the same address in jabber or ask on our IRC channel: -(#i3 on irc.freenode.net). +hesitate to contact me. I will help you out. Please see +https://i3wm.org/contact/ Thanks again for your efforts, Michael diff --git a/README.md b/README.md index f8b3f06..d94d62c 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ ## How do I install i3-gaps? -Please refer to the [wiki](https://github.com/Airblader/i3/wiki). +Please refer to the [wiki](https://github.com/Airblader/i3/wiki/installation). ## Where can I get help? diff --git a/RELEASE-NOTES-4.18.1 b/RELEASE-NOTES-4.18.1 deleted file mode 100644 index c05180f..0000000 --- a/RELEASE-NOTES-4.18.1 +++ /dev/null @@ -1,32 +0,0 @@ - - ┌──────────────────────────────┐ - │ Release notes for i3 v4.18.1 │ - └──────────────────────────────┘ - -This is i3 v4.18.1. This version is considered stable. All users of i3 are -strongly encouraged to upgrade. - -This is a bugfix release for v4.18. - - ┌────────────────────────────┐ - │ Bugfixes │ - └────────────────────────────┘ - - • Move parent nodes in scratchpad correctly - • i3bar: Call cont_child() more liberally - • Fix load_layout crash when floating node doesn't have CT_FLOATING_CON parent - • Fix SEGFAULT when i3bar receives invalid input - • Revert "floating_reposition: avoid extra tree_render" - • Call tree_render if floating move changes workspace - • Update EWMH properties on workspace move - • cmd_focus_sibling: Fix crash on workspace level - - ┌────────────────────────────┐ - │ Thanks! │ - └────────────────────────────┘ - -Thanks for testing, bugfixes, discussions and everything I forgot go out to: - - Heman Gandhi, Orestis Floros - --- Michael Stapelberg, 2020-04-22 diff --git a/RELEASE-NOTES-4.19 b/RELEASE-NOTES-4.19 new file mode 100644 index 0000000..cd5bf2c --- /dev/null +++ b/RELEASE-NOTES-4.19 @@ -0,0 +1,81 @@ + + ┌──────────────────────────────┐ + │ Release notes for i3 v4.19 │ + └──────────────────────────────┘ + +This is i3 v4.19. This version is considered stable. All users of i3 are +strongly encouraged to upgrade. + +In this release, we switched from the autotools build system to the meson build +system (https://mesonbuild.com/). Check https://github.com/i3/i3/issues/4086 for +details. If this causes problems for you, you can revert the commit which +removed autotools from the tree: we tried our best to keep both build systems +working. Please reach out to us in that case! + + ┌────────────────────────────┐ + │ Changes in i3 v4.19 │ + └────────────────────────────┘ + + • userguide: explain button6 and button7 (scroll wheel right/left) + • ipc: always include the marks property (even if empty) + • ipc: introduce GET_BINDING_STATE command + • ipc: clarify workspace name field semantics + • ipc: document parse_error COMMAND reply field + • i3bar: launch using exec to avoid leaving useless shell process + • i3bar: make dock client order deterministic (sorted by class/instance) as a + side effect, i3bars without an explicit bar-id will be sorted according + to their definition order in the config file + • i3bar: update config when necessary (reduces redraws on bar mode changes) + • i3bar: add coordinates relative to the current output in i3bar click events + • i3bar: add “nonprimary” output option + • i3bar: set WM_CLASS instance to bar id + • i3-input: add different exit codes for when i3-input fails + • i3-dmenu-desktop: Support symlinks in search path + • pod2html: render without stylesheet by default + • introduce “tiling_from” and ”floating_from” criteria + • mention rofi in default config file + • allow ppt values in move direction and move position commands + • allow matching on empty properties like class, title, etc. + + ┌────────────────────────────┐ + │ Bugfixes │ + └────────────────────────────┘ + + • i3-nagbar: Use _PATH_BSHELL to ensure using a bourne shell + • i3bar: fix Xorg memory leak + • i3bar: fix hang when pausing/resuming bar program + • i3bar: fix crash on invalid JSON input + • i3bar: kick tray clients before destroying the bar + • ensure client windows have a size of at least 1px after resize + • correctly handle overlapping decorations + • limit workspace numbers within 0..INT32_MAX + • fix a bug with tiling resize inside floating container + • correctly handle mouse resize in fullscreen containers by + not propagating $mod+right click to fullscreen clients + • do not try to resize fullscreen and non-fullscreen windows + • do not focus floating windows changing workspace with ConfigureNotify + • set _NET_DESKTOP_VIEWPORT after randr changes + • fix a bug with i3-nagbar not starting after it has already started once + • fix conflict when moving parent of fullscreen window to workspace + • fix named workspace assignments on output changes + • fix named workspace assignment precedence on workspace renames + • fix windows getting swallowed more than once + • erase i3 --moreversion progress line before overwriting + • fix test case 180-fd-leaks when running on Fedora + • fix crash in `focus next sibling` + • fix moving tiling windows out of the scratchpad + • floating_maybe_reassign_ws: only re-focus if previously focused + (fixes a focus issue with KDE notifications) + • fix crash on invalid JSON input in stored layouts + • fix monitor change during/with i3 restart by moving + content for non-existing output containers + +Thanks for testing, bugfixes, discussions and everything I forgot go out to: + + 6144, acheronfail, Albert Safin, Alessandro Vinciguerra, Andrey Burov, + Francesc Hervada-Sala, Heman Gandhi, Ian Fan, Ingo Bürk, izzel, Jason, Jason + Nader, Jorg Heymans, Joseph, Konstantin Kharlamov, Lukas Kern, Mark Guptill, + Martin T. H. Sandsmark, Matthew Martin, Maxim Schuwalow, Mike Sharov, Orestis + Floros, Vasily Fomin, Wilhelm Schuster, xzfc, zero77 + +-- Michael Stapelberg, 2020-11-15 diff --git a/configure.ac b/configure.ac deleted file mode 100644 index fe34d6b..0000000 --- a/configure.ac +++ /dev/null @@ -1,202 +0,0 @@ -# -*- Autoconf -*- -# Run autoreconf -fi to generate a configure script from this file. - -AC_PREREQ([2.69]) -AC_INIT([i3], [4.18.1], [https://github.com/i3/i3/issues]) -# For AX_EXTEND_SRCDIR -AX_ENABLE_BUILDDIR -AM_INIT_AUTOMAKE([foreign subdir-objects -Wall no-dist-gzip dist-bzip2]) -# Default to silent rules, use V=1 to get verbose compilation output. -AM_SILENT_RULES([yes]) -# Make it possible to disable maintainer mode to disable re-generation of build -# system files. -AM_MAINTAINER_MODE([enable]) -AC_CONFIG_SRCDIR([libi3/ipc_recv_message.c]) -AC_CONFIG_HEADERS([config.h]) -AC_CONFIG_MACRO_DIR([m4]) - -dnl Verify macros defined in m4/ such as AX_SANITIZERS are not present in the -dnl output, i.e. are replaced as expected. This line results in a better error -dnl message when using aclocal < 1.13 (which does not understand -dnl AC_CONFIG_MACRO_DIR) without passing the -I m4 parameter. -m4_pattern_forbid([AX_SANITIZERS]) - -# Verify we are using GNU make because we use '%'-style pattern rules in -# Makefile.am, which are a GNU make extension. Pull requests to replace -# '%'-style pattern rules with a more portable alternative are welcome. -AX_CHECK_GNU_MAKE -AS_VAR_IF([_cv_gnu_make_command], [""], [AC_MSG_ERROR([the i3 Makefile.am requires GNU make])]) - -AX_EXTEND_SRCDIR - -AS_IF([test -e ${srcdir}/.git], - [ - VERSION="$(git -C ${srcdir} describe --tags --abbrev=0)" - I3_VERSION="$(git -C ${srcdir} describe --tags --always) ($(git -C ${srcdir} rev-list --format=%cd --date=short -n1 $(git rev-parse HEAD) | tail -n1), branch \\\"$(git -C ${srcdir} describe --tags --always --all | sed s:heads/::)\\\")" - # Mirrors what libi3/is_debug_build.c does: - is_release=$(test $(echo "${I3_VERSION}" | cut -d '(' -f 1 | wc -m) -lt 10 && echo yes || echo no) - ], - [ - VERSION="$(cut -d '-' -f 1 ${srcdir}/I3_VERSION | cut -d ' ' -f 1)" - I3_VERSION="$(sed -e 's/@<:@\"?\\@:>@/\\&/g' ${srcdir}/I3_VERSION)" - is_release="$(grep -q non-git ${srcdir}/I3_VERSION && echo no || echo yes)" - ]) -AC_SUBST([I3_VERSION], [$I3_VERSION]) -MAJOR_VERSION="$(echo ${VERSION} | cut -d '.' -f 1)" -MINOR_VERSION="$(echo ${VERSION} | cut -d '.' -f 2)" -PATCH_VERSION="$(echo ${VERSION} | cut -d '.' -f 3)" -AS_IF([test "x${PATCH_VERSION}" = x], [PATCH_VERSION=0]) -AC_DEFINE_UNQUOTED([I3_VERSION], ["${I3_VERSION}"], [i3 version]) -AC_DEFINE_UNQUOTED([MAJOR_VERSION], [${MAJOR_VERSION}], [i3 major version]) -AC_DEFINE_UNQUOTED([MINOR_VERSION], [${MINOR_VERSION}], [i3 minor version]) -AC_DEFINE_UNQUOTED([PATCH_VERSION], [${PATCH_VERSION}], [i3 patch version]) - -AX_CODE_COVERAGE - -dnl is_release must be lowercase because AX_CHECK_ENABLE_DEBUG calls m4_tolower -dnl on its fourth argument. -AX_CHECK_ENABLE_DEBUG([yes], , [UNUSED_NDEBUG], [$is_release]) - -AC_PROG_CC_C99 - -# For strnlen() and vasprintf(). -AC_USE_SYSTEM_EXTENSIONS - -# Checks for typedefs, structures, and compiler characteristics. -AC_CHECK_HEADER_STDBOOL -dnl The error message should include the specific type which could not be -dnl found, but I do not see a way to achieve that. -AC_CHECK_TYPES([mode_t, off_t, pid_t, size_t, ssize_t], , [AC_MSG_FAILURE([cannot find required type])]) - -# Checks for library functions. -AC_FUNC_FORK -AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK -AC_FUNC_STRNLEN -AC_CHECK_FUNCS([atexit dup2 ftruncate getcwd gettimeofday localtime_r memchr memset mkdir rmdir setlocale socket strcasecmp strchr strdup strerror strncasecmp strrchr strspn strstr strtol strtoul], , [AC_MSG_FAILURE([cannot find the $ac_func function, which i3 requires])]) -AC_REPLACE_FUNCS([mkdirp strndup]) - -# Checks for libraries. - -AC_SEARCH_LIBS([floor], [m], , [AC_MSG_FAILURE([cannot find the required floor() function despite trying to link with -lm])]) - -# libev does not ship with a pkg-config file :(. -AC_SEARCH_LIBS([ev_run], [ev], , [AC_MSG_FAILURE([cannot find the required ev_run() function despite trying to link with -lev])]) - -AC_SEARCH_LIBS([shm_open], [rt], [], [], [-pthread]) - -AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [iconv_open(0, 0)])], , - [LIBS="-liconv $LIBS" - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [iconv_open(0, 0)])], , - [AC_MSG_FAILURE([cannot find the required iconv_open() function despite trying to link with -liconv])])] -) - -AX_PTHREAD - -dnl Each prefix corresponds to a source tarball which users might have -dnl downloaded in a newer version and would like to overwrite. -PKG_CHECK_MODULES([LIBSN], [libstartup-notification-1.0]) -PKG_CHECK_MODULES([XCB], [xcb xcb-xkb xcb-xinerama xcb-randr xcb-shape]) -PKG_CHECK_MODULES([XCB_UTIL], [xcb-event xcb-util]) -PKG_CHECK_MODULES([XCB_UTIL_CURSOR], [xcb-cursor]) -PKG_CHECK_MODULES([XCB_UTIL_KEYSYMS], [xcb-keysyms]) -PKG_CHECK_MODULES([XCB_UTIL_WM], [xcb-icccm]) -PKG_CHECK_MODULES([XCB_UTIL_XRM], [xcb-xrm]) -PKG_CHECK_MODULES([XKBCOMMON], [xkbcommon xkbcommon-x11]) -PKG_CHECK_MODULES([YAJL], [yajl]) -PKG_CHECK_MODULES([LIBPCRE], [libpcre >= 8.10]) -PKG_CHECK_MODULES([PANGOCAIRO], [cairo >= 1.14.4 pangocairo]) -PKG_CHECK_MODULES([GLIBGOBJECT], [glib-2.0 gobject-2.0]) - -# Checks for programs. -AC_PROG_AWK -AC_PROG_CPP -AC_PROG_INSTALL -AC_PROG_MAKE_SET -AC_PROG_RANLIB -AC_PROG_LN_S - -AC_ARG_ENABLE(docs, - AS_HELP_STRING( - [--disable-docs], - [disable building documentation]), - [ax_docs=$enableval], - [ax_docs=yes]) -AC_ARG_ENABLE(mans, - AS_HELP_STRING( - [--disable-mans], - [disable building manual pages]), - [ax_mans=$enableval], - [ax_mans=yes]) -AS_IF([test x$ax_docs = xyes || test x$ax_mans = xyes], [ - AC_PATH_PROG([PATH_ASCIIDOC], [asciidoc]) -]) -AS_IF([test x$ax_mans = xyes], [ - AC_PATH_PROG([PATH_XMLTO], [xmlto]) - AC_PATH_PROG([PATH_POD2MAN], [pod2man]) -]) -AM_CONDITIONAL([BUILD_MANS], [test x$ax_mans = xyes && test x$PATH_ASCIIDOC != x && test x$PATH_XMLTO != x && test x$PATH_POD2MAN != x]) -AM_CONDITIONAL([BUILD_DOCS], [test x$ax_docs = xyes && test x$PATH_ASCIIDOC != x]) - -AM_PROG_AR - -AX_FLAGS_WARN_ALL -AX_CHECK_COMPILE_FLAG([-Wunused-value], [AX_APPEND_FLAG([-Wunused-value], [AM_CFLAGS])]) -AC_SUBST(AM_CFLAGS) - -# Checks for header files. -AC_CHECK_HEADERS([fcntl.h float.h inttypes.h limits.h locale.h netinet/in.h paths.h stddef.h stdint.h stdlib.h string.h sys/param.h sys/socket.h sys/time.h unistd.h], , [AC_MSG_FAILURE([cannot find the $ac_header header, which i3 requires])]) - -AC_CONFIG_FILES([Makefile testcases/lib/i3test.pm man/asciidoc.conf]) -AC_CONFIG_FILES([testcases/complete-run.pl], [chmod +x testcases/complete-run.pl]) - -# Enable address sanitizer for non-release builds. The performance hit is a -# 50% increase of wallclock time for the testsuite on my machine. -if test x$is_release = xyes; then - default_sanitizers= -else - default_sanitizers=address -fi -AX_SANITIZERS(, [$default_sanitizers], [AC_DEFINE([I3_ASAN_ENABLED], [], [Enable ASAN])]) - -AC_OUTPUT - -if test -z "${BUILD_DOCS_TRUE}"; then - print_BUILD_DOCS=yes -else - print_BUILD_DOCS=no -fi - - -if test -z "${BUILD_MANS_TRUE}"; then - print_BUILD_MANS=yes -else - print_BUILD_MANS=no -fi - -in_git_worktree=`git rev-parse --is-inside-work-tree 2>/dev/null` -if [[ "$in_git_worktree" = "true" ]]; then - git_dir=`git rev-parse --git-dir 2>/dev/null` - srcdir=`dirname "$git_dir"` - exclude_dir=`pwd | sed "s,^$srcdir,,g"` - if ! grep -q "^$exclude_dir" "$git_dir/info/exclude"; then - echo "$exclude_dir" >> "$git_dir/info/exclude" - fi -fi - -echo \ -"-------------------------------------------------------------------------------- -build configured: - -AS_HELP_STRING([i3 version:], [`echo ${I3_VERSION} | sed 's,\\\\,,g'`]) -AS_HELP_STRING([is release version:], [${is_release}]) - -AS_HELP_STRING([build manpages:], [${print_BUILD_MANS}]) -AS_HELP_STRING([build docs:], [${print_BUILD_DOCS}]) -AS_HELP_STRING([enable debug flags:], [${ax_enable_debug}]) -AS_HELP_STRING([code coverage:], [${CODE_COVERAGE_ENABLED}]) -AS_HELP_STRING([enabled sanitizers:], [${ax_enabled_sanitizers}]) - -To compile, run: - - cd `pwd` && make -j8 ---------------------------------------------------------------------------------" diff --git a/debian/changelog b/debian/changelog index 059fa32..c9df867 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,27 @@ +i3-wm (4.19.1-1) unstable; urgency=medium + + * New upstream release. + + -- Michael Stapelberg Mon, 19 Oct 2020 22:48:30 +0200 + +i3-wm (4.19-1) unstable; urgency=medium + + * New upstream release. + + -- Michael Stapelberg Sun, 15 Nov 2020 18:28:11 +0100 + +i3-wm (4.18.3-1) unstable; urgency=medium + + * New upstream release. + + -- Michael Stapelberg Mon, 19 Oct 2020 22:48:30 +0200 + +i3-wm (4.18.2-1) unstable; urgency=medium + + * New upstream release. + + -- Michael Stapelberg Sun, 26 Jul 2020 10:24:46 +0200 + i3-wm (4.18.1-1) unstable; urgency=medium * New upstream release. diff --git a/debian/compat b/debian/compat index ec63514..f599e28 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -9 +10 diff --git a/debian/control b/debian/control index 843e655..5cd27cd 100644 --- a/debian/control +++ b/debian/control @@ -2,8 +2,8 @@ Section: x11 Priority: extra Maintainer: Michael Stapelberg -Build-Depends: debhelper (>= 9), - dh-autoreconf, +Build-Depends: debhelper (>= 10), + meson, libx11-dev, libxcb-util0-dev (>= 0.3.8), libxcb-keysyms1-dev, diff --git a/debian/i3-wm.docs b/debian/i3-wm.docs deleted file mode 100644 index 437175b..0000000 --- a/debian/i3-wm.docs +++ /dev/null @@ -1,32 +0,0 @@ -docs/debugging.html -docs/hacking-howto.html -docs/i3bar-protocol.html -docs/userguide.html -docs/bigpicture.png -docs/single_terminal.png -docs/snapping.png -docs/two_columns.png -docs/two_terminals.png -docs/modes.png -docs/ipc.html -docs/multi-monitor.html -docs/wsbar.html -docs/wsbar.png -docs/keyboard-layer1.png -docs/keyboard-layer2.png -docs/testsuite.html -docs/i3-sync-working.png -docs/i3-sync.png -docs/tree-layout1.png -docs/tree-layout2.png -docs/tree-shot1.png -docs/tree-shot2.png -docs/tree-shot3.png -docs/tree-shot4.png -docs/refcard.html -docs/refcard_style.css -docs/logo-30.png -docs/lib-i3test.html -docs/lib-i3test-test.html -docs/layout-saving.html -docs/layout-saving-1.png diff --git a/debian/i3-wm.manpages b/debian/i3-wm.manpages deleted file mode 100644 index 1953b6a..0000000 --- a/debian/i3-wm.manpages +++ /dev/null @@ -1,13 +0,0 @@ -man/i3.1 -man/i3-msg.1 -man/i3-input.1 -man/i3-nagbar.1 -man/i3-config-wizard.1 -man/i3-dump-log.1 -man/i3-migrate-config-to-v4.1 -man/i3-sensible-pager.1 -man/i3-sensible-editor.1 -man/i3-sensible-terminal.1 -man/i3-dmenu-desktop.1 -man/i3-save-tree.1 -man/i3bar.1 diff --git a/debian/rules b/debian/rules index d5c3068..26e303e 100755 --- a/debian/rules +++ b/debian/rules @@ -14,12 +14,12 @@ # TODO: enable tests override_dh_auto_configure: - # The default is /usr/share/doc/i3 - dh_auto_configure -- --docdir=/usr/share/doc/i3-wm + # Set -Ddocdir; the default is /usr/share/doc/i3 + dh_auto_configure -- -Ddocdir=/usr/share/doc/i3-wm -Dmans=true override_dh_builddeb: # bintray does not support xz currently. dh_builddeb -- -Zgzip %: - dh $@ --parallel --builddirectory=build --with=autoreconf + dh $@ --buildsystem=meson diff --git a/docs/bigpicture.asy b/docs/bigpicture.asy new file mode 100644 index 0000000..4b3656c --- /dev/null +++ b/docs/bigpicture.asy @@ -0,0 +1,19 @@ +import drawtree; +treeLevelStep = 2cm; +TreeNode n94457831379296 = makeNode("``root'' (splith) []"); +TreeNode n94457831380944 = makeNode(n94457831379296, "``\_\_i3'' (output) []"); +TreeNode n94457831384048 = makeNode(n94457831380944, "``content'' (splith) []"); +TreeNode n94457831387184 = makeNode(n94457831384048, "``\_\_i3\_scratch'' (splith) []"); +TreeNode n94457831390576 = makeNode(n94457831379296, "``eDP-1'' (output) []"); +TreeNode n94457831393744 = makeNode(n94457831390576, "``topdock'' (dockarea) []"); +TreeNode n94457831396992 = makeNode(n94457831390576, "``content'' (splith) []"); +TreeNode n94457831628304 = makeNode(n94457831396992, "``1'' (splith) []"); +TreeNode n94457831571040 = makeNode(n94457831628304, "``Hacking i3: How To - Mozilla Firefox'' (leaf) []"); +TreeNode n94457831246384 = makeNode(n94457831628304, "``vim'' (leaf) []"); +TreeNode n94457831461088 = makeNode(n94457831396992, "``Named workspace'' (splith) []"); +TreeNode n94457831471424 = makeNode(n94457831461088, "``[Empty]'' (tabbed) []"); +TreeNode n94457831570576 = makeNode(n94457831471424, "``contrib/dump-asy.pl --no-gv'' (leaf) [Marks go here]"); +TreeNode n94457831645488 = makeNode(n94457831471424, "``ipython'' (leaf) []"); +TreeNode n94457831400192 = makeNode(n94457831390576, "``bottomdock'' (dockarea) []"); +TreeNode n94457831424848 = makeNode(n94457831400192, "``i3bar for output eDP-1'' (leaf) []"); +draw(n94457831379296, (0, 0)); diff --git a/docs/bigpicture.png b/docs/bigpicture.png index fc3c8db..031673b 100644 Binary files a/docs/bigpicture.png and b/docs/bigpicture.png differ diff --git a/docs/bigpicture.xcf b/docs/bigpicture.xcf deleted file mode 100644 index ead0071..0000000 Binary files a/docs/bigpicture.xcf and /dev/null differ diff --git a/docs/hacking-howto b/docs/hacking-howto index 2ca44a5..cc08cd1 100644 --- a/docs/hacking-howto +++ b/docs/hacking-howto @@ -8,83 +8,82 @@ you understand why things are like they are. If it does not mention something you find necessary, please do not hesitate to contact me. +++++ +
+WARNING! +

+++++ +This document is not 100% up to date. Specifically, everything up to and +including <> has been updated recently. The rest might contain +outdated information. +++++ +

+
+++++ + == Building i3 -You can build i3 like you build any other software package which uses autotools. -Here’s a memory refresher: - - $ autoreconf -fi +You can build i3 like you build any other software package which uses +https://mesonbuild.com/[The Meson Build system]; see +https://mesonbuild.com/Quick-guide.html#compiling-a-meson-project[Quickstart +Guide → Compiling a Meson project]. In case you’re unfamiliar: + $ mkdir -p build && cd build - $ ../configure - $ make -j8 - -(The autoreconf -fi step is unnecessary if you are building from a release tarball, - but shouldn’t hurt either.) + $ meson .. + $ ninja === Build system features -* We use the AX_ENABLE_BUILDDIR macro to enforce builds happening in a separate - directory. This is a prerequisite for the AX_EXTEND_SRCDIR macro and building +* We use the +AX_ENABLE_BUILDDIR+ macro to enforce builds happening in a separate + directory. This is a prerequisite for the +AX_EXTEND_SRCDIR+ macro and building in a separate directory is common practice anyway. In case this causes any trouble when packaging i3 for your distribution, please open an issue. -* “make check” runs the i3 testsuite. See docs/testsuite for details. - -* “make distcheck” (runs testsuite on “make dist” result, tiny bit quicker +* +make check+ runs the i3 testsuite. See docs/testsuite for details. + +* +make distcheck+ (runs testsuite on +make dist+ result, tiny bit quicker feedback cycle than waiting for the travis build to catch the issue). -* “make uninstall” (occasionally requested by users who compile from source) - -* “make” will build manpages/docs by default if the tools are installed. +* +make uninstall+ (occasionally requested by users who compile from source) + +* +make+ will build manpages/docs by default if the tools are installed. Conversely, manpages/docs are not tried to be built for users who don’t want - to install all these dependencies to get started hacking on i3. + to install all these dependencies to get started hacking on i3. Manpages and + docs can be disabled with the +--disable-mans++ and ++--disable-docs++ + configure options respectively. * non-release builds will enable address sanitizer by default. Use the - --disable-sanitizers configure option to turn off all sanitizers, and see - --help for available sanitizers. - -* Support for pre-compiled headers (PCH) has been dropped for now in the - interest of simplicity. If you need support for PCH, please open an issue. - -* Coverage reports are now generated using “make check-code-coverage”, which - requires specifying --enable-code-coverage when calling configure. - -== Using git / sending patches - -For a short introduction into using git, see -https://web.archive.org/web/20121024222556/http://www.spheredev.org/wiki/Git_for_the_lazy -or, for more documentation, see https://git-scm.com/documentation + +--disable-sanitizers+ configure option to turn off all sanitizers, and see + +--help+ for available sanitizers. + +* Coverage reports are now generated using +make check-code-coverage+, which + requires specifying +--enable-code-coverage+ when calling configure. + +== Pull requests Please talk to us before working on new features to see whether they will be accepted. A good way for this is to open an issue and asking for opinions on it. -Even for accepted features, this can be a good way to refine an idea upfront. However, -we don't want to see certain features in i3, e.g., switching window focus in an -Alt+Tab like way. - -When working on bugfixes, please make sure you mention that you are working on -it in the corresponding bug report at https://github.com/i3/i3/issues. In case -there is no bug report yet, please create one. +Even for accepted features, this can be a good way to refine an idea upfront. +However, we don't want to see certain features in i3, e.g., switching window +focus in an Alt+Tab like way. + +When working on bugfixes, please make sure you mention that you are working on it +in the corresponding bug report at https://github.com/i3/i3/issues. In case there +is no bug report yet, please create one. After you are done, please submit your work for review as a pull request at -https://github.com/i3/i3. - -Do not send emails to the mailing list or any author directly, and don’t submit -them in the bugtracker, since all reviews should be done in public at -https://github.com/i3/i3. In order to make your review go as fast as possible, you -could have a look at previous reviews and see what the common mistakes are. +https://github.com/i3/i3. In order to make your review go as fast as possible, +you could have a look at previous reviews and see what the common mistakes are. === Which branch to use? -Work on i3 generally happens in two branches: “master” and “next” (the latter -being the default branch, the one that people get when they check out the git -repository). - -The contents of “master” are always stable. That is, it contains the source code +Work on i3 generally happens in two branches: “next” (default) and “stable”. + +The contents of “stable” are always stable. That is, it contains the source code of the latest release, plus any bugfixes that were applied since that release. -New features are only found in the “next” branch. Therefore, if you are working -on a new feature, use the “next” branch. If you are working on a bugfix, use the -“next” branch, too, but make sure your code also works on “master”. +New features are only found in the “next” branch. Always use this branch when +writing new code (both bugfixes and features). == Window Managers @@ -106,9 +105,9 @@ the first client of X) and manage them (reparent them, create window decorations, etc.) . When new windows are created, manage them -. Handle the client’s `_WM_STATE` property, but only `_WM_STATE_FULLSCREEN` and - `_NET_WM_STATE_DEMANDS_ATTENTION` -. Handle the client’s `WM_NAME` property +. Handle the client’s +_WM_STATE+ property, but only +_WM_STATE_FULLSCREEN+ and + +_NET_WM_STATE_DEMANDS_ATTENTION+ +. Handle the client’s +WM_NAME+ property . Handle the client’s size hints to display them proportionally . Handle the client’s urgency hint . Handle enter notifications (focus follows mouse) @@ -123,11 +122,11 @@ === Tiling window managers -Traditionally, there are two approaches to managing windows: The most common -one nowadays is floating, which means the user can freely move/resize the -windows. The other approach is called tiling, which means that your window -manager distributes windows to use as much space as possible while not -overlapping each other. +Traditionally, there are two approaches to managing windows: The most common one +nowadays is stacking (or floating, using i3's terminology), which means the user +can freely move/resize the windows, potentially overlapping them. The other +approach is called tiling, which means that the window manager distributes +windows to use as much space as possible while not overlapping each other. The idea behind tiling is that you should not need to waste your time moving/resizing windows while you usually want to get some work done. After @@ -161,63 +160,67 @@ == Files -include/atoms.xmacro:: -A file containing all X11 atoms which i3 uses. This file will be included -various times (for defining, requesting and receiving the atoms), each time -with a different definition of xmacro(). +i3's source code is in the +src+ folder while header files reside in +include+. +Other tools such as i3bar and i3-nagbar have their own folders. i3 and its tools +share an internal library called ``libi3'' which also has its own folder. + +The following list gives an overview of the codebase, explaining the +functionality of the most important, core source code files. Other files in the +tree that are not mentioned here implement specific functionalities: for example, ++src/scratchpad.c+ is obviously about the scratchpad functionality. include/data.h:: -Contains data definitions used by nearly all files. You really need to read -this first. +Contains data definitions used by nearly all files. include/*.h:: Contains forward definitions for all public functions, as well as doxygen-compatible comments (so if you want to get a bit more of the big picture, either browse all header files or use doxygen if you prefer that). -src/config_parser.c:: -Contains a custom configuration parser. See src/command_parser.c for rationale - on why we use a custom parser. - -src/click.c:: -Contains all functions which handle mouse button clicks (right mouse button -clicks initiate resizing and thus are relatively complex). - -src/command_parser.c:: -Contains a hand-written parser to parse commands (commands are what -you bind on keys and what you can send to i3 using the IPC interface, like -'move left' or 'workspace 4'). +src/config_directives.c:: +src/commands.c:: +Contain the definitions for all high-level config and command directives. These +are excellent places to start with a top-to-bottom approach to understand +specific i3 behavior. For example, if you want to investigate a bug that happens +for the +move to mark+ command, you can use gdb to pause in ++cmd_move_con_to_mark+ and then work your way from there, stepping into +lower-level functions. src/con.c:: -Contains all functions which deal with containers directly (creating -containers, searching containers, getting specific properties from containers, -…). - -src/config.c:: -Contains all functions handling the configuration file (calling the parser -src/config_parser.c) with the correct path, switching key bindings mode). - -src/ewmh.c:: -Functions to get/set certain EWMH properties easily. - -src/floating.c:: -Contains functions for floating mode (mostly resizing/dragging). +Contains all functions which deal with containers directly (creating containers, +searching containers, getting specific properties from containers, …). Contains +abstractions and auxiliary functions necessary to work with the container +structure which is used in almost all parts of the codebase. + +src/tree.c:: +Contains functions which deal with the tree abstraction. However, be aware that ++src/con.c+ also contains functions that heavily interact with the tree +structure. Some functions that are included in +str/tree.c+ are those that handle +opening and closing containers in the tree, finding the container that should be +focused next and flattening the tree. See also +src/move.c+ for other +move-specific functions that interact with the tree, which were moved into their +own file because they are so long. + +src/workspace.c:: +Contains functions which deal with workspaces. Includes code that creates new +workspaces, shows existing ones and deals with workspace assignments. src/handlers.c:: Contains all handlers for all kinds of X events (new window title, new hints, -unmapping, key presses, button presses, …). - -src/ipc.c:: -Contains code for the IPC interface. - -src/load_layout.c:: -Contains code for loading layouts from JSON files. - -src/log.c:: -Contains the logging functions. - -src/main.c:: -Initializes the window manager. +unmapping, key presses, button presses, …). This is a very important file to +understand how i3 interacts with changes to its environment. + +src/command_parser.c:: +src/config_parser.c:: +Contain a hand-written parser to parse commands and configuration (commands are what +you bind on keys and what you can send to i3 using the IPC interface, like ++move left+ or +workspace 4+). +src/config.c+ is responsible for calling the +configuration parser. + +src/click.c:: +src/resize.c:: +Contain functions which handle mouse button clicks (right mouse button +clicks initiate resizing and thus are relatively complex). src/manage.c:: Looks at existing or new windows and decides whether to manage them. If so, it @@ -226,93 +229,66 @@ src/match.c:: A "match" is a data structure which acts like a mask or expression to match certain windows or not. For example, when using commands, you can specify a -command like this: [title="*Firefox*"] kill. The title member of the match +command like this: +[title="*Firefox*"] kill+. The title member of the match data structure will then be filled and i3 will check each window using -match_matches_window() to find the windows affected by this command. - -src/move.c:: -Contains code to move a container in a specific direction. - -src/output.c:: -Functions to handle CT_OUTPUT cons. ++match_matches_window()+ to find the windows affected by this command. src/randr.c:: The RandR API is used to get (and re-query) the configured outputs (monitors, -…). +…). Legacy Xinerama support resides in +src/xinerama.c+. src/render.c:: Renders the tree data structure by assigning coordinates to every node. These values will later be pushed to X11 in +src/x.c+. -src/resize.c:: -Contains the functions to resize containers. - -src/restore_layout.c:: -Everything for restored containers that is not pure state parsing (which can be -found in load_layout.c). - src/sighandler.c:: Handles +SIGSEGV+, +SIGABRT+ and +SIGFPE+ by showing a dialog that i3 crashed. -You can chose to let it dump core, to restart it in-place or to restart it -in-place but forget about the layout. - -src/tree.c:: -Contains functions which open or close containers in the tree, change focus or -cleanup ("flatten") the tree. See also +src/move.c+ for another similar -function, which was moved into its own file because it is so long. - -src/util.c:: -Contains useful functions which are not really dependent on anything. +You can choose to let it dump core and restart i3 in-place (either trying to +preserve layout or forget about it). src/window.c:: Handlers to update X11 window properties like +WM_CLASS+, +_NET_WM_NAME+, +CLIENT_LEADER+, etc. -src/workspace.c:: -Contains all functions related to workspaces (displaying, hiding, renaming…) - -src/x.c:: -Transfers our in-memory tree (see +src/render.c+) to X11. - -src/xcb.c:: -Contains wrappers to use xcb more easily. - -src/xcursor.c:: -XCursor functions (for cursor themes). - -src/xinerama.c:: -Legacy support for Xinerama. See +src/randr.c+ for the preferred API. - +include/*.xmacro.*:: +A file containing all X11 atoms which i3 uses. This file will be included +various times (for defining, requesting and receiving the atoms), each time +with a different definition of xmacro(). + +[[data_structures]] == Data structures - -See include/data.h for documented data structures. The most important ones are -explained right here. - -///////////////////////////////////////////////////////////////////////////////// -// TODO: update image - -image:bigpicture.png[The Big Picture] - -///////////////////////////////////////////////////////////////////////////////// - -So, the hierarchy is: - -. *X11 root window*, the root container -. *Output container* (LVDS1 in this example) -. *Content container* (there are also containers for dock windows) -. *Workspaces* (Workspace 1 in this example, with horizontal orientation) -. *Split container* (vertically split) -. *X11 window containers* +See +include/data.h+ for documented data structures. The most important ones are +explained here. + +The following picture is generated by the +contrib/dump-asy.pl+ script. + +image:bigpicture.png["The Big Picture",width=1000,link="bigpicture.png"] + +The hierarchy is: + +. *Root container* +. *Output containers*: +eDP-1+ in this example and the internal +__i3++ output +. *Content and 2 dockarea containers* +. *Workspaces*: Numbered workspace ``1'' and a ``Named workspace'' +. *Split containers*: One horizontal in the first workspace and a tabbed one in + the named one. +. *Leaf containers*: Windows like vim and an i3bar dock. The data type is +Con+, in all cases. -=== X11 root window - -The X11 root window is a single window per X11 display (a display is identified -by +:0+ or +:1+ etc.). The root window is what you draw your background image -on. It spans all the available outputs, e.g. +VGA1+ is a specific part of the -root window and +LVDS1+ is a specific part of the root window. +=== Root container + +The root container (global variable +croot+) is the up-most ascendant of every i3 +container. It can be used to iterate over the whole tree structure. E.g., it is +used to reply to the +GET_WORKSPACES+ request, iterating over it's children to +find all workspaces. This is different from the X11 root window. + +The X11 root window (global variable +root+) is a single window per X11 display +(a display is identified by +:0+ or +:1+ etc.). The root window is what you draw +your background image on. It spans all the available outputs, e.g. +VGA1+ is a +specific part of the root window and +LVDS1+ is a specific part of the root +window. === Output container @@ -334,8 +310,8 @@ === Content container Each output has multiple children. Two of them are dock containers which hold -dock clients. The other one is the content container, which holds the actual -content (workspaces) of this output. +the top and bottom dock clients. The other one is the content container, which +holds the actual content (workspaces) of this output. === Workspace @@ -354,21 +330,20 @@ Split containers (and X11 window containers, which are a subtype of split containers) can have different border styles. -=== X11 window container - -An X11 window container holds exactly one X11 window. These are the leaf nodes -of the layout tree, they cannot have any children. +=== Leaf containers + +A leaf container holds exactly one X11 window. They can't have any children. == List/queue macros i3 makes heavy use of the list macros defined in BSD operating systems. To ensure that the operating system on which i3 is compiled has all the expected -features, i3 comes with `include/queue.h`. On BSD systems, you can use man -`queue(3)`. On Linux, you have to use google (or read the source). +features, i3 comes with +include/queue.h+. On BSD systems, you can use +man +queue(3)+. On Linux, you have to use google (or read the source). The lists used are +SLIST+ (single linked lists), +CIRCLEQ+ (circular queues) and +TAILQ+ (tail queues). Usually, only forward traversal is necessary, -so an `SLIST` works fine. If inserting elements at arbitrary positions or at +so an +SLIST+ works fine. If inserting elements at arbitrary positions or at the end of a list is necessary, a +TAILQ+ is used instead. However, for the windows inside a container, a +CIRCLEQ+ is necessary to go from the currently selected window to the window above/below. @@ -378,10 +353,10 @@ There is a row of standard variables used in many events. The following names should be chosen for those: - * ``conn'' is the xcb_connection_t - * ``event'' is the event of the particular type - * ``con'' names a container - * ``current'' is a loop variable when using +TAILQ_FOREACH+ etc. + * +conn+ is the xcb_connection_t + * +event+ is the event of the particular type + * +con+ names a container + * +current+ is a loop variable when using +TAILQ_FOREACH+ etc. == Startup (src/mainx.c, main()) @@ -430,7 +405,7 @@ == Manage windows (src/main.c, manage_window() and reparent_window()) -`manage_window()` does some checks to decide whether the window should be ++manage_window()+ does some checks to decide whether the window should be managed at all: * Windows have to be mapped, that is, visible on screen @@ -438,18 +413,18 @@ not be managed by a window manager Afterwards, i3 gets the initial geometry and reparents the window (see -`reparent_window()`) if it wasn’t already managed. ++reparent_window()+) if it wasn’t already managed. Reparenting means that for each window which is reparented, a new window, slightly larger than the original one, is created. The original window is then reparented to the bigger one (called "frame"). -After reparenting, the window type (`_NET_WM_WINDOW_TYPE`) is checked to see -whether this window is a dock (`_NET_WM_WINDOW_TYPE_DOCK`), like dzen2 for +After reparenting, the window type (+_NET_WM_WINDOW_TYPE+) is checked to see +whether this window is a dock (+_NET_WM_WINDOW_TYPE_DOCK+), like dzen2 for example. Docks are handled differently, they don’t have decorations and are not assigned to a specific container. Instead, they are positioned at the bottom or top of the screen (in the appropriate dock area containers). To get the -height which needs to be reserved for the window, the `_NET_WM_STRUT_PARTIAL` +height which needs to be reserved for the window, the +_NET_WM_STRUT_PARTIAL+ property is used. Furthermore, the list of assignments (to other workspaces, which may be on @@ -460,10 +435,10 @@ == What happens when an application is started? i3 does not care about applications. All it notices is when new windows are -mapped (see `src/handlers.c`, `handle_map_request()`). The window is then +mapped (see +src/handlers.c+, +handle_map_request()+). The window is then reparented (see section "Manage windows"). -After reparenting the window, `render_tree()` is called which renders the +After reparenting the window, +render_tree()+ is called which renders the internal layout table. The new window has been placed in the currently focused container and therefore the new window and the old windows (if any) need to be moved/resized so that the currently active layout (default/stacking/tabbed mode) @@ -482,7 +457,7 @@ Only the _NET_WM_STATE_FULLSCREEN and _NET_WM_STATE_DEMANDS_ATTENTION atoms are handled. -The former calls ``toggle_fullscreen()'' for the specific client which just +The former calls +toggle_fullscreen()+ for the specific client which just configures the client to use the whole screen on which it currently is. Also, it is set as fullscreen_client for the i3Screen. @@ -539,7 +514,7 @@ === Rendering the root container -The i3 root container (`con->type == CT_ROOT`) represents the X11 root window. +The i3 root container (+con->type == CT_ROOT+) represents the X11 root window. It contains one child container for every output (like LVDS1, VGA1, …), which is available on your computer. @@ -558,7 +533,7 @@ === Rendering an output -Output containers (`con->layout == L_OUTPUT`) represent a hardware output like +Output containers (+con->layout == L_OUTPUT+) represent a hardware output like LVDS1, VGA1, etc. An output container has three children (at the moment): One content container (having workspaces as children) and the top/bottom dock area containers. @@ -566,7 +541,7 @@ The rendering happens in the function +render_l_output()+ in the following steps: -1. Find the content container (`con->type == CT_CON`) +1. Find the content container (+con->type == CT_CON+) 2. Get the currently visible workspace (+con_get_fullscreen_con(content, CF_OUTPUT)+). 3. If there is a fullscreened window on that workspace, directly render it and @@ -574,22 +549,22 @@ 4. Sum up the space used by all the dock windows (they have a variable height only). 5. Set the workspace rects (x/y/width/height) based on the position of the - output (stored in `con->rect`) and the usable space - (`con->rect.{width,height}` without the space used for dock windows). + output (stored in +con->rect+) and the usable space + (+con->rect.{width,height}+ without the space used for dock windows). 6. Recursively raise and render the output’s child containers (meaning dock area containers and the content container). === Rendering a workspace or split container From here on, there really is no difference anymore. All containers are of -`con->type == CT_CON` (whether workspace or split container) and some of them -have a `con->window`, meaning they represent an actual window instead of a ++con->type == CT_CON+ (whether workspace or split container) and some of them +have a +con->window+, meaning they represent an actual window instead of a split container. ==== Default layout In default layout, containers are placed horizontally or vertically next to -each other (depending on the `con->orientation`). If a child is a leaf node (as +each other (depending on the +con->orientation+). If a child is a leaf node (as opposed to a split container) and has border style "normal", appropriate space will be reserved for its window decoration. @@ -835,8 +810,8 @@ the beginning. + NOTE: Note that you can specify multiple literals in the same line. This has - exactly the same effect as if you specified `direction = - 'next_on_output' -> call cmd_workspace($direction)` and so forth. + + exactly the same effect as if you specified +direction = + 'next_on_output' -> call cmd_workspace($direction)+ and so forth. + NOTE: Also note that the order of literals is important here: If 'next' were ordered before 'next_on_output', then 'next_on_output' would never @@ -1020,11 +995,11 @@ == Gotchas -* Forgetting to call `xcb_flush(conn);` after sending a request. This usually +* Forgetting to call +xcb_flush(conn);+ after sending a request. This usually leads to code which looks like it works fine but which does not work under certain conditions. -* Forgetting to call `floating_fix_coordinates(con, old_rect, new_rect)` after +* Forgetting to call +floating_fix_coordinates(con, old_rect, new_rect)+ after moving workspaces across outputs. Coordinates for floating containers are not relative to workspace boundaries, so you must correct their coordinates or those containers will show up in the wrong workspace or not at all. diff --git a/docs/i3bar-protocol b/docs/i3bar-protocol index cadcd8a..c1bf8f8 100644 --- a/docs/i3bar-protocol +++ b/docs/i3bar-protocol @@ -103,9 +103,11 @@ version:: The version number (as an integer) of the i3bar protocol you will use. stop_signal:: - Specify to i3bar the signal (as an integer) to send to stop your - processing. - The default value (if none is specified) is SIGSTOP. + Specify the signal (as an integer) that i3bar should send to request that you + pause your output. This is used to conserve battery power when the bar is + hidden by not unnecessarily computing bar updates. The default value is SIGSTOP, + which will unconditionally stop your process. If this is an issue, this feature + can be disabled by setting the value to 0. cont_signal:: Specify to i3bar the signal (as an integer) to send to continue your processing. @@ -258,6 +260,8 @@ relative_x, relative_y:: Coordinates where the click occurred, with respect to the top left corner of the block +output_x, output_y:: + Coordinates relative to the current output where the click occurred width, height:: Width and height (in px) of the block modifiers:: @@ -271,10 +275,12 @@ "instance": "eth0", "button": 1, "modifiers": ["Shift", "Mod1"], - "x": 1320, + "x": 1925, "y": 1400, "relative_x": 12, "relative_y": 8, + "output_x": 5, + "output_y": 1400, "width": 50, "height": 22 } diff --git a/docs/ipc b/docs/ipc index 5bc40e2..bb8719c 100644 --- a/docs/ipc +++ b/docs/ipc @@ -1,7 +1,7 @@ IPC interface (interprocess communication) ========================================== Michael Stapelberg -September 2017 +June 2020 This document describes how to interface with i3 from a separate process. This is useful for example to remote-control i3 (to write test cases for example) or @@ -66,6 +66,7 @@ | 9 | +GET_CONFIG+ | <<_config_reply,CONFIG>> | Returns the last loaded i3 config. | 10 | +SEND_TICK+ | <<_tick_reply,TICK>> | Sends a tick event with the specified payload. | 11 | +SYNC+ | <<_sync_reply,SYNC>> | Sends an i3 sync event with the specified random value to the specified window. +| 12 | +GET_BINDING_STATE+ | <<_binding_state_reply,BINDING_STATE>> | Request the current binding state, i.e. the currently active binding mode name. |====================================================== So, a typical message could look like this: @@ -131,6 +132,8 @@ Reply to the GET_CONFIG message. TICK (10):: Reply to the SEND_TICK message. +GET_BINDING_STATE (12):: + Reply to the GET_BINDING_STATE message. [[_command_reply]] === COMMAND reply @@ -156,6 +159,14 @@ *Example:* ------------------- [{ "success": true }] +------------------- + +When the specified command cannot be parsed, `success` will be false and +`parse_error` will be true: + +*Example:* +------------------- +[{ "success": false, "parse_error": true }] ------------------- [[_workspaces_reply]] @@ -172,8 +183,8 @@ The logical number of the workspace. Corresponds to the command to switch to this workspace. For named workspaces, this will be -1. name (string):: - The name of this workspace (by default num+1), as changed by the - user. Encoded in UTF-8. + The name of this workspace if changed by the user, otherwise defaults + to the string representation of the +num+ field). Encoded in UTF-8. visible (boolean):: Whether this workspace is currently visible on an output (multiple workspaces can be visible at the same time). @@ -709,6 +720,17 @@ { "success": true } ------------------- +[[_binding_state_reply]] +=== GET_BINDING_STATE reply + +The binding_state reply is a map which currently only contains the "name" +member, which is the name of the currently active binding mode as a string. + +*Example:* +------------------- +{ "name": "default" } +------------------- + == Events [[events]] diff --git a/docs/refcard.html b/docs/refcard.html index 6d71c98..0e3a412 100644 --- a/docs/refcard.html +++ b/docs/refcard.html @@ -15,7 +15,7 @@ h1 { font-size: 1.1em; } header a { font-size: 0.7em; } header p { margin: 5px 0; font-size: 0.8em; text-align: left; } - kbd { font-family: LinuxBiolinumKeyboard, Linux Biolinum Keyboard O, Linux Biolinum Keyboard, DejaVu Sans Mono, monospace; font-size: 0.9em; } + kbd { font-family: LinuxBiolinumKeyboard, Linux Biolinum Keyboard O, Linux Biolinum Keyboard, DejaVu Sans Mono, monospace; font-size: 1.2em; } code { font-family: DejaVu Sans Mono, monospace; font-size: 0.8em; } section { break-inside: avoid-column; -moz-break-inside: -moz-avoid-column; -webkit-break-inside: avoid-column; } h2 { margin: 7px 0 2px; padding: 2px 4px; font-size: 1.1em; font-family: LinuxBiolinum, Linux Biolinum O, Linux Biolinum, sans; background-color: #b3b3b3; } diff --git a/docs/testsuite b/docs/testsuite index b535e7c..145da15 100644 --- a/docs/testsuite +++ b/docs/testsuite @@ -120,13 +120,11 @@ --------------------------------------- $ cd ~/i3 -$ autoreconf -fi - $ mkdir -p build && cd build -$ ../configure - -$ make -j8 +$ meson .. + +$ ninja # output omitted because it is very long $ cd testcases @@ -183,13 +181,11 @@ --------------------------------------- $ cd ~/i3 -$ autoreconf -fi - $ mkdir -p build && cd build -$ ../configure - -$ make -j8 +$ meson .. + +$ ninja # output omitted because it is very long $ make check diff --git a/docs/userguide b/docs/userguide index 02130cd..2ad3418 100644 --- a/docs/userguide +++ b/docs/userguide @@ -54,7 +54,7 @@ image:two_terminals.png[Two terminals] To move the focus between the two terminals, you can use the direction keys -which you may know from the editor +vi+. However, in i3, your homerow is used +which you might know from the editor +vi+. However, in i3, your homerow is used for these keys (in +vi+, the keys are shifted to the left by one for compatibility with most keyboard layouts). Therefore, +$mod+j+ is left, +$mod+k+ is down, +$mod+l+ is up and `$mod+;` is right. So, to switch between the @@ -245,7 +245,7 @@ So, how can you open a new terminal window to the *right* of the current one? The solution is to use +focus parent+, which will focus the +Parent Container+ of -the current +Container+. In default configuration, use +$mod+a+ to navigate one +the current +Container+. In default configuration, use +$mod+a+ to navigate one +Container+ up the tree (you can repeat this multiple times until you get to the +Workspace Container+). In this case, you would focus the +Vertical Split Container+ which is *inside* the horizontally oriented workspace. Thus, now new windows will be @@ -263,7 +263,7 @@ windows are directly attached to one node inside i3’s layout tree, the workspace node. By default, the workspace node’s orientation is +horizontal+. -Now you move one of these terminals down (+$mod+Shift+k+ by default). The +Now you move one of these terminals down (+$mod+Shift+j+ by default). The workspace node’s orientation will be changed to +vertical+. The terminal window you moved down is directly attached to the workspace and appears on the bottom of the screen. A new (horizontal) container was created to accommodate the @@ -924,7 +924,7 @@ If your X server supports RandR 1.5 or newer, i3 will use RandR monitor objects instead of output objects. Run +xrandr --listmonitors+ to see a list. Usually, a monitor object contains exactly one output, and has the same name as the -output; but should that not be the case, you may specify the name of either the +output; but should that not be the case, you can specify the name of either the monitor or the output in i3's configuration. For example, the Dell UP2414Q uses two scalers internally, so its output names might be “DP1” and “DP2”, but the monitor name is “Dell UP2414Q”. @@ -1066,7 +1066,7 @@ === Popups during fullscreen mode When you are in fullscreen mode, some applications still open popup windows -(take Xpdf for example). This is because these applications may not be aware +(take Xpdf for example). This is because these applications might not be aware that they are in fullscreen mode (they do not check the corresponding hint). There are three things which are possible to do in this situation: @@ -1176,9 +1176,9 @@ === Delaying urgency hint reset on workspace change If an application on another workspace sets an urgency hint, switching to this -workspace may lead to immediate focus of the application, which also means the +workspace might lead to immediate focus of the application, which also means the window decoration color would be immediately reset to +client.focused+. This -may make it unnecessarily hard to tell which window originally raised the +might make it unnecessarily hard to tell which window originally raised the event. In order to prevent this, you can tell i3 to delay resetting the urgency state @@ -1201,9 +1201,9 @@ === Focus on window activation If a window is activated, e.g., via +google-chrome www.google.com+, it may request -to take focus. Since this may not be preferable, different reactions can be configured. - -Note that this may not affect windows that are being opened. To prevent new windows +to take focus. Since this might not be preferable, different reactions can be configured. + +Note that this might not affect windows that are being opened. To prevent new windows from being focused, see <>. *Syntax*: @@ -1350,9 +1350,11 @@ The mode option can be changed during runtime through the +bar mode+ command. On reload the mode will be reverted to its configured value. -The hide mode maximizes screen space that can be used for actual windows. Also, -i3bar sends the +SIGSTOP+ and +SIGCONT+ signals to the statusline process to -save battery power. +The hide mode maximizes screen space that can be used for actual windows. When +the bar is hidden, i3bar sends the +SIGSTOP+ and +SIGCONT+ signals to the ++status_command+ process in order to conserve battery power. This feature can +be disabled by the +status_command+ process by setting the appropriate values +in its JSON header message. Invisible mode allows to permanently maximize screen space, as the bar is never shown. Thus, you can configure i3bar to not disturb you by popping up because @@ -1413,7 +1415,7 @@ Scroll wheel right. button7:: Scroll wheel left. - + Please note that the old +wheel_up_cmd+ and +wheel_down_cmd+ commands are deprecated and will be removed in a future release. We strongly recommend using the more general @@ -1482,9 +1484,16 @@ To make a particular i3bar instance handle multiple outputs, specify the output directive multiple times. +These output names have a special meaning: + +primary:: + Selects the output that is configured as primary in the X server. +nonprimary:: + Selects every output that is not configured as primary in the X server. + *Syntax*: --------------- -output primary| +output primary|nonprimary| --------------- *Example*: @@ -1640,7 +1649,7 @@ By default, the width a workspace button is determined by the width of the text showing the workspace name. If the name is too short (say, one letter), then the -workspace button may look too small. +workspace button might look too small. This option specifies the minimum width for workspace buttons. If the name of a workspace is too short to cover the button, an additional padding is added on @@ -1650,7 +1659,7 @@ The setting also applies to the current binding mode indicator. -Note that the specified pixels refer to logical pixels, which may translate +Note that the specified pixels refer to logical pixels, which might translate into more pixels on HiDPI displays. *Syntax*: @@ -1680,8 +1689,8 @@ the form "[n][:][NAME]" will display only the number. The default is to display the full name within the workspace button. Be aware -that the colon in the workspace name is optional, so `[n][NAME]` will also -have the the workspace name and number stripped correctly. +that the colon in the workspace name is optional, so `[n][NAME]` will also +have the workspace name and number stripped correctly. *Syntax*: ------------------------------ @@ -2155,12 +2164,15 @@ # Moves the container into the given direction. # The optional pixel argument specifies how far the # container should be moved if it is floating and -# defaults to 10 pixels. -move [ px] +# defaults to 10 pixels. The optional ppt argument +# means "percentage points", and if specified it indicates +# how many points the container should be moved if it is +# floating rather than by a pixel value. +move [ [px|ppt]] # Moves the container to the specified pos_x and pos_y # coordinates on the screen. -move position [px] [px] +move position [px|ppt] [px|ppt] # Moves the container to the center of the screen. # If 'absolute' is used, it is moved to the center of @@ -2476,7 +2488,7 @@ === Jumping to specific windows Often when in a multi-monitor environment, you want to quickly jump to a -specific window. For example, while working on workspace 3 you may want to +specific window. For example, while working on workspace 3 you might want to jump to your mail client to email your boss that you’ve achieved some important goal. Instead of figuring out how to navigate to your mail client, it would be more convenient to have a shortcut. You can use the +focus+ command @@ -2511,7 +2523,7 @@ can also prefix this command and display a custom prompt for the input dialog. The additional +--toggle+ option will remove the mark if the window already has -this mark or add it otherwise. Note that you may need to use this in +this mark or add it otherwise. Note that you might need to use this in combination with +--add+ (see below) as any other marks will otherwise be removed. @@ -2610,7 +2622,7 @@ to the normal and pixel styles. Note that "pixel" refers to logical pixel. On HiDPI displays, a logical pixel -may be represented by multiple physical pixels, so +pixel 1+ might not +is represented by multiple physical pixels, so +pixel 1+ might not necessarily translate into a single pixel row wide border. *Syntax*: @@ -2873,7 +2885,7 @@ === Interesting configuration for multi-monitor environments -There are several things to configure in i3 which may be interesting if you +There are several things to configure in i3 which might be interesting if you have more than one monitor: 1. You can specify which workspace should be put on which screen. This diff --git a/etc/config b/etc/config index 2591c18..19cb8c4 100644 --- a/etc/config +++ b/etc/config @@ -52,10 +52,11 @@ bindsym Mod1+Shift+q kill # start dmenu (a program launcher) -bindsym Mod1+d exec dmenu_run -# There also is the (new) i3-dmenu-desktop which only displays applications -# shipping a .desktop file. It is a wrapper around dmenu, so you need that -# installed. +bindsym Mod1+d exec --no-startup-id dmenu_run +# A more modern dmenu replacement is rofi: +# bindsym Mod1+d exec rofi -modi drun,run -show drun +# There also is i3-dmenu-desktop which only displays applications shipping a +# .desktop file. It is a wrapper around dmenu, so you need that installed. # bindsym Mod1+d exec --no-startup-id i3-dmenu-desktop # change focus diff --git a/etc/config.keycodes b/etc/config.keycodes index 951c0a2..aa79901 100644 --- a/etc/config.keycodes +++ b/etc/config.keycodes @@ -46,11 +46,12 @@ bindcode $mod+Shift+24 kill # start dmenu (a program launcher) -bindcode $mod+40 exec dmenu_run -# There also is the (new) i3-dmenu-desktop which only displays applications -# shipping a .desktop file. It is a wrapper around dmenu, so you need that -# installed. -# bindsym $mod+d exec --no-startup-id i3-dmenu-desktop +bindcode $mod+40 exec --no-startup-id dmenu_run +# A more modern dmenu replacement is rofi: +# bindcode $mod+40 exec rofi -modi drun,run -show drun +# There also is i3-dmenu-desktop which only displays applications shipping a +# .desktop file. It is a wrapper around dmenu, so you need that installed. +bindcode $mod+40 exec --no-startup-id i3-dmenu-desktop # change focus bindcode $mod+44 focus left diff --git a/generate-command-parser.pl b/generate-command-parser.pl index a017eda..77502db 100755 --- a/generate-command-parser.pl +++ b/generate-command-parser.pl @@ -117,6 +117,7 @@ open(my $enumfh, '>', "GENERATED_${prefix}_enums.h"); my %statenum; +say $enumfh '#pragma once'; say $enumfh 'typedef enum {'; my $cnt = 0; for my $state (@keys, '__CALL') { @@ -131,6 +132,7 @@ # Third step: Generate the call function. open(my $callfh, '>', "GENERATED_${prefix}_call.h"); my $resultname = uc(substr($prefix, 0, 1)) . substr($prefix, 1) . 'ResultIR'; +say $callfh '#pragma once'; say $callfh "static void GENERATED_call(const int call_identifier, struct $resultname *result) {"; say $callfh ' switch (call_identifier) {'; my $call_id = 0; @@ -206,6 +208,7 @@ # Fourth step: Generate the token datastructures. open(my $tokfh, '>', "GENERATED_${prefix}_tokens.h"); +say $tokfh '#pragma once'; for my $state (@keys) { my $tokens = $states{$state}; diff --git a/i3-config-wizard/atoms.xmacro b/i3-config-wizard/atoms.xmacro deleted file mode 100644 index 8f94cea..0000000 --- a/i3-config-wizard/atoms.xmacro +++ /dev/null @@ -1,6 +0,0 @@ -xmacro(_NET_WM_NAME) -xmacro(_NET_WM_WINDOW_TYPE) -xmacro(_NET_WM_WINDOW_TYPE_DIALOG) -xmacro(ATOM) -xmacro(CARDINAL) -xmacro(UTF8_STRING) diff --git a/i3-config-wizard/i3-config-wizard-atoms.xmacro.h b/i3-config-wizard/i3-config-wizard-atoms.xmacro.h new file mode 100644 index 0000000..2d50467 --- /dev/null +++ b/i3-config-wizard/i3-config-wizard-atoms.xmacro.h @@ -0,0 +1,8 @@ +// clang-format off +#define CONFIG_WIZARD_ATOMS_XMACRO \ +xmacro(_NET_WM_NAME) \ +xmacro(_NET_WM_WINDOW_TYPE) \ +xmacro(_NET_WM_WINDOW_TYPE_DIALOG) \ +xmacro(ATOM) \ +xmacro(CARDINAL) \ +xmacro(UTF8_STRING) diff --git a/i3-config-wizard/main.c b/i3-config-wizard/main.c index f999de3..25117f2 100644 --- a/i3-config-wizard/main.c +++ b/i3-config-wizard/main.c @@ -10,6 +10,8 @@ */ #include +#include "libi3.h" + #if defined(__FreeBSD__) #include #endif @@ -23,37 +25,33 @@ #define _WITH_GETLINE #endif -#include -#include -#include -#include -#include -#include #include +#include #include -#include -#include +#include #include #include +#include +#include #include -#include -#include -#include +#include +#include #include #include #include #include - +#include #include -#include #define SN_API_NOT_YET_FROZEN 1 #include +#include #include #include -#include + +#include "i3-config-wizard-atoms.xmacro.h" /* We need SYSCONFDIR for the path to the keycode config template, so raise an * error if it’s not defined for whatever reason */ @@ -69,7 +67,6 @@ #include "xcb.h" xcb_visualtype_t *visual_type = NULL; -#include "libi3.h" #define TEXT_PADDING logical_px(4) #define WIN_POS_X logical_px(490) @@ -848,7 +845,7 @@ /* Place requests for the atoms we need as soon as possible */ #define xmacro(atom) \ xcb_intern_atom_cookie_t atom##_cookie = xcb_intern_atom(conn, 0, strlen(#atom), #atom); -#include "atoms.xmacro" + CONFIG_WIZARD_ATOMS_XMACRO #undef xmacro /* Init startup notification. */ @@ -905,7 +902,7 @@ A_##name = reply->atom; \ free(reply); \ } while (0); -#include "atoms.xmacro" + CONFIG_WIZARD_ATOMS_XMACRO #undef xmacro /* Set dock mode */ diff --git a/i3-config-wizard/xcb.h b/i3-config-wizard/xcb.h index f3e204e..dc8568a 100644 --- a/i3-config-wizard/xcb.h +++ b/i3-config-wizard/xcb.h @@ -3,6 +3,8 @@ /* from X11/keysymdef.h */ #define XCB_NUM_LOCK 0xff7f +#include "i3-config-wizard-atoms.xmacro.h" + #define xmacro(atom) xcb_atom_t A_##atom; -#include "atoms.xmacro" +CONFIG_WIZARD_ATOMS_XMACRO #undef xmacro diff --git a/i3-dmenu-desktop b/i3-dmenu-desktop index 5c34b2b..07fe833 100755 --- a/i3-dmenu-desktop +++ b/i3-dmenu-desktop @@ -13,6 +13,7 @@ use File::Find; use File::Basename qw(basename); use File::Temp qw(tempfile); +use List::Util 'first'; use Getopt::Long; use Pod::Usage; use v5.10; @@ -123,6 +124,8 @@ # Cleanup the paths, maybe some application does not cope with double slashes # (the field code %k is replaced with the .desktop file location). @searchdirs = map { s,//,/,g; $_ } @searchdirs; +# Also remove any trailing slashes. +@searchdirs = map { s,/*$,,g; $_ } @searchdirs; # To avoid errors by File::Find’s find(), only pass existing directories. @searchdirs = grep { -d $_ } @searchdirs; @@ -133,8 +136,15 @@ return unless substr($_, -1 * length('.desktop')) eq '.desktop'; my $relative = $File::Find::name; - # + 1 for the trailing /, which is missing in ::topdir. - substr($relative, 0, length($File::Find::topdir) + 1) = ''; + # Find and then replace the directory in @searchdirs in which the + # current file is located. We used to do this with + # $File::Find::topdir but it is not supported when using the + # 'follow' or 'follow_fast' options. + # See #3973, #4031. + my $topdir = first { substr($relative, 0, length($_)) eq $_ } @searchdirs; + + # + 1 for the trailing /, which is missing in $topdir. + substr($relative, 0, length($topdir) + 1) = ''; # Don’t overwrite files with the same relative path, we search in # descending order of importance. diff --git a/i3-dump-log/main.c b/i3-dump-log/main.c index ba60d39..e58b0c3 100644 --- a/i3-dump-log/main.c +++ b/i3-dump-log/main.c @@ -9,27 +9,22 @@ */ #include +#include "libi3.h" +#include "shmlog.h" + +#include +#include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include #include -#include #include -#include -#include -#include -#include -#include -#include #include #include -#include - -#include "libi3.h" -#include "shmlog.h" -#include +#include #if !defined(__OpenBSD__) static uint32_t offset_next_write; diff --git a/i3-input/keysym2ucs.c b/i3-input/keysym2ucs.c index 52bdc04..8037509 100644 --- a/i3-input/keysym2ucs.c +++ b/i3-input/keysym2ucs.c @@ -31,8 +31,9 @@ * This software is in the public domain. Share and enjoy! */ +#include "keysym2ucs.h" + #include -#include "keysym2ucs.h" struct codepair { unsigned short keysym; diff --git a/i3-input/main.c b/i3-input/main.c index e495fe1..ef9e070 100644 --- a/i3-input/main.c +++ b/i3-input/main.c @@ -8,35 +8,37 @@ * to i3. * */ +#include +#include +#include #include +#include +#include #include -#include -#include #include -#include -#include -#include -#include -#include -#include #include #include -#include #include xcb_visualtype_t *visual_type = NULL; +#include "i3-input.h" +#include "keysym2ucs.h" #include "libi3.h" #include - -#include "keysym2ucs.h" - -#include "i3-input.h" #define MAX_WIDTH logical_px(500) #define BORDER logical_px(2) #define PADDING logical_px(2) + +/* Exit codes for i3-input: + * 0 if i3-input exited successfully and the command was run + * 1 if the user canceled input + * 2 if i3-input fails for any other reason */ +const int EXIT_OK = 0; +const int EXIT_CANCEL = 1; +const int EXIT_ERROR = 2; /* IPC format string. %s will be replaced with what the user entered, then * the command will be sent to i3 */ @@ -192,11 +194,11 @@ /* prefix the command if a prefix was specified on commandline */ printf("command = %s\n", full); - ipc_send_message(sockfd, strlen(full), 0, (uint8_t *)full); + int ret = ipc_send_message(sockfd, strlen(full), 0, (uint8_t *)full); free(full); - exit(0); + exit(ret == 0 ? EXIT_OK : EXIT_ERROR); } /* @@ -245,7 +247,7 @@ return 1; } if (sym == XK_Escape) { - exit(0); + exit(EXIT_CANCEL); } /* TODO: handle all of these? */ @@ -303,7 +305,7 @@ xcb_intern_atom_reply_t *nswc_reply = xcb_intern_atom_reply(conn, nswc_cookie, NULL); if (nswc_reply == NULL) { ELOG("Could not intern atom _NET_SUPPORTING_WM_CHECK\n"); - exit(-1); + exit(EXIT_ERROR); } A__NET_SUPPORTING_WM_CHECK = nswc_reply->atom; free(nswc_reply); @@ -373,9 +375,8 @@ } int main(int argc, char *argv[]) { - format = sstrdup("%s"); char *socket_path = NULL; - char *pattern = sstrdup("pango:monospace 8"); + char *pattern = NULL; int o, option_index = 0; static struct option long_options[] = { @@ -399,7 +400,7 @@ break; case 'v': printf("i3-input " I3_VERSION); - return 0; + return EXIT_OK; case 'p': /* This option is deprecated, but will still work in i3 v4.1, 4.2 and 4.3 */ fprintf(stderr, "i3-input: WARNING: the -p option is DEPRECATED in favor of the -F (format) option\n"); @@ -427,8 +428,11 @@ printf("\n"); printf("Example:\n"); printf(" i3-input -F 'workspace \"%%s\"' -P 'Switch to workspace: '\n"); - return 0; + return EXIT_OK; } + } + if (!format) { + format = "%s"; } printf("using format \"%s\"\n", format); @@ -446,7 +450,7 @@ symbols = xcb_key_symbols_alloc(conn); init_dpi(); - font = load_font(pattern, true); + font = load_font(pattern ? pattern : "pango:monospace 8", true); set_font(&font); if (prompt != NULL) @@ -495,7 +499,7 @@ if (reply->status != XCB_GRAB_STATUS_SUCCESS) { fprintf(stderr, "Could not grab keyboard, status = %d\n", reply->status); - exit(-1); + exit(EXIT_ERROR); } xcb_flush(conn); @@ -531,5 +535,5 @@ } draw_util_surface_free(conn, &surface); - return 0; -} + return EXIT_OK; +} diff --git a/i3-msg/main.c b/i3-msg/main.c index 3a89741..c1c8bb8 100644 --- a/i3-msg/main.c +++ b/i3-msg/main.c @@ -16,27 +16,17 @@ */ #include "libi3.h" +#include +#include +#include +#include +#include #include -#include -#include -#include -#include #include +#include #include -#include -#include -#include -#include -#include -#include #include -#include - -#include -#include - -#include /* * Having verboselog() and errorlog() is necessary when using libi3. @@ -199,6 +189,8 @@ message_type = I3_IPC_MESSAGE_TYPE_GET_BAR_CONFIG; } else if (strcasecmp(optarg, "get_binding_modes") == 0) { message_type = I3_IPC_MESSAGE_TYPE_GET_BINDING_MODES; + } else if (strcasecmp(optarg, "get_binding_state") == 0) { + message_type = I3_IPC_MESSAGE_TYPE_GET_BINDING_STATE; } else if (strcasecmp(optarg, "get_version") == 0) { message_type = I3_IPC_MESSAGE_TYPE_GET_VERSION; } else if (strcasecmp(optarg, "get_config") == 0) { @@ -209,7 +201,7 @@ message_type = I3_IPC_MESSAGE_TYPE_SUBSCRIBE; } else { printf("Unknown message type\n"); - printf("Known types: run_command, get_workspaces, get_outputs, get_tree, get_marks, get_bar_config, get_binding_modes, get_version, get_config, send_tick, subscribe\n"); + printf("Known types: run_command, get_workspaces, get_outputs, get_tree, get_marks, get_bar_config, get_binding_modes, get_binding_state, get_version, get_config, send_tick, subscribe\n"); exit(EXIT_FAILURE); } } else if (o == 'q') { diff --git a/i3-nagbar/atoms.xmacro b/i3-nagbar/atoms.xmacro deleted file mode 100644 index 333ba2d..0000000 --- a/i3-nagbar/atoms.xmacro +++ /dev/null @@ -1,6 +0,0 @@ -xmacro(_NET_WM_WINDOW_TYPE) -xmacro(_NET_WM_WINDOW_TYPE_DOCK) -xmacro(_NET_WM_STRUT_PARTIAL) -xmacro(I3_SOCKET_PATH) -xmacro(ATOM) -xmacro(CARDINAL) diff --git a/i3-nagbar/i3-nagbar-atoms.xmacro.h b/i3-nagbar/i3-nagbar-atoms.xmacro.h new file mode 100644 index 0000000..c430b59 --- /dev/null +++ b/i3-nagbar/i3-nagbar-atoms.xmacro.h @@ -0,0 +1,8 @@ +// clang-format off +#define NAGBAR_ATOMS_XMACRO \ +xmacro(_NET_WM_WINDOW_TYPE) \ +xmacro(_NET_WM_WINDOW_TYPE_DOCK) \ +xmacro(_NET_WM_STRUT_PARTIAL) \ +xmacro(I3_SOCKET_PATH) \ +xmacro(ATOM) \ +xmacro(CARDINAL) diff --git a/i3-nagbar/i3-nagbar.h b/i3-nagbar/i3-nagbar.h deleted file mode 100644 index cb672be..0000000 --- a/i3-nagbar/i3-nagbar.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include - -#include - -#define die(...) errx(EXIT_FAILURE, __VA_ARGS__); -#define FREE(pointer) \ - do { \ - free(pointer); \ - pointer = NULL; \ - } while (0) - -#define xmacro(atom) xcb_atom_t A_##atom; -#include "atoms.xmacro" -#undef xmacro - -extern xcb_window_t root; diff --git a/i3-nagbar/main.c b/i3-nagbar/main.c index e59f5a6..b13ee13 100644 --- a/i3-nagbar/main.c +++ b/i3-nagbar/main.c @@ -8,35 +8,34 @@ * when the user has an error in their configuration file. * */ -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include + +#include "libi3.h" + #include -#include +#include #include #include -#include #include - +#include +#include +#include +#include +#include +#include +#include + +#include #include #include -#include -#include #include xcb_visualtype_t *visual_type = NULL; -#include "libi3.h" #define SN_API_NOT_YET_FROZEN 1 #include -#include "i3-nagbar.h" +#include "i3-nagbar-atoms.xmacro.h" #define MSG_PADDING logical_px(8) #define BTN_PADDING logical_px(3) @@ -44,6 +43,12 @@ #define BTN_GAP logical_px(20) #define CLOSE_BTN_GAP logical_px(15) #define BAR_BORDER logical_px(2) + +#define xmacro(atom) xcb_atom_t A_##atom; +NAGBAR_ATOMS_XMACRO +#undef xmacro + +#define die(...) errx(EXIT_FAILURE, __VA_ARGS__); static char *argv0 = NULL; @@ -314,8 +319,8 @@ goto free_resources; free_resources: - FREE(res); - FREE(primary); + free(res); + free(primary); return result; } @@ -423,7 +428,7 @@ /* Place requests for the atoms we need as soon as possible */ #define xmacro(atom) \ xcb_intern_atom_cookie_t atom##_cookie = xcb_intern_atom(conn, 0, strlen(#atom), #atom); -#include "atoms.xmacro" + NAGBAR_ATOMS_XMACRO #undef xmacro /* Init startup notification. */ @@ -505,7 +510,7 @@ A_##name = reply->atom; \ free(reply); \ } while (0); -#include "atoms.xmacro" + NAGBAR_ATOMS_XMACRO #undef xmacro /* Set dock mode */ @@ -598,7 +603,7 @@ free(event); } - FREE(pattern); + free(pattern); draw_util_surface_free(conn, &bar); return 0; diff --git a/i3bar/include/child.h b/i3bar/include/child.h index 3afed81..adc638b 100644 --- a/i3bar/include/child.h +++ b/i3bar/include/child.h @@ -85,4 +85,4 @@ * Generates a click event, if enabled. * */ -void send_block_clicked(int button, const char *name, const char *instance, int x, int y, int x_rel, int y_rel, int width, int height, int mods); +void send_block_clicked(int button, const char *name, const char *instance, int x, int y, int x_rel, int y_rel, int out_x, int out_y, int width, int height, int mods); diff --git a/i3bar/include/common.h b/i3bar/include/common.h index 222f42d..52f77b0 100644 --- a/i3bar/include/common.h +++ b/i3bar/include/common.h @@ -9,7 +9,6 @@ #include -#include #include #include #include "libi3.h" @@ -78,12 +77,10 @@ char *name; char *instance; - TAILQ_ENTRY(status_block) - blocks; + TAILQ_ENTRY(status_block) blocks; }; -extern TAILQ_HEAD(statusline_head, status_block) - statusline_head; +extern TAILQ_HEAD(statusline_head, status_block) statusline_head; #include "child.h" #include "ipc.h" @@ -94,5 +91,4 @@ #include "trayclients.h" #include "xcb.h" #include "configuration.h" -#include "libi3.h" #include "parse_json_header.h" diff --git a/i3bar/include/configuration.h b/i3bar/include/configuration.h index f1fb9a5..589c639 100644 --- a/i3bar/include/configuration.h +++ b/i3bar/include/configuration.h @@ -29,23 +29,18 @@ char *command; bool release; - TAILQ_ENTRY(binding_t) - bindings; + TAILQ_ENTRY(binding_t) bindings; } binding_t; typedef struct tray_output_t { char *output; - TAILQ_ENTRY(tray_output_t) - tray_outputs; + TAILQ_ENTRY(tray_output_t) tray_outputs; } tray_output_t; typedef struct config_t { uint32_t modifier; - - TAILQ_HEAD(bindings_head, binding_t) - bindings; - + TAILQ_HEAD(bindings_head, binding_t) bindings; position_t position; bool verbose; uint32_t bar_height; @@ -60,10 +55,7 @@ char *command; char *fontname; i3String *separator_symbol; - - TAILQ_HEAD(tray_outputs_head, tray_output_t) - tray_outputs; - + TAILQ_HEAD(tray_outputs_head, tray_output_t) tray_outputs; int tray_padding; int num_outputs; char **outputs; diff --git a/i3bar/include/outputs.h b/i3bar/include/outputs.h index 5bb19c4..4685e51 100644 --- a/i3bar/include/outputs.h +++ b/i3bar/include/outputs.h @@ -73,6 +73,5 @@ struct ws_head* workspaces; /* The workspaces on this output */ struct tc_head* trayclients; /* The tray clients on this output */ - SLIST_ENTRY(i3_output) - slist; /* Pointer for the SLIST-Macro */ + SLIST_ENTRY(i3_output) slist; /* Pointer for the SLIST-Macro */ }; diff --git a/i3bar/include/trayclients.h b/i3bar/include/trayclients.h index 3f215ce..bcf5595 100644 --- a/i3bar/include/trayclients.h +++ b/i3bar/include/trayclients.h @@ -21,6 +21,5 @@ char *class_class; char *class_instance; - TAILQ_ENTRY(trayclient) - tailq; /* Pointer for the TAILQ-Macro */ + TAILQ_ENTRY(trayclient) tailq; /* Pointer for the TAILQ-Macro */ }; diff --git a/i3bar/include/workspaces.h b/i3bar/include/workspaces.h index 0ef5c0a..ff61450 100644 --- a/i3bar/include/workspaces.h +++ b/i3bar/include/workspaces.h @@ -41,6 +41,5 @@ rect rect; /* The rect of the ws (not used (yet)) */ struct i3_output *output; /* The current output of the ws */ - TAILQ_ENTRY(i3_ws) - tailq; /* Pointer for the TAILQ-Macro */ + TAILQ_ENTRY(i3_ws) tailq; /* Pointer for the TAILQ-Macro */ }; diff --git a/i3bar/src/child.c b/i3bar/src/child.c index e56145f..bece314 100644 --- a/i3bar/src/child.c +++ b/i3bar/src/child.c @@ -10,25 +10,21 @@ #include "common.h" #include "yajl_utils.h" +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + +#include #include -#include -#include -#include - -#include /* Global variables for child_*() */ i3bar_child child; @@ -638,7 +634,7 @@ * Generates a click event, if enabled. * */ -void send_block_clicked(int button, const char *name, const char *instance, int x, int y, int x_rel, int y_rel, int width, int height, int mods) { +void send_block_clicked(int button, const char *name, const char *instance, int x, int y, int x_rel, int y_rel, int out_x, int out_y, int width, int height, int mods) { if (!child.click_events) { return; } @@ -690,6 +686,12 @@ ystr("relative_y"); yajl_gen_integer(gen, y_rel); + ystr("output_x"); + yajl_gen_integer(gen, out_x); + + ystr("output_y"); + yajl_gen_integer(gen, out_y); + ystr("width"); yajl_gen_integer(gen, width); diff --git a/i3bar/src/config.c b/i3bar/src/config.c index 11d8e0a..c962779 100644 --- a/i3bar/src/config.c +++ b/i3bar/src/config.c @@ -9,15 +9,12 @@ */ #include "common.h" +#include +#include #include -#include -#include -#include -#include + +#include #include -#include - -#include config_t config; static char *cur_key; diff --git a/i3bar/src/ipc.c b/i3bar/src/ipc.c index 37bdbac..f2c105a 100644 --- a/i3bar/src/ipc.c +++ b/i3bar/src/ipc.c @@ -9,16 +9,13 @@ */ #include "common.h" +#include +#include +#include +#include #include -#include +#include #include -#include -#include -#include -#include -#include -#include -#include #ifdef I3_ASAN_ENABLED #include #endif diff --git a/i3bar/src/main.c b/i3bar/src/main.c index 65cb00f..4e72934 100644 --- a/i3bar/src/main.c +++ b/i3bar/src/main.c @@ -7,15 +7,13 @@ */ #include "common.h" -#include -#include -#include -#include -#include -#include #include #include #include +#include +#include +#include +#include struct ev_loop *main_loop; diff --git a/i3bar/src/mode.c b/i3bar/src/mode.c index 97087ce..13d0211 100644 --- a/i3bar/src/mode.c +++ b/i3bar/src/mode.c @@ -9,12 +9,10 @@ */ #include "common.h" +#include #include -#include -#include -#include + #include -#include /* A datatype to pass through the callbacks to save the state */ struct mode_json_params { diff --git a/i3bar/src/outputs.c b/i3bar/src/outputs.c index 6ebb7cc..168f3ee 100644 --- a/i3bar/src/outputs.c +++ b/i3bar/src/outputs.c @@ -9,13 +9,12 @@ */ #include "common.h" +#include +#include +#include #include -#include -#include -#include -#include + #include -#include /* A datatype to pass through the callbacks to save the state */ struct outputs_json_params { @@ -193,11 +192,12 @@ /* See if we actually handle that output */ if (config.num_outputs > 0) { + const bool is_primary = params->outputs_walk->primary; bool handle_output = false; for (int c = 0; c < config.num_outputs; c++) { - if (strcasecmp(params->outputs_walk->name, config.outputs[c]) == 0 || - (strcasecmp(config.outputs[c], "primary") == 0 && - params->outputs_walk->primary)) { + if ((strcasecmp(params->outputs_walk->name, config.outputs[c]) == 0) || + (strcasecmp(config.outputs[c], "primary") == 0 && is_primary) || + (strcasecmp(config.outputs[c], "nonprimary") == 0 && !is_primary)) { handle_output = true; break; } diff --git a/i3bar/src/parse_json_header.c b/i3bar/src/parse_json_header.c index 3d4c2a6..c74a62f 100644 --- a/i3bar/src/parse_json_header.c +++ b/i3bar/src/parse_json_header.c @@ -10,22 +10,10 @@ */ #include "common.h" -#include -#include -#include -#include #include -#include -#include #include -#include -#include -#include -#include -#include -#include + #include -#include static enum { KEY_VERSION, diff --git a/i3bar/src/workspaces.c b/i3bar/src/workspaces.c index 6868661..bd56f5d 100644 --- a/i3bar/src/workspaces.c +++ b/i3bar/src/workspaces.c @@ -9,12 +9,10 @@ */ #include "common.h" +#include #include -#include -#include -#include + #include -#include /* A datatype to pass through the callbacks to save the state */ struct workspaces_json_params { diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index 15c6f82..89b3410 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -9,26 +9,15 @@ */ #include "common.h" -#include -#include -#include +#include +#include +#include +#include +#include + #include #include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include +#include #ifdef I3_ASAN_ENABLED #include @@ -454,7 +443,7 @@ return false; } -static void child_handle_button(xcb_button_press_event_t *event, i3_output *output, uint32_t statusline_x) { +static void child_handle_button(xcb_button_press_event_t *event, i3_output *output, uint32_t statusline_x, uint32_t statusline_y) { if (statusline_x > (uint32_t)output->statusline_width) { return; } @@ -483,9 +472,13 @@ /* x of the click event relative to the current block. */ const uint32_t relative_x = statusline_x - last_block_x; if (relative_x <= full_render_width) { + const uint32_t output_x = event->event_x; + const uint32_t output_y = statusline_y + event->event_y; + send_block_clicked(event->detail, block->name, block->instance, event->root_x, event->root_y, relative_x, - event->event_y, full_render_width, bar_height, + event->event_y, output_x, output_y, + full_render_width, bar_height, event->state); return; } @@ -553,9 +546,9 @@ /* Calculate the horizontal coordinate (x) of the start of the * statusline by subtracting its width and the width of the tray from * the bar width. */ - const int offset = walk->rect.w - walk->statusline_width - - tray_width - logical_px((tray_width > 0) * sb_hoff_px); - if (x >= offset) { + const int offset_x = walk->rect.w - walk->statusline_width - + tray_width - logical_px((tray_width > 0) * sb_hoff_px); + if (x >= offset_x) { /* Click was after the start of the statusline, return to avoid * executing any other actions even if a click event is not * produced eventually. */ @@ -563,8 +556,10 @@ if (!event_is_release) { /* x of the click event relative to the start of the * statusline. */ - const uint32_t statusline_x = x - offset; - child_handle_button(event, walk, statusline_x); + const uint32_t statusline_x = x - offset_x; + const uint32_t statusline_y = event->root_y - walk->rect.y - event->event_y; + + child_handle_button(event, walk, statusline_x, statusline_y); } return; @@ -1628,15 +1623,18 @@ * */ void destroy_window(i3_output *output) { - if (output == NULL) { + if (output == NULL || output->bar.id == XCB_NONE) { return; } - if (output->bar.id == XCB_NONE) { - return; - } kick_tray_clients(output); + + draw_util_surface_free(xcb_connection, &(output->bar)); + draw_util_surface_free(xcb_connection, &(output->buffer)); + draw_util_surface_free(xcb_connection, &(output->statusline_buffer)); xcb_destroy_window(xcb_connection, output->bar.id); + xcb_free_pixmap(xcb_connection, output->buffer.id); + xcb_free_pixmap(xcb_connection, output->statusline_buffer.id); output->bar.id = XCB_NONE; } diff --git a/include/all.h b/include/all.h index aa2b5b2..5511194 100644 --- a/include/all.h +++ b/include/all.h @@ -15,31 +15,24 @@ #include #include +#include +#include +#include +#include #include +#include +#include #include -#include #include -#include -#include -#include #include #include -#include -#include -#include -#include -#include -#include -#include #include #include +#include #include -#include -#include -#include - +#include "libi3.h" #include "data.h" #include "util.h" #include "ipc.h" @@ -72,7 +65,6 @@ #include "ewmh.h" #include "assignments.h" #include "regex.h" -#include "libi3.h" #include "startup.h" #include "scratchpad.h" #include "commands.h" diff --git a/include/atoms.xmacro b/include/atoms.xmacro deleted file mode 100644 index 730e569..0000000 --- a/include/atoms.xmacro +++ /dev/null @@ -1,2 +0,0 @@ -#include "atoms_NET_SUPPORTED.xmacro" -#include "atoms_rest.xmacro" diff --git a/include/atoms_NET_SUPPORTED.xmacro b/include/atoms_NET_SUPPORTED.xmacro deleted file mode 100644 index a81948a..0000000 --- a/include/atoms_NET_SUPPORTED.xmacro +++ /dev/null @@ -1,35 +0,0 @@ -xmacro(_NET_SUPPORTED) -xmacro(_NET_SUPPORTING_WM_CHECK) -xmacro(_NET_WM_NAME) -xmacro(_NET_WM_VISIBLE_NAME) -xmacro(_NET_WM_MOVERESIZE) -xmacro(_NET_WM_STATE_STICKY) -xmacro(_NET_WM_STATE_FULLSCREEN) -xmacro(_NET_WM_STATE_DEMANDS_ATTENTION) -xmacro(_NET_WM_STATE_MODAL) -xmacro(_NET_WM_STATE_HIDDEN) -xmacro(_NET_WM_STATE_FOCUSED) -xmacro(_NET_WM_STATE) -xmacro(_NET_WM_WINDOW_TYPE) -xmacro(_NET_WM_WINDOW_TYPE_NORMAL) -xmacro(_NET_WM_WINDOW_TYPE_DOCK) -xmacro(_NET_WM_WINDOW_TYPE_DIALOG) -xmacro(_NET_WM_WINDOW_TYPE_UTILITY) -xmacro(_NET_WM_WINDOW_TYPE_TOOLBAR) -xmacro(_NET_WM_WINDOW_TYPE_SPLASH) -xmacro(_NET_WM_WINDOW_TYPE_MENU) -xmacro(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU) -xmacro(_NET_WM_WINDOW_TYPE_POPUP_MENU) -xmacro(_NET_WM_WINDOW_TYPE_TOOLTIP) -xmacro(_NET_WM_WINDOW_TYPE_NOTIFICATION) -xmacro(_NET_WM_DESKTOP) -xmacro(_NET_WM_STRUT_PARTIAL) -xmacro(_NET_CLIENT_LIST) -xmacro(_NET_CLIENT_LIST_STACKING) -xmacro(_NET_CURRENT_DESKTOP) -xmacro(_NET_NUMBER_OF_DESKTOPS) -xmacro(_NET_DESKTOP_NAMES) -xmacro(_NET_DESKTOP_VIEWPORT) -xmacro(_NET_ACTIVE_WINDOW) -xmacro(_NET_CLOSE_WINDOW) -xmacro(_NET_MOVERESIZE_WINDOW) diff --git a/include/atoms_rest.xmacro b/include/atoms_rest.xmacro deleted file mode 100644 index b65a81d..0000000 --- a/include/atoms_rest.xmacro +++ /dev/null @@ -1,20 +0,0 @@ -xmacro(_NET_WM_USER_TIME) -xmacro(_NET_STARTUP_ID) -xmacro(_NET_WORKAREA) -xmacro(WM_PROTOCOLS) -xmacro(WM_DELETE_WINDOW) -xmacro(UTF8_STRING) -xmacro(WM_STATE) -xmacro(WM_CLIENT_LEADER) -xmacro(WM_TAKE_FOCUS) -xmacro(WM_WINDOW_ROLE) -xmacro(I3_SOCKET_PATH) -xmacro(I3_CONFIG_PATH) -xmacro(I3_SYNC) -xmacro(I3_SHMLOG_PATH) -xmacro(I3_PID) -xmacro(I3_FLOATING_WINDOW) -xmacro(_NET_REQUEST_FRAME_EXTENTS) -xmacro(_NET_FRAME_EXTENTS) -xmacro(_MOTIF_WM_HINTS) -xmacro(WM_CHANGE_STATE) diff --git a/include/commands.h b/include/commands.h index de066e4..4b2f99b 100644 --- a/include/commands.h +++ b/include/commands.h @@ -219,10 +219,10 @@ void cmd_sticky(I3_CMD, const char *action); /** - * Implementation of 'move [ [px]]'. - * - */ -void cmd_move_direction(I3_CMD, const char *direction_str, long move_px); + * Implementation of 'move [ [px|ppt]]'. + * + */ +void cmd_move_direction(I3_CMD, const char *direction_str, long amount, const char *mode); /** * Implementation of 'layout default|stacked|stacking|tabbed|splitv|splith'. @@ -267,10 +267,10 @@ void cmd_focus_output(I3_CMD, const char *name); /** - * Implementation of 'move [window|container] [to] [absolute] position [px] [px] - * - */ -void cmd_move_window_to_position(I3_CMD, long x, long y); + * Implementation of 'move [window|container] [to] [absolute] position [ [px|ppt] [px|ppt]] + * + */ +void cmd_move_window_to_position(I3_CMD, long x, const char *mode_x, long y, const char *mode_y); /** * Implementation of 'move [window|container] [to] [absolute] position center @@ -315,10 +315,16 @@ void cmd_rename_workspace(I3_CMD, const char *old_name, const char *new_name); /** - * Implementation of 'bar (hidden_state hide|show|toggle)|(mode dock|hide|invisible|toggle) []' - * - */ -void cmd_bar(I3_CMD, const char *bar_type, const char *bar_value, const char *bar_id); + * Implementation of 'bar mode dock|hide|invisible|toggle []' + * + */ +void cmd_bar_mode(I3_CMD, const char *bar_mode, const char *bar_id); + +/** + * Implementation of 'bar hidden_state hide|show|toggle []' + * + */ +void cmd_bar_hidden_state(I3_CMD, const char *bar_hidden_state, const char *bar_id); /** * Implementation of 'shmlog |toggle|on|off' diff --git a/include/configuration.h b/include/configuration.h index cd5daa8..eff28e6 100644 --- a/include/configuration.h +++ b/include/configuration.h @@ -12,9 +12,6 @@ */ #pragma once -#include "libi3.h" - -#include #include "queue.h" #include "i3.h" @@ -69,8 +66,7 @@ char *value; char *next_match; - SLIST_ENTRY(Variable) - variables; + SLIST_ENTRY(Variable) variables; }; /** @@ -84,8 +80,7 @@ bool pango_markup; struct bindings_head *bindings; - SLIST_ENTRY(Mode) - modes; + SLIST_ENTRY(Mode) modes; }; /** @@ -284,8 +279,7 @@ /* List of outputs on which the tray is allowed to be shown, in order. * The special value "none" disables it (per default, it will be shown) and * the special value "primary" enabled it on the primary output. */ - TAILQ_HEAD(tray_outputs_head, tray_output_t) - tray_outputs; + TAILQ_HEAD(tray_outputs_head, tray_output_t) tray_outputs; /* Padding around the tray icons. */ int tray_padding; @@ -307,8 +301,7 @@ /** Bar modifier (to show bar when in hide mode). */ uint32_t modifier; - TAILQ_HEAD(bar_bindings_head, Barbinding) - bar_bindings; + TAILQ_HEAD(bar_bindings_head, Barbinding) bar_bindings; /** Bar position (bottom by default). */ enum { P_BOTTOM = 0, @@ -385,8 +378,7 @@ char *binding_mode_text; } colors; - TAILQ_ENTRY(Barconfig) - configs; + TAILQ_ENTRY(Barconfig) configs; }; /** @@ -404,15 +396,13 @@ /** If true, the command will be executed after the button is released. */ bool release; - TAILQ_ENTRY(Barbinding) - bindings; + TAILQ_ENTRY(Barbinding) bindings; }; struct tray_output_t { char *output; - TAILQ_ENTRY(tray_output_t) - tray_outputs; + TAILQ_ENTRY(tray_output_t) tray_outputs; }; typedef enum { @@ -440,9 +430,3 @@ * */ void ungrab_all_keys(xcb_connection_t *conn); - -/** - * Sends the current bar configuration as an event to all barconfig_update listeners. - * - */ -void update_barconfig(void); diff --git a/include/data.h b/include/data.h index 2dfb86c..9ea09a8 100644 --- a/include/data.h +++ b/include/data.h @@ -9,13 +9,10 @@ */ #pragma once -#include "libi3.h" - #define SN_API_NOT_YET_FROZEN 1 #include #include -#include #include #include @@ -228,8 +225,7 @@ char *output; gaps_t gaps; - TAILQ_ENTRY(Workspace_Assignment) - ws_assignments; + TAILQ_ENTRY(Workspace_Assignment) ws_assignments; }; struct Ignore_Event { @@ -237,8 +233,7 @@ int response_type; time_t added; - SLIST_ENTRY(Ignore_Event) - ignore_events; + SLIST_ENTRY(Ignore_Event) ignore_events; }; /** @@ -257,8 +252,7 @@ * completed) */ time_t delete_at; - TAILQ_ENTRY(Startup_Sequence) - sequences; + TAILQ_ENTRY(Startup_Sequence) sequences; }; /** @@ -284,9 +278,7 @@ struct Binding_Keycode { xcb_keycode_t keycode; i3_event_state_mask_t modifiers; - - TAILQ_ENTRY(Binding_Keycode) - keycodes; + TAILQ_ENTRY(Binding_Keycode) keycodes; }; /****************************************************************************** @@ -347,14 +339,12 @@ /** Only in use if symbol != NULL. Contains keycodes which generate the * specified symbol. Useful for unbinding and checking which binding was * used when a key press event comes in. */ - TAILQ_HEAD(keycodes_head, Binding_Keycode) - keycodes_head; + TAILQ_HEAD(keycodes_head, Binding_Keycode) keycodes_head; /** Command, like in command mode */ char *command; - TAILQ_ENTRY(Binding) - bindings; + TAILQ_ENTRY(Binding) bindings; }; /** @@ -370,19 +360,13 @@ /** no_startup_id flag for start_application(). Determines whether a * startup notification context/ID should be created. */ bool no_startup_id; - - TAILQ_ENTRY(Autostart) - autostarts; - - TAILQ_ENTRY(Autostart) - autostarts_always; + TAILQ_ENTRY(Autostart) autostarts; + TAILQ_ENTRY(Autostart) autostarts_always; }; struct output_name { char *name; - - SLIST_ENTRY(output_name) - names; + SLIST_ENTRY(output_name) names; }; /** @@ -409,8 +393,7 @@ /** List of names for the output. * An output always has at least one name; the first name is * considered the primary one. */ - SLIST_HEAD(names_head, output_name) - names_head; + SLIST_HEAD(names_head, output_name) names_head; /** Pointer to the Con which represents this output */ Con *con; @@ -418,8 +401,7 @@ /** x, y, width, height */ Rect rect; - TAILQ_ENTRY(xoutput) - outputs; + TAILQ_ENTRY(xoutput) outputs; }; /** @@ -513,6 +495,9 @@ /* Time when the window became managed. Used to determine whether a window * should be swallowed after initial management. */ time_t managed_since; + + /* The window has been swallowed. */ + bool swallowed; }; /** @@ -570,8 +555,7 @@ M_ASSIGN_WS, M_BELOW } insert_where; - TAILQ_ENTRY(Match) - matches; + TAILQ_ENTRY(Match) matches; /* Whether this match was generated when restarting i3 inplace. * Leads to not setting focus when managing a new window, because the old @@ -618,8 +602,7 @@ char *output; } dest; - TAILQ_ENTRY(Assignment) - assignments; + TAILQ_ENTRY(Assignment) assignments; }; /** Fullscreen modes. Used by Con.fullscreen_mode. */ @@ -630,8 +613,7 @@ struct mark_t { char *name; - TAILQ_ENTRY(mark_t) - marks; + TAILQ_ENTRY(mark_t) marks; }; /** @@ -698,8 +680,7 @@ char *sticky_group; /* user-definable marks to jump to this container later */ - TAILQ_HEAD(marks_head, mark_t) - marks_head; + TAILQ_HEAD(marks_head, mark_t) marks_head; /* cached to decide whether a redraw is needed */ bool mark_changed; @@ -718,17 +699,12 @@ struct deco_render_params *deco_render_params; /* Only workspace-containers can have floating clients */ - TAILQ_HEAD(floating_head, Con) - floating_head; - - TAILQ_HEAD(nodes_head, Con) - nodes_head; - - TAILQ_HEAD(focus_head, Con) - focus_head; - - TAILQ_HEAD(swallow_head, Match) - swallow_head; + TAILQ_HEAD(floating_head, Con) floating_head; + + TAILQ_HEAD(nodes_head, Con) nodes_head; + TAILQ_HEAD(focus_head, Con) focus_head; + + TAILQ_HEAD(swallow_head, Match) swallow_head; fullscreen_mode_t fullscreen_mode; @@ -766,17 +742,10 @@ FLOATING_USER_ON = 3 } floating; - TAILQ_ENTRY(Con) - nodes; - - TAILQ_ENTRY(Con) - focused; - - TAILQ_ENTRY(Con) - all_cons; - - TAILQ_ENTRY(Con) - floating_windows; + TAILQ_ENTRY(Con) nodes; + TAILQ_ENTRY(Con) focused; + TAILQ_ENTRY(Con) all_cons; + TAILQ_ENTRY(Con) floating_windows; /** callbacks */ void (*on_remove_child)(Con *); diff --git a/include/floating.h b/include/floating.h index 8e60f78..612874f 100644 --- a/include/floating.h +++ b/include/floating.h @@ -25,7 +25,7 @@ * floating_windows list of the workspace. * */ -void floating_enable(Con *con, bool automatic); +bool floating_enable(Con *con, bool automatic); /** * Disables floating mode for the given container by re-attaching the container diff --git a/include/handlers.h b/include/handlers.h index d2c79c5..81012e7 100644 --- a/include/handlers.h +++ b/include/handlers.h @@ -47,22 +47,3 @@ * */ void property_handlers_init(void); - -#if 0 -/** - * Configuration notifies are only handled because we need to set up ignore - * for the following enter notify events - * - */ -int handle_configure_event(void *prophs, xcb_connection_t *conn, xcb_configure_notify_event_t *event); -#endif - -#if 0 -/** - * Handles _NET_WM_WINDOW_TYPE changes - * - */ -int handle_window_type(void *data, xcb_connection_t *conn, uint8_t state, - xcb_window_t window, xcb_atom_t atom, - xcb_get_property_reply_t *property); -#endif diff --git a/include/i3/ipc.h b/include/i3/ipc.h index 884a0cf..187640c 100644 --- a/include/i3/ipc.h +++ b/include/i3/ipc.h @@ -66,6 +66,9 @@ /** Trigger an i3 sync protocol message via IPC. */ #define I3_IPC_MESSAGE_TYPE_SYNC 11 +/** Request the current binding state. */ +#define I3_IPC_MESSAGE_TYPE_GET_BINDING_STATE 12 + /* * Messages from i3 to clients * @@ -82,6 +85,7 @@ #define I3_IPC_REPLY_TYPE_CONFIG 9 #define I3_IPC_REPLY_TYPE_TICK 10 #define I3_IPC_REPLY_TYPE_SYNC 11 +#define I3_IPC_REPLY_TYPE_GET_BINDING_STATE 12 /* * Events from i3 to clients. Events have the first bit set high. diff --git a/include/i3-atoms_NET_SUPPORTED.xmacro.h b/include/i3-atoms_NET_SUPPORTED.xmacro.h new file mode 100644 index 0000000..b491da9 --- /dev/null +++ b/include/i3-atoms_NET_SUPPORTED.xmacro.h @@ -0,0 +1,37 @@ +// clang-format off +#define I3_NET_SUPPORTED_ATOMS_XMACRO \ +xmacro(_NET_SUPPORTED) \ +xmacro(_NET_SUPPORTING_WM_CHECK) \ +xmacro(_NET_WM_NAME) \ +xmacro(_NET_WM_VISIBLE_NAME) \ +xmacro(_NET_WM_MOVERESIZE) \ +xmacro(_NET_WM_STATE_STICKY) \ +xmacro(_NET_WM_STATE_FULLSCREEN) \ +xmacro(_NET_WM_STATE_DEMANDS_ATTENTION) \ +xmacro(_NET_WM_STATE_MODAL) \ +xmacro(_NET_WM_STATE_HIDDEN) \ +xmacro(_NET_WM_STATE_FOCUSED) \ +xmacro(_NET_WM_STATE) \ +xmacro(_NET_WM_WINDOW_TYPE) \ +xmacro(_NET_WM_WINDOW_TYPE_NORMAL) \ +xmacro(_NET_WM_WINDOW_TYPE_DOCK) \ +xmacro(_NET_WM_WINDOW_TYPE_DIALOG) \ +xmacro(_NET_WM_WINDOW_TYPE_UTILITY) \ +xmacro(_NET_WM_WINDOW_TYPE_TOOLBAR) \ +xmacro(_NET_WM_WINDOW_TYPE_SPLASH) \ +xmacro(_NET_WM_WINDOW_TYPE_MENU) \ +xmacro(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU) \ +xmacro(_NET_WM_WINDOW_TYPE_POPUP_MENU) \ +xmacro(_NET_WM_WINDOW_TYPE_TOOLTIP) \ +xmacro(_NET_WM_WINDOW_TYPE_NOTIFICATION) \ +xmacro(_NET_WM_DESKTOP) \ +xmacro(_NET_WM_STRUT_PARTIAL) \ +xmacro(_NET_CLIENT_LIST) \ +xmacro(_NET_CLIENT_LIST_STACKING) \ +xmacro(_NET_CURRENT_DESKTOP) \ +xmacro(_NET_NUMBER_OF_DESKTOPS) \ +xmacro(_NET_DESKTOP_NAMES) \ +xmacro(_NET_DESKTOP_VIEWPORT) \ +xmacro(_NET_ACTIVE_WINDOW) \ +xmacro(_NET_CLOSE_WINDOW) \ +xmacro(_NET_MOVERESIZE_WINDOW) diff --git a/include/i3-atoms_rest.xmacro.h b/include/i3-atoms_rest.xmacro.h new file mode 100644 index 0000000..75a5f23 --- /dev/null +++ b/include/i3-atoms_rest.xmacro.h @@ -0,0 +1,22 @@ +// clang-format off +#define I3_REST_ATOMS_XMACRO \ +xmacro(_NET_WM_USER_TIME) \ +xmacro(_NET_STARTUP_ID) \ +xmacro(_NET_WORKAREA) \ +xmacro(WM_PROTOCOLS) \ +xmacro(WM_DELETE_WINDOW) \ +xmacro(UTF8_STRING) \ +xmacro(WM_STATE) \ +xmacro(WM_CLIENT_LEADER) \ +xmacro(WM_TAKE_FOCUS) \ +xmacro(WM_WINDOW_ROLE) \ +xmacro(I3_SOCKET_PATH) \ +xmacro(I3_CONFIG_PATH) \ +xmacro(I3_SYNC) \ +xmacro(I3_SHMLOG_PATH) \ +xmacro(I3_PID) \ +xmacro(I3_FLOATING_WINDOW) \ +xmacro(_NET_REQUEST_FRAME_EXTENTS) \ +xmacro(_NET_FRAME_EXTENTS) \ +xmacro(_MOTIF_WM_HINTS) \ +xmacro(WM_CHANGE_STATE) diff --git a/include/i3.h b/include/i3.h index aef3471..2c550fa 100644 --- a/include/i3.h +++ b/include/i3.h @@ -57,7 +57,8 @@ extern char **start_argv; extern Display *xlibdpy, *xkbdpy; extern int xkb_current_group; -extern TAILQ_HEAD(bindings_head, Binding) * bindings; +extern TAILQ_HEAD(bindings_head, Binding) *bindings; +extern const char *current_binding_mode; extern TAILQ_HEAD(autostarts_head, Autostart) autostarts; extern TAILQ_HEAD(autostarts_always_head, Autostart) autostarts_always; extern TAILQ_HEAD(ws_assignments_head, Workspace_Assignment) ws_assignments; diff --git a/include/ipc.h b/include/ipc.h index 8ea9fd2..0d19daf 100644 --- a/include/ipc.h +++ b/include/ipc.h @@ -12,7 +12,6 @@ #include #include -#include #include #include @@ -41,8 +40,7 @@ uint8_t *buffer; size_t buffer_size; - TAILQ_ENTRY(ipc_client) - clients; + TAILQ_ENTRY(ipc_client) clients; } ipc_client; /* diff --git a/include/libi3.h b/include/libi3.h index d9c89dd..c0b9ddb 100644 --- a/include/libi3.h +++ b/include/libi3.h @@ -101,7 +101,7 @@ #if !defined(DLOG) void debuglog(char *fmt, ...) __attribute__((format(printf, 1, 2))); -#define DLOG(fmt, ...) debuglog("%s:%s:%d - " fmt, STRIPPED__FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define DLOG(fmt, ...) debuglog("%s:%s:%d - " fmt, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__) #endif /** @@ -347,7 +347,7 @@ */ uint32_t get_colorpixel(const char *hex) __attribute__((const)); -#ifndef HAVE_strndup +#ifndef HAVE_STRNDUP /** * Taken from FreeBSD * Returns a pointer to a new string which is a duplicate of the @@ -532,7 +532,7 @@ */ char *get_config_path(const char *override_configpath, bool use_system_paths); -#ifndef HAVE_mkdirp +#ifndef HAVE_MKDIRP /** * Emulates mkdir -p (creates any missing folders) * @@ -543,9 +543,9 @@ /** Helper structure for usage in format_placeholders(). */ typedef struct placeholder_t { /* The placeholder to be replaced, e.g., "%title". */ - char *name; + const char *name; /* The value this placeholder should be replaced with. */ - char *value; + const char *value; } placeholder_t; /** diff --git a/include/log.h b/include/log.h index 5c53023..c275844 100644 --- a/include/log.h +++ b/include/log.h @@ -10,9 +10,6 @@ #pragma once #include - -#include -#include /* We will include libi3.h which define its own version of LOG, ELOG. * We want *our* version, so we undef the libi3 one. */ @@ -29,7 +26,7 @@ is, delete the preceding comma */ #define LOG(fmt, ...) verboselog(fmt, ##__VA_ARGS__) #define ELOG(fmt, ...) errorlog("ERROR: " fmt, ##__VA_ARGS__) -#define DLOG(fmt, ...) debuglog("%s:%s:%d - " fmt, STRIPPED__FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define DLOG(fmt, ...) debuglog("%s:%s:%d - " fmt, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__) extern char *errorfilename; extern char *shmlogname; diff --git a/include/shmlog.h b/include/shmlog.h index dc8081f..7b7e133 100644 --- a/include/shmlog.h +++ b/include/shmlog.h @@ -12,7 +12,6 @@ #include -#include #if !defined(__OpenBSD__) #include #endif diff --git a/include/util.h b/include/util.h index f0db03a..09ad941 100644 --- a/include/util.h +++ b/include/util.h @@ -143,13 +143,13 @@ void start_nagbar(pid_t *nagbar_pid, char *argv[]); /** - * Kills the i3-nagbar process, if *nagbar_pid != -1. + * Kills the i3-nagbar process, if nagbar_pid != -1. * * If wait_for_it is set (restarting i3), this function will waitpid(), * otherwise, ev is assumed to handle it (reloading). * */ -void kill_nagbar(pid_t *nagbar_pid, bool wait_for_it); +void kill_nagbar(pid_t nagbar_pid, bool wait_for_it); /** * Converts a string into a long using strtol(). diff --git a/include/workspace.h b/include/workspace.h index 69974a2..2193ed0 100644 --- a/include/workspace.h +++ b/include/workspace.h @@ -46,6 +46,19 @@ Con *get_existing_workspace_by_num(int num); /** + * Returns the first output that is assigned to a workspace specified by the + * given name or number. Returns NULL if no such output exists. + * + * If an assignment matches by number but there is an assignment later that + * matches by name, the second one is preferred. + * The order of the 'ws_assignments' queue is respected: if multiple + * assignments match the criteria, the first one is returned. + * 'name' is ignored when NULL, 'parsed_num' is ignored when it is -1. + * + */ +Con *get_assigned_output(const char *name, long parsed_num); + +/** * Returns true if the first output assigned to a workspace with the given * workspace assignment is the same as the given output. * @@ -57,11 +70,8 @@ * creating the workspace if necessary (by allocating the necessary amount of * memory and initializing the data structures correctly). * - * If created is not NULL, *created will be set to whether or not the - * workspace has just been created. - * */ -Con *workspace_get(const char *num, bool *created); +Con *workspace_get(const char *num); /** * Extracts workspace names from keybindings (e.g. “web” from “bindsym $mod+1 @@ -136,51 +146,6 @@ */ Con *workspace_back_and_forth_get(void); -#if 0 -/** - * Assigns the given workspace to the given screen by correctly updating its - * state and reconfiguring all the clients on this workspace. - * - * This is called when initializing a screen and when re-assigning it to a - * different screen which just got available (if you configured it to be on - * screen 1 and you just plugged in screen 1). - * - */ -void workspace_assign_to(Workspace *ws, Output *screen, bool hide_it); - -/** - * Initializes the given workspace if it is not already initialized. The given - * screen is to be understood as a fallback, if the workspace itself either - * was not assigned to a particular screen or cannot be placed there because - * the screen is not attached at the moment. - * - */ -void workspace_initialize(Workspace *ws, Output *screen, bool recheck); - -/** - * Gets the first unused workspace for the given screen, taking into account - * the preferred_screen setting of every workspace (workspace assignments). - * - */ -Workspace *get_first_workspace_for_output(Output *screen); - -/** - * Unmaps all clients (and stack windows) of the given workspace. - * - * This needs to be called separately when temporarily rendering a workspace - * which is not the active workspace to force reconfiguration of all clients, - * like in src/xinerama.c when re-assigning a workspace to another screen. - * - */ -void workspace_unmap_clients(xcb_connection_t *conn, Workspace *u_ws); - -/** - * Maps all clients (and stack windows) of the given workspace. - * - */ -void workspace_map_clients(xcb_connection_t *conn, Workspace *ws); -#endif - /** * Goes through all clients on the given workspace and updates the workspace’s * urgent flag accordingly. diff --git a/include/xcb.h b/include/xcb.h index 1513260..ba4ff2f 100644 --- a/include/xcb.h +++ b/include/xcb.h @@ -49,8 +49,12 @@ XCB_EVENT_MASK_FOCUS_CHANGE | \ XCB_EVENT_MASK_ENTER_WINDOW) +#include "i3-atoms_rest.xmacro.h" +#include "i3-atoms_NET_SUPPORTED.xmacro.h" + #define xmacro(atom) extern xcb_atom_t A_##atom; -#include "atoms.xmacro" +I3_NET_SUPPORTED_ATOMS_XMACRO +I3_REST_ATOMS_XMACRO #undef xmacro extern unsigned int xcb_numlock_mask; diff --git a/include/xinerama.h b/include/xinerama.h index f01ee56..52a5db3 100644 --- a/include/xinerama.h +++ b/include/xinerama.h @@ -13,8 +13,6 @@ #include -#include "data.h" - /** * We have just established a connection to the X server and need the initial * Xinerama information to setup workspaces for each screen. diff --git a/libi3/dpi.c b/libi3/dpi.c index d15e35b..dec38bc 100644 --- a/libi3/dpi.c +++ b/libi3/dpi.c @@ -9,6 +9,7 @@ #include #include + #include static long dpi; diff --git a/libi3/draw_util.c b/libi3/draw_util.c index 092ac96..313dc29 100644 --- a/libi3/draw_util.c +++ b/libi3/draw_util.c @@ -9,11 +9,10 @@ #include "libi3.h" #include -#include #include + #include #include -#include /* The default visual_type to use if none is specified when creating the surface. Must be defined globally. */ extern xcb_visualtype_t *visual_type; diff --git a/libi3/fake_configure_notify.c b/libi3/fake_configure_notify.c index 145f451..5d87c3d 100644 --- a/libi3/fake_configure_notify.c +++ b/libi3/fake_configure_notify.c @@ -8,7 +8,6 @@ #include "libi3.h" #include -#include #include #include diff --git a/libi3/font.c b/libi3/font.c index e01edb5..477509d 100644 --- a/libi3/font.c +++ b/libi3/font.c @@ -8,14 +8,12 @@ #include "libi3.h" #include +#include +#include +#include #include #include #include -#include -#include - -#include -#include static const i3Font *savedFont = NULL; diff --git a/libi3/format_placeholders.c b/libi3/format_placeholders.c index 770e383..71870a7 100644 --- a/libi3/format_placeholders.c +++ b/libi3/format_placeholders.c @@ -8,7 +8,6 @@ #include "libi3.h" #include -#include #include #ifndef CS_STARTS_WITH diff --git a/libi3/g_utf8_make_valid.c b/libi3/g_utf8_make_valid.c index b15873b..71beafd 100644 --- a/libi3/g_utf8_make_valid.c +++ b/libi3/g_utf8_make_valid.c @@ -19,8 +19,8 @@ #include "libi3.h" +#include #include -#include /* Copied from: * https://gitlab.gnome.org/GNOME/glib/blob/f928dfdf57bf92c883b53b16d7a9d49add504f52/glib/gutf8.c#L1752-1815 */ diff --git a/libi3/get_colorpixel.c b/libi3/get_colorpixel.c index 09ce70b..45e4772 100644 --- a/libi3/get_colorpixel.c +++ b/libi3/get_colorpixel.c @@ -6,22 +6,19 @@ * */ #include "libi3.h" +#include "queue.h" +#include #include -#include #include - -#include "queue.h" struct Colorpixel { char hex[8]; uint32_t pixel; - SLIST_ENTRY(Colorpixel) - colorpixels; + SLIST_ENTRY(Colorpixel) colorpixels; }; -SLIST_HEAD(colorpixel_head, Colorpixel) -colorpixels; +SLIST_HEAD(colorpixel_head, Colorpixel) colorpixels; /* * Returns the colorpixel to use for the given hex color (think of HTML). diff --git a/libi3/get_exe_path.c b/libi3/get_exe_path.c index 430fb2e..3b46ef8 100644 --- a/libi3/get_exe_path.c +++ b/libi3/get_exe_path.c @@ -7,12 +7,10 @@ */ #include "libi3.h" +#include +#include +#include #include -#include -#include -#include -#include -#include /* * This function returns the absolute path to the executable it is running in. diff --git a/libi3/get_mod_mask.c b/libi3/get_mod_mask.c index 98031d4..92af456 100644 --- a/libi3/get_mod_mask.c +++ b/libi3/get_mod_mask.c @@ -9,6 +9,7 @@ #include #include + #include #include diff --git a/libi3/get_process_filename.c b/libi3/get_process_filename.c index 7e2ecbd..21429ec 100644 --- a/libi3/get_process_filename.c +++ b/libi3/get_process_filename.c @@ -7,17 +7,11 @@ */ #include "libi3.h" -#include -#include +#include +#include #include -#include -#include -#include #include -#include -#include #include -#include /* * Returns the name of a temporary file with the specified prefix. diff --git a/libi3/ipc_connect.c b/libi3/ipc_connect.c index f659a1a..871fe08 100644 --- a/libi3/ipc_connect.c +++ b/libi3/ipc_connect.c @@ -7,14 +7,12 @@ */ #include "libi3.h" -#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include /* * Connects to the i3 IPC socket and returns the file descriptor for the diff --git a/libi3/ipc_recv_message.c b/libi3/ipc_recv_message.c index 84da5aa..516405b 100644 --- a/libi3/ipc_recv_message.c +++ b/libi3/ipc_recv_message.c @@ -7,15 +7,12 @@ */ #include "libi3.h" +#include +#include +#include +#include #include -#include -#include -#include #include -#include -#include - -#include /* * Reads a message from the given socket file descriptor and stores its length diff --git a/libi3/ipc_send_message.c b/libi3/ipc_send_message.c index c2cc012..4faeea7 100644 --- a/libi3/ipc_send_message.c +++ b/libi3/ipc_send_message.c @@ -7,14 +7,8 @@ */ #include "libi3.h" -#include -#include -#include +#include #include -#include -#include - -#include /* * Formats a message (payload) of the given size and type and sends it to i3 via diff --git a/libi3/is_debug_build.c b/libi3/is_debug_build.c index 52187bd..9458f75 100644 --- a/libi3/is_debug_build.c +++ b/libi3/is_debug_build.c @@ -8,7 +8,6 @@ #include "libi3.h" #include -#include /* * Returns true if this version of i3 is a debug build (anything which is not a @@ -17,10 +16,16 @@ */ bool is_debug_build(void) { /* i3_version contains either something like this: - * "4.0.2 (2011-11-11, branch "release")". - * or: "4.0.2-123-gCOFFEEBABE (2011-11-11, branch "next")". + * "4.0.2 (2011-11-11)" (release version) + * or: "4.0.2-123-gC0FFEE" (debug version) * * So we check for the offset of the first opening round bracket to * determine whether this is a git version or a release version. */ + if (strchr(I3_VERSION, '(') == NULL) { + return true; // e.g. 4.0.2-123-gC0FFEE + } + /* In practice, debug versions do not contain parentheses at all, + * but leave the logic as it was before so that we can re-add + * parentheses if we chose to. */ return ((strchr(I3_VERSION, '(') - I3_VERSION) > 10); } diff --git a/libi3/mkdirp.c b/libi3/mkdirp.c index 35a3047..d29bb95 100644 --- a/libi3/mkdirp.c +++ b/libi3/mkdirp.c @@ -12,7 +12,7 @@ #include #include -#ifndef HAVE_mkdirp +#ifndef HAVE_MKDIRP /* * Emulates mkdir -p (creates any missing folders) * diff --git a/libi3/root_atom_contents.c b/libi3/root_atom_contents.c index d6394d4..6feb31b 100644 --- a/libi3/root_atom_contents.c +++ b/libi3/root_atom_contents.c @@ -7,12 +7,9 @@ */ #include "libi3.h" -#include +#include +#include #include -#include -#include -#include -#include #include #include diff --git a/libi3/safewrappers.c b/libi3/safewrappers.c index fdea636..767a0f0 100644 --- a/libi3/safewrappers.c +++ b/libi3/safewrappers.c @@ -7,13 +7,11 @@ */ #include "libi3.h" -#include -#include -#include -#include -#include #include #include +#include +#include +#include /* * The s* functions (safe) are wrappers around malloc, strdup, …, which exits if one of diff --git a/libi3/string.c b/libi3/string.c index 9efa369..da18c55 100644 --- a/libi3/string.c +++ b/libi3/string.c @@ -11,10 +11,9 @@ */ #include "libi3.h" +#include #include #include - -#include struct _i3String { char *utf8; diff --git a/libi3/strndup.c b/libi3/strndup.c index e215a76..8911732 100644 --- a/libi3/strndup.c +++ b/libi3/strndup.c @@ -7,10 +7,9 @@ */ #include "libi3.h" -#include #include -#ifndef HAVE_strndup +#ifndef HAVE_STRNDUP /* * Taken from FreeBSD * Returns a pointer to a new string which is a duplicate of the diff --git a/libi3/ucs2_conversion.c b/libi3/ucs2_conversion.c index c651cdb..c746723 100644 --- a/libi3/ucs2_conversion.c +++ b/libi3/ucs2_conversion.c @@ -8,7 +8,6 @@ #include "libi3.h" #include -#include #include #include #include diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4 deleted file mode 100644 index 08f2e07..0000000 --- a/m4/ax_append_flag.m4 +++ /dev/null @@ -1,71 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_append_flag.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) -# -# DESCRIPTION -# -# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space -# added in between. -# -# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. -# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains -# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly -# FLAG. -# -# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. -# -# LICENSE -# -# Copyright (c) 2008 Guido U. Draheim -# Copyright (c) 2011 Maarten Bosmans -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 6 - -AC_DEFUN([AX_APPEND_FLAG], -[dnl -AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF -AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])]) -AS_VAR_SET_IF(FLAGS,[ - AS_CASE([" AS_VAR_GET(FLAGS) "], - [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])], - [ - AS_VAR_APPEND(FLAGS,[" $1"]) - AC_RUN_LOG([: FLAGS="$FLAGS"]) - ]) - ], - [ - AS_VAR_SET(FLAGS,[$1]) - AC_RUN_LOG([: FLAGS="$FLAGS"]) - ]) -AS_VAR_POPDEF([FLAGS])dnl -])dnl AX_APPEND_FLAG diff --git a/m4/ax_cflags_warn_all.m4 b/m4/ax_cflags_warn_all.m4 deleted file mode 100644 index 1f07799..0000000 --- a/m4/ax_cflags_warn_all.m4 +++ /dev/null @@ -1,122 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] -# AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] -# AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])] -# -# DESCRIPTION -# -# Try to find a compiler option that enables most reasonable warnings. -# -# For the GNU compiler it will be -Wall (and -ansi -pedantic) The result -# is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default. -# -# Currently this macro knows about the GCC, Solaris, Digital Unix, AIX, -# HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and -# Intel compilers. For a given compiler, the Fortran flags are much more -# experimental than their C equivalents. -# -# - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS -# - $2 add-value-if-not-found : nothing -# - $3 action-if-found : add value to shellvariable -# - $4 action-if-not-found : nothing -# -# NOTE: These macros depend on AX_APPEND_FLAG. -# -# LICENSE -# -# Copyright (c) 2008 Guido U. Draheim -# Copyright (c) 2010 Rhys Ulerich -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 15 - -AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl -AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl -AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl -AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings], -VAR,[VAR="no, unknown" -ac_save_[]FLAGS="$[]FLAGS" -for ac_arg dnl -in "-warn all % -warn all" dnl Intel - "-pedantic % -Wall" dnl GCC - "-xstrconst % -v" dnl Solaris C - "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix - "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX - "-ansi -ansiE % -fullwarn" dnl IRIX - "+ESlit % +w1" dnl HP-UX C - "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10) - "-h conform % -h msglevel 2" dnl Cray C (Unicos) - # -do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` - AC_COMPILE_IFELSE([AC_LANG_PROGRAM], - [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) -done -FLAGS="$ac_save_[]FLAGS" -]) -AS_VAR_POPDEF([FLAGS])dnl -AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) -case ".$VAR" in - .ok|.ok,*) m4_ifvaln($3,$3) ;; - .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;; - *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;; -esac -AS_VAR_POPDEF([VAR])dnl -])dnl AX_FLAGS_WARN_ALL -dnl implementation tactics: -dnl the for-argument contains a list of options. The first part of -dnl these does only exist to detect the compiler - usually it is -dnl a global option to enable -ansi or -extrawarnings. All other -dnl compilers will fail about it. That was needed since a lot of -dnl compilers will give false positives for some option-syntax -dnl like -Woption or -Xoption as they think of it is a pass-through -dnl to later compile stages or something. The "%" is used as a -dnl delimiter. A non-option comment can be given after "%%" marks -dnl which will be shown but not added to the respective C/CXXFLAGS. - -AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl -AC_LANG_PUSH([C]) -AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) -AC_LANG_POP([C]) -]) - -AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl -AC_LANG_PUSH([C++]) -AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) -AC_LANG_POP([C++]) -]) - -AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl -AC_LANG_PUSH([Fortran]) -AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) -AC_LANG_POP([Fortran]) -]) diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4 deleted file mode 100644 index ca36397..0000000 --- a/m4/ax_check_compile_flag.m4 +++ /dev/null @@ -1,74 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) -# -# DESCRIPTION -# -# Check whether the given FLAG works with the current language's compiler -# or gives an error. (Warnings, however, are ignored) -# -# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on -# success/failure. -# -# If EXTRA-FLAGS is defined, it is added to the current language's default -# flags (e.g. CFLAGS) when the check is done. The check is thus made with -# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to -# force the compiler to issue an error when a bad flag is given. -# -# INPUT gives an alternative input source to AC_COMPILE_IFELSE. -# -# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this -# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. -# -# LICENSE -# -# Copyright (c) 2008 Guido U. Draheim -# Copyright (c) 2011 Maarten Bosmans -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 4 - -AC_DEFUN([AX_CHECK_COMPILE_FLAG], -[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF -AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl -AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ - ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS - _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" - AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], - [AS_VAR_SET(CACHEVAR,[yes])], - [AS_VAR_SET(CACHEVAR,[no])]) - _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) -AS_VAR_IF(CACHEVAR,yes, - [m4_default([$2], :)], - [m4_default([$3], :)]) -AS_VAR_POPDEF([CACHEVAR])dnl -])dnl AX_CHECK_COMPILE_FLAGS diff --git a/m4/ax_check_enable_debug.m4 b/m4/ax_check_enable_debug.m4 deleted file mode 100644 index f99d75f..0000000 --- a/m4/ax_check_enable_debug.m4 +++ /dev/null @@ -1,124 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_check_enable_debug.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CHECK_ENABLE_DEBUG([enable by default=yes/info/profile/no], [ENABLE DEBUG VARIABLES ...], [DISABLE DEBUG VARIABLES NDEBUG ...], [IS-RELEASE]) -# -# DESCRIPTION -# -# Check for the presence of an --enable-debug option to configure, with -# the specified default value used when the option is not present. Return -# the value in the variable $ax_enable_debug. -# -# Specifying 'yes' adds '-g -O0' to the compilation flags for all -# languages. Specifying 'info' adds '-g' to the compilation flags. -# Specifying 'profile' adds '-g -pg' to the compilation flags and '-pg' to -# the linking flags. Otherwise, nothing is added. -# -# Define the variables listed in the second argument if debug is enabled, -# defaulting to no variables. Defines the variables listed in the third -# argument if debug is disabled, defaulting to NDEBUG. All lists of -# variables should be space-separated. -# -# If debug is not enabled, ensure AC_PROG_* will not add debugging flags. -# Should be invoked prior to any AC_PROG_* compiler checks. -# -# IS-RELEASE can be used to change the default to 'no' when making a -# release. Set IS-RELEASE to 'yes' or 'no' as appropriate. By default, it -# uses the value of $ax_is_release, so if you are using the AX_IS_RELEASE -# macro, there is no need to pass this parameter. -# -# AX_IS_RELEASE([git-directory]) -# AX_CHECK_ENABLE_DEBUG() -# -# LICENSE -# -# Copyright (c) 2011 Rhys Ulerich -# Copyright (c) 2014, 2015 Philip Withnall -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. - -#serial 5 - -AC_DEFUN([AX_CHECK_ENABLE_DEBUG],[ - AC_BEFORE([$0],[AC_PROG_CC])dnl - AC_BEFORE([$0],[AC_PROG_CXX])dnl - AC_BEFORE([$0],[AC_PROG_F77])dnl - AC_BEFORE([$0],[AC_PROG_FC])dnl - - AC_MSG_CHECKING(whether to enable debugging) - - ax_enable_debug_default=m4_tolower(m4_normalize(ifelse([$1],,[no],[$1]))) - ax_enable_debug_is_release=m4_tolower(m4_normalize(ifelse([$4],, - [$ax_is_release], - [$4]))) - - # If this is a release, override the default. - AS_IF([test "$ax_enable_debug_is_release" = "yes"], - [ax_enable_debug_default="no"]) - - m4_define(ax_enable_debug_vars,[m4_normalize(ifelse([$2],,,[$2]))]) - m4_define(ax_disable_debug_vars,[m4_normalize(ifelse([$3],,[NDEBUG],[$3]))]) - - AC_ARG_ENABLE(debug, - [AS_HELP_STRING([--enable-debug=]@<:@yes/info/profile/no@:>@,[compile with debugging])], - [],enable_debug=$ax_enable_debug_default) - - # empty mean debug yes - AS_IF([test "x$enable_debug" = "x"], - [enable_debug="yes"]) - - # case of debug - AS_CASE([$enable_debug], - [yes],[ - AC_MSG_RESULT(yes) - CFLAGS="${CFLAGS} -g -O0" - CXXFLAGS="${CXXFLAGS} -g -O0" - FFLAGS="${FFLAGS} -g -O0" - FCFLAGS="${FCFLAGS} -g -O0" - OBJCFLAGS="${OBJCFLAGS} -g -O0" - ], - [info],[ - AC_MSG_RESULT(info) - CFLAGS="${CFLAGS} -g" - CXXFLAGS="${CXXFLAGS} -g" - FFLAGS="${FFLAGS} -g" - FCFLAGS="${FCFLAGS} -g" - OBJCFLAGS="${OBJCFLAGS} -g" - ], - [profile],[ - AC_MSG_RESULT(profile) - CFLAGS="${CFLAGS} -g -pg" - CXXFLAGS="${CXXFLAGS} -g -pg" - FFLAGS="${FFLAGS} -g -pg" - FCFLAGS="${FCFLAGS} -g -pg" - OBJCFLAGS="${OBJCFLAGS} -g -pg" - LDFLAGS="${LDFLAGS} -pg" - ], - [ - AC_MSG_RESULT(no) - dnl Ensure AC_PROG_CC/CXX/F77/FC/OBJC will not enable debug flags - dnl by setting any unset environment flag variables - AS_IF([test "x${CFLAGS+set}" != "xset"], - [CFLAGS=""]) - AS_IF([test "x${CXXFLAGS+set}" != "xset"], - [CXXFLAGS=""]) - AS_IF([test "x${FFLAGS+set}" != "xset"], - [FFLAGS=""]) - AS_IF([test "x${FCFLAGS+set}" != "xset"], - [FCFLAGS=""]) - AS_IF([test "x${OBJCFLAGS+set}" != "xset"], - [OBJCFLAGS=""]) - ]) - - dnl Define various variables if debugging is disabled. - dnl assert.h is a NOP if NDEBUG is defined, so define it by default. - AS_IF([test "x$enable_debug" = "xyes"], - [m4_map_args_w(ax_enable_debug_vars, [AC_DEFINE(], [,,[Define if debugging is enabled])])], - [m4_map_args_w(ax_disable_debug_vars, [AC_DEFINE(], [,,[Define if debugging is disabled])])]) - ax_enable_debug=$enable_debug -]) diff --git a/m4/ax_check_gnu_make.m4 b/m4/ax_check_gnu_make.m4 deleted file mode 100644 index 6762e9e..0000000 --- a/m4/ax_check_gnu_make.m4 +++ /dev/null @@ -1,84 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_check_gnu_make.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CHECK_GNU_MAKE() -# -# DESCRIPTION -# -# This macro searches for a GNU version of make. If a match is found: -# -# * The makefile variable `ifGNUmake' is set to the empty string, otherwise -# it is set to "#". This is useful for including a special features in a -# Makefile, which cannot be handled by other versions of make. -# * The variable `_cv_gnu_make_command` is set to the command to invoke -# GNU make if it exists, the empty string otherwise. -# * The variable `ax_cv_gnu_make_command` is set to the command to invoke -# GNU make by copying `_cv_gnu_make_command`, otherwise it is unset. -# * If GNU Make is found, its version is extracted from the output of -# `make --version` as the last field of a record of space-separated -# columns and saved into the variable `ax_check_gnu_make_version`. -# -# Here is an example of its use: -# -# Makefile.in might contain: -# -# # A failsafe way of putting a dependency rule into a makefile -# $(DEPEND): -# $(CC) -MM $(srcdir)/*.c > $(DEPEND) -# -# @ifGNUmake@ ifeq ($(DEPEND),$(wildcard $(DEPEND))) -# @ifGNUmake@ include $(DEPEND) -# @ifGNUmake@ endif -# -# Then configure.in would normally contain: -# -# AX_CHECK_GNU_MAKE() -# AC_OUTPUT(Makefile) -# -# Then perhaps to cause gnu make to override any other make, we could do -# something like this (note that GNU make always looks for GNUmakefile -# first): -# -# if ! test x$_cv_gnu_make_command = x ; then -# mv Makefile GNUmakefile -# echo .DEFAULT: > Makefile ; -# echo \ $_cv_gnu_make_command \$@ >> Makefile; -# fi -# -# Then, if any (well almost any) other make is called, and GNU make also -# exists, then the other make wraps the GNU make. -# -# LICENSE -# -# Copyright (c) 2008 John Darrington -# Copyright (c) 2015 Enrico M. Crisostomo -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 8 - -AC_DEFUN([AX_CHECK_GNU_MAKE],dnl - [AC_PROG_AWK - AC_CACHE_CHECK([for GNU make],[_cv_gnu_make_command],[dnl - _cv_gnu_make_command="" ; -dnl Search all the common names for GNU make - for a in "$MAKE" make gmake gnumake ; do - if test -z "$a" ; then continue ; fi ; - if "$a" --version 2> /dev/null | grep GNU 2>&1 > /dev/null ; then - _cv_gnu_make_command=$a ; - AX_CHECK_GNU_MAKE_HEADLINE=$("$a" --version 2> /dev/null | grep "GNU Make") - ax_check_gnu_make_version=$(echo ${AX_CHECK_GNU_MAKE_HEADLINE} | ${AWK} -F " " '{ print $(NF); }') - break ; - fi - done ;]) -dnl If there was a GNU version, then set @ifGNUmake@ to the empty string, '#' otherwise - AS_VAR_IF([_cv_gnu_make_command], [""], [AS_VAR_SET([ifGNUmake], ["#"])], [AS_VAR_SET([ifGNUmake], [""])]) - AS_VAR_IF([_cv_gnu_make_command], [""], [AS_UNSET(ax_cv_gnu_make_command)], [AS_VAR_SET([ax_cv_gnu_make_command], [${_cv_gnu_make_command}])]) - AC_SUBST([ifGNUmake]) -]) diff --git a/m4/ax_check_link_flag.m4 b/m4/ax_check_link_flag.m4 deleted file mode 100644 index eb01a6c..0000000 --- a/m4/ax_check_link_flag.m4 +++ /dev/null @@ -1,74 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) -# -# DESCRIPTION -# -# Check whether the given FLAG works with the linker or gives an error. -# (Warnings, however, are ignored) -# -# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on -# success/failure. -# -# If EXTRA-FLAGS is defined, it is added to the linker's default flags -# when the check is done. The check is thus made with the flags: "LDFLAGS -# EXTRA-FLAGS FLAG". This can for example be used to force the linker to -# issue an error when a bad flag is given. -# -# INPUT gives an alternative input source to AC_LINK_IFELSE. -# -# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this -# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. -# -# LICENSE -# -# Copyright (c) 2008 Guido U. Draheim -# Copyright (c) 2011 Maarten Bosmans -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 4 - -AC_DEFUN([AX_CHECK_LINK_FLAG], -[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF -AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl -AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ - ax_check_save_flags=$LDFLAGS - LDFLAGS="$LDFLAGS $4 $1" - AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], - [AS_VAR_SET(CACHEVAR,[yes])], - [AS_VAR_SET(CACHEVAR,[no])]) - LDFLAGS=$ax_check_save_flags]) -AS_VAR_IF(CACHEVAR,yes, - [m4_default([$2], :)], - [m4_default([$3], :)]) -AS_VAR_POPDEF([CACHEVAR])dnl -])dnl AX_CHECK_LINK_FLAGS diff --git a/m4/ax_code_coverage.m4 b/m4/ax_code_coverage.m4 deleted file mode 100644 index 1f1bc70..0000000 --- a/m4/ax_code_coverage.m4 +++ /dev/null @@ -1,273 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_code_coverage.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CODE_COVERAGE() -# -# DESCRIPTION -# -# Defines CODE_COVERAGE_CPPFLAGS, CODE_COVERAGE_CFLAGS, -# CODE_COVERAGE_CXXFLAGS and CODE_COVERAGE_LDFLAGS which should be -# included in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LDFLAGS variables of -# every build target (program or library) which should be built with code -# coverage support. Also defines CODE_COVERAGE_RULES which should be -# substituted in your Makefile; and $enable_code_coverage which can be -# used in subsequent configure output. CODE_COVERAGE_ENABLED is defined -# and substituted, and corresponds to the value of the -# --enable-code-coverage option, which defaults to being disabled. -# -# Test also for gcov program and create GCOV variable that could be -# substituted. -# -# Note that all optimisation flags in CFLAGS must be disabled when code -# coverage is enabled. -# -# Usage example: -# -# configure.ac: -# -# AX_CODE_COVERAGE -# -# Makefile.am: -# -# @CODE_COVERAGE_RULES@ -# my_program_LIBS = ... $(CODE_COVERAGE_LDFLAGS) ... -# my_program_CPPFLAGS = ... $(CODE_COVERAGE_CPPFLAGS) ... -# my_program_CFLAGS = ... $(CODE_COVERAGE_CFLAGS) ... -# my_program_CXXFLAGS = ... $(CODE_COVERAGE_CXXFLAGS) ... -# -# This results in a "check-code-coverage" rule being added to any -# Makefile.am which includes "@CODE_COVERAGE_RULES@" (assuming the module -# has been configured with --enable-code-coverage). Running `make -# check-code-coverage` in that directory will run the module's test suite -# (`make check`) and build a code coverage report detailing the code which -# was touched, then print the URI for the report. -# -# This code was derived from Makefile.decl in GLib, originally licenced -# under LGPLv2.1+. -# -# LICENSE -# -# Copyright (c) 2012, 2016 Philip Withnall -# Copyright (c) 2012 Xan Lopez -# Copyright (c) 2012 Christian Persch -# Copyright (c) 2012 Paolo Borelli -# Copyright (c) 2012 Dan Winship -# Copyright (c) 2015 Bastien ROUCARIES -# -# This library is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or (at -# your option) any later version. -# -# This library is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -# General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see . - -#serial 15 - -AC_DEFUN([AX_CODE_COVERAGE],[ - dnl Check for --enable-code-coverage - AC_REQUIRE([AC_PROG_SED]) - - # allow to override gcov location - AC_ARG_WITH([gcov], - [AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])], - [_AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov], - [_AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov]) - - AC_MSG_CHECKING([whether to build with code coverage support]) - AC_ARG_ENABLE([code-coverage], - AS_HELP_STRING([--enable-code-coverage], - [Whether to enable code coverage support]),, - enable_code_coverage=no) - - AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes]) - AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage]) - AC_MSG_RESULT($enable_code_coverage) - - AS_IF([ test "$enable_code_coverage" = "yes" ], [ - # check for gcov - AC_CHECK_TOOL([GCOV], - [$_AX_CODE_COVERAGE_GCOV_PROG_WITH], - [:]) - AS_IF([test "X$GCOV" = "X:"], - [AC_MSG_ERROR([gcov is needed to do coverage])]) - AC_SUBST([GCOV]) - - dnl Check if gcc is being used - AS_IF([ test "$GCC" = "no" ], [ - AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage]) - ]) - - # List of supported lcov versions. - lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11 1.12 1.13" - - AC_CHECK_PROG([LCOV], [lcov], [lcov]) - AC_CHECK_PROG([GENHTML], [genhtml], [genhtml]) - - AS_IF([ test "$LCOV" ], [ - AC_CACHE_CHECK([for lcov version], ax_cv_lcov_version, [ - ax_cv_lcov_version=invalid - lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'` - for lcov_check_version in $lcov_version_list; do - if test "$lcov_version" = "$lcov_check_version"; then - ax_cv_lcov_version="$lcov_check_version (ok)" - fi - done - ]) - ], [ - lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list" - AC_MSG_ERROR([$lcov_msg]) - ]) - - case $ax_cv_lcov_version in - ""|invalid[)] - lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)." - AC_MSG_ERROR([$lcov_msg]) - LCOV="exit 0;" - ;; - esac - - AS_IF([ test -z "$GENHTML" ], [ - AC_MSG_ERROR([Could not find genhtml from the lcov package]) - ]) - - dnl Build the code coverage flags - CODE_COVERAGE_CPPFLAGS="-DNDEBUG" - CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" - CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" - CODE_COVERAGE_LDFLAGS="-lgcov" - - AC_SUBST([CODE_COVERAGE_CPPFLAGS]) - AC_SUBST([CODE_COVERAGE_CFLAGS]) - AC_SUBST([CODE_COVERAGE_CXXFLAGS]) - AC_SUBST([CODE_COVERAGE_LDFLAGS]) - ]) - -[CODE_COVERAGE_RULES=' -# Code coverage -# -# Optional: -# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting. -# Multiple directories may be specified, separated by whitespace. -# (Default: $(top_builddir)) -# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated -# by lcov for code coverage. (Default: -# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info) -# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage -# reports to be created. (Default: -# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage) -# - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage, -# set to 0 to disable it and leave empty to stay with the default. -# (Default: empty) -# - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov -# instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) -# - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov -# instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) -# - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov -# - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the -# collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) -# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov -# instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) -# - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering -# lcov instance. (Default: empty) -# - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov -# instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) -# - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the -# genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) -# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml -# instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) -# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore -# -# The generated report will be titled using the $(PACKAGE_NAME) and -# $(PACKAGE_VERSION). In order to add the current git hash to the title, -# use the git-version-gen script, available online. - -# Optional variables -CODE_COVERAGE_DIRECTORY ?= $(top_builddir) -CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info -CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage -CODE_COVERAGE_BRANCH_COVERAGE ?= -CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ ---rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) -CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) -CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)" -CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) -CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) -CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?= -CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) -CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\ -$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ ---rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) -CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULTS) -CODE_COVERAGE_IGNORE_PATTERN ?= - -code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V)) -code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY)) -code_coverage_v_lcov_cap_0 = @echo " LCOV --capture"\ - $(CODE_COVERAGE_OUTPUT_FILE); -code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V)) -code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY)) -code_coverage_v_lcov_ign_0 = @echo " LCOV --remove /tmp/*"\ - $(CODE_COVERAGE_IGNORE_PATTERN); -code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V)) -code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY)) -code_coverage_v_genhtml_0 = @echo " GEN " $(CODE_COVERAGE_OUTPUT_DIRECTORY); -code_coverage_quiet = $(code_coverage_quiet_$(V)) -code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY)) -code_coverage_quiet_0 = --quiet - -# sanitizes the test-name: replaces with underscores: dashes and dots -code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1))) - -# Use recursive makes in order to ignore errors during check -check-code-coverage: -ifeq ($(CODE_COVERAGE_ENABLED),yes) - -$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check - $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture -else - @echo "Need to reconfigure with --enable-code-coverage" -endif - -# Capture code coverage data -code-coverage-capture: code-coverage-capture-hook -ifeq ($(CODE_COVERAGE_ENABLED),yes) - $(code_coverage_v_lcov_cap)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(call code_coverage_sanitize,$(PACKAGE_NAME)-$(PACKAGE_VERSION))" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS) - $(code_coverage_v_lcov_ign)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS) - -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp - $(code_coverage_v_genhtml)LANG=C $(GENHTML) $(code_coverage_quiet) $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS) - @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html" -else - @echo "Need to reconfigure with --enable-code-coverage" -endif - -# Hook rule executed before code-coverage-capture, overridable by the user -code-coverage-capture-hook: - -ifeq ($(CODE_COVERAGE_ENABLED),yes) -clean: code-coverage-clean -code-coverage-clean: - -$(LCOV) --directory $(top_builddir) -z - -rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY) - -find . -name "*.gcda" -o -name "*.gcov" -delete -endif - -GITIGNOREFILES ?= -GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) - -A''M_DISTCHECK_CONFIGURE_FLAGS ?= -A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage - -.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean -'] - - AC_SUBST([CODE_COVERAGE_RULES]) - m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])]) -]) diff --git a/m4/ax_configure_args.m4 b/m4/ax_configure_args.m4 deleted file mode 100644 index 0726b1b..0000000 --- a/m4/ax_configure_args.m4 +++ /dev/null @@ -1,70 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_configure_args.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CONFIGURE_ARGS -# -# DESCRIPTION -# -# Helper macro for AX_ENABLE_BUILDDIR. -# -# The traditional way of starting a subdir-configure is running the script -# with ${1+"$@"} but since autoconf 2.60 this is broken. Instead we have -# to rely on eval'ing $ac_configure_args however some old autoconf -# versions do not provide that. To ensure maximum portability of autoconf -# extension macros this helper can be AC_REQUIRE'd so that -# $ac_configure_args will alsways be present. -# -# Sadly, the traditional "exec $SHELL" of the enable_builddir macros is -# spoiled now and must be replaced by "eval + exit $?". -# -# Example: -# -# AC_DEFUN([AX_ENABLE_SUBDIR],[dnl -# AC_REQUIRE([AX_CONFIGURE_ARGS])dnl -# eval $SHELL $ac_configure_args || exit $? -# ...]) -# -# LICENSE -# -# Copyright (c) 2008 Guido U. Draheim -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 9 - -AC_DEFUN([AX_CONFIGURE_ARGS],[ - # [$]@ is unsable in 2.60+ but earlier autoconf had no ac_configure_args - if test "${ac_configure_args+set}" != "set" ; then - ac_configure_args= - for ac_arg in ${1+"[$]@"}; do - ac_configure_args="$ac_configure_args '$ac_arg'" - done - fi -]) diff --git a/m4/ax_enable_builddir.m4 b/m4/ax_enable_builddir.m4 deleted file mode 100644 index 5f4ba32..0000000 --- a/m4/ax_enable_builddir.m4 +++ /dev/null @@ -1,302 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_enable_builddir.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_ENABLE_BUILDDIR [(dirstring-or-command [,Makefile.mk [,-all]])] -# -# DESCRIPTION -# -# If the current configure was run within the srcdir then we move all -# configure-files into a subdir and let the configure steps continue -# there. We provide an option --disable-builddir to suppress the move into -# a separate builddir. -# -# Defaults: -# -# $1 = $host (overridden with $HOST) -# $2 = Makefile.mk -# $3 = -all -# -# This macro must be called before AM_INIT_AUTOMAKE. It creates a default -# toplevel srcdir Makefile from the information found in the created -# toplevel builddir Makefile. It just copies the variables and -# rule-targets, each extended with a default rule-execution that recurses -# into the build directory of the current "HOST". You can override the -# auto-dection through `config.guess` and build-time of course, as in -# -# make HOST=i386-mingw-cross -# -# which can of course set at configure time as well using -# -# configure --host=i386-mingw-cross -# -# After the default has been created, additional rules can be appended -# that will not just recurse into the subdirectories and only ever exist -# in the srcdir toplevel makefile - these parts are read from the $2 = -# Makefile.mk file -# -# The automatic rules are usually scanning the toplevel Makefile for lines -# like '#### $host |$builddir' to recognize the place where to recurse -# into. Usually, the last one is the only one used. However, almost all -# targets have an additional "*-all" rule which makes the script to -# recurse into _all_ variants of the current HOST (!!) setting. The "-all" -# suffix can be overriden for the macro as well. -# -# a special rule is only given for things like "dist" that will copy the -# tarball from the builddir to the sourcedir (or $(PUB)) for reason of -# convenience. -# -# LICENSE -# -# Copyright (c) 2009 Guido U. Draheim -# Copyright (c) 2009 Alan Jenkins -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 25 - -AC_DEFUN([AX_ENABLE_BUILDDIR],[ -AC_REQUIRE([AC_CANONICAL_HOST])[]dnl -AC_REQUIRE([AC_CANONICAL_TARGET])[]dnl -AC_REQUIRE([AX_CONFIGURE_ARGS])[]dnl -AC_REQUIRE([AM_AUX_DIR_EXPAND])[]dnl -AC_BEFORE([$0],[AM_INIT_AUTOMAKE])dnl -AS_VAR_PUSHDEF([SUB],[ax_enable_builddir])dnl -AS_VAR_PUSHDEF([AUX],[ax_enable_builddir_auxdir])dnl -AS_VAR_PUSHDEF([SED],[ax_enable_builddir_sed])dnl -SUB="." -AC_ARG_ENABLE([builddir], AS_HELP_STRING( - [--disable-builddir],[disable automatic build in subdir of sources]) - ,[SUB="$enableval"], [SUB="auto"]) -if test ".$ac_srcdir_defaulted" != ".no" ; then -if test ".$srcdir" = ".." ; then - if test -f config.status ; then - AC_MSG_NOTICE(toplevel srcdir already configured... skipping subdir build) - else - test ".$SUB" = "." && SUB="." - test ".$SUB" = ".no" && SUB="." - test ".$TARGET" = "." && TARGET="$target" - test ".$SUB" = ".auto" && SUB="m4_ifval([$1], [$1],[$TARGET])" - if test ".$SUB" != ".." ; then # we know where to go and - AS_MKDIR_P([$SUB]) - echo __.$SUB.__ > $SUB/conftest.tmp - cd $SUB - if grep __.$SUB.__ conftest.tmp >/dev/null 2>/dev/null ; then - rm conftest.tmp - AC_MSG_RESULT([continue configure in default builddir "./$SUB"]) - else - AC_MSG_ERROR([could not change to default builddir "./$SUB"]) - fi - srcdir=`echo "$SUB" | - sed -e 's,^\./,,;s,[[^/]]$,&/,;s,[[^/]]*/,../,g;s,[[/]]$,,;'` - # going to restart from subdirectory location - test -f $srcdir/config.log && mv $srcdir/config.log . - test -f $srcdir/confdefs.h && mv $srcdir/confdefs.h . - test -f $srcdir/conftest.log && mv $srcdir/conftest.log . - test -f $srcdir/$cache_file && mv $srcdir/$cache_file . - AC_MSG_RESULT(....exec $SHELL $srcdir/[$]0 "--srcdir=$srcdir" "--enable-builddir=$SUB" ${1+"[$]@"}) - case "[$]0" in # restart - [[\\/]]* | ?:[[\\/]]*) # Asbolute name - eval $SHELL "'[$]0'" "'--srcdir=$srcdir'" "'--enable-builddir=$SUB'" $ac_configure_args ;; - *) eval $SHELL "'$srcdir/[$]0'" "'--srcdir=$srcdir'" "'--enable-builddir=$SUB'" $ac_configure_args ;; - esac ; exit $? - fi - fi -fi fi -test ".$SUB" = ".auto" && SUB="." -dnl ac_path_prog uses "set dummy" to override $@ which would defeat the "exec" -AC_PATH_PROG(SED,gsed sed, sed) -AUX="$am_aux_dir" -AS_VAR_POPDEF([SED])dnl -AS_VAR_POPDEF([AUX])dnl -AS_VAR_POPDEF([SUB])dnl -AC_CONFIG_COMMANDS([buildir],[dnl .............. config.status .............. -AS_VAR_PUSHDEF([SUB],[ax_enable_builddir])dnl -AS_VAR_PUSHDEF([TOP],[top_srcdir])dnl -AS_VAR_PUSHDEF([SRC],[ac_top_srcdir])dnl -AS_VAR_PUSHDEF([AUX],[ax_enable_builddir_auxdir])dnl -AS_VAR_PUSHDEF([SED],[ax_enable_builddir_sed])dnl -pushdef([END],[Makefile.mk])dnl -pushdef([_ALL],[ifelse([$3],,[-all],[$3])])dnl - SRC="$ax_enable_builddir_srcdir" - if test ".$SUB" = ".." ; then - if test -f "$TOP/Makefile" ; then - AC_MSG_NOTICE([skipping TOP/Makefile - left untouched]) - else - AC_MSG_NOTICE([skipping TOP/Makefile - not created]) - fi - else - if test -f "$SRC/Makefile" ; then - a=`grep "^VERSION " "$SRC/Makefile"` ; b=`grep "^VERSION " Makefile` - test "$a" != "$b" && rm "$SRC/Makefile" - fi - if test -f "$SRC/Makefile" ; then - echo "$SRC/Makefile : $SRC/Makefile.in" > $tmp/conftemp.mk - echo " []@ echo 'REMOVED,,,' >\$[]@" >> $tmp/conftemp.mk - eval "${MAKE-make} -f $tmp/conftemp.mk 2>/dev/null >/dev/null" - if grep '^REMOVED,,,' "$SRC/Makefile" >/dev/null - then rm $SRC/Makefile ; fi - cp $tmp/conftemp.mk $SRC/makefiles.mk~ ## DEBUGGING - fi - if test ! -f "$SRC/Makefile" ; then - AC_MSG_NOTICE([create TOP/Makefile guessed from local Makefile]) - x='`' ; cat >$tmp/conftemp.sed <<_EOF -/^\$/n -x -/^\$/bS -x -/\\\\\$/{H;d;} -{H;s/.*//;x;} -bM -:S -x -/\\\\\$/{h;d;} -{h;s/.*//;x;} -:M -s/\\(\\n\\) /\\1 /g -/^ /d -/^[[ ]]*[[\\#]]/d -/^VPATH *=/d -s/^srcdir *=.*/srcdir = ./ -s/^top_srcdir *=.*/top_srcdir = ./ -/[[:=]]/!d -/^\\./d -dnl Now handle rules (i.e. lines containing ":" but not " = "). -/ = /b -/ .= /b -/:/!b -s/:.*/:/ -s/ / /g -s/ \\([[a-z]][[a-z-]]*[[a-zA-Z0-9]]\\)\\([[ :]]\\)/ \\1 \\1[]_ALL\\2/g -s/^\\([[a-z]][[a-z-]]*[[a-zA-Z0-9]]\\)\\([[ :]]\\)/\\1 \\1[]_ALL\\2/ -s/ / /g -/^all all[]_ALL[[ :]]/i\\ -all-configured : all[]_ALL -dnl dist-all exists... and would make for dist-all-all -s/ [[a-zA-Z0-9-]]*[]_ALL [[a-zA-Z0-9-]]*[]_ALL[]_ALL//g -/[]_ALL[]_ALL/d -a\\ - @ HOST="\$(HOST)\" \\\\\\ - ; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\ - ; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\ - ; use=$x basename "\$\@" _ALL $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\ - ; echo "MAKE \$\$HOST : \$\$n * \$\@"; if test "\$\$n" -eq "0" ; then : \\\\\\ - ; BUILD=$x grep "^####.*|" Makefile |tail -1| sed -e 's/.*|//' $x ; fi \\\\\\ - ; test ".\$\$BUILD" = "." && BUILD="." \\\\\\ - ; test "\$\$use" = "\$\@" && BUILD=$x echo "\$\$BUILD" | tail -1 $x \\\\\\ - ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\ - ; (cd "\$\$i" && test ! -f configure && \$(MAKE) \$\$use) || exit; done -dnl special rule add-on: "dist" copies the tarball to $(PUB). (source tree) -/dist[]_ALL *:/a\\ - @ HOST="\$(HOST)\" \\\\\\ - ; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\ - ; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\ - ; found=$x echo \$\$BUILD | wc -w $x \\\\\\ - ; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).tar.*" \\\\\\ - ; if test "\$\$found" -eq "0" ; then : \\\\\\ - ; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\ - ; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\ - ; for f in \$\$i/\$(PACKAGE)-\$(VERSION).tar.* \\\\\\ - ; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done -dnl special rule add-on: "dist-foo" copies all the archives to $(PUB). (source tree) -/dist-[[a-zA-Z0-9]]*[]_ALL *:/a\\ - @ HOST="\$(HOST)\" \\\\\\ - ; test ".\$\$HOST" = "." && HOST=$x sh ./config.guess $x \\\\\\ - ; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\ - ; found=$x echo \$\$BUILD | wc -w $x \\\\\\ - ; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).*" \\\\\\ - ; if test "\$\$found" -eq "0" ; then : \\\\\\ - ; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\ - ; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\ - ; for f in \$\$i/\$(PACKAGE)-\$(VERSION).* \\\\\\ - ; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done -dnl special rule add-on: "distclean" removes all local builddirs completely -/distclean[]_ALL *:/a\\ - @ HOST="\$(HOST)\" \\\\\\ - ; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\ - ; BUILD=$x grep "^#### .*|" Makefile | sed -e 's/.*|//' $x \\\\\\ - ; use=$x basename "\$\@" _ALL $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\ - ; echo "MAKE \$\$HOST : \$\$n * \$\@ (all local builds)" \\\\\\ - ; test ".\$\$BUILD" = "." && BUILD="." \\\\\\ - ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\ - ; echo "# rm -r \$\$i"; done ; echo "# (sleep 3)" ; sleep 3 \\\\\\ - ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\ - ; echo "\$\$i" | grep "^/" > /dev/null && continue \\\\\\ - ; echo "\$\$i" | grep "^../" > /dev/null && continue \\\\\\ - ; echo "rm -r \$\$i"; (rm -r "\$\$i") ; done ; rm Makefile -_EOF - cp "$tmp/conftemp.sed" "$SRC/makefile.sed~" ## DEBUGGING - $SED -f $tmp/conftemp.sed Makefile >$SRC/Makefile - if test -f "$SRC/m4_ifval([$2],[$2],[END])" ; then - AC_MSG_NOTICE([extend TOP/Makefile with TOP/m4_ifval([$2],[$2],[END])]) - cat $SRC/END >>$SRC/Makefile - fi ; xxxx="####" - echo "$xxxx CONFIGURATIONS FOR TOPLEVEL MAKEFILE: " >>$SRC/Makefile - # sanity check - if grep '^; echo "MAKE ' $SRC/Makefile >/dev/null ; then - AC_MSG_NOTICE([buggy sed found - it deletes tab in "a" text parts]) - $SED -e '/^@ HOST=/s/^/ /' -e '/^; /s/^/ /' $SRC/Makefile \ - >$SRC/Makefile~ - (test -s $SRC/Makefile~ && mv $SRC/Makefile~ $SRC/Makefile) 2>/dev/null - fi - else - xxxx="\\#\\#\\#\\#" - # echo "/^$xxxx *$ax_enable_builddir_host /d" >$tmp/conftemp.sed - echo "s!^$xxxx [[^|]]* | *$SUB *\$!$xxxx ...... $SUB!" >$tmp/conftemp.sed - $SED -f "$tmp/conftemp.sed" "$SRC/Makefile" >$tmp/mkfile.tmp - cp "$tmp/conftemp.sed" "$SRC/makefiles.sed~" ## DEBUGGING - cp "$tmp/mkfile.tmp" "$SRC/makefiles.out~" ## DEBUGGING - if cmp -s "$SRC/Makefile" "$tmp/mkfile.tmp" 2>/dev/null ; then - AC_MSG_NOTICE([keeping TOP/Makefile from earlier configure]) - rm "$tmp/mkfile.tmp" - else - AC_MSG_NOTICE([reusing TOP/Makefile from earlier configure]) - mv "$tmp/mkfile.tmp" "$SRC/Makefile" - fi - fi - AC_MSG_NOTICE([build in $SUB (HOST=$ax_enable_builddir_host)]) - xxxx="####" - echo "$xxxx" "$ax_enable_builddir_host" "|$SUB" >>$SRC/Makefile - fi -popdef([END])dnl -AS_VAR_POPDEF([SED])dnl -AS_VAR_POPDEF([AUX])dnl -AS_VAR_POPDEF([SRC])dnl -AS_VAR_POPDEF([TOP])dnl -AS_VAR_POPDEF([SUB])dnl -],[dnl -ax_enable_builddir_srcdir="$srcdir" # $srcdir -ax_enable_builddir_host="$HOST" # $HOST / $host -ax_enable_builddir_version="$VERSION" # $VERSION -ax_enable_builddir_package="$PACKAGE" # $PACKAGE -ax_enable_builddir_auxdir="$ax_enable_builddir_auxdir" # $AUX -ax_enable_builddir_sed="$ax_enable_builddir_sed" # $SED -ax_enable_builddir="$ax_enable_builddir" # $SUB -])dnl -]) diff --git a/m4/ax_extend_srcdir.m4 b/m4/ax_extend_srcdir.m4 deleted file mode 100644 index 40f3787..0000000 --- a/m4/ax_extend_srcdir.m4 +++ /dev/null @@ -1,86 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_extend_srcdir.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_EXTEND_SRCDIR -# -# DESCRIPTION -# -# The AX_EXTEND_SRCDIR macro extends $srcdir by one path component. -# -# As an example, when working in /home/michael/i3-4.12/build and calling -# ../configure, your $srcdir is "..". After calling AX_EXTEND_SRCDIR, -# $srcdir will be set to "../../i3-4.12". -# -# The result of extending $srcdir is that filenames (e.g. in the output of -# the "backtrace" gdb command) will include one more path component of the -# absolute source path. The additional path component makes it easy for -# users to recognize which files belong to the PACKAGE, and -- provided a -# dist tarball was unpacked -- which version of PACKAGE was used. -# -# As an example, in "backtrace", you will see: -# -# #0 main (argc=1, argv=0x7fffffff1fc8) at ../../i3-4.12/src/main.c:187 -# -# instead of: -# -# #0 main (argc=1, argv=0x7fffffff1fc8) at ../src/main.c:187 -# -# In case your code uses the __FILE__ preprocessor directive to refer to -# the filename of the current source file (e.g. in debug messages), using -# the extended path might be undesirable. For this purpose, -# AX_EXTEND_SRCDIR defines the output variable AX_EXTEND_SRCDIR_CPPFLAGS, -# which can be added to AM_CPPFLAGS in Makefile.am in order to define the -# preprocessor directive STRIPPED__FILE__. As an example, when compiling -# the file "../../i3-4.12/src/main.c", STRIPPED__FILE__ evaluates to -# "main.c". -# -# There are some caveats: When $srcdir is "." (i.e. when ./configure was -# called instead of ../configure in a separate build directory), -# AX_EXTEND_SRCDIR will still extend $srcdir, but the intended effect will -# not be achieved because of the way automake specifies file paths: -# automake defines COMPILE to use "`test -f '$source' || echo -# '\$(srcdir)/'`$source" in order to prefer files in the current directory -# over specifying $srcdir explicitly. -# -# The AX_EXTEND_SRCDIR author is not aware of any way to influence this -# automake behavior. Patches very welcome. -# -# To work around this issue, you can use AX_ENABLE_BUILDDIR i.e. by adding -# the following code to configure.ac: -# -# AX_ENABLE_BUILDDIR -# dnl ... -# AX_EXTEND_SRCDIR -# -# Then also add this bit to Makefile.am (if you wish to use -# STRIPPED__FILE__ in your code): -# -# AM_CPPFLAGS = @AX_EXTEND_SRCDIR_CPPFLAGS@ -# -# LICENSE -# -# Copyright (c) 2016 Michael Stapelberg -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 3 - -AC_DEFUN([AX_EXTEND_SRCDIR], -[dnl -AS_CASE([$srcdir], - [.|.*|/*], - [ - # pwd -P is specified in IEEE 1003.1 from 2004 - as_dir=`cd "$srcdir" && pwd -P` - as_base=`AS_BASENAME([$as_dir])` - srcdir=${srcdir}/../${as_base} - - AC_SUBST([AX_EXTEND_SRCDIR_CPPFLAGS], ["-DSTRIPPED__FILE__=AS_ESCAPE([\"$$(basename $<)\"])"]) - ]) -])dnl AX_EXTEND_SRCDIR diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4 deleted file mode 100644 index 4c4051e..0000000 --- a/m4/ax_pthread.m4 +++ /dev/null @@ -1,485 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_pthread.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) -# -# DESCRIPTION -# -# This macro figures out how to build C programs using POSIX threads. It -# sets the PTHREAD_LIBS output variable to the threads library and linker -# flags, and the PTHREAD_CFLAGS output variable to any special C compiler -# flags that are needed. (The user can also force certain compiler -# flags/libs to be tested by setting these environment variables.) -# -# Also sets PTHREAD_CC to any special C compiler that is needed for -# multi-threaded programs (defaults to the value of CC otherwise). (This -# is necessary on AIX to use the special cc_r compiler alias.) -# -# NOTE: You are assumed to not only compile your program with these flags, -# but also to link with them as well. For example, you might link with -# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS -# -# If you are only building threaded programs, you may wish to use these -# variables in your default LIBS, CFLAGS, and CC: -# -# LIBS="$PTHREAD_LIBS $LIBS" -# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" -# CC="$PTHREAD_CC" -# -# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant -# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to -# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). -# -# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the -# PTHREAD_PRIO_INHERIT symbol is defined when compiling with -# PTHREAD_CFLAGS. -# -# ACTION-IF-FOUND is a list of shell commands to run if a threads library -# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it -# is not found. If ACTION-IF-FOUND is not specified, the default action -# will define HAVE_PTHREAD. -# -# Please let the authors know if this macro fails on any platform, or if -# you have any other suggestions or comments. This macro was based on work -# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help -# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by -# Alejandro Forero Cuervo to the autoconf macro repository. We are also -# grateful for the helpful feedback of numerous users. -# -# Updated for Autoconf 2.68 by Daniel Richard G. -# -# LICENSE -# -# Copyright (c) 2008 Steven G. Johnson -# Copyright (c) 2011 Daniel Richard G. -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or (at your -# option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 23 - -AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) -AC_DEFUN([AX_PTHREAD], [ -AC_REQUIRE([AC_CANONICAL_HOST]) -AC_REQUIRE([AC_PROG_CC]) -AC_REQUIRE([AC_PROG_SED]) -AC_LANG_PUSH([C]) -ax_pthread_ok=no - -# We used to check for pthread.h first, but this fails if pthread.h -# requires special compiler flags (e.g. on Tru64 or Sequent). -# It gets checked for in the link test anyway. - -# First of all, check if the user has set any of the PTHREAD_LIBS, -# etcetera environment variables, and if threads linking works using -# them: -if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then - ax_pthread_save_CC="$CC" - ax_pthread_save_CFLAGS="$CFLAGS" - ax_pthread_save_LIBS="$LIBS" - AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) - AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) - AC_MSG_RESULT([$ax_pthread_ok]) - if test "x$ax_pthread_ok" = "xno"; then - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" - fi - CC="$ax_pthread_save_CC" - CFLAGS="$ax_pthread_save_CFLAGS" - LIBS="$ax_pthread_save_LIBS" -fi - -# We must check for the threads library under a number of different -# names; the ordering is very important because some systems -# (e.g. DEC) have both -lpthread and -lpthreads, where one of the -# libraries is broken (non-POSIX). - -# Create a list of thread flags to try. Items starting with a "-" are -# C compiler flags, and other items are library names, except for "none" -# which indicates that we try without any flags at all, and "pthread-config" -# which is a program returning the flags for the Pth emulation library. - -ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" - -# The ordering *is* (sometimes) important. Some notes on the -# individual items follow: - -# pthreads: AIX (must check this before -lpthread) -# none: in case threads are in libc; should be tried before -Kthread and -# other compiler flags to prevent continual compiler warnings -# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) -# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 -# (Note: HP C rejects this with "bad form for `-t' option") -# -pthreads: Solaris/gcc (Note: HP C also rejects) -# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it -# doesn't hurt to check since this sometimes defines pthreads and -# -D_REENTRANT too), HP C (must be checked before -lpthread, which -# is present but should not be used directly; and before -mthreads, -# because the compiler interprets this as "-mt" + "-hreads") -# -mthreads: Mingw32/gcc, Lynx/gcc -# pthread: Linux, etcetera -# --thread-safe: KAI C++ -# pthread-config: use pthread-config program (for GNU Pth library) - -case $host_os in - - freebsd*) - - # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) - # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) - - ax_pthread_flags="-kthread lthread $ax_pthread_flags" - ;; - - hpux*) - - # From the cc(1) man page: "[-mt] Sets various -D flags to enable - # multi-threading and also sets -lpthread." - - ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" - ;; - - openedition*) - - # IBM z/OS requires a feature-test macro to be defined in order to - # enable POSIX threads at all, so give the user a hint if this is - # not set. (We don't define these ourselves, as they can affect - # other portions of the system API in unpredictable ways.) - - AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], - [ -# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) - AX_PTHREAD_ZOS_MISSING -# endif - ], - [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) - ;; - - solaris*) - - # On Solaris (at least, for some versions), libc contains stubbed - # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (N.B.: The stubs are missing - # pthread_cleanup_push, or rather a function called by this macro, - # so we could check for that, but who knows whether they'll stub - # that too in a future libc.) So we'll check first for the - # standard Solaris way of linking pthreads (-mt -lpthread). - - ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" - ;; -esac - -# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) - -AS_IF([test "x$GCC" = "xyes"], - [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) - -# The presence of a feature test macro requesting re-entrant function -# definitions is, on some systems, a strong hint that pthreads support is -# correctly enabled - -case $host_os in - darwin* | hpux* | linux* | osf* | solaris*) - ax_pthread_check_macro="_REENTRANT" - ;; - - aix*) - ax_pthread_check_macro="_THREAD_SAFE" - ;; - - *) - ax_pthread_check_macro="--" - ;; -esac -AS_IF([test "x$ax_pthread_check_macro" = "x--"], - [ax_pthread_check_cond=0], - [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) - -# Are we compiling with Clang? - -AC_CACHE_CHECK([whether $CC is Clang], - [ax_cv_PTHREAD_CLANG], - [ax_cv_PTHREAD_CLANG=no - # Note that Autoconf sets GCC=yes for Clang as well as GCC - if test "x$GCC" = "xyes"; then - AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], - [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ -# if defined(__clang__) && defined(__llvm__) - AX_PTHREAD_CC_IS_CLANG -# endif - ], - [ax_cv_PTHREAD_CLANG=yes]) - fi - ]) -ax_pthread_clang="$ax_cv_PTHREAD_CLANG" - -ax_pthread_clang_warning=no - -# Clang needs special handling, because older versions handle the -pthread -# option in a rather... idiosyncratic way - -if test "x$ax_pthread_clang" = "xyes"; then - - # Clang takes -pthread; it has never supported any other flag - - # (Note 1: This will need to be revisited if a system that Clang - # supports has POSIX threads in a separate library. This tends not - # to be the way of modern systems, but it's conceivable.) - - # (Note 2: On some systems, notably Darwin, -pthread is not needed - # to get POSIX threads support; the API is always present and - # active. We could reasonably leave PTHREAD_CFLAGS empty. But - # -pthread does define _REENTRANT, and while the Darwin headers - # ignore this macro, third-party headers might not.) - - PTHREAD_CFLAGS="-pthread" - PTHREAD_LIBS= - - ax_pthread_ok=yes - - # However, older versions of Clang make a point of warning the user - # that, in an invocation where only linking and no compilation is - # taking place, the -pthread option has no effect ("argument unused - # during compilation"). They expect -pthread to be passed in only - # when source code is being compiled. - # - # Problem is, this is at odds with the way Automake and most other - # C build frameworks function, which is that the same flags used in - # compilation (CFLAGS) are also used in linking. Many systems - # supported by AX_PTHREAD require exactly this for POSIX threads - # support, and in fact it is often not straightforward to specify a - # flag that is used only in the compilation phase and not in - # linking. Such a scenario is extremely rare in practice. - # - # Even though use of the -pthread flag in linking would only print - # a warning, this can be a nuisance for well-run software projects - # that build with -Werror. So if the active version of Clang has - # this misfeature, we search for an option to squash it. - - AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], - [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], - [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown - # Create an alternate version of $ac_link that compiles and - # links in two steps (.c -> .o, .o -> exe) instead of one - # (.c -> exe), because the warning occurs only in the second - # step - ax_pthread_save_ac_link="$ac_link" - ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' - ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` - ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" - ax_pthread_save_CFLAGS="$CFLAGS" - for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do - AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) - CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" - ac_link="$ax_pthread_save_ac_link" - AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], - [ac_link="$ax_pthread_2step_ac_link" - AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], - [break]) - ]) - done - ac_link="$ax_pthread_save_ac_link" - CFLAGS="$ax_pthread_save_CFLAGS" - AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) - ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" - ]) - - case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in - no | unknown) ;; - *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; - esac - -fi # $ax_pthread_clang = yes - -if test "x$ax_pthread_ok" = "xno"; then -for ax_pthread_try_flag in $ax_pthread_flags; do - - case $ax_pthread_try_flag in - none) - AC_MSG_CHECKING([whether pthreads work without any flags]) - ;; - - -mt,pthread) - AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) - PTHREAD_CFLAGS="-mt" - PTHREAD_LIBS="-lpthread" - ;; - - -*) - AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) - PTHREAD_CFLAGS="$ax_pthread_try_flag" - ;; - - pthread-config) - AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) - AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) - PTHREAD_CFLAGS="`pthread-config --cflags`" - PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" - ;; - - *) - AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) - PTHREAD_LIBS="-l$ax_pthread_try_flag" - ;; - esac - - ax_pthread_save_CFLAGS="$CFLAGS" - ax_pthread_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - - # Check for various functions. We must include pthread.h, - # since some functions may be macros. (On the Sequent, we - # need a special flag -Kthread to make this header compile.) - # We check for pthread_join because it is in -lpthread on IRIX - # while pthread_create is in libc. We check for pthread_attr_init - # due to DEC craziness with -lpthreads. We check for - # pthread_cleanup_push because it is one of the few pthread - # functions on Solaris that doesn't have a non-functional libc stub. - # We try pthread_create on general principles. - - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include -# if $ax_pthread_check_cond -# error "$ax_pthread_check_macro must be defined" -# endif - static void routine(void *a) { a = 0; } - static void *start_routine(void *a) { return a; }], - [pthread_t th; pthread_attr_t attr; - pthread_create(&th, 0, start_routine, 0); - pthread_join(th, 0); - pthread_attr_init(&attr); - pthread_cleanup_push(routine, 0); - pthread_cleanup_pop(0) /* ; */])], - [ax_pthread_ok=yes], - []) - - CFLAGS="$ax_pthread_save_CFLAGS" - LIBS="$ax_pthread_save_LIBS" - - AC_MSG_RESULT([$ax_pthread_ok]) - AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) - - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" -done -fi - -# Various other checks: -if test "x$ax_pthread_ok" = "xyes"; then - ax_pthread_save_CFLAGS="$CFLAGS" - ax_pthread_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - - # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. - AC_CACHE_CHECK([for joinable pthread attribute], - [ax_cv_PTHREAD_JOINABLE_ATTR], - [ax_cv_PTHREAD_JOINABLE_ATTR=unknown - for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], - [int attr = $ax_pthread_attr; return attr /* ; */])], - [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], - []) - done - ]) - AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ - test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ - test "x$ax_pthread_joinable_attr_defined" != "xyes"], - [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], - [$ax_cv_PTHREAD_JOINABLE_ATTR], - [Define to necessary symbol if this constant - uses a non-standard name on your system.]) - ax_pthread_joinable_attr_defined=yes - ]) - - AC_CACHE_CHECK([whether more special flags are required for pthreads], - [ax_cv_PTHREAD_SPECIAL_FLAGS], - [ax_cv_PTHREAD_SPECIAL_FLAGS=no - case $host_os in - solaris*) - ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" - ;; - esac - ]) - AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ - test "x$ax_pthread_special_flags_added" != "xyes"], - [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" - ax_pthread_special_flags_added=yes]) - - AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], - [ax_cv_PTHREAD_PRIO_INHERIT], - [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], - [[int i = PTHREAD_PRIO_INHERIT;]])], - [ax_cv_PTHREAD_PRIO_INHERIT=yes], - [ax_cv_PTHREAD_PRIO_INHERIT=no]) - ]) - AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ - test "x$ax_pthread_prio_inherit_defined" != "xyes"], - [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) - ax_pthread_prio_inherit_defined=yes - ]) - - CFLAGS="$ax_pthread_save_CFLAGS" - LIBS="$ax_pthread_save_LIBS" - - # More AIX lossage: compile with *_r variant - if test "x$GCC" != "xyes"; then - case $host_os in - aix*) - AS_CASE(["x/$CC"], - [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], - [#handle absolute path differently from PATH based program lookup - AS_CASE(["x$CC"], - [x/*], - [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], - [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) - ;; - esac - fi -fi - -test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" - -AC_SUBST([PTHREAD_LIBS]) -AC_SUBST([PTHREAD_CFLAGS]) -AC_SUBST([PTHREAD_CC]) - -# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: -if test "x$ax_pthread_ok" = "xyes"; then - ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) - : -else - ax_pthread_ok=no - $2 -fi -AC_LANG_POP -])dnl AX_PTHREAD diff --git a/m4/ax_require_defined.m4 b/m4/ax_require_defined.m4 deleted file mode 100644 index cae1111..0000000 --- a/m4/ax_require_defined.m4 +++ /dev/null @@ -1,37 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_require_defined.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_REQUIRE_DEFINED(MACRO) -# -# DESCRIPTION -# -# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have -# been defined and thus are available for use. This avoids random issues -# where a macro isn't expanded. Instead the configure script emits a -# non-fatal: -# -# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found -# -# It's like AC_REQUIRE except it doesn't expand the required macro. -# -# Here's an example: -# -# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) -# -# LICENSE -# -# Copyright (c) 2014 Mike Frysinger -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 1 - -AC_DEFUN([AX_REQUIRE_DEFINED], [dnl - m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) -])dnl AX_REQUIRE_DEFINED diff --git a/m4/ax_sanitizers.m4 b/m4/ax_sanitizers.m4 deleted file mode 100644 index 836d4af..0000000 --- a/m4/ax_sanitizers.m4 +++ /dev/null @@ -1,130 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_sanitizers.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_SANITIZERS([SANITIZERS], [ENABLED-BY-DEFAULT], [ACTION-SUCCESS]) -# -# DESCRIPTION -# -# Offers users to enable one or more sanitizers (see -# https://github.com/google/sanitizers) with the corresponding -# --enable--sanitizer option. -# -# SANITIZERS is a whitespace-separated list of sanitizers to offer via -# --enable--sanitizer options, e.g. "address memory" for the -# address sanitizer and the memory sanitizer. If SANITIZERS is not specified, -# all known sanitizers to AX_SANITIZERS will be offered, which at the time of -# writing are "address memory undefined". -# NOTE that SANITIZERS is expanded at autoconf time, not at configure time, -# i.e. you cannot use shell variables in SANITIZERS. -# -# ENABLED-BY-DEFAULT is a whitespace-separated list of sanitizers which -# should be enabled by default, e.g. "memory undefined". Note that not all -# sanitizers can be combined, e.g. memory sanitizer cannot be enabled when -# address sanitizer is already enabled. -# Set ENABLED-BY-DEFAULT to a single whitespace in order to disable all -# sanitizers by default. -# ENABLED-BY-DEFAULT is expanded at configure time, so you can use shell -# variables. -# -# ACTION-SUCCESS allows to specify shell commands to execute on success, i.e. -# when one of the sanitizers was successfully enabled. This is a good place -# to call AC_DEFINE for any precompiler constants you might need to make your -# code play nice with sanitizers. -# -# The variable ax_enabled_sanitizers contains a whitespace-separated list of -# all enabled sanitizers, so that you can print them at the end of configure, -# if you wish. -# -# The additional --enable-sanitizers option allows users to enable/disable -# all sanitizers, effectively overriding ENABLED-BY-DEFAULT. -# -# EXAMPLES -# -# AX_SANITIZERS([address]) -# dnl offer users to enable address sanitizer via --enable-address-sanitizer -# -# is_debug_build=… -# if test "x$is_debug_build" = "xyes"; then -# default_sanitizers="address memory" -# else -# default_sanitizers= -# fi -# AX_SANITIZERS([address memory], [$default_sanitizers]) -# dnl enable address sanitizer and memory sanitizer by default for debug -# dnl builds, e.g. when building from git instead of a dist tarball. -# -# AX_SANITIZERS(, , [ -# AC_DEFINE([SANITIZERS_ENABLED], -# [], -# [At least one sanitizer was enabled])]) -# dnl enable all sanitizers known to AX_SANITIZERS by default and set the -# dnl SANITIZERS_ENABLED precompiler constant. -# -# AX_SANITIZERS(, [ ]) -# dnl provide all sanitizers, but enable none by default. -# -# LICENSE -# -# Copyright (c) 2016 Michael Stapelberg -# -# Copying and distribution of this file, with or without modification, -# are permitted in any medium without royalty provided the copyright -# notice and this notice are preserved. This file is offered as-is, -# without any warranty. - -AC_DEFUN([AX_SANITIZERS], -[AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG]) -AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) -AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) -AC_ARG_ENABLE(sanitizers, - AS_HELP_STRING( - [--enable-sanitizers], - [enable all known sanitizers]), - [ax_sanitizers_default=$enableval], - [ax_sanitizers_default=]) -ax_enabled_sanitizers= -m4_foreach_w([mysan], m4_default($1, [address memory undefined]), [ - dnl If ax_sanitizers_default is unset, i.e. the user neither explicitly - dnl enabled nor explicitly disabled all sanitizers, we get the default value - dnl for this sanitizer based on whether it is listed in ENABLED-BY-DEFAULT. - AS_IF([test "x$ax_sanitizers_default" = "x"], [dnl - ax_sanitizer_default= - for mycheck in m4_default([$2], [address memory undefined]); do - AS_IF([test "x$mycheck" = "x[]mysan"], [ax_sanitizer_default=yes]) - done - AS_IF([test "x$ax_sanitizer_default" = "x"], [ax_sanitizer_default=no]) - ], - [ax_sanitizer_default=$ax_sanitizers_default]) - AC_ARG_ENABLE(mysan[]-sanitizer, - AS_HELP_STRING( - [--enable-[]mysan[]-sanitizer], - [enable -fsanitize=mysan]), - [ax_sanitizer_enabled=$enableval], - [ax_sanitizer_enabled=$ax_sanitizer_default]) - -AS_IF([test "x$ax_sanitizer_enabled" = "xyes"], [ -dnl Not using AX_APPEND_COMPILE_FLAGS and AX_APPEND_LINK_FLAGS because they -dnl lack the ability to specify ACTION-SUCCESS. - AX_CHECK_COMPILE_FLAG([-fsanitize=[]mysan], [ - AX_CHECK_LINK_FLAG([-fsanitize=[]mysan], [ - AX_APPEND_FLAG([-fsanitize=[]mysan], []) -dnl If and only if libtool is being used, LDFLAGS needs to contain -Wc,-fsanitize=…. -dnl See e.g. https://sources.debian.net/src/systemd/231-7/configure.ac/?hl=128#L135 -dnl TODO: how can recognize that situation and add -Wc,? - AX_APPEND_FLAG([-fsanitize=[]mysan], [LDFLAGS]) -dnl TODO: add -fPIE -pie for memory - # -fno-omit-frame-pointer results in nicer stack traces in error - # messages, see http://clang.llvm.org/docs/AddressSanitizer.html#usage - AX_CHECK_COMPILE_FLAG([-fno-omit-frame-pointer], [ - AX_APPEND_FLAG([-fno-omit-frame-pointer], [])]) -dnl TODO: at least for clang, we should specify exactly -O1, not -O2 or -O0, so that performance is reasonable but stacktraces are not tampered with (due to inlining), see http://clang.llvm.org/docs/AddressSanitizer.html#usage - m4_default([$3], :) - ax_enabled_sanitizers="[]mysan $ax_enabled_sanitizers" - ]) - ]) -]) -])dnl -])dnl AX_SANITIZERS diff --git a/meson/meson-dist-script b/meson/meson-dist-script new file mode 100755 index 0000000..47d9ce3 --- /dev/null +++ b/meson/meson-dist-script @@ -0,0 +1,36 @@ +#!/bin/sh + +set -eu + +cd "${MESON_DIST_ROOT}" + +# Delete everything we do not want to have in the release tarballs: +rm -rf \ + contrib/banner.svg \ + contrib/show-download-count.sh \ + contrib/sticker-7x5cm-stickma.tif.lzma \ + contrib/sticker_stickma_black.svg \ + debian/ \ + docs/GPN-2009-06-27/ \ + docs/NoName-2009-03-12/ \ + docs/slides-2012-01-25/ \ + docs/slides-2012-03-16/ \ + testcases/.gitignore \ + travis/ \ + .clang-format \ + .editorconfig \ + i3bar/.gitignore \ + .travis.yml \ + logo.svg \ + README.md \ + RELEASE-NOTES-next \ + release.sh + +mkdir build +cd build +meson .. -Dprefix=/usr -Ddocs=true -Dmans=true +ninja +cp *.1 ../man/ +cp *.html ../docs/ +cd .. +rm -rf build diff --git a/meson/meson-install-i3-with-shmlog b/meson/meson-install-i3-with-shmlog new file mode 100755 index 0000000..2290a47 --- /dev/null +++ b/meson/meson-install-i3-with-shmlog @@ -0,0 +1,2 @@ +#!/bin/sh +ln -sf "i3" "${MESON_INSTALL_DESTDIR_PREFIX}/$1/i3-with-shmlog" diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..11541e2 --- /dev/null +++ b/meson.build @@ -0,0 +1,719 @@ +# -*- mode: meson -*- + +# Style objective: be consistent with what mesonbuild.com documents/uses, and/or +# the meson book: https://meson-manual.com/ + +project( + 'i3', + 'c', + version: '4.19', + default_options: [ + 'c_std=c11', + 'warning_level=1', # enable all warnings (-Wall) + # TODO(https://github.com/i3/i3/issues/4087): switch to + # 'buildtype=debugoptimized', + ], + # Ubuntu 18.04 (supported until 2023) has meson 0.45. + # We can revisit our minimum supported meson version + # if it turns out to be too hard to maintain. + meson_version: '>=0.45.0', +) + +cc = meson.get_compiler('c') +add_project_arguments(cc.get_supported_arguments(['-Wunused-value']), language: 'c') + +if meson.version().version_compare('>=0.48.0') + # https://github.com/mesonbuild/meson/issues/2166#issuecomment-629696911 + meson.add_dist_script('meson/meson-dist-script') +else + message('meson <0.48.0 detected, dist tarballs will not be filtered') +endif + +################################################################################ +# Version handling +################################################################################ + +cdata = configuration_data() + +version_array = meson.project_version().split('.') +cdata.set('MAJOR_VERSION', version_array[0].to_int()) +cdata.set('MINOR_VERSION', version_array[1].to_int()) +if version_array.length() > 2 + cdata.set('PATCH_VERSION', version_array[2].to_int()) +else + cdata.set('PATCH_VERSION', 0) +endif +cdata.set_quoted('I3_VERSION', '@VCS_TAG@') +cdata.set_quoted('SYSCONFDIR', join_paths(get_option('prefix'), get_option('sysconfdir'))) + +if get_option('b_sanitize').split(',').contains('address') + cdata.set('I3_ASAN_ENABLED', 1) +endif + +cdata.set('HAVE_STRNDUP', cc.has_function('strndup')) +cdata.set('HAVE_MKDIRP', cc.has_function('mkdirp')) + +# Instead of generating config.h directly, make vcs_tag generate it so that +# @VCS_TAG@ is replaced. +config_h_in = configure_file( + output: 'config.h.in', + configuration: cdata, +) +config_h = declare_dependency( + sources: vcs_tag( + input: config_h_in, + output: 'config.h', + fallback: meson.project_version() + ' (2020-11-15)', + ) +) + +################################################################################ +# docs generation +################################################################################ + +docdir = get_option('docdir') +if docdir == '' + docdir = join_paths(get_option('datadir'), 'doc', 'i3') +endif + +if get_option('docs') + asciidoc = find_program('asciidoc') + doc_toc_inputs = [ + 'docs/hacking-howto', + 'docs/userguide', + 'docs/ipc', + 'docs/multi-monitor', + 'docs/wsbar', + 'docs/testsuite', + 'docs/i3bar-protocol', + 'docs/layout-saving', + ] + foreach m : doc_toc_inputs + custom_target( + m.underscorify()+'_asciidoc', + input: m, + output: '@BASENAME@.html', + command: [ + asciidoc, + '-a', 'toc', + '-n', + '-o', '@OUTPUT@', + '@INPUT@', + ], + install: true, + install_dir: docdir, + ) + endforeach + + doc_notoc_inputs = [ + 'docs/debugging', + ] + foreach m : doc_notoc_inputs + custom_target( + m.underscorify()+'_asciidoc', + input: m, + output: '@BASENAME@.html', + command: [ + asciidoc, + '-n', + '-o', '@OUTPUT@', + '@INPUT@', + ], + install: true, + install_dir: docdir, + ) + endforeach + +else + if run_command('[', '-f', 'docs/hacking-howto.html', ']').returncode() == 0 + install_data( + [ + 'docs/hacking-howto.html', + 'docs/userguide.html', + 'docs/ipc.html', + 'docs/multi-monitor.html', + 'docs/wsbar.html', + 'docs/testsuite.html', + 'docs/i3bar-protocol.html', + 'docs/layout-saving.html', + 'docs/debugging.html', + ], + install_dir: docdir, + ) + endif +endif + +install_data( + [ + 'docs/bigpicture.png', + 'docs/single_terminal.png', + 'docs/snapping.png', + 'docs/two_columns.png', + 'docs/two_terminals.png', + 'docs/modes.png', + 'docs/wsbar.png', + 'docs/keyboard-layer1.png', + 'docs/keyboard-layer2.png', + 'docs/i3-sync-working.png', + 'docs/i3-sync.png', + 'docs/tree-layout1.png', + 'docs/tree-layout2.png', + 'docs/tree-shot1.png', + 'docs/tree-shot2.png', + 'docs/tree-shot3.png', + 'docs/tree-shot4.png', + 'docs/refcard.html', + 'docs/refcard_style.css', + 'docs/logo-30.png', + 'docs/layout-saving-1.png', + ], + install_dir: docdir, +) + +if meson.version().version_compare('>=0.53') + summary('build docs (-Ddocs)', get_option('docs')) +endif + +################################################################################ +# manpages +################################################################################ + +man1 = join_paths(get_option('mandir'), 'man1') + +if get_option('mans') + asciidoc = find_program('asciidoc') + asciidoc_cdata = configuration_data() + asciidoc_cdata.set('PACKAGE_VERSION', meson.project_version()) + asciidoc_conf = configure_file( + input: 'man/asciidoc.conf.in', + output: 'asciidoc.conf', + configuration: asciidoc_cdata, + ) + + xmlto = find_program('xmlto') + + pod2man = find_program('pod2man') + + man_inputs = [ + 'man/i3.man', + 'man/i3bar.man', + 'man/i3-msg.man', + 'man/i3-input.man', + 'man/i3-nagbar.man', + 'man/i3-config-wizard.man', + 'man/i3-migrate-config-to-v4.man', + 'man/i3-sensible-editor.man', + 'man/i3-sensible-pager.man', + 'man/i3-sensible-terminal.man', + 'man/i3-dump-log.man', + ] + + foreach m : man_inputs + xml = custom_target( + m.underscorify()+'_asciidoc', + input: m, + output: '@BASENAME@.xml', + command: [ + asciidoc, + '-d', 'manpage', + '-b', 'docbook', + '-f', asciidoc_conf, + '-o', '@OUTPUT@', + '@INPUT@', + ], + ) + + custom_target( + m.underscorify()+'_xmlto', + input: xml, + output: '@BASENAME@.1', + command: [ + xmlto, + 'man', + '-o', + '@OUTDIR@', + '@INPUT@', + ], + # We should use install and install_dir instead of install_man as per: + # https://github.com/mesonbuild/meson/issues/4981#issuecomment-467084867 + # https://github.com/mesonbuild/meson/issues/1550#issuecomment-370164307 + install: true, + install_dir: man1, + ) + endforeach + + pod2man_inputs = [ + 'i3-dmenu-desktop', + 'i3-save-tree', + ] + foreach m : pod2man_inputs + custom_target( + m.underscorify()+'_pod2man', + input: m, + output: '@BASENAME@.1', + command: [ + pod2man, + '--utf8', + '@INPUT@', + '@OUTPUT@', + ], + # We should use install and install_dir instead of install_man as per: + # https://github.com/mesonbuild/meson/issues/4981#issuecomment-467084867 + # https://github.com/mesonbuild/meson/issues/1550#issuecomment-370164307 + install: true, + install_dir: man1, + ) + endforeach + +else + if run_command('[', '-f', 'man/i3.1', ']').returncode() == 0 + install_data( + [ + 'man/i3.1', + 'man/i3bar.1', + 'man/i3-msg.1', + 'man/i3-input.1', + 'man/i3-nagbar.1', + 'man/i3-config-wizard.1', + 'man/i3-migrate-config-to-v4.1', + 'man/i3-sensible-editor.1', + 'man/i3-sensible-pager.1', + 'man/i3-sensible-terminal.1', + 'man/i3-dump-log.1', + 'man/i3-dmenu-desktop.1', + 'man/i3-save-tree.1', + ], + install_dir: man1, + ) + endif +endif + +if meson.version().version_compare('>=0.53') + summary('build manpages (-Dmans)', get_option('mans')) +endif + +# Required for e.g. struct ucred to be defined as per unix(7). +add_project_arguments('-D_GNU_SOURCE', language: 'c') + +# https://mesonbuild.com/howtox.html#add-math-library-lm-portably +m_dep = cc.find_library('m', required: false) +rt_dep = cc.find_library('rt', required: false) +iconv_dep = cc.find_library('iconv', required: false) + +libsn_dep = dependency('libstartup-notification-1.0', method: 'pkg-config') +xcb_dep = dependency('xcb', method: 'pkg-config') +xcb_xkb_dep = dependency('xcb-xkb', method: 'pkg-config') +xcb_xinerama_dep = dependency('xcb-xinerama', method: 'pkg-config') +xcb_randr_dep = dependency('xcb-randr', method: 'pkg-config') +xcb_shape_dep = dependency('xcb-shape', method: 'pkg-config') +xcb_util_dep = dependency('xcb-util', method: 'pkg-config') +xcb_util_cursor_dep = dependency('xcb-cursor', method: 'pkg-config') +xcb_util_keysyms_dep = dependency('xcb-keysyms', method: 'pkg-config') +xcb_util_wm_dep = dependency('xcb-icccm', method: 'pkg-config') +xcb_util_xrm_dep = dependency('xcb-xrm', method: 'pkg-config') +xkbcommon_dep = dependency('xkbcommon', method: 'pkg-config') +xkbcommon_x11_dep = dependency('xkbcommon-x11', method: 'pkg-config') +yajl_dep = dependency('yajl', method: 'pkg-config') +libpcre_dep = dependency('libpcre', version: '>=8.10', method: 'pkg-config') +cairo_dep = dependency('cairo', version: '>=1.14.4', method: 'pkg-config') +pangocairo_dep = dependency('pangocairo', method: 'pkg-config') +glib_dep = dependency('glib-2.0', method: 'pkg-config') +gobject_dep = dependency('gobject-2.0', method: 'pkg-config') + +ev_dep = cc.find_library('ev') + +inc = include_directories('include') + +libi3srcs = [ + 'libi3/dpi.c', + 'libi3/draw_util.c', + 'libi3/fake_configure_notify.c', + 'libi3/font.c', + 'libi3/format_placeholders.c', + 'libi3/get_colorpixel.c', + 'libi3/get_config_path.c', + 'libi3/get_exe_path.c', + 'libi3/get_mod_mask.c', + 'libi3/get_process_filename.c', + 'libi3/get_visualtype.c', + 'libi3/g_utf8_make_valid.c', + 'libi3/ipc_connect.c', + 'libi3/ipc_recv_message.c', + 'libi3/ipc_send_message.c', + 'libi3/is_debug_build.c', + 'libi3/resolve_tilde.c', + 'libi3/root_atom_contents.c', + 'libi3/safewrappers.c', + 'libi3/string.c', + 'libi3/ucs2_conversion.c', +] + +if not cdata.get('HAVE_STRNDUP') + libi3srcs += 'libi3/strndup.c' +endif + +if not cdata.get('HAVE_MKDIRP') + libi3srcs += 'libi3/mkdirp.c' +endif + +libi3 = static_library( + 'i3', + libi3srcs, + include_directories: inc, + dependencies: [ + pangocairo_dep, + config_h, + ], +) + +i3srcs = [ + 'src/assignments.c', + 'src/bindings.c', + 'src/click.c', + 'src/commands.c', + 'src/commands_parser.c', + 'src/con.c', + 'src/config.c', + 'src/config_directives.c', + 'src/config_parser.c', + 'src/display_version.c', + 'src/drag.c', + 'src/ewmh.c', + 'src/fake_outputs.c', + 'src/floating.c', + 'src/handlers.c', + 'src/ipc.c', + 'src/key_press.c', + 'src/load_layout.c', + 'src/log.c', + 'src/main.c', + 'src/manage.c', + 'src/match.c', + 'src/move.c', + 'src/output.c', + 'src/randr.c', + 'src/regex.c', + 'src/render.c', + 'src/resize.c', + 'src/restore_layout.c', + 'src/scratchpad.c', + 'src/sd-daemon.c', + 'src/sighandler.c', + 'src/startup.c', + 'src/sync.c', + 'src/tree.c', + 'src/util.c', + 'src/version.c', + 'src/window.c', + 'src/workspace.c', + 'src/x.c', + 'src/xcb.c', + 'src/xcursor.c', + 'src/xinerama.c', +] + +# Verify the perl interpreter is present for running parser_gen, +# ensuring a good error message when it isn’t: +perl = find_program('perl') +parser_gen = find_program('generate-command-parser.pl') + +command_parser = custom_target( + 'command_parser', + input: 'parser-specs/commands.spec', + output: [ + 'GENERATED_command_enums.h', + 'GENERATED_command_tokens.h', + 'GENERATED_command_call.h', + ], + command: [perl, parser_gen, '--input=@INPUT@', '--prefix=command'], +) + +i3srcs += command_parser + +config_parser = custom_target( + 'config_parser', + input: 'parser-specs/config.spec', + output: [ + 'GENERATED_config_enums.h', + 'GENERATED_config_tokens.h', + 'GENERATED_config_call.h', + ], + command: [parser_gen, '--input=@INPUT@', '--prefix=config'], +) + +i3srcs += config_parser + +# src/log.c uses threading primitives for synchronization +thread_dep = dependency('threads') + +common_deps = [ + thread_dep, + m_dep, + iconv_dep, + rt_dep, + libsn_dep, + xcb_dep, + xcb_xkb_dep, + xcb_xinerama_dep, + xcb_randr_dep, + xcb_shape_dep, + xcb_util_dep, + xcb_util_cursor_dep, + xcb_util_keysyms_dep, + xcb_util_wm_dep, + xcb_util_xrm_dep, + xkbcommon_dep, + xkbcommon_x11_dep, + yajl_dep, + libpcre_dep, + cairo_dep, + pangocairo_dep, + glib_dep, + gobject_dep, + ev_dep, + config_h, +] + +executable( + 'i3', + i3srcs, + install: true, + include_directories: inc, + dependencies: common_deps, + link_with: libi3, +) + +# This is the only currently working way of installing a symbolic link: +meson.add_install_script( + 'meson/meson-install-i3-with-shmlog', + get_option('bindir'), +) + +executable( + 'i3bar', + [ + 'i3bar/src/child.c', + 'i3bar/src/config.c', + 'i3bar/src/ipc.c', + 'i3bar/src/main.c', + 'i3bar/src/mode.c', + 'i3bar/src/outputs.c', + 'i3bar/src/parse_json_header.c', + 'i3bar/src/workspaces.c', + 'i3bar/src/xcb.c', + ], + install: true, + include_directories: include_directories('include', 'i3bar/include'), + dependencies: common_deps, + link_with: libi3, +) + +executable( + 'i3-config-wizard', + [ + 'i3-config-wizard/i3-config-wizard-atoms.xmacro.h', + 'i3-config-wizard/main.c', + 'i3-config-wizard/xcb.h', + ], + install: true, + include_directories: include_directories('include', 'i3-config-wizard'), + dependencies: common_deps, + link_with: libi3, +) + +executable( + 'i3-dump-log', + 'i3-dump-log/main.c', + install: true, + include_directories: inc, + dependencies: common_deps, + link_with: libi3, +) + +executable( + 'i3-input', + [ + 'i3-input/i3-input.h', + 'i3-input/keysym2ucs.h', + 'i3-input/keysym2ucs.c', + 'i3-input/main.c', + ], + install: true, + include_directories: inc, + dependencies: common_deps, + link_with: libi3, +) + +executable( + 'i3-msg', + 'i3-msg/main.c', + install: true, + include_directories: inc, + dependencies: common_deps, + link_with: libi3, +) + +executable( + 'i3-nagbar', + [ + 'i3-nagbar/i3-nagbar-atoms.xmacro.h', + 'i3-nagbar/main.c', + ], + install: true, + include_directories: include_directories('include', 'i3-nagbar'), + dependencies: common_deps, + link_with: libi3, +) + +install_data( + [ + 'i3-dmenu-desktop', + 'i3-migrate-config-to-v4', + 'i3-save-tree', + 'i3-sensible-editor', + 'i3-sensible-pager', + 'i3-sensible-terminal', + ], + install_dir: 'bin', +) + +install_subdir( + 'etc', + strip_directory: true, + install_dir: join_paths(get_option('sysconfdir'), 'i3'), +) + +install_subdir( + 'share/', + strip_directory: true, + install_dir: get_option('datadir'), +) + +install_headers( + 'include/i3/ipc.h', + subdir: 'i3', +) + +# We cannot use configure_file for complete-run.pl.in and i3test.pm.in +# because configure_file strips the backslash in e.g. \@display, +# resulting in @display, breaking our Perl code: +# https://github.com/mesonbuild/meson/issues/7165 +bash = find_program('bash') +replace_dirs = [ + bash, '-c', # Use bash to capture output and mark as executable + 'sed -e \'s,@abs_top_builddir@,' + + meson.current_build_dir() + + ',g;s,@abs_top_srcdir@,' + + meson.current_source_dir()+',g\'' + # Only mark files ending in .pl as executables + + ' "$0" > "$1" && { [[ "${1##*.}" == pl ]] && chmod +x "$1" || true; }', + '@INPUT0@', # $0 + '@OUTPUT0@', # $1 +] +complete_run = custom_target( + 'complete-run', + input: ['testcases/complete-run.pl.in'], + output: ['complete-run.pl'], + command: replace_dirs, + # build this target when running e.g. ninja or ninja test. + # This is required for older meson versions (< 0.46.0). + build_by_default: true, +) +i3test_pm = custom_target( + 'i3test-pm', + input: ['testcases/lib/i3test.pm.in'], + output: ['i3test.pm'], + command: replace_dirs, + # build this target when running e.g. ninja or ninja test. + # This is required for older meson versions (< 0.46.0). + build_by_default: true, +) + +if get_option('docs') + i3_pod2html = find_program('docs/i3-pod2html') + + custom_target( + 'lib-i3test.html', + input: i3test_pm, + output: 'lib-i3test.html', + command: [ + i3_pod2html, + '@INPUT@', + '@OUTPUT@', + ], + install: true, + install_dir: join_paths(get_option('datadir'), 'doc', 'i3'), + ) + + custom_target( + 'lib-i3test-test.html', + input: 'testcases/lib/i3test/Test.pm', + output: 'lib-i3test-test.html', + command: [ + i3_pod2html, + '@INPUT@', + '@OUTPUT@', + ], + install: true, + install_dir: join_paths(get_option('datadir'), 'doc', 'i3'), + ) +endif + +executable( + 'test.inject_randr15', + 'testcases/inject_randr1.5.c', + include_directories: inc, + dependencies: common_deps, + link_with: libi3, +) + +executable( + 'test.commands_parser', + 'src/commands_parser.c', + include_directories: inc, + c_args: '-DTEST_PARSER', + dependencies: common_deps, + link_with: libi3, +) + +executable( + 'test.config_parser', + 'src/config_parser.c', + include_directories: inc, + c_args: '-DTEST_PARSER', + dependencies: common_deps, + link_with: libi3, +) + +anyevent_i3 = custom_target( + 'anyevent-i3', + # Should be AnyEvent-I3/blib/lib/AnyEvent/I3.pm, + # but see https://github.com/mesonbuild/meson/issues/2320 + output: 'AnyEvent-I3.stamp', + command: [ + 'sh', + '-c', + 'cp -r @0@/AnyEvent-I3 . && cd AnyEvent-I3 && perl Makefile.PL && make && touch ../AnyEvent-I3.stamp'.format(meson.current_source_dir()), + ], +) + +if meson.version().version_compare('>=0.46.0') + test( + 'complete-run', + perl, + args: [complete_run], + depends: [ + anyevent_i3, + i3test_pm, + ], + ) +else + # meson < 0.46.0 does not support the depends arg in test targets. + # Just hope for the best. + test( + 'complete-run', + perl, + args: [complete_run], + ) + message('meson < 0.46 detected, you might need to run ninja test twice') +endif diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000..0c4d4cf --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,10 @@ +# -*- mode: meson -*- + +option('docs', type: 'boolean', value: false, + description: 'Build documentation from source (release tarballs contain a generated copy)') + +option('mans', type: 'boolean', value: false, + description: 'Build manpages from source (release tarballs contain a generated copy)') + +option('docdir', type: 'string', value: '', + description: 'documentation directory (default: $datadir/docs/i3)') diff --git a/parser-specs/commands.spec b/parser-specs/commands.spec index f6e541e..20de3e4 100644 --- a/parser-specs/commands.spec +++ b/parser-specs/commands.spec @@ -149,7 +149,7 @@ -> call cmd_workspace_back_and_forth() 'number' -> WORKSPACE_NUMBER - workspace = string + workspace = string -> call cmd_workspace_name($workspace, $no_auto_back_and_forth) state WORKSPACE_NUMBER: @@ -339,14 +339,15 @@ new_name = string -> call cmd_rename_workspace($old_name, $new_name) -# move [ [px]] + +# move [ [px|ppt]] # move [window|container] [to] workspace [|next|prev|next_on_output|prev_on_output|current] # move [window|container] [to] output # move [window|container] [to] mark # move [window|container] [to] scratchpad # move workspace to [output] # move scratchpad -# move [window|container] [to] [absolute] position [ [ [px] [px]] | center ] +# move [window|container] [to] [absolute] position [ [ [px|ppt] [px|ppt] ] | center ] # move [window|container] [to] position mouse|cursor|pointer state MOVE: 'window' @@ -373,16 +374,16 @@ -> MOVE_TO_ABSOLUTE_POSITION state MOVE_DIRECTION: - pixels = number - -> MOVE_DIRECTION_PX - end - -> call cmd_move_direction($direction, 10) - -state MOVE_DIRECTION_PX: - 'px' - -> call cmd_move_direction($direction, &pixels) - end - -> call cmd_move_direction($direction, &pixels) + amount = number + -> MOVE_DIRECTION_NUMBER + end + -> call cmd_move_direction($direction, 10, "px") + +state MOVE_DIRECTION_NUMBER: + mode = 'px', 'ppt' + -> call cmd_move_direction($direction, &amount, $mode) + end + -> call cmd_move_direction($direction, &amount, "px") state MOVE_WORKSPACE: 'to ' @@ -427,14 +428,16 @@ -> MOVE_TO_POSITION_X state MOVE_TO_POSITION_X: - 'px' + mode_x = 'px', 'ppt' -> coord_y = number -> MOVE_TO_POSITION_Y state MOVE_TO_POSITION_Y: - 'px', end - -> call cmd_move_window_to_position(&coord_x, &coord_y) + mode_y = 'px', 'ppt' + -> call cmd_move_window_to_position(&coord_x, $mode_x, &coord_y, $mode_y) + end + -> call cmd_move_window_to_position(&coord_x, $mode_x, &coord_y, 0) # mode state MODE: @@ -472,21 +475,27 @@ # bar (hidden_state hide|show|toggle)|(mode dock|hide|invisible|toggle) [] state BAR: - bar_type = 'hidden_state' + 'hidden_state' -> BAR_HIDDEN_STATE - bar_type = 'mode' + 'mode' -> BAR_MODE state BAR_HIDDEN_STATE: bar_value = 'hide', 'show', 'toggle' - -> BAR_W_ID + -> BAR_HIDDEN_STATE_ID + +state BAR_HIDDEN_STATE_ID: + bar_id = word + -> + end + -> call cmd_bar_hidden_state($bar_value, $bar_id) state BAR_MODE: bar_value = 'dock', 'hide', 'invisible', 'toggle' - -> BAR_W_ID - -state BAR_W_ID: + -> BAR_MODE_ID + +state BAR_MODE_ID: bar_id = word -> end - -> call cmd_bar($bar_type, $bar_value, $bar_id) + -> call cmd_bar_mode($bar_value, $bar_id) diff --git a/release.sh b/release.sh index 095bc50..c6b045c 100755 --- a/release.sh +++ b/release.sh @@ -1,8 +1,8 @@ #!/bin/zsh # This script is used to prepare a new release of i3. -export RELEASE_VERSION="4.17" -export PREVIOUS_VERSION="4.16" +export RELEASE_VERSION="4.19" +export PREVIOUS_VERSION="4.18" export RELEASE_BRANCH="next" if [ ! -e "../i3.github.io" ] @@ -55,49 +55,43 @@ cp "${STARTDIR}/RELEASE-NOTES-${RELEASE_VERSION}" "RELEASE-NOTES-${RELEASE_VERSION}" git add RELEASE-NOTES-${RELEASE_VERSION} git rm RELEASE-NOTES-${PREVIOUS_VERSION} -sed -i "s,RELEASE-NOTES-${PREVIOUS_VERSION},RELEASE-NOTES-${RELEASE_VERSION},g" Makefile.am -sed -i "s/AC_INIT(\[i3\], \[${PREVIOUS_VERSION}\]/AC_INIT([i3], [${RELEASE_VERSION}]/" configure.ac -echo "${RELEASE_VERSION} ($(date +%F))" > I3_VERSION -git add I3_VERSION +sed -i "s/^\s*version: '${PREVIOUS_VERSION}'/ version: '${RELEASE_VERSION}'/" meson.build git commit -a -m "release i3 ${RELEASE_VERSION}" git tag "${RELEASE_VERSION}" -m "release i3 ${RELEASE_VERSION}" --sign --local-user=0x4AC8EE1D -autoreconf -fi mkdir build -(cd build && ../configure && make dist-bzip2 -j8) -cp build/i3-${RELEASE_VERSION}.tar.bz2 . +(cd build && meson .. && ninja dist) +cp build/meson-build/i3-${RELEASE_VERSION}.tar.xz . echo "Differences in the release tarball file lists:" -diff -u \ - <(tar tf ../i3-${PREVIOUS_VERSION}.tar.bz2 | sed "s,i3-${PREVIOUS_VERSION}/,,g" | sort) \ - <(tar tf i3-${RELEASE_VERSION}.tar.bz2 | sed "s,i3-${RELEASE_VERSION}/,,g" | sort) \ - | colordiff - - -gpg --armor -b i3-${RELEASE_VERSION}.tar.bz2 +diff --color -u \ + <(tar tf ../i3-${PREVIOUS_VERSION}.tar.xz | sed "s,i3-${PREVIOUS_VERSION}/,,g" | sort) \ + <(tar tf i3-${RELEASE_VERSION}.tar.xz | sed "s,i3-${RELEASE_VERSION}/,,g" | sort) + +gpg --armor -b i3-${RELEASE_VERSION}.tar.xz echo "${RELEASE_VERSION}-non-git" > I3_VERSION git add I3_VERSION git commit -a -m "Set non-git version to ${RELEASE_VERSION}-non-git." -if [ "${RELEASE_BRANCH}" = "master" ]; then - git checkout master +if [ "${RELEASE_BRANCH}" = "stable" ]; then + git checkout stable git merge --no-ff release-${RELEASE_VERSION} -m "Merge branch 'release-${RELEASE_VERSION}'" git checkout next - git merge --no-ff -s recursive -X ours -X no-renames master -m "Merge branch 'master' into next" + git merge --no-ff -s recursive -X ours -X no-renames stable -m "Merge branch 'stable' into next" else git checkout next git merge --no-ff release-${RELEASE_VERSION} -m "Merge branch 'release-${RELEASE_VERSION}'" - git checkout master - git merge --no-ff -s recursive -X theirs -X no-renames next -m "Merge branch 'next' into master" + git checkout stable + git merge --no-ff -s recursive -X theirs -X no-renames next -m "Merge branch 'next' into stable" fi git remote remove origin git remote add origin git@github.com:i3/i3.git git config --add remote.origin.push "+refs/tags/*:refs/tags/*" git config --add remote.origin.push "+refs/heads/next:refs/heads/next" -git config --add remote.origin.push "+refs/heads/master:refs/heads/master" +git config --add remote.origin.push "+refs/heads/stable:refs/heads/stable" ################################################################################ # Section 2: Debian packaging @@ -115,9 +109,9 @@ FROM debian:sid RUN sed -i 's,^deb \(.*\),deb \1\ndeb-src \1,g' /etc/apt/sources.list RUN apt-get update && apt-get install -y dpkg-dev devscripts -COPY i3/i3-${RELEASE_VERSION}.tar.bz2 /usr/src/i3-wm_${RELEASE_VERSION}.orig.tar.bz2 +COPY i3/i3-${RELEASE_VERSION}.tar.xz /usr/src/i3-wm_${RELEASE_VERSION}.orig.tar.xz WORKDIR /usr/src/ -RUN tar xf i3-wm_${RELEASE_VERSION}.orig.tar.bz2 +RUN tar xf i3-wm_${RELEASE_VERSION}.orig.tar.xz WORKDIR /usr/src/i3-${RELEASE_VERSION} COPY i3/debian /usr/src/i3-${RELEASE_VERSION}/debian/ RUN mkdir debian/source @@ -130,7 +124,7 @@ EOT CONTAINER_NAME=$(echo "i3-${TMPDIR}" | sed 's,/,,g') -docker build -t i3 . +docker build --no-cache -t i3 . for file in $(docker run --name "${CONTAINER_NAME}" i3 /bin/sh -c "ls /usr/src/i3*_${RELEASE_VERSION}*") do docker cp "${CONTAINER_NAME}:${file}" ${TMPDIR}/debian/ @@ -161,14 +155,14 @@ git add docs/${PREVIOUS_VERSION} git commit -a -m "save docs for ${PREVIOUS_VERSION}" -cp ${TMPDIR}/i3/i3-${RELEASE_VERSION}.tar.bz2* downloads/ -git add downloads/i3-${RELEASE_VERSION}.tar.bz2* +cp ${TMPDIR}/i3/i3-${RELEASE_VERSION}.tar.xz* downloads/ +git add downloads/i3-${RELEASE_VERSION}.tar.xz* cp ${TMPDIR}/i3/RELEASE-NOTES-${RELEASE_VERSION} downloads/RELEASE-NOTES-${RELEASE_VERSION}.txt git add downloads/RELEASE-NOTES-${RELEASE_VERSION}.txt sed -i "s,

Documentation for i3 v[^<]*

,

Documentation for i3 v${RELEASE_VERSION}

,g" docs/index.html sed -i "s,[^<]*,${RELEASE_VERSION},g" index.html sed -i "s,The current stable version is .*$,The current stable version is ${RELEASE_VERSION}.,g" downloads/index.html -sed -i "s,,\n \n ${RELEASE_VERSION}\n i3-${RELEASE_VERSION}.tar.bz2\n $(LC_ALL=en_US.UTF-8 ls -lh ../i3/i3-${RELEASE_VERSION}.tar.bz2 | awk -F " " {'print $5'} | sed 's/K$/ KiB/g' | sed 's/M$/ MiB/g')\n signature\n $(date +'%Y-%m-%d')\n release notes\n \n,g" downloads/index.html +sed -i "s,,\n \n ${RELEASE_VERSION}\n i3-${RELEASE_VERSION}.tar.xz\n $(LC_ALL=en_US.UTF-8 ls -lh ../i3/i3-${RELEASE_VERSION}.tar.xz | awk -F " " {'print $5'} | sed 's/K$/ KiB/g' | sed 's/M$/ MiB/g')\n signature\n $(date +'%Y-%m-%d')\n release notes\n \n,g" downloads/index.html git commit -a -m "add ${RELEASE_VERSION} release" diff --git a/src/bindings.c b/src/bindings.c index 03dc230..d6255e7 100644 --- a/src/bindings.c +++ b/src/bindings.c @@ -8,8 +8,10 @@ */ #include "all.h" +#include + +#include #include -#include static struct xkb_context *xkb_context; static struct xkb_keymap *xkb_keymap; @@ -626,6 +628,7 @@ ungrab_all_keys(conn); bindings = mode->bindings; + current_binding_mode = mode->name; translate_keysyms(); grab_all_keys(conn); diff --git a/src/click.c b/src/click.c index 12e391b..7a2c032 100644 --- a/src/click.c +++ b/src/click.c @@ -10,11 +10,6 @@ #include "all.h" #include -#include - -#include - -#include typedef enum { CLICK_BORDER = 0, CLICK_DECORATION = 1, @@ -277,14 +272,18 @@ /* 7: floating modifier pressed, initiate a resize */ if (dest == CLICK_INSIDE && mod_pressed && is_right_click) { - floating_mod_on_tiled_client(con, event); + if (floating_mod_on_tiled_client(con, event)) { + return; + } /* Avoid propagating events to clients, since the user expects - * $mod + click to be handled by i3. */ + * $mod+click to be handled by i3. */ + xcb_allow_events(conn, XCB_ALLOW_ASYNC_POINTER, event->time); + xcb_flush(conn); return; } /* 8: otherwise, check for border/decoration clicks and resize */ - else if ((dest == CLICK_BORDER || dest == CLICK_DECORATION) && - is_left_or_right_click) { + if ((dest == CLICK_BORDER || dest == CLICK_DECORATION) && + is_left_or_right_click) { DLOG("Trying to resize (tiling)\n"); tiling_resize(con, event, dest, dest == CLICK_DECORATION && !was_focused); } diff --git a/src/commands.c b/src/commands.c index 69bb426..26ea876 100644 --- a/src/commands.c +++ b/src/commands.c @@ -8,14 +8,11 @@ * */ #include "all.h" - +#include "shmlog.h" + +#include #include -#include -#include #include -#include - -#include "shmlog.h" // Macros to make the YAJL API a bit easier to use. #define y(x, ...) (cmd_output->json_gen != NULL ? yajl_gen_##x(cmd_output->json_gen, ##__VA_ARGS__) : 0) @@ -132,9 +129,7 @@ */ typedef struct owindow { Con *con; - - TAILQ_ENTRY(owindow) - owindows; + TAILQ_ENTRY(owindow) owindows; } owindow; typedef TAILQ_HEAD(owindows_head, owindow) owindows_head; @@ -362,7 +357,7 @@ LOG("should move window to workspace %s\n", name); /* get the workspace */ - Con *ws = workspace_get(name, NULL); + Con *ws = workspace_get(name); if (no_auto_back_and_forth == NULL) { ws = maybe_auto_back_and_forth_workspace(ws); @@ -393,7 +388,7 @@ Con *ws = get_existing_workspace_by_num(parsed_num); if (!ws) { - ws = workspace_get(which, NULL); + ws = workspace_get(which); } if (no_auto_back_and_forth == NULL) { @@ -1402,7 +1397,7 @@ CMD_FOCUS_WARN_CHILDREN; - Con *__i3_scratch = workspace_get("__i3_scratch", NULL); + Con *__i3_scratch = workspace_get("__i3_scratch"); owindow *current; TAILQ_FOREACH (current, &owindows, owindows) { Con *ws = con_get_workspace(current->con); @@ -1495,34 +1490,37 @@ } /* - * Implementation of 'move [ [px]]'. - * - */ -void cmd_move_direction(I3_CMD, const char *direction_str, long move_px) { + * Implementation of 'move [ [px|ppt]]'. + * + */ +void cmd_move_direction(I3_CMD, const char *direction_str, long amount, const char *mode) { owindow *current; HANDLE_EMPTY_MATCH; Con *initially_focused = focused; direction_t direction = parse_direction(direction_str); - TAILQ_FOREACH (current, &owindows, owindows) { - DLOG("moving in direction %s, px %ld\n", direction_str, move_px); + const bool is_ppt = mode && strcmp(mode, "ppt") == 0; + + DLOG("moving in direction %s, %ld %s\n", direction_str, amount, mode); + TAILQ_FOREACH (current, &owindows, owindows) { if (con_is_floating(current->con)) { - DLOG("floating move with %ld pixels\n", move_px); + DLOG("floating move with %ld %s\n", amount, mode); Rect newrect = current->con->parent->rect; + Con *output = con_get_output(current->con); switch (direction) { case D_LEFT: - newrect.x -= move_px; + newrect.x -= is_ppt ? output->rect.width * ((double)amount / 100.0) : amount; break; case D_RIGHT: - newrect.x += move_px; + newrect.x += is_ppt ? output->rect.width * ((double)amount / 100.0) : amount; break; case D_UP: - newrect.y -= move_px; + newrect.y -= is_ppt ? output->rect.height * ((double)amount / 100.0) : amount; break; case D_DOWN: - newrect.y += move_px; + newrect.y += is_ppt ? output->rect.height * ((double)amount / 100.0) : amount; break; } @@ -1618,14 +1616,25 @@ */ void cmd_reload(I3_CMD) { LOG("reloading\n"); - kill_nagbar(&config_error_nagbar_pid, false); - kill_nagbar(&command_error_nagbar_pid, false); + + kill_nagbar(config_error_nagbar_pid, false); + kill_nagbar(command_error_nagbar_pid, false); + /* start_nagbar() will refuse to start a new process if the passed pid is + * set. This will happen when our child watcher is triggered by libev when + * the loop re-starts. However, config errors might be detected before + * that since we will read the config right now with load_configuration. + * See #4104. */ + config_error_nagbar_pid = command_error_nagbar_pid = -1; + load_configuration(NULL, C_RELOAD); x_set_i3_atoms(); /* Send an IPC event just in case the ws names have changed */ ipc_send_workspace_event("reload", NULL, NULL); - /* Send an update event for the barconfig just in case it has changed */ - update_barconfig(); + /* Send an update event for each barconfig just in case it has changed */ + Barconfig *current; + TAILQ_FOREACH (current, &barconfigs, configs) { + ipc_send_barconfig_update_event(current); + } // XXX: default reply for now, make this a better reply ysuccess(true); @@ -1715,10 +1724,10 @@ } /* - * Implementation of 'move [window|container] [to] [absolute] position [px] [px] - * - */ -void cmd_move_window_to_position(I3_CMD, long x, long y) { + * Implementation of 'move [window|container] [to] [absolute] position [ [px|ppt] [px|ppt]] + * + */ +void cmd_move_window_to_position(I3_CMD, long x, const char *mode_x, long y, const char *mode_y) { bool has_error = false; owindow *current; @@ -1737,10 +1746,11 @@ } Rect newrect = current->con->parent->rect; - - DLOG("moving to position %ld %ld\n", x, y); - newrect.x = x; - newrect.y = y; + Con *output = con_get_output(current->con); + + newrect.x = mode_x && strcmp(mode_x, "ppt") == 0 ? output->rect.width * ((double)x / 100.0) : x; + newrect.y = mode_y && strcmp(mode_y, "ppt") == 0 ? output->rect.height * ((double)y / 100.0) : y; + DLOG("moving to position %d %s %d %s\n", newrect.x, mode_x, newrect.y, mode_y); if (!floating_reposition(current->con->parent, newrect)) { yerror("Cannot move window/container out of bounds."); @@ -2018,26 +2028,9 @@ con_attach(workspace, parent, false); ipc_send_workspace_event("rename", workspace, NULL); - /* Move the workspace to the correct output if it has an assignment */ - struct Workspace_Assignment *assignment = NULL; - TAILQ_FOREACH (assignment, &ws_assignments, ws_assignments) { - if (assignment->output == NULL) - continue; - if (strcmp(assignment->name, workspace->name) != 0 && (!name_is_digits(assignment->name) || ws_name_to_number(assignment->name) != workspace->num)) { - continue; - } - - Output *target_output = get_output_by_name(assignment->output, true); - if (!target_output) { - LOG("Could not get output named \"%s\"\n", assignment->output); - continue; - } - if (!output_triggers_assignment(target_output, assignment)) { - continue; - } - workspace_move_to_output(workspace, target_output); - - break; + Con *assigned = get_assigned_output(workspace->name, workspace->num); + if (assigned) { + workspace_move_to_output(workspace, get_output_for_con(assigned)); } bool can_restore_focus = previously_focused != NULL; @@ -2078,7 +2071,7 @@ * Implementation of 'bar mode dock|hide|invisible|toggle []' * */ -static bool cmd_bar_mode(const char *bar_mode, const char *bar_id) { +void cmd_bar_mode(I3_CMD, const char *bar_mode, const char *bar_id) { int mode = M_DOCK; bool toggle = false; if (strcmp(bar_mode, "dock") == 0) @@ -2091,39 +2084,53 @@ toggle = true; else { ELOG("Unknown bar mode \"%s\", this is a mismatch between code and parser spec.\n", bar_mode); - return false; - } - - bool changed_sth = false; + assert(false); + } + + if (TAILQ_EMPTY(&barconfigs)) { + yerror("No bars found\n"); + return; + } + Barconfig *current = NULL; TAILQ_FOREACH (current, &barconfigs, configs) { - if (bar_id && strcmp(current->id, bar_id) != 0) + if (bar_id && strcmp(current->id, bar_id) != 0) { continue; - - if (toggle) + } + + if (toggle) { mode = (current->mode + 1) % 2; - - DLOG("Changing bar mode of bar_id '%s' to '%s (%d)'\n", current->id, bar_mode, mode); - current->mode = mode; - changed_sth = true; - - if (bar_id) - break; - } - - if (bar_id && !changed_sth) { - DLOG("Changing bar mode of bar_id %s failed, bar_id not found.\n", bar_id); - return false; - } - - return true; + } + + DLOG("Changing bar mode of bar_id '%s' from '%d' to '%s (%d)'\n", + current->id, current->mode, bar_mode, mode); + if ((int)current->mode != mode) { + current->mode = mode; + ipc_send_barconfig_update_event(current); + } + + if (bar_id) { + /* We are looking for a specific bar and we found it */ + ysuccess(true); + return; + } + } + + if (bar_id) { + /* We are looking for a specific bar and we did not find it */ + yerror("Changing bar mode of bar_id %s failed, bar_id not found.\n", bar_id); + } else { + /* We have already handled the case of no bars, so we must have + * updated all active bars now. */ + ysuccess(true); + } } /* * Implementation of 'bar hidden_state hide|show|toggle []' * */ -static bool cmd_bar_hidden_state(const char *bar_hidden_state, const char *bar_id) { +void cmd_bar_hidden_state(I3_CMD, const char *bar_hidden_state, const char *bar_id) { int hidden_state = S_SHOW; bool toggle = false; if (strcmp(bar_hidden_state, "hide") == 0) @@ -2134,54 +2141,46 @@ toggle = true; else { ELOG("Unknown bar state \"%s\", this is a mismatch between code and parser spec.\n", bar_hidden_state); - return false; - } - - bool changed_sth = false; + assert(false); + } + + if (TAILQ_EMPTY(&barconfigs)) { + yerror("No bars found\n"); + return; + } + Barconfig *current = NULL; TAILQ_FOREACH (current, &barconfigs, configs) { - if (bar_id && strcmp(current->id, bar_id) != 0) + if (bar_id && strcmp(current->id, bar_id) != 0) { continue; - - if (toggle) + } + + if (toggle) { hidden_state = (current->hidden_state + 1) % 2; - - DLOG("Changing bar hidden_state of bar_id '%s' to '%s (%d)'\n", current->id, bar_hidden_state, hidden_state); - current->hidden_state = hidden_state; - changed_sth = true; - - if (bar_id) - break; - } - - if (bar_id && !changed_sth) { - DLOG("Changing bar hidden_state of bar_id %s failed, bar_id not found.\n", bar_id); - return false; - } - - return true; -} - -/* - * Implementation of 'bar (hidden_state hide|show|toggle)|(mode dock|hide|invisible|toggle) []' - * - */ -void cmd_bar(I3_CMD, const char *bar_type, const char *bar_value, const char *bar_id) { - bool ret; - if (strcmp(bar_type, "mode") == 0) - ret = cmd_bar_mode(bar_value, bar_id); - else if (strcmp(bar_type, "hidden_state") == 0) - ret = cmd_bar_hidden_state(bar_value, bar_id); - else { - ELOG("Unknown bar option type \"%s\", this is a mismatch between code and parser spec.\n", bar_type); - ret = false; - } - - ysuccess(ret); - if (!ret) - return; - - update_barconfig(); + } + + DLOG("Changing bar hidden_state of bar_id '%s' from '%d' to '%s (%d)'\n", + current->id, current->hidden_state, bar_hidden_state, hidden_state); + if ((int)current->hidden_state != hidden_state) { + current->hidden_state = hidden_state; + ipc_send_barconfig_update_event(current); + } + + if (bar_id) { + /* We are looking for a specific bar and we found it */ + ysuccess(true); + return; + } + } + + if (bar_id) { + /* We are looking for a specific bar and we did not find it */ + yerror("Changing bar hidden_state of bar_id %s failed, bar_id not found.\n", bar_id); + } else { + /* We have already handled the case of no bars, so we must have + * updated all active bars now. */ + ysuccess(true); + } } /* @@ -2244,32 +2243,8 @@ int pixels = logical_px(atoi(value)); Con *workspace = con_get_workspace(focused); -#define CMD_GAPS(type) \ +#define CMD_SET_GAPS_VALUE(type, value, reset) \ do { \ - int current_value = config.gaps.type; \ - if (strcmp(scope, "current") == 0) \ - current_value += workspace->gaps.type; \ - \ - bool reset = false; \ - if (!strcmp(mode, "plus")) \ - current_value += pixels; \ - else if (!strcmp(mode, "minus")) \ - current_value -= pixels; \ - else if (!strcmp(mode, "set")) { \ - current_value = pixels; \ - reset = true; \ - } else if (!strcmp(mode, "toggle")) { \ - current_value = !current_value * pixels; \ - reset = true; \ - } else { \ - ELOG("Invalid mode %s when changing gaps", mode); \ - ysuccess(false); \ - return; \ - } \ - \ - if (current_value < 0) \ - current_value = 0; \ - \ if (!strcmp(scope, "all")) { \ Con *output, *cur_ws = NULL; \ TAILQ_FOREACH (output, &(croot->nodes_head), nodes) { \ @@ -2277,19 +2252,71 @@ TAILQ_FOREACH (cur_ws, &(content->nodes_head), nodes) { \ if (reset) \ cur_ws->gaps.type = 0; \ - else if (current_value + cur_ws->gaps.type < 0) \ - cur_ws->gaps.type = -current_value; \ + else if (value + cur_ws->gaps.type < 0) \ + cur_ws->gaps.type = -value; \ } \ } \ \ - config.gaps.type = current_value; \ + config.gaps.type = value; \ } else { \ - workspace->gaps.type = current_value - config.gaps.type; \ + workspace->gaps.type = value - config.gaps.type; \ } \ } while (0) +#define CMD_GAPS(type) \ + do { \ + int current_value = config.gaps.type; \ + if (strcmp(scope, "current") == 0) \ + current_value += workspace->gaps.type; \ + \ + bool reset = false; \ + if (!strcmp(mode, "plus")) \ + current_value += pixels; \ + else if (!strcmp(mode, "minus")) \ + current_value -= pixels; \ + else if (!strcmp(mode, "set")) { \ + current_value = pixels; \ + reset = true; \ + } else if (!strcmp(mode, "toggle")) { \ + current_value = !current_value * pixels; \ + reset = true; \ + } else { \ + ELOG("Invalid mode %s when changing gaps", mode); \ + ysuccess(false); \ + return; \ + } \ + \ + /* see issue 262 */ \ + int min_value = 0; \ + if (strcmp(#type, "inner") != 0) { \ + min_value = strcmp(scope, "all") ? -config.gaps.inner - workspace->gaps.inner : -config.gaps.inner; \ + } \ + \ + if (current_value < min_value) \ + current_value = min_value; \ + \ + CMD_SET_GAPS_VALUE(type, current_value, reset); \ + } while (0) + +#define CMD_UPDATE_GAPS(type) \ + do { \ + if (!strcmp(scope, "all")) { \ + if (config.gaps.type + config.gaps.inner < 0) \ + CMD_SET_GAPS_VALUE(type, -config.gaps.inner, true); \ + } else { \ + if (config.gaps.type + workspace->gaps.type + config.gaps.inner + workspace->gaps.inner < 0) { \ + CMD_SET_GAPS_VALUE(type, -config.gaps.inner - workspace->gaps.inner, true); \ + } \ + } \ + } while (0) + if (!strcmp(type, "inner")) { CMD_GAPS(inner); + // update inconsistent values + CMD_UPDATE_GAPS(top); + CMD_UPDATE_GAPS(bottom); + CMD_UPDATE_GAPS(right); + CMD_UPDATE_GAPS(left); } else if (!strcmp(type, "outer")) { CMD_GAPS(top); CMD_GAPS(bottom); diff --git a/src/commands_parser.c b/src/commands_parser.c index 2fd7630..6c79141 100644 --- a/src/commands_parser.c +++ b/src/commands_parser.c @@ -24,13 +24,6 @@ * */ #include "all.h" - -#include -#include -#include -#include -#include -#include // Macros to make the YAJL API a bit easier to use. #define y(x, ...) (command_output.json_gen != NULL ? yajl_gen_##x(command_output.json_gen, ##__VA_ARGS__) : 0) diff --git a/src/con.c b/src/con.c index d9aaa5e..22f87c1 100644 --- a/src/con.c +++ b/src/con.c @@ -10,7 +10,6 @@ * */ #include "all.h" - #include "yajl_utils.h" static void con_on_remove_child(Con *con); @@ -92,8 +91,8 @@ FREE(mark->name); FREE(mark); } + DLOG("con %p freed\n", con); free(con); - DLOG("con %p freed\n", con); } static void _con_attach(Con *con, Con *parent, Con *previous, bool ignore_focus) { @@ -515,8 +514,7 @@ struct bfs_entry { Con *con; - TAILQ_ENTRY(bfs_entry) - entries; + TAILQ_ENTRY(bfs_entry) entries; }; /* @@ -528,9 +526,7 @@ /* TODO: is breadth-first-search really appropriate? (check as soon as * fullscreen levels and fullscreen for containers is implemented) */ - TAILQ_HEAD(bfs_head, bfs_entry) - bfs_head = TAILQ_HEAD_INITIALIZER(bfs_head); - + TAILQ_HEAD(bfs_head, bfs_entry) bfs_head = TAILQ_HEAD_INITIALIZER(bfs_head); struct bfs_entry *entry = smalloc(sizeof(struct bfs_entry)); entry->con = con; TAILQ_INSERT_TAIL(&bfs_head, entry, entries); @@ -1262,9 +1258,17 @@ } /* If moving a fullscreen container and the destination already has a - * fullscreen window on it, un-fullscreen the target's fullscreen con. */ + * fullscreen window on it, un-fullscreen the target's fullscreen con. + * con->fullscreen_mode is not enough in some edge cases: + * 1. con is CT_FLOATING_CON, child is fullscreen. + * 2. con is the parent of a fullscreen container, can be triggered by + * moving the parent with command criteria. + */ Con *fullscreen = con_get_fullscreen_con(target_ws, CF_OUTPUT); - if (con->fullscreen_mode != CF_NONE && fullscreen != NULL) { + const bool con_has_fullscreen = con->fullscreen_mode != CF_NONE || + con_get_fullscreen_con(con, CF_GLOBAL) || + con_get_fullscreen_con(con, CF_OUTPUT); + if (con_has_fullscreen && fullscreen != NULL) { con_toggle_fullscreen(fullscreen, CF_OUTPUT); fullscreen = NULL; } @@ -1363,7 +1367,7 @@ } /* For target containers in the scratchpad, we just send the window to the scratchpad. */ - if (con_get_workspace(target) == workspace_get("__i3_scratch", NULL)) { + if (con_get_workspace(target) == workspace_get("__i3_scratch")) { DLOG("target container is in the scratchpad, moving container to scratchpad.\n"); scratchpad_move(con); return true; @@ -2373,11 +2377,11 @@ char *formatted_str = format_placeholders(con->title_format, &placeholders[0], num); i3String *formatted = i3string_from_utf8(formatted_str); i3string_set_markup(formatted, pango_markup); - FREE(formatted_str); - - for (size_t i = 0; i < num; i++) { - FREE(placeholders[i].value); - } + + free(formatted_str); + free(title); + free(class); + free(instance); return formatted; } diff --git a/src/config.c b/src/config.c index 112f2ba..77ba38c 100644 --- a/src/config.c +++ b/src/config.c @@ -26,17 +26,6 @@ void ungrab_all_keys(xcb_connection_t *conn) { DLOG("Ungrabbing all keys\n"); xcb_ungrab_key(conn, XCB_GRAB_ANY, root, XCB_BUTTON_MASK_ANY); -} - -/* - * Sends the current bar configuration as an event to all barconfig_update listeners. - * - */ -void update_barconfig(void) { - Barconfig *current; - TAILQ_FOREACH (current, &barconfigs, configs) { - ipc_send_barconfig_update_event(current); - } } static void free_configuration(void) { @@ -185,6 +174,7 @@ SLIST_INSERT_HEAD(&modes, default_mode, modes); bindings = default_mode->bindings; + current_binding_mode = default_mode->name; /* Clear the old config or initialize the data structure */ memset(&config, 0, sizeof(config)); diff --git a/src/config_directives.c b/src/config_directives.c index cf81cc1..5236254 100644 --- a/src/config_directives.c +++ b/src/config_directives.c @@ -8,9 +8,6 @@ * */ #include "all.h" - -#include -#include /******************************************************************************* * Criteria functions. diff --git a/src/config_parser.c b/src/config_parser.c index f120cfa..f78e75f 100644 --- a/src/config_parser.c +++ b/src/config_parser.c @@ -25,16 +25,17 @@ */ #include "all.h" +#include +#include +#include #include #include #include -#include -#include -#include +#include #include #include -#include -#include +#include + #include // Macros to make the YAJL API a bit easier to use. diff --git a/src/display_version.c b/src/display_version.c index e44540e..32250c1 100644 --- a/src/display_version.c +++ b/src/display_version.c @@ -10,13 +10,9 @@ */ #include "all.h" -#include -#include -#include -#include -#include #include #include +#include static bool human_readable_key, loaded_config_file_name_key; static char *human_readable_version, *loaded_config_file_name; diff --git a/src/ewmh.c b/src/ewmh.c index 1cdf894..c61fb5f 100644 --- a/src/ewmh.c +++ b/src/ewmh.c @@ -8,6 +8,8 @@ * */ #include "all.h" + +#include "i3-atoms_NET_SUPPORTED.xmacro.h" xcb_window_t ewmh_window; @@ -305,7 +307,7 @@ void ewmh_setup_hints(void) { xcb_atom_t supported_atoms[] = { #define xmacro(atom) A_##atom, -#include "atoms_NET_SUPPORTED.xmacro" + I3_NET_SUPPORTED_ATOMS_XMACRO #undef xmacro }; diff --git a/src/floating.c b/src/floating.c index fd313a5..02e6ac3 100644 --- a/src/floating.c +++ b/src/floating.c @@ -8,6 +8,8 @@ * */ #include "all.h" + +#include #ifndef MAX #define MAX(x, y) ((x) > (y) ? (x) : (y)) @@ -221,22 +223,22 @@ } } -void floating_enable(Con *con, bool automatic) { +bool floating_enable(Con *con, bool automatic) { bool set_focus = (con == focused); if (con_is_docked(con)) { LOG("Container is a dock window, not enabling floating mode.\n"); - return; + return false; } if (con_is_floating(con)) { LOG("Container is already in floating mode, not doing anything.\n"); - return; + return false; } if (con->type == CT_WORKSPACE) { LOG("Container is a workspace, not enabling floating mode.\n"); - return; + return false; } Con *focus_head_placeholder = NULL; @@ -419,6 +421,7 @@ floating_set_hint_atom(nc, true); ipc_send_window_event("floating", con); + return true; } void floating_disable(Con *con) { diff --git a/src/handlers.c b/src/handlers.c index d6d6e20..eba5fe2 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -10,9 +10,9 @@ */ #include "all.h" +#include #include -#include -#include + #include #define SN_API_NOT_YET_FROZEN 1 #include @@ -727,7 +727,7 @@ return; } - if (con_is_internal(ws) && ws != workspace_get("__i3_scratch", NULL)) { + if (con_is_internal(ws) && ws != workspace_get("__i3_scratch")) { DLOG("Workspace is internal but not scratchpad, ignoring _NET_ACTIVE_WINDOW\n"); return; } @@ -841,12 +841,13 @@ * let's float it and make it sticky. */ DLOG("The window was requested to be visible on all workspaces, making it sticky and floating.\n"); - floating_enable(con, false); - con->floating = FLOATING_AUTO_ON; - - con->sticky = true; - ewmh_update_sticky(con->window->id, true); - output_push_sticky_windows(focused); + if (floating_enable(con, false)) { + con->floating = FLOATING_AUTO_ON; + + con->sticky = true; + ewmh_update_sticky(con->window->id, true); + output_push_sticky_windows(focused); + } } else { Con *ws = ewmh_get_workspace_by_index(index); if (ws == NULL) { diff --git a/src/ipc.c b/src/ipc.c index e2b9725..eac4d9b 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -7,23 +7,25 @@ * ipc.c: UNIX domain socket IPC (initialization, client handling, protocol). * */ + #include "all.h" - #include "yajl_utils.h" +#include +#include +#include +#include #include #include #include -#include -#include -#include +#include + #include #include char *current_socketpath = NULL; -TAILQ_HEAD(ipc_client_head, ipc_client) -all_clients = TAILQ_HEAD_INITIALIZER(all_clients); +TAILQ_HEAD(ipc_client_head, ipc_client) all_clients = TAILQ_HEAD_INITIALIZER(all_clients); /* * Puts the given socket file descriptor into non-blocking mode or dies if @@ -1363,9 +1365,27 @@ ipc_send_client_message(client, strlen(reply), I3_IPC_REPLY_TYPE_SYNC, (const uint8_t *)reply); } +IPC_HANDLER(get_binding_state) { + yajl_gen gen = ygenalloc(); + + y(map_open); + + ystr("name"); + ystr(current_binding_mode); + + y(map_close); + + const unsigned char *payload; + ylength length; + y(get_buf, &payload, &length); + + ipc_send_client_message(client, length, I3_IPC_REPLY_TYPE_GET_BINDING_STATE, payload); + y(free); +} + /* The index of each callback function corresponds to the numeric * value of the message type (see include/i3/ipc.h) */ -handler_t handlers[12] = { +handler_t handlers[13] = { handle_run_command, handle_get_workspaces, handle_subscribe, @@ -1378,6 +1398,7 @@ handle_get_config, handle_send_tick, handle_sync, + handle_get_binding_state, }; /* diff --git a/src/load_layout.c b/src/load_layout.c index acc83fb..c117f9c 100644 --- a/src/load_layout.c +++ b/src/load_layout.c @@ -10,10 +10,9 @@ */ #include "all.h" -#include -#include +#include + #include -#include /* TODO: refactor the whole parsing thing */ @@ -46,9 +45,7 @@ * array. */ struct focus_mapping { int old_id; - - TAILQ_ENTRY(focus_mapping) - focus_mappings; + TAILQ_ENTRY(focus_mapping) focus_mappings; }; static TAILQ_HEAD(focus_mappings_head, focus_mapping) focus_mappings = diff --git a/src/log.c b/src/log.c index 31db8b3..326f82b 100644 --- a/src/log.c +++ b/src/log.c @@ -9,26 +9,23 @@ */ #include +#include "all.h" +#include "shmlog.h" + +#include +#include #include +#include #include +#include #include -#include -#include +#include +#include #include #include -#include -#include -#include -#include #if !defined(__OpenBSD__) #include #endif - -#include "util.h" -#include "log.h" -#include "i3.h" -#include "libi3.h" -#include "shmlog.h" #if defined(__APPLE__) #include diff --git a/src/main.c b/src/main.c index 369f2f6..2201955 100644 --- a/src/main.c +++ b/src/main.c @@ -8,24 +8,31 @@ * */ #include "all.h" +#include "shmlog.h" #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include #include -#include -#include -#include -#include -#include -#include "shmlog.h" +#include #ifdef I3_ASAN_ENABLED #include #endif #include "sd-daemon.h" + +#include "i3-atoms_NET_SUPPORTED.xmacro.h" +#include "i3-atoms_rest.xmacro.h" /* The original value of RLIMIT_CORE when i3 was started. We need to restore * this before starting any other process, since we set RLIMIT_CORE to @@ -72,6 +79,7 @@ /* The list of key bindings */ struct bindings_head *bindings; +const char *current_binding_mode = NULL; /* The list of exec-lines */ struct autostarts_head autostarts = TAILQ_HEAD_INITIALIZER(autostarts); @@ -94,7 +102,8 @@ /* Define all atoms as global variables */ #define xmacro(atom) xcb_atom_t A_##atom; -#include "atoms.xmacro" +I3_NET_SUPPORTED_ATOMS_XMACRO +I3_REST_ATOMS_XMACRO #undef xmacro /* @@ -173,6 +182,10 @@ ipc_shutdown(SHUTDOWN_REASON_EXIT, -1); unlink(config.ipc_socket_path); xcb_disconnect(conn); + + /* If a nagbar is active, kill it */ + kill_nagbar(config_error_nagbar_pid, false); + kill_nagbar(command_error_nagbar_pid, false); /* We need ev >= 4 for the following code. Since it is not *that* important (it * only makes sure that there are no i3-nagbar instances left behind) we still @@ -372,6 +385,11 @@ char *socket_path = root_atom_contents("I3_SOCKET_PATH", NULL, 0); if (socket_path) { printf("%s\n", socket_path); + /* With -O2 (i.e. the buildtype=debugoptimized meson + * option, which we set by default), gcc 9.2.1 optimizes + * away socket_path at this point, resulting in a Leak + * Sanitizer report. An explicit free helps: */ + free(socket_path); exit(EXIT_SUCCESS); } @@ -555,7 +573,8 @@ /* Place requests for the atoms we need as soon as possible */ #define xmacro(atom) \ xcb_intern_atom_cookie_t atom##_cookie = xcb_intern_atom(conn, 0, strlen(#atom), #atom); -#include "atoms.xmacro" + I3_NET_SUPPORTED_ATOMS_XMACRO + I3_REST_ATOMS_XMACRO #undef xmacro root_depth = root_screen->root_depth; @@ -601,7 +620,8 @@ A_##name = reply->atom; \ free(reply); \ } while (0); -#include "atoms.xmacro" + I3_NET_SUPPORTED_ATOMS_XMACRO + I3_REST_ATOMS_XMACRO #undef xmacro load_configuration(override_configpath, C_LOAD); diff --git a/src/manage.c b/src/manage.c index 4e2803a..82c0ff8 100644 --- a/src/manage.c +++ b/src/manage.c @@ -8,10 +8,6 @@ * */ #include "all.h" - -#include "yajl_utils.h" - -#include /* * Match frame and window depth. This is needed because X will refuse to reparent a @@ -274,6 +270,7 @@ DLOG("Initial geometry: (%d, %d, %d, %d)\n", geom->x, geom->y, geom->width, geom->height); /* See if any container swallows this new window */ + cwindow->swallowed = false; Match *match = NULL; Con *nc = con_for_window(search_at, cwindow, &match); const bool match_from_restart_mode = (match && match->restart_mode); @@ -295,7 +292,7 @@ /* A_TO_WORKSPACE type assignment or fallback from A_TO_WORKSPACE_NUMBER * when the target workspace number does not exist yet. */ if (!assigned_ws) { - assigned_ws = workspace_get(assignment->dest.workspace, NULL); + assigned_ws = workspace_get(assignment->dest.workspace); } nc = con_descend_tiling_focused(assigned_ws); @@ -326,7 +323,7 @@ } else if (startup_ws) { /* If it was started on a specific workspace, we want to open it there. */ DLOG("Using workspace on which this application was started (%s)\n", startup_ws); - nc = con_descend_tiling_focused(workspace_get(startup_ws, NULL)); + nc = con_descend_tiling_focused(workspace_get(startup_ws)); DLOG("focused on ws %s: %p / %s\n", startup_ws, nc, nc->name); if (nc->type == CT_WORKSPACE) nc = tree_open_con(nc, cwindow); @@ -362,6 +359,8 @@ match_free(match); FREE(match); } + + cwindow->swallowed = true; } DLOG("new container = %p\n", nc); @@ -537,8 +536,9 @@ * was not specified */ bool automatic_border = (motif_border_style == BS_NORMAL); - floating_enable(nc, automatic_border); - nc->floating = FLOATING_AUTO_ON; + if (floating_enable(nc, automatic_border)) { + nc->floating = FLOATING_AUTO_ON; + } } /* explicitly set the border width to the default */ @@ -698,6 +698,11 @@ * */ Con *remanage_window(Con *con) { + /* Make sure this windows hasn't already been swallowed. */ + if (con->window->swallowed) { + run_assignments(con->window); + return con; + } Match *match; Con *nc = con_for_window(croot, con->window, &match); if (nc == NULL || nc->window == NULL || nc->window == con->window) { @@ -743,5 +748,6 @@ ewmh_update_wm_desktop(); } + nc->window->swallowed = true; return nc; } diff --git a/src/randr.c b/src/randr.c index b163eca..8e000ca 100644 --- a/src/randr.c +++ b/src/randr.c @@ -12,6 +12,7 @@ #include "all.h" #include + #include /* Pointer to the result of the query for primary output */ @@ -50,11 +51,11 @@ Output *output; bool get_primary = (strcasecmp("primary", name) == 0); TAILQ_FOREACH (output, &outputs, outputs) { + if (require_active && !output->active) { + continue; + } if (output->primary && get_primary) { return output; - } - if (require_active && !output->active) { - continue; } struct output_name *output_name; SLIST_FOREACH (output_name, &output->names_head, names) { @@ -437,34 +438,29 @@ Con *content = output_get_content(output->con); Con *previous_focus = con_get_workspace(focused); - /* go through all assignments and move the existing workspaces to this output */ - struct Workspace_Assignment *assignment; - TAILQ_FOREACH (assignment, &ws_assignments, ws_assignments) { - if (!output_triggers_assignment(output, assignment)) { - continue; - } - Con *workspace = get_existing_workspace_by_name(assignment->name); - if (workspace == NULL) - continue; - - /* check that this workspace is not already attached (that means the - * user configured this assignment twice) */ - Con *workspace_out = con_get_output(workspace); - if (workspace_out == output->con) { - LOG("Workspace \"%s\" assigned to output \"%s\", but it is already " - "there. Do you have two assignment directives for the same " - "workspace in your configuration file?\n", - workspace->name, output_primary_name(output)); - continue; - } - - DLOG("Moving workspace \"%s\" from output \"%s\" to \"%s\" due to assignment\n", - workspace->name, workspace_out->name, output_primary_name(output)); - /* Need to copy output's rect since content is not yet rendered. We - * can't call render_con here because render_output only proceeds if a - * workspace exists. */ - content->rect = output->con->rect; - workspace_move_to_output(workspace, output); + /* Iterate over all workspaces and check if any of them should be assigned + * to this output. */ + Con *output_con; + TAILQ_FOREACH (output_con, &(croot->nodes_head), nodes) { + if (con_is_internal(output_con)) { + continue; + } + + Con *workspace; + TAILQ_FOREACH (workspace, &(output_get_content(output_con)->nodes_head), nodes) { + Con *workspace_out = get_assigned_output(workspace->name, workspace->num); + if (output->con != workspace_out) { + continue; + } + + DLOG("Moving workspace \"%s\" from output \"%s\" to \"%s\" due to assignment\n", + workspace->name, workspace_out->name, output_primary_name(output)); + /* Need to copy output's rect since content is not yet rendered. We + * can't call render_con here because render_output only proceeds + * if a workspace exists. */ + content->rect = output->con->rect; + workspace_move_to_output(workspace, output); + } } /* Temporarily set the focused container, might not be initialized yet. */ @@ -484,6 +480,7 @@ } /* otherwise, we create the first assigned ws for this output */ + struct Workspace_Assignment *assignment; TAILQ_FOREACH (assignment, &ws_assignments, ws_assignments) { if (!output_triggers_assignment(output, assignment)) { continue; @@ -1022,6 +1019,7 @@ } /* render_layout flushes */ + ewmh_update_desktop_properties(); tree_render(); FREE(primary); diff --git a/src/render.c b/src/render.c index 79bf7eb..072daeb 100644 --- a/src/render.c +++ b/src/render.c @@ -9,6 +9,8 @@ * */ #include "all.h" + +#include /* Forward declarations */ static int *precalculate_sizes(Con *con, render_params *p); @@ -453,7 +455,7 @@ /* Since the tab width may be something like 31,6 px per tab, we * let the last tab have all the extra space (0,6 * children). */ if (i == (p->children - 1)) { - child->deco_rect.width += (child->rect.width - (child->deco_rect.x + child->deco_rect.width)); + child->deco_rect.width = child->rect.width - child->deco_rect.x; } if (p->children > 1 || (child->border_style != BS_PIXEL && child->border_style != BS_NONE)) { diff --git a/src/restore_layout.c b/src/restore_layout.c index 25f631b..c51bfcb 100644 --- a/src/restore_layout.c +++ b/src/restore_layout.c @@ -29,8 +29,7 @@ /** The drawable surface */ surface_t surface; - TAILQ_ENTRY(placeholder_state) - state; + TAILQ_ENTRY(placeholder_state) state; } placeholder_state; static TAILQ_HEAD(state_head, placeholder_state) state_head = diff --git a/src/scratchpad.c b/src/scratchpad.c index e8d70be..24cde61 100644 --- a/src/scratchpad.c +++ b/src/scratchpad.c @@ -32,7 +32,7 @@ } DLOG("should move con %p to __i3_scratch\n", con); - Con *__i3_scratch = workspace_get("__i3_scratch", NULL); + Con *__i3_scratch = workspace_get("__i3_scratch"); if (con_get_workspace(con) == __i3_scratch) { DLOG("This window is already on __i3_scratch.\n"); return; @@ -84,7 +84,7 @@ */ bool scratchpad_show(Con *con) { DLOG("should show scratchpad window %p\n", con); - Con *__i3_scratch = workspace_get("__i3_scratch", NULL); + Con *__i3_scratch = workspace_get("__i3_scratch"); Con *floating; /* If this was 'scratchpad show' without criteria, we check if the @@ -245,7 +245,7 @@ * */ void scratchpad_fix_resolution(void) { - Con *__i3_scratch = workspace_get("__i3_scratch", NULL); + Con *__i3_scratch = workspace_get("__i3_scratch"); Con *__i3_output = con_get_output(__i3_scratch); DLOG("Current resolution: (%d, %d) %d x %d\n", __i3_output->rect.x, __i3_output->rect.y, diff --git a/src/sd-daemon.c b/src/sd-daemon.c index 28a88bf..8476102 100644 --- a/src/sd-daemon.c +++ b/src/sd-daemon.c @@ -28,21 +28,21 @@ #define _GNU_SOURCE #endif +#include "sd-daemon.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include #include -#include -#include -#include -#include #include -#include -#include -#include -#include - -#include "sd-daemon.h" int sd_listen_fds(int unset_environment) { int r, fd; diff --git a/src/sighandler.c b/src/sighandler.c index 86921b4..2be69c3 100644 --- a/src/sighandler.c +++ b/src/sighandler.c @@ -7,23 +7,16 @@ */ #include "all.h" -#include -#include #include #include - -#include - -#include +#include typedef struct dialog_t { xcb_window_t id; xcb_colormap_t colormap; Rect dims; surface_t surface; - - TAILQ_ENTRY(dialog_t) - dialogs; + TAILQ_ENTRY(dialog_t) dialogs; } dialog_t; static TAILQ_HEAD(dialogs_head, dialog_t) dialogs = TAILQ_HEAD_INITIALIZER(dialogs); diff --git a/src/startup.c b/src/startup.c index e994e0a..9b0576e 100644 --- a/src/startup.c +++ b/src/startup.c @@ -11,12 +11,12 @@ * */ #include "all.h" - #include "sd-daemon.h" +#include #include #include -#include +#include #define SN_API_NOT_YET_FROZEN 1 #include diff --git a/src/util.c b/src/util.c index 3544297..cf7f41c 100644 --- a/src/util.c +++ b/src/util.c @@ -10,19 +10,16 @@ */ #include "all.h" +#include +#include +#include +#include +#include #include -#include +#include #if defined(__OpenBSD__) #include #endif -#include -#include -#include -#include -#include - -#define SN_API_NOT_YET_FROZEN 1 -#include int min(int a, int b) { return (a < b ? a : b); @@ -290,8 +287,8 @@ void i3_restart(bool forget_layout) { char *restart_filename = forget_layout ? NULL : store_restart_layout(); - kill_nagbar(&config_error_nagbar_pid, true); - kill_nagbar(&command_error_nagbar_pid, true); + kill_nagbar(config_error_nagbar_pid, true); + kill_nagbar(command_error_nagbar_pid, true); restore_geometry(); @@ -339,30 +336,19 @@ static void nagbar_exited(EV_P_ ev_child *watcher, int revents) { ev_child_stop(EV_A_ watcher); + int exitcode = WEXITSTATUS(watcher->rstatus); if (!WIFEXITED(watcher->rstatus)) { - ELOG("ERROR: i3-nagbar did not exit normally.\n"); - return; - } - - int exitcode = WEXITSTATUS(watcher->rstatus); - DLOG("i3-nagbar process exited with status %d\n", exitcode); - if (exitcode == 2) { - ELOG("ERROR: i3-nagbar could not be found. Is it correctly installed on your system?\n"); - } - - *((pid_t *)watcher->data) = -1; -} - -/* - * Cleanup handler. Will be called when i3 exits. Kills i3-nagbar with signal - * SIGKILL (9) to make sure there are no left-over i3-nagbar processes. - * - */ -static void nagbar_cleanup(EV_P_ ev_cleanup *watcher, int revent) { - pid_t *nagbar_pid = (pid_t *)watcher->data; - if (*nagbar_pid != -1) { - LOG("Sending SIGKILL (%d) to i3-nagbar with PID %d\n", SIGKILL, *nagbar_pid); - kill(*nagbar_pid, SIGKILL); + ELOG("i3-nagbar (%d) did not exit normally. This is not an error if the config was reloaded while a nagbar was active.\n", watcher->pid); + } else if (exitcode != 0) { + ELOG("i3-nagbar (%d) process exited with status %d\n", watcher->pid, exitcode); + } else { + DLOG("i3-nagbar (%d) process exited with status %d\n", watcher->pid, exitcode); + } + + pid_t *nagbar_pid = watcher->data; + if (*nagbar_pid == watcher->pid) { + /* Only reset if the watched nagbar is the active nagbar */ + *nagbar_pid = -1; } } @@ -398,27 +384,20 @@ ev_child_init(child, &nagbar_exited, *nagbar_pid, 0); child->data = nagbar_pid; ev_child_start(main_loop, child); - - /* install a cleanup watcher (will be called when i3 exits and i3-nagbar is - * still running) */ - ev_cleanup *cleanup = smalloc(sizeof(ev_cleanup)); - ev_cleanup_init(cleanup, nagbar_cleanup); - cleanup->data = nagbar_pid; - ev_cleanup_start(main_loop, cleanup); -} - -/* - * Kills the i3-nagbar process, if *nagbar_pid != -1. +} + +/* + * Kills the i3-nagbar process, if nagbar_pid != -1. * * If wait_for_it is set (restarting i3), this function will waitpid(), * otherwise, ev is assumed to handle it (reloading). * */ -void kill_nagbar(pid_t *nagbar_pid, bool wait_for_it) { - if (*nagbar_pid == -1) +void kill_nagbar(pid_t nagbar_pid, bool wait_for_it) { + if (nagbar_pid == -1) return; - if (kill(*nagbar_pid, SIGTERM) == -1) + if (kill(nagbar_pid, SIGTERM) == -1) warn("kill(configerror_nagbar) failed"); if (!wait_for_it) @@ -428,7 +407,7 @@ * exec(), our old pid is no longer watched. So, ev won’t handle SIGCHLD * for us and we would end up with a process. Therefore we * waitpid() here. */ - waitpid(*nagbar_pid, NULL, 0); + waitpid(nagbar_pid, NULL, 0); } /* diff --git a/src/window.c b/src/window.c index d84f886..bee3fa6 100644 --- a/src/window.c +++ b/src/window.c @@ -8,6 +8,8 @@ * */ #include "all.h" + +#include /* * Frees an i3Window and all its members. diff --git a/src/workspace.c b/src/workspace.c index 569d2e9..e77d544 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -72,16 +72,16 @@ /* * Returns the first output that is assigned to a workspace specified by the - * given name or number or NULL if no such output exists. If there is a - * workspace with a matching name and another workspace with a matching number, - * the output assigned to the first one is returned. - * The order of the 'ws_assignments' queue is respected: if multiple assignments - * match the specified workspace, the first one is returned. - * If 'name' is NULL it will be ignored. - * If 'parsed_num' is -1 it will be ignored. - * - */ -static Con *get_assigned_output(const char *name, long parsed_num) { + * given name or number. Returns NULL if no such output exists. + * + * If an assignment matches by number but there is an assignment later that + * matches by name, the second one is preferred. + * The order of the 'ws_assignments' queue is respected: if multiple + * assignments match the criteria, the first one is returned. + * 'name' is ignored when NULL, 'parsed_num' is ignored when it is -1. + * + */ +Con *get_assigned_output(const char *name, long parsed_num) { Con *output = NULL; struct Workspace_Assignment *assignment; TAILQ_FOREACH (assignment, &ws_assignments, ws_assignments) { @@ -90,7 +90,8 @@ } if (name && strcmp(assignment->name, name) == 0) { - DLOG("Found workspace name assignment to output \"%s\"\n", assignment->output); + DLOG("Found workspace name=\"%s\" assignment to output \"%s\"\n", + name, assignment->output); Output *assigned_by_name = get_output_by_name(assignment->output, true); if (assigned_by_name) { /* When the name matches exactly, skip numbered assignments. */ @@ -100,7 +101,8 @@ parsed_num != -1 && name_is_digits(assignment->name) && ws_name_to_number(assignment->name) == parsed_num) { - DLOG("Found workspace number assignment to output \"%s\"\n", assignment->output); + DLOG("Found workspace number=%ld assignment to output \"%s\"\n", + parsed_num, assignment->output); Output *assigned_by_num = get_output_by_name(assignment->output, true); if (assigned_by_num) { output = assigned_by_num->con; @@ -126,63 +128,56 @@ * memory and initializing the data structures correctly). * */ -Con *workspace_get(const char *num, bool *created) { +Con *workspace_get(const char *num) { Con *workspace = get_existing_workspace_by_name(num); - - if (workspace == NULL) { - LOG("Creating new workspace \"%s\"\n", num); - gaps_t gaps = (gaps_t){0, 0, 0, 0, 0}; - - /* We set workspace->num to the number if this workspace’s name begins - * with a positive number. Otherwise it’s a named ws and num will be - * -1. */ - long parsed_num = ws_name_to_number(num); - - struct Workspace_Assignment *assignment; - TAILQ_FOREACH (assignment, &ws_assignments, ws_assignments) { - if (strcmp(assignment->name, num) == 0) { - gaps = assignment->gaps; - break; - } else if (parsed_num != -1 && name_is_digits(assignment->name) && ws_name_to_number(assignment->name) == parsed_num) { - gaps = assignment->gaps; - } - } - - Con *output = get_assigned_output(num, parsed_num); - /* if an assignment is not found, we create this workspace on the current output */ - if (!output) { - output = con_get_output(focused); - } - - Con *content = output_get_content(output); - LOG("got output %p with content %p\n", output, content); - /* We need to attach this container after setting its type. con_attach - * will handle CT_WORKSPACEs differently */ - workspace = con_new(NULL, NULL); - char *name; - sasprintf(&name, "[i3 con] workspace %s", num); - x_set_name(workspace, name); - free(name); - workspace->type = CT_WORKSPACE; - FREE(workspace->name); - workspace->name = sstrdup(num); - workspace->workspace_layout = config.default_layout; - workspace->num = parsed_num; - LOG("num = %d\n", workspace->num); - workspace->gaps = gaps; - - workspace->parent = content; - _workspace_apply_default_orientation(workspace); - - con_attach(workspace, content, false); - - ipc_send_workspace_event("init", workspace, NULL); - ewmh_update_desktop_properties(); - if (created != NULL) - *created = true; - } else if (created != NULL) { - *created = false; - } + if (workspace) { + return workspace; + } + + LOG("Creating new workspace \"%s\"\n", num); + gaps_t gaps = (gaps_t){0, 0, 0, 0, 0}; + + /* We set workspace->num to the number if this workspace’s name begins with + * a positive number. Otherwise it’s a named ws and num will be 1. */ + const long parsed_num = ws_name_to_number(num); + + struct Workspace_Assignment *assignment; + TAILQ_FOREACH (assignment, &ws_assignments, ws_assignments) { + if (strcmp(assignment->name, num) == 0) { + gaps = assignment->gaps; + break; + } else if (parsed_num != -1 && name_is_digits(assignment->name) && ws_name_to_number(assignment->name) == parsed_num) { + gaps = assignment->gaps; + } + } + + Con *output = get_assigned_output(num, parsed_num); + /* if an assignment is not found, we create this workspace on the current output */ + if (!output) { + output = con_get_output(focused); + } + + /* No parent because we need to attach this container after setting its + * type. con_attach will handle CT_WORKSPACEs differently. */ + workspace = con_new(NULL, NULL); + + char *name; + sasprintf(&name, "[i3 con] workspace %s", num); + x_set_name(workspace, name); + free(name); + + FREE(workspace->name); + workspace->name = sstrdup(num); + workspace->workspace_layout = config.default_layout; + workspace->num = parsed_num; + workspace->type = CT_WORKSPACE; + workspace->gaps = gaps; + + con_attach(workspace, output_get_content(output), false); + _workspace_apply_default_orientation(workspace); + + ipc_send_workspace_event("init", workspace, NULL); + ewmh_update_desktop_properties(); return workspace; } @@ -577,9 +572,7 @@ * */ void workspace_show_by_name(const char *num) { - Con *workspace; - workspace = workspace_get(num, NULL); - workspace_show(workspace); + workspace_show(workspace_get(num)); } /* @@ -846,10 +839,7 @@ return NULL; } - Con *workspace; - workspace = workspace_get(previous_workspace_name, NULL); - - return workspace; + return workspace_get(previous_workspace_name); } static bool get_urgency_flag(Con *con) { @@ -1036,7 +1026,7 @@ /* so create the workspace referenced to by this assignment */ DLOG("Creating workspace from assignment %s.\n", assignment->name); - workspace_get(assignment->name, NULL); + workspace_get(assignment->name); used_assignment = true; break; } diff --git a/src/x.c b/src/x.c index 712cf89..48af5f3 100644 --- a/src/x.c +++ b/src/x.c @@ -9,6 +9,8 @@ * */ #include "all.h" + +#include #ifndef MAX #define MAX(x, y) ((x) > (y) ? (x) : (y)) @@ -61,26 +63,18 @@ char *name; - CIRCLEQ_ENTRY(con_state) - state; - - CIRCLEQ_ENTRY(con_state) - old_state; - - TAILQ_ENTRY(con_state) - initial_mapping_order; + CIRCLEQ_ENTRY(con_state) state; + CIRCLEQ_ENTRY(con_state) old_state; + TAILQ_ENTRY(con_state) initial_mapping_order; } con_state; -CIRCLEQ_HEAD(state_head, con_state) -state_head = +CIRCLEQ_HEAD(state_head, con_state) state_head = CIRCLEQ_HEAD_INITIALIZER(state_head); -CIRCLEQ_HEAD(old_state_head, con_state) -old_state_head = +CIRCLEQ_HEAD(old_state_head, con_state) old_state_head = CIRCLEQ_HEAD_INITIALIZER(old_state_head); -TAILQ_HEAD(initial_mapping_head, con_state) -initial_mapping_head = +TAILQ_HEAD(initial_mapping_head, con_state) initial_mapping_head = TAILQ_HEAD_INITIALIZER(initial_mapping_head); /* @@ -590,11 +584,6 @@ } } - /* if this is a borderless/1pixel window, we don’t need to render the - * decoration. */ - if (p->border_style != BS_NORMAL) - goto copy_pixmaps; - /* If the parent hasn't been set up yet, skip the decoration rendering * for now. */ if (parent->frame_buffer.id == XCB_NONE) @@ -607,6 +596,11 @@ draw_util_clear_surface(&(con->parent->frame_buffer), COLOR_TRANSPARENT); FREE(con->parent->deco_render_params); } + + /* if this is a borderless/1pixel window, we don’t need to render the + * decoration. */ + if (p->border_style != BS_NORMAL) + goto copy_pixmaps; /* 4: paint the bar */ draw_util_rectangle(&(parent->frame_buffer), p->color->background, diff --git a/src/xcursor.c b/src/xcursor.c index cffb094..cb98399 100644 --- a/src/xcursor.c +++ b/src/xcursor.c @@ -9,13 +9,12 @@ */ #include +#include "all.h" + #include #include + #include - -#include "i3.h" -#include "xcb.h" -#include "xcursor.h" static xcb_cursor_context_t *ctx; static xcb_cursor_t cursors[XCURSOR_CURSOR_MAX]; diff --git a/testcases/complete-run.pl.in b/testcases/complete-run.pl.in index 96b93be..00f8e60 100755 --- a/testcases/complete-run.pl.in +++ b/testcases/complete-run.pl.in @@ -18,7 +18,7 @@ use IO::Handle; # these are shipped with the testsuite -use lib qw(@abs_top_builddir@/testcases/lib @abs_top_srcdir@/testcases/lib @abs_top_srcdir@/AnyEvent-I3/blib/lib); +use lib qw(@abs_top_builddir@ @abs_top_builddir@/testcases/lib @abs_top_srcdir@/testcases/lib @abs_top_builddir@/AnyEvent-I3/blib/lib); use i3test::Util qw(slurp); use StartXServer; use StatusLine; @@ -78,12 +78,12 @@ # Check for missing executables my @binaries = qw( @abs_top_builddir@/i3 - @abs_top_builddir@/i3bar/i3bar - @abs_top_builddir@/i3-config-wizard/i3-config-wizard - @abs_top_builddir@/i3-dump-log/i3-dump-log - @abs_top_builddir@/i3-input/i3-input - @abs_top_builddir@/i3-msg/i3-msg - @abs_top_builddir@/i3-nagbar/i3-nagbar + @abs_top_builddir@/i3bar + @abs_top_builddir@/i3-config-wizard + @abs_top_builddir@/i3-dump-log + @abs_top_builddir@/i3-input + @abs_top_builddir@/i3-msg + @abs_top_builddir@/i3-nagbar ); foreach my $binary (@binaries) { @@ -103,12 +103,6 @@ } $ENV{PATH} = join(':', - '@abs_top_builddir@/i3-nagbar', - '@abs_top_builddir@/i3-msg', - '@abs_top_builddir@/i3-input', - '@abs_top_builddir@/i3-dump-log', - '@abs_top_builddir@/i3-config-wizard', - '@abs_top_builddir@/i3bar', '@abs_top_builddir@', '@abs_top_srcdir@', $ENV{PATH}); diff --git a/testcases/inject_randr1.5.c b/testcases/inject_randr1.5.c index 819c029..9c0b73d 100644 --- a/testcases/inject_randr1.5.c +++ b/testcases/inject_randr1.5.c @@ -16,15 +16,17 @@ #include #include +#include +#include +#include +#include +#include +#include +#include #include -#include #include -#include -#include -#include -#include #include -#include +#include static void uds_connection_cb(EV_P_ ev_io *w, int revents); static void read_client_setup_request_cb(EV_P_ ev_io *w, int revents); diff --git a/testcases/lib/i3test/XTEST.pm b/testcases/lib/i3test/XTEST.pm index 4c464c5..89b8fac 100644 --- a/testcases/lib/i3test/XTEST.pm +++ b/testcases/lib/i3test/XTEST.pm @@ -7,7 +7,7 @@ use Test::More; use i3test::Util qw(get_socket_path); -use lib qw(@abs_top_srcdir@/AnyEvent-I3/blib/lib); +use lib qw(@abs_top_builddir@/AnyEvent-I3/blib/lib); use AnyEvent::I3; use ExtUtils::PkgConfig; diff --git a/testcases/lib/i3test.pm.in b/testcases/lib/i3test.pm.in index 161ddf7..aedaa60 100644 --- a/testcases/lib/i3test.pm.in +++ b/testcases/lib/i3test.pm.in @@ -7,7 +7,7 @@ use X11::XCB::Rect; use X11::XCB::Window; use X11::XCB qw(:all); -use lib qw(@abs_top_srcdir@/AnyEvent-I3/blib/lib); +use lib qw(@abs_top_builddir@/AnyEvent-I3/blib/lib); use AnyEvent::I3; use List::Util qw(first); use Time::HiRes qw(sleep); diff --git a/testcases/t/124-move.t b/testcases/t/124-move.t index b7ef0b2..b4a8ca3 100644 --- a/testcases/t/124-move.t +++ b/testcases/t/124-move.t @@ -220,21 +220,49 @@ is($absolute->width, $absolute_before->width, 'width not changed'); is($absolute->height, $absolute_before->height, 'height not changed'); -###################################################################### -# 6) test moving floating window to a specified position +$absolute_before = $absolute; +$top_before = $top; + +###################################################################### +# 7) test moving floating containers with a specific amount of ppt +###################################################################### + +cmd 'move right 25 ppt'; + +sync_with_i3; + +($absolute, $top) = $floatwin->rect; + +is($absolute->x, int($x->root->rect->width * 0.25) + $absolute_before->x, 'moved 25 ppt to the right'); +is($absolute->y, $absolute_before->y, 'y not changed'); +is($absolute->width, $absolute_before->width, 'width not changed'); +is($absolute->height, $absolute_before->height, 'height not changed'); + +###################################################################### +# 8) test moving floating window to a specified position # and to absolute center ###################################################################### $tmp = fresh_workspace; open_floating_window; my @floatcon; +# Move to specified position with px cmd 'move position 5 px 15 px'; @floatcon = @{get_ws($tmp)->{floating_nodes}}; -is($floatcon[0]->{rect}->{x}, 5, 'moved to position 5 x'); -is($floatcon[0]->{rect}->{y}, 15, 'moved to position 15 y'); - +is($floatcon[0]->{rect}->{x}, 5, 'moved to position 5 (px) x'); +is($floatcon[0]->{rect}->{y}, 15, 'moved to position 15 (px) y'); + +# Move to specified position with ppt +cmd 'move position 20 ppt 20 ppt'; + +@floatcon = @{get_ws($tmp)->{floating_nodes}}; + +is($floatcon[0]->{rect}->{x}, int($x->root->rect->width * 0.20), "moved to position 20 (ppt) x"); +is($floatcon[0]->{rect}->{y}, int($x->root->rect->height * 0.20), "moved to position 20 (ppt) y"); + +# Move to absolute center cmd 'move absolute position center'; @floatcon = @{get_ws($tmp)->{floating_nodes}}; diff --git a/testcases/t/132-move-workspace.t b/testcases/t/132-move-workspace.t index 60705f9..c7721c3 100644 --- a/testcases/t/132-move-workspace.t +++ b/testcases/t/132-move-workspace.t @@ -340,6 +340,53 @@ is(@{$ws->{floating_nodes}}, 1, 'one floating node on second workspace'); ################################################################### +# Test that when moving a fullscreen floating window to a workspace +# that already has an other fullscreen container, the second +# container gets un-fullscreened. +# See #4124 +################################################################### +$tmp2 = fresh_workspace; +$second = open_window; +cmd 'fullscreen enable'; +$ws = get_ws($tmp2); +is($ws->{nodes}->[0]->{fullscreen_mode}, 1, 'sanity check: fullscreen enabled'); + +$tmp = fresh_workspace; +$first = open_window; +cmd 'floating enable, fullscreen enable'; +cmd "move workspace $tmp2"; + +$ws = get_ws($tmp2); +is_num_children($tmp2, 1, 'one regular node on second workspace'); +is_num_fullscreen($tmp2, 1, 'one fullscreen node on second workspace'); +is(@{$ws->{floating_nodes}}, 1, 'one floating node on second workspace'); +is($ws->{nodes}->[0]->{fullscreen_mode}, 0, 'previous fullscreen disabled'); + +################################################################### +# Same as above, but trigger the bug with the parent of a +# fullscreen container, instead of a CT_FLOATING_CON. +################################################################### +$tmp2 = fresh_workspace; +$second = open_window; +cmd 'fullscreen enable'; +$ws = get_ws($tmp2); +is($ws->{nodes}->[0]->{fullscreen_mode}, 1, 'sanity check: fullscreen enabled'); + +$tmp = fresh_workspace; +open_window; +$first = open_window; +cmd 'layout tabbed'; +cmd 'focus parent, mark a, focus child'; +cmd 'fullscreen enable'; +cmd "[con_mark=a] move workspace $tmp2"; + +$ws = get_ws($tmp2); +is(sum_nodes(get_ws_content($tmp2)), 4, '3 leafs & 1 split node in second workspace'); +# is_num_fullscreen does not catch this nested fullscreen container +is($ws->{nodes}->[0]->{fullscreen_mode}, 0, 'previous fullscreen disabled'); +is($ws->{nodes}->[1]->{nodes}->[1]->{fullscreen_mode}, 1, 'nested fullscreen from moved container preserved'); + +################################################################### # Check that moving an empty workspace using criteria doesn't # create unfocused empty workspace. ################################################################### diff --git a/testcases/t/193-ipc-version.t b/testcases/t/193-ipc-version.t index d5f4bad..82449de 100644 --- a/testcases/t/193-ipc-version.t +++ b/testcases/t/193-ipc-version.t @@ -32,6 +32,5 @@ is(int($version->{minor}), $version->{minor}, 'minor version is an integer'); is(int($version->{patch}), $version->{patch}, 'patch version is an integer'); -like($version->{human_readable}, qr/branch/, 'human readable version contains branch name'); done_testing; diff --git a/testcases/t/297-assign-workspace-to-output.t b/testcases/t/297-assign-workspace-to-output.t index eb8f24b..4e251e5 100644 --- a/testcases/t/297-assign-workspace-to-output.t +++ b/testcases/t/297-assign-workspace-to-output.t @@ -41,7 +41,7 @@ sub check_output { my ($workspace, $output, $msg) = @_; - is(get_output_for_workspace($workspace), $output, $msg); + is(get_output_for_workspace($workspace), $output, "[$workspace->$output] " . $msg); } check_output('9', '', 'Numbered workspace with a big number that is assigned to output that does not exist is not used'); @@ -82,6 +82,10 @@ workspace foo output doesnotexist1 doesnotexist2 doesnotexist3 workspace bar output doesnotexist workspace bar output fake-0 +workspace 5 output fake-0 +workspace 5:xxx output fake-1 +workspace 6:xxx output fake-0 +workspace 6 output fake-1 EOT $pid = launch_with_config($config); @@ -90,8 +94,11 @@ do_test('2', 'fake-3', 'First output out of multiple assignments is used'); do_test('3', 'fake-0', 'First existing output is used'); do_test('4', 'fake-0', 'Excessive whitespace is ok'); -do_test('5', 'fake-1', 'Numbered initialization for fake-1'); -do_test('6', 'fake-2', 'Numbered initialization for fake-2'); +do_test('5', 'fake-0', 'Numbered assignment ok'); +do_test('5:xxx', 'fake-1', 'Named assignment overrides number'); +do_test('6', 'fake-1', 'Numbered assignment ok'); +do_test('6:xxx', 'fake-0', 'Named assignment overrides number'); +do_test('7', 'fake-2', 'Numbered initialization for fake-2'); cmd 'focus output fake-0, workspace foo'; check_output('foo', 'fake-0', 'Workspace with only non-existing assigned outputs opened in current output'); @@ -103,5 +110,14 @@ cmd 'workspace 2, move workspace to output left'; check_output('2', 'fake-2', 'Moved assigned workspace up'); +# Specific name overrides assignment by number after renaming +# See #4021 +cmd 'workspace 5, rename workspace to 5:xxx'; +check_output('5:xxx', 'fake-1', 'workspace triggered correct, specific assignment after renaming'); + +# Same but opposite order +cmd 'workspace 6, rename workspace to 6:xxx'; +check_output('6:xxx', 'fake-0', 'workspace triggered correct, specific assignment after renaming'); + exit_gracefully($pid); done_testing; diff --git a/testcases/t/310-client-message-sticky.t b/testcases/t/310-client-message-sticky.t new file mode 100644 index 0000000..0e7d8b7 --- /dev/null +++ b/testcases/t/310-client-message-sticky.t @@ -0,0 +1,70 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • https://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • https://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • https://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Verify that _NET_WM_DESKTOP sticky requests do not conflict with dock +# clients, resulting in a crash +# Ticket: #4039 +# Bug still in: 4.18-238-g4d55bba7f +use i3test; + +sub send_sticky_request { + my ($win) = @_; + + my $msg = pack "CCSLLLLLL", + X11::XCB::CLIENT_MESSAGE, # response_type + 32, # format + 0, # sequence + $win->id, # window + $x->atom(name => '_NET_WM_DESKTOP')->id, # message type + hex '0xFFFFFFFF', # data32[0] = NET_WM_DESKTOP_ALL + 0, # data32[1] + 0, # data32[2] + 0, # data32[3] + 0; # data32[4] + + $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg); +} + +# Test the normal functionality first +my $ws = fresh_workspace; +my $win = open_window; + +is(@{get_ws($ws)->{floating_nodes}}, 0, 'No floating windows yet'); +send_sticky_request($win); +sync_with_i3; + +is(@{get_ws($ws)->{floating_nodes}}, 1, 'One floating (sticky) window'); +$ws = fresh_workspace; +is(@{get_ws($ws)->{floating_nodes}}, 1, 'Sticky window in new workspace'); + +# See #4039 +kill_all_windows; +$win = open_window({ + window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK') +}); + +send_sticky_request($win); +sync_with_i3; +is(@{get_ws($ws)->{floating_nodes}}, 0, 'Dock client did not get sticky/floating'); + +# Cause a ConfigureRequest by setting the window’s position/size. +my ($a, $t) = $win->rect; +$win->rect(X11::XCB::Rect->new(x => 0, y => 0, width => $a->width, height => $a->height)); + +does_i3_live; +is(@{get_ws($ws)->{floating_nodes}}, 0, 'Dock client still not sticky/floating'); + +done_testing; diff --git a/testcases/t/311-get-binding-modes.t b/testcases/t/311-get-binding-modes.t new file mode 100644 index 0000000..3a00f69 --- /dev/null +++ b/testcases/t/311-get-binding-modes.t @@ -0,0 +1,41 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • https://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • https://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • https://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Verifies the GET_BINDING_MODE IPC command +# Ticket: #3892 +# Bug still in: 4.18-318-g50160eb1 +use i3test i3_config => <connect->recv; +# TODO: use the symbolic name for the command/reply type instead of the +# numerical 12: +my $binding_state = $i3->message(12, "")->recv; +is($binding_state->{name}, 'default', 'at startup, binding mode is default'); + +cmd 'mode extra'; + +$binding_state = $i3->message(12, "")->recv; +is($binding_state->{name}, 'extra', 'after switching, binding mode is extra'); + +done_testing; diff --git a/testcases/t/542-layout-restore-remanage.t b/testcases/t/542-layout-restore-remanage.t index 26b5083..82ec84d 100644 --- a/testcases/t/542-layout-restore-remanage.t +++ b/testcases/t/542-layout-restore-remanage.t @@ -83,4 +83,70 @@ close($fh); +############################################################ +# Make sure window only gets swallowed once +############################################################ +# Regression, issue #3888 +$ws = fresh_workspace; + +($fh, $filename) = tempfile(UNLINK => 1); +print $fh <<'EOT'; +// vim:ts=4:sw=4:et +{ + // splith split container with 2 children + "layout": "splith", + "type": "con", + "nodes": [ + { + "type": "con", + "swallows": [ + { + "class": "^foo$" + } + ] + }, + { + // splitv split container with 2 children + "layout": "splitv", + "type": "con", + "nodes": [ + { + "type": "con", + "swallows": [ + { + "class": "^foo$" + } + ] + }, + { + "type": "con", + "swallows": [ + { + "class": "^foo$" + } + ] + } + ] + } + ] +} +EOT +$fh->flush; +cmd "append_layout $filename"; + +$window = open_window wm_class => 'foo'; + +# Changing an unrelated window property originally resulted in the window +# getting remanaged and swallowd by a different placeholder, even though the +# matching property (class for the layout above) didn't change. +change_window_title($window, "different_title"); + +@content = @{get_ws_content($ws)}; + +subtest 'regression test that window gets only swallowed once', sub { + is($content[0]->{nodes}[0]->{window}, $window->id, 'first placeholder swallowed window'); + isnt($content[0]->{nodes}[1]->{nodes}[0]->{window}, $window->id, 'second placeholder did not swallow window'); + isnt($content[0]->{nodes}[1]->{nodes}[1]->{window}, $window->id, 'thid placeholder did not swallow window'); +}; + done_testing; diff --git a/travis/bintray-autobuild-debian.json b/travis/bintray-autobuild-debian.json index 23fe605..d01b7db 100644 --- a/travis/bintray-autobuild-debian.json +++ b/travis/bintray-autobuild-debian.json @@ -13,7 +13,7 @@ "files": [ { - "includePattern": "build/deb/debian-amd64/(.*\\.deb)$", + "includePattern": "distbuild/deb/debian-amd64/(.*\\.deb)$", "matrixParams": { "deb_distribution": "sid", "deb_component": "main", @@ -22,7 +22,7 @@ "uploadPattern": "$1" }, { - "includePattern": "build/deb/debian-i386/(.*\\.deb)$", + "includePattern": "distbuild/deb/debian-i386/(.*\\.deb)$", "matrixParams": { "deb_distribution": "sid", "deb_component": "main", diff --git a/travis/bintray-autobuild-ubuntu.json b/travis/bintray-autobuild-ubuntu.json index 37f2f18..4c0d611 100644 --- a/travis/bintray-autobuild-ubuntu.json +++ b/travis/bintray-autobuild-ubuntu.json @@ -13,7 +13,7 @@ "files": [ { - "includePattern": "build/deb/ubuntu-amd64/(.*\\.deb)$", + "includePattern": "distbuild/deb/ubuntu-amd64/(.*\\.deb)$", "matrixParams": { "deb_distribution": "bionic", "deb_component": "main", @@ -22,7 +22,7 @@ "uploadPattern": "$1" }, { - "includePattern": "build/deb/ubuntu-i386/(.*\\.deb)$", + "includePattern": "distbuild/deb/ubuntu-i386/(.*\\.deb)$", "matrixParams": { "deb_distribution": "bionic", "deb_component": "main", diff --git a/travis/check-formatting.sh b/travis/check-formatting.sh index 7aa2f56..3424513 100755 --- a/travis/check-formatting.sh +++ b/travis/check-formatting.sh @@ -3,4 +3,4 @@ set -e set -x -clang-format-6.0 -i $(find . -name "*.[ch]" | tr '\n' ' ') && git diff --exit-code || (echo 'Code was not formatted using clang-format!'; false) +clang-format-9 -i $(find . -name "*.[ch]" | tr '\n' ' ') && git diff --exit-code || (echo 'Code was not formatted using clang-format!'; false) diff --git a/travis/check-spelling.pl b/travis/check-spelling.pl index 45770c5..f2e79b5 100755 --- a/travis/check-spelling.pl +++ b/travis/check-spelling.pl @@ -33,12 +33,12 @@ }; my @binaries = qw( build/i3 - build/i3-config-wizard/i3-config-wizard - build/i3-dump-log/i3-dump-log - build/i3-input/i3-input - build/i3-msg/i3-msg - build/i3-nagbar/i3-nagbar - build/i3bar/i3bar + build/i3-config-wizard + build/i3-dump-log + build/i3-input + build/i3-msg + build/i3-nagbar + build/i3bar ); for my $binary (@binaries) { check_spelling(slurp($binary), $binary_spelling_exceptions, sub { diff --git a/travis/debian-build.sh b/travis/debian-build.sh index 9ce5a5a..6e66155 100755 --- a/travis/debian-build.sh +++ b/travis/debian-build.sh @@ -5,14 +5,10 @@ DEST=$1 -mkdir -p build -cd build -../configure -make echo-version > ../I3_VERSION -make dist-bzip2 +cd distbuild # unpack dist tarball mkdir -p "${DEST}" -tar xf *.tar.bz2 -C "${DEST}" --strip-components=1 +tar xf meson-dist/*.tar.xz -C "${DEST}" --strip-components=1 cp -r ../debian "${DEST}" sed -i '/^\s*libxcb-xrm-dev/d' deb/ubuntu-*/DIST/debian/control || true cd "${DEST}" diff --git a/travis/docker-build-and-push.sh b/travis/docker-build-and-push.sh index 686b81b..243d36a 100755 --- a/travis/docker-build-and-push.sh +++ b/travis/docker-build-and-push.sh @@ -4,10 +4,6 @@ BASENAME=$1 DOCKERFILE=$2 - -# .dockerignore is created on demand so that release.sh and other scripts are -# not influenced by our travis setup. -echo .git > .dockerignore docker build --pull --no-cache --rm -t=${BASENAME} -f ${DOCKERFILE} . # For pull requests, travis does not add secure environment variables to the diff --git a/travis/docs.sh b/travis/docs.sh index 043104a..501946f 100755 --- a/travis/docs.sh +++ b/travis/docs.sh @@ -3,20 +3,24 @@ set -e set -x -for f in $(grep '\.html$' debian/i3-wm.docs | grep -v 'docs/refcard.html' | grep -v 'docs/lib-i3test') +# TODO: install the docs via meson, inject styles with an option + +for f in $(sed -n "s/^\s*'\(docs\/.*\)',$/\1/gp" meson.build | grep -vF .) do asciidoc -a linkcss -a stylesdir=https://i3wm.org/css -a scriptsdir=https://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf $(dirname $f)/$(basename $f .html) done + ./docs/i3-pod2html --stylesurl=https://i3wm.org/css i3-dmenu-desktop man/i3-dmenu-desktop.html ./docs/i3-pod2html --stylesurl=https://i3wm.org/css i3-save-tree man/i3-save-tree.html -./docs/i3-pod2html --stylesurl=https://i3wm.org/css build/testcases/lib/i3test.pm docs/lib-i3test.html +./docs/i3-pod2html --stylesurl=https://i3wm.org/css build/i3test.pm docs/lib-i3test.html ./docs/i3-pod2html --stylesurl=https://i3wm.org/css testcases/lib/i3test/Test.pm docs/lib-i3test-test.html -for file in $(sed 's/\.1$/.man/g' debian/i3-wm.manpages) + +for file in $(sed -n "s/^\s*'\(man\/.*\).man',$/\1.man/gp" meson.build) do [ -f "$file" ] && asciidoc -a linkcss -a stylesdir=https://i3wm.org/css -a scriptsdir=https://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf "$file" done mkdir -p deb/COPY-DOCS -cp $(tr "\n" ' ' < debian/i3-wm.docs) deb/COPY-DOCS/ -cp $(sed 's/\.1$/.html/g' debian/i3-wm.manpages | tr "\n" ' ') deb/COPY-DOCS/ +cp $(sed -n "s/^\s*'\(docs\/.*\)',$/\1/gp" meson.build | grep -F .) deb/COPY-DOCS/ +cp $(sed -n "s/^\s*'\(man\/.*\).man',$/\1.html/gp" meson.build) deb/COPY-DOCS/ diff --git a/travis/run-tests.sh b/travis/run-tests.sh index eac2ea8..4cc7047 100755 --- a/travis/run-tests.sh +++ b/travis/run-tests.sh @@ -26,7 +26,7 @@ # Try running the tests in parallel so that the common case (tests pass) is # quick, but fall back to running them in sequence to make debugging easier. -if ! make check +if ! ninja test then - ./testcases/complete-run.pl --parallel=1 || (cat latest/complete-run.log; false) + ./complete-run.pl --parallel=1 || (cat latest/complete-run.log; false) fi diff --git a/travis/travis-base-386.Dockerfile b/travis/travis-base-386.Dockerfile index 355c258..fc03503 100644 --- a/travis/travis-base-386.Dockerfile +++ b/travis/travis-base-386.Dockerfile @@ -13,12 +13,12 @@ # (3608 kB/s)). Hence, let’s stick with httpredir.debian.org (default) for now. # Install mk-build-deps (for installing the i3 build dependencies), -# clang and clang-format-6.0 (for checking formatting and building with clang), +# clang and clang-format-9 (for checking formatting and building with clang), # lintian (for checking spelling errors), RUN linux32 apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ dpkg-dev devscripts git equivs \ - clang clang-format-6.0 \ + build-essential clang clang-format-9 \ lintian && \ rm -rf /var/lib/apt/lists/* diff --git a/travis/travis-base-ubuntu-386.Dockerfile b/travis/travis-base-ubuntu-386.Dockerfile index d52df4b..747330a 100644 --- a/travis/travis-base-ubuntu-386.Dockerfile +++ b/travis/travis-base-ubuntu-386.Dockerfile @@ -13,12 +13,12 @@ # (3608 kB/s)). Hence, let’s stick with httpredir.debian.org (default) for now. # Install mk-build-deps (for installing the i3 build dependencies), -# clang and clang-format-6.0 (for checking formatting and building with clang), +# clang and clang-format-9 (for checking formatting and building with clang), # lintian (for checking spelling errors), RUN linux32 apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ dpkg-dev devscripts git equivs \ - clang clang-format-6.0 \ + build-essential clang clang-format-9 \ lintian && \ rm -rf /var/lib/apt/lists/* diff --git a/travis/travis-base-ubuntu.Dockerfile b/travis/travis-base-ubuntu.Dockerfile index d1057a3..8a728af 100644 --- a/travis/travis-base-ubuntu.Dockerfile +++ b/travis/travis-base-ubuntu.Dockerfile @@ -13,13 +13,13 @@ # (3608 kB/s)). Hence, let’s stick with httpredir.debian.org (default) for now. # Install mk-build-deps (for installing the i3 build dependencies), -# clang and clang-format-6.0 (for checking formatting and building with clang), +# clang and clang-format-9 (for checking formatting and building with clang), # lintian (for checking spelling errors), # test suite dependencies (for running tests) RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ dpkg-dev devscripts git equivs \ - clang clang-format-6.0 \ + build-essential clang clang-format-9 \ lintian && \ rm -rf /var/lib/apt/lists/* diff --git a/travis/travis-base.Dockerfile b/travis/travis-base.Dockerfile index def7598..e5552c1 100644 --- a/travis/travis-base.Dockerfile +++ b/travis/travis-base.Dockerfile @@ -11,13 +11,13 @@ # (3608 kB/s)). Hence, let’s stick with httpredir.debian.org (default) for now. # Install mk-build-deps (for installing the i3 build dependencies), -# clang and clang-format-6.0 (for checking formatting and building with clang), +# clang and clang-format-9 (for checking formatting and building with clang), # lintian (for checking spelling errors), # test suite dependencies (for running tests) RUN apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ dpkg-dev devscripts git equivs \ - clang clang-format-6.0 \ + build-essential clang clang-format-9 \ lintian \ libmodule-install-perl libanyevent-perl libextutils-pkgconfig-perl xcb-proto cpanminus xvfb xserver-xephyr xauth libinline-perl libinline-c-perl libxml-simple-perl libmouse-perl libmousex-nativetraits-perl libextutils-depends-perl perl libtest-deep-perl libtest-exception-perl libxml-parser-perl libtest-simple-perl libtest-fatal-perl libdata-dump-perl libtest-differences-perl libxml-tokeparser-perl libipc-run-perl libxcb-xtest0-dev libx11-xcb-perl libjson-xs-perl x11-xserver-utils && \ rm -rf /var/lib/apt/lists/*