This commit probably comes as a surprise to some, given that one of i3’s
explicitly stated goals used to be “Do not use programs such as
autoconf/automake for configuration and creating unreadable/broken makefiles”.
I phrased this goal over 7 years ago, based largely on a grudge that I
inherited, which — as I’ve realized in the meantime — was largely held against
FOSS in general, and not actually nuanced criticism of autotools.
In the meantime, I have come to realize that the knee-jerk reaction of “I could
do this better!” (i.e. writing our own build system in this particular case) is
usually misguided, and nowadays I strongly suggest trying hard to fix the
existing system for the benefit of all existing and future users.
Further, I recently got to experience the other side of the coin, as I packaged
a new version of FreeRADIUS for Debian, which at the time of writing used
autoconf in combination with boilermake, a custom make-based build system that
only FreeRADIUS uses. Understanding the build system enough to fix issues and
enable parallel compilation took me an entire day. That time is time which
potentially every downstream maintainer needs to invest, and the resulting
knowledge cannot be applied to any other project.
Hence, I believe it’s a good idea switch i3 to autotools. Yes, it might be that
particular features were easier to implement/understand in our custom
Makefiles, and there might be individuals who have an easier time reading
through our custom Makefiles than learning autotools. All of these
considerations are outweighed by the benefits we get from using the same build
system as literally thousands of other FOSS software packages.
Aside from these somewhat philosophical considerations, there’s also practical
improvements which this change brings us. See the “changes” section below.
┌──────────────────────────────────────────────────────────────────────────────┐
│ new workflow │
└──────────────────────────────────────────────────────────────────────────────┘
You can now build i3 like you build any other software package which uses
autotools. Here’s a memory refresher:
autoreconf -fi
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.)
I very much recommend reading “A Practitioner's Guide to GNU Autoconf,
Automake, and Libtool” by John Calcote (https://www.nostarch.com/autotools.htm).
That book is from 2010 and, AFAICT, is the most up to date comprehensive
description of autotools. Do not read older documentation. In particular, if a
document you’re reading mentions configure.in (deprecated filename) or
recursive make (now considered harmful), it’s likely outdated.
This commit implements the following new functionality/changes in behavior:
• 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 let me know.
• “make check” runs the i3 testsuite.
You can still use ./testcases/complete-run.pl to get the interactive progress
output.
• “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.
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.
• 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 simplicitly. Maybe we can re-add it later.
• coverage reports are now generated using “make check-code-coverage”, which
requires specifying --enable-code-coverage when calling configure.
┌──────────────────────────────────────────────────────────────────────────────┐
│ build system feature parity/testing │
└──────────────────────────────────────────────────────────────────────────────┘
In addition to what’s described above, I tested the following features:
• “make install” installs the same files (plus documentation and manpages)
cd i3-old && make install PREFIX=/tmp/inst/old
cd i3-new && ./configure --prefix=/tmp/inst/new
cd /tmp/inst
(cd old && for f in $(find); do [ -e "../new/$f" ] || echo "$f missing"; done)
• make dist generates a tarball which includes the same files
cd i3-old && make dist
cd i3-new/x86_64-pc-linux-gnu && make dist
colordiff -u <(tar tf i3-old/i3-4.12.tar.bz2 | sort) \
<(tar tf i3-new/x86_64-pc-linux-gnu/i3-4.12.tar.gz | sort)
There are some expected differences:
• Some files have been renamed (e.g. the new etc/ and share/ subdirectories)
• Some files will now be generated at build-time, so only their corresponding
.in file is shipped (e.g. testcases/complete-run.pl)
• The generated parser files are shipped in the dist tarball (they only
depend on the parser-specs/* files, not on the target system)
• autotools infrastructure is shipped (e.g. “configure”, “missing”, etc.)
• DLOG and ELOG statements still produce the same file name in logfiles
• Listing source code in gdb still works.
• gdb backtraces contain the i3-<version> path component
• release.sh still works
• version embedding
1. git checkout shows “4.12-136-gf720023 (2016-10-10, branch "autotools")”
2. tarball of a git version shows “4.12-non-git”
3. release tarball shows 4.13
• debug mode is enabled by default for non-release builds
There is no noticeable difference in compilation speed itself (of binaries,
documentation and manpages):
i3-old $ time make all docs mans -j8
make all docs mans -j8 28.92s user 2.15s system 640% cpu 4.852 total
i3-new $ time make -j8
make -j8 27.08s user 1.92s system 620% cpu 4.669 total
In terms of one-time costs:
configuring the build system (../configure) takes about 2.7s on my machine,
generating the build system (autoreconf -fi) takes about 3.1s on my machine.
All files in m4/ have been copied from the autoconf-archive package in version b6aeb1988f4b6c78bf39d97b6c4f6e1d594d59b9 and should be updated whenever they
change.
This commit has been tested with autoconf 2.69 and automake 1.15.
Ingo Bürk [Tue, 11 Oct 2016 18:46:25 +0000 (20:46 +0200)]
Handle ResizeRequests for tray clients. (#2495)
Some tray clients such as VLC use override_redirect on their tray window. As per
specification this means i3bar won't receive a ConfigureRequest, but instead a
ResizeRequest will be triggered. If not selected, the X server will simply confirm
the request which leads to a broken tray window size.
This commit selects and handles the event just like a configure request is handled.
The idea was to ensure the symbol would always be present. For that, we need
__attribute__((used)), not __attribute__((unused)). Further, ensure the
variable has static storage, as the used attribute only applies to variables
with static storage. See also http://stackoverflow.com/a/29545417/712014
Remove conditional compilation for cairo/pangocairo (#2480)
We strive to avoid conditional compilation in i3 as much as possible.
cairo and pangocairo have been around long enough in the versions that
we need that it’s time to unconditionally depend on them.
Also update DEPENDS with the last-known-good-versions while at it.
Handle _NET_ACTIVE_WINDOW for scratchpad windows. (#2458)
We call scratchpad_show() on _NET_ACTIVE_WINDOW requests if the request
came from a pager. This is consistent with the i3 »focus« command because
we assume the user requested to see the window, so we do the only
sensible thing.
Check output crossing on ENTER_NOTIFY to dockarea. (#2477)
When receiving an ENTER_NOTIFY event on a dock client we returned as to not
focus the dock client (cf. #321 and #323). However, we still need to check
for crossing output boundaries and if that happened focus the new output.
Otherwise it can happen that the cursor is on a different output than the
focused output. When opening a window, this would open it on the old output
and then warp the mouse there. This effect will be even worse if the window
is immediately moved with 'move position mouse' as the window will end up
in its correct position on the new output and the cursor warped to the old
output.
We add $HOME to the environment variables we define for a test case
in order to redirect it from the user's actual home directory. This
is necessary because xcb-util-xrm will fall back to $HOME/.Xresources
when determining the DPI. If a user has this set to, e.g., 192 on their
machine, this would break tests.
Since tests shouldn't rely on the system they run in, we redirect the
home directory altogether to simulate a clean slate.
When I3SOCK is present, socket_path might be a pointer to an
environment variable, which cannot be free'd in line 157. This
commit duplicates the string if I3SOCK is present, thus making
socket_path a free-able pointer again.
* Using the static default colormap we determine on startup if the
con has the corresponding depth. This avoids creating pointless
colormaps.
* Not freeing the default colormap to not have stray colormaps on
containers. This fixes an issue with certain programs such as xwd.
* Creating a custom colormap when necessary and freeing it when the
container is killed.
Previously, we always discarded the NumLock bit when looking up key
bindings for key press events, and we always grabbed every keycode with
and without the NumLock modifier.
With this commit, the NumLock bit is no longer discarded: since the
previous commit 3bd5e6e5c81b448f9f0ac84454671a871fbfea66 we can
correctly look up key bindings with/without the NumLock bit, as both
variants are stored in |keycodes_head|.
Further, before adding the NumLock fallback (resulting in grabbing the
keycode with the NumLock modifier), we now check whether the key has the
same meaning when NumLock is enabled. This correctly distinguishes the
KP_End vs. KP_1 case, i.e. one can now use the following key bindings:
# No longer accidentally triggered when pressing KP_1.
bindsym KP_End nop KP_End
since OpenBSD pthread does not support pthread_condattr_setpshared().
This patch could also stay in the OpenBSD ports tree or depend on a
configure test macro rather than defined __OpenBSD__.
Ingo Bürk [Wed, 11 May 2016 18:11:35 +0000 (20:11 +0200)]
Don't trigger binding on window border click unless --border is given. (#2349)
Prior to this commit a binding specifying only --whole-window would
trigger even when clicking on the window border. However, this should
only happen if --border is specified.
Smart option added to hide_edge_borders config param (#2191) (#2191)
Use case:
* When managing multiple terminals in a workspace, the borders makes it easier
to know where the focus is, but when there is only one it's obvious where the
focus is.
* When there's only a web browser for example, the borders are actually counter-
productive since it makes clicking a side scrollbar or a tab a bit harder (if I
smash my cursor to the side or the top of the workspace, I have to move it in
the other direction by just a few pixels to be able to grab it)
Behaviour:
* No borders when there's a single window in a workspace
* Borders when there are multiple windows in a workspace
Ingo Bürk [Sun, 8 May 2016 10:55:27 +0000 (12:55 +0200)]
Introduce support for specifying variables from X resources. (#2286)
This patch introduces a new 'set_from_resource' config directive which
allows defining a variable by retrieving its value from the X resource
database. This avoids having to configure a color scheme in multiple
files. The directive takes an additional fallback value which is used
in case the resource cannot be found or during config validation where
no X connection is available.
Furthermore, this patch includes the following changes:
- If the same variable is defined twice, we now properly overwrite the
value of the assignment rather than inserting two variable definitions
with the same key.
- We now depend on xcb-util-xrm to query the resource.
- Increase the buffer size for variable / resource assignments.
is used, it can happen that we first write the layout to disk and only
then receive the RandR change events. This leads to a situation where
the restored tree will contain these outputs, but the restarted i3
process will not receive the RandR events, thus the internal output in i3
is marked disabled.
This patch finds these cases after a restart and force-disables the
affected outputs.
Ingo Bürk [Thu, 5 May 2016 18:46:33 +0000 (20:46 +0200)]
Use the last known timestamp when calling xcb_set_input_focus(). (#2332)
In most cases this won't make a difference, but consider the following
scenario:
* Some application acquires input focus on its own (which the window manager
is not involved in, so it will "always" work).
* Before the FocusIn / FocusOut events are processed by i3, the
workflow to push X changes is run, resulting in xcb_set_input_focus()
being called.
Using XCB_CURRENT_TIME, this means i3 will "win" and override the focus,
even though it simply wasn't aware (yet) that focus had already been taken
over by someone else. When processing the FocusIn / FocusOut events, i3
assumes that the focus is already set which results in a broken focus
state as i3 assumes some container has the input focus when it doesn't.
With the new behavior, i3's attempt to set the input focus will fail if
the FocusIn / FocusOut events have not yet processed. Once they are processed,
the focus state will be automatically corrected.
Ingo Bürk [Thu, 5 May 2016 12:18:04 +0000 (14:18 +0200)]
Remove dead code guarded with "#if 0 … #endif" (#2338)
This code has been neutralized for many years now and served no purpose
other than cluttering up the code. We obviously don't need it and it's
out of date anyway.
If there's ever any reason to restore (parts of) it, we have git for
that. But we don't need to keep commented out code around.
Ingo Bürk [Sun, 1 May 2016 16:59:50 +0000 (18:59 +0200)]
Remove title indentation in nested containers. (#2330)
This commit removes the title indentation in certain nested container
situations. The behavior was considered broken as it didn't seem to
make sense and it was unclear why this was introduced.
Given that nobody on i3-discuss@ complained about removing this logic
within two weeks, we are now removing it to make the title rendering
code a little less complex.
i3-input: Proper position in non-standard cases. (#2313)
This commit fixes two issues:
* We detect the EWMH support window from the root window. If this window
currently has the input focus, we ignore this. We do this because this
window is not a window the user is aware of and positioning relative to
it makes no sense.
* We also detect whether the current input focus is in an i3-frame window.
This can happen, e.g., when selecting a parent (split) container. Since
frame windows are direct children of the root window, we must not
translate its coordinates or we get weird results and i3-input ends up
off-screen (see #2312). For all other windows, including those without
any WM_CLASS, we proceed as before.
When allowing multiple marks on a container, we renamed the "mark"
field to "marks". This breaks i3-save-tree which will now filter out
the marks on a window because it doesn't match anymore. This commit
fixes that issue.
Thanks to /u/xenomachina for hinting to this issue.
Since we don't actually stop drawing a title (or marks) with the
distance of the border width on the right side, but instead with
a hard-coded two pixel distance, we can only redraw that much of
the border without potentiall cutting off text.
Correctly count the number of windows for no_focus. (#2296)
Previously we counted the number of (direct) children of the workspace to
decide whether no_focus should be applied or not. However, this doesn't
work correctly if there's a single container with multiple windows on the
workspace.
This patch correctly counts all windows on the workspace.