If conn == NULL or display == NULL, init_dpi() jumps to init_dpi_end
before (declaring and) initializing resource. In init_dpi_end, there
is a free(resource) call conditionally on resource != NULL, so this
may lead to a bogus free. Found by clang -Wsometimes-uninitialized.
Including config.h is necessary to get e.g. the _GNU_SOURCE define and
any other definitions that autoconf declares. Hence, config.h needs to
be included as the first header in each file.
This is done either via:
1. Including "common.h" (i3bar)
2. Including "libi3.h"
3. Including "all.h" (i3)
4. Including <config.h> directly
Also remove now-unused I3__FILE__, add copyright/license statement
where missing and switch include/all.h to #pragma once.
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.)
┌──────────────────────────────────────────────────────────────────────────────┐
│ recommended reading │
└──────────────────────────────────────────────────────────────────────────────┘
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.
┌──────────────────────────────────────────────────────────────────────────────┐
│ changes │
└──────────────────────────────────────────────────────────────────────────────┘
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
• enabling verbose builds via V=1
┌──────────────────────────────────────────────────────────────────────────────┐
│ speed │
└──────────────────────────────────────────────────────────────────────────────┘
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.
┌──────────────────────────────────────────────────────────────────────────────┐
│ m4 macros │
└──────────────────────────────────────────────────────────────────────────────┘
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.
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.
We now build a docker base container based on debian sid (where the very
latest packages are available). That base container is updated once a
month, or whenever travis-build.Dockerfile or debian/control change, but
re-used for subsequent travis runs. While the initial build might take
up to 15 minutes, subsequent builds typically run in a minute or two.
All the different steps that we run on travis are now factored into
separate scripts in the travis/ directory.
Switching to docker should also help with issue #2174.
Commit 287a0b4 introduced a segfault when validating the i3 config
as the root_screen will not be set in this case, causing a null
pointer dereference.
fixes#2144
This patch moves the title_format information from windows to containers.
Furthermore, it allows correctly setting it on window-less containers and
displays the title accordingly for split containers.
We now also dump and read title_format in GET_TREE / during restarts.
fixes#2120
Re-introduce fully-fledged get_colorpixel function, which enables arbitrary
color depths for the display. The previous code is kept as an optimization for
the case of a true color display, where a X11 roundtrip is unnecessary.
Corrects the cases where the colorpixel is not 0xRRGGBB : we have to
use the full color_t struct to describe font colors, as Pango expects
RGB values and not an XCB colorpixel value.
We now only log an error but do not exit when creating the graphics
context fails. While, if this happens, rendering will likely be wrong,
this is still better than terminating the user's session entirely due
to a rendering problem, potentially causing data loss.
relates to #2094
If a window with border is set to "border none" and then closed, we would
call cairo_destroy / cairo_surface_destroy twice, causing an assertion
failure in cairo as the objects already had zero references the second
time. We fix this by explicitly setting these objects to NULL.
relates to #1278
With this patch, we use 32-bit visuals per default whenever it is
available. Otherwise, we fall back to the actual root window's
depth, which will typically be 24-bit.
Before this patch, we already used 32-bit depth for containers with
a window that uses 32-bit. However, this means that we didn't use
32-bit for split parent containers on which decoration is drawn.
For 32-bit windows using transparency, this caused a graphical glitch
because the decoration pixmap behind it would show through. This
behavior is fixed with this change.
relates to #1278
With this patch we remove the temporary draw_util_colorpixel_to_color
function we introduced previously by parsing the colors as color_t to
begin with.
relates to #1278
We return early from drawing functions if the surface to draw to is not
initialized properly. There is no immediate need to do so, at least no
crashes have been observed, but it mirrors the previous behavior a bit
more closely. Furthermore, i3 should not crash due to not being able to
make some rendering call, so this provides some stability.
relates to #1278
This patch migrates all decoration rendering of i3 to cairo. Using the
compile switch CAIRO_SUPPORT, rendering can be switched back to the
previous XCB behavior, just like with the previous migration to cairo
in i3bar.
This patch also fixes a bug in draw_util.c where copying one surface
to another would use incorrect coordinates if the source coordinates
are not 0, 0.
Furthermore, this patch implicitly fixes some minor issues in the
decoration rendering which would be ignored previously due to the fact
that errors would only show up in the event queue, but not cause the
rendering code path to crash. One example is zero-height pixmaps which
are not allowed. Using cairo, these would cause i3 to instantly segfault,
so this patch avoids this.
Lastly, this patch annotates other issues found but not fixed in this patch
using TODO comments, e.g., the zero-height check not working correctly
and the comment that it should probably work the same way for zero-width
pixmaps.
relates to #1278
This patch fixes a bug when copying one surface to another.
Since it only exposes itself when used with non-trivial source
coordinates, it didn't surface before when only used for i3bar.
relates to #1278
In order to prepare for using cairo for rendering i3 decorations,
we need to make the draw_util.c from i3bar available via libi3 such
that both i3bar and i3 can use it.
relates to #1278
We pass alpha channel information to the current text drawing code
and use it if it is available. The previous behavior of using full
opacity for RGB format colors is preserved.
This patch creates all necessary windows for i3bar with 32-bit visuals if available.
It also introduces the possibility to define RGBA colors (next to RGB colors), which
allows the user to set the opacity of any color. This requires running a compositor.
With this patch we also start supporting _NET_SYSTEM_TRAY_VISUAL, which is necessary
for the tray icons so they create the tray window with the correct depth and visual.
* common.mk: use -lsocket -liconv -lgen on Illumos/Solaris
* mkdirp: return int and accept a mode argument
* use i3's mkdirp on everything except Illumos
The format string set with "title_format" can contain the placeholder "%title" which will be replaced with the actual window title.
By not overwriting window->name itself, we make sure that assignment matching still works as expected.
fixes#1723
If I restart i3 4.10.2 twice, e.g. with
$ i3-msg restart; sleep 3; i3-msg restart
the second time I get the following two errors:
05/22/15 10:46:03 - ERROR: mkdir(/tmp/i3-theo.toAK7N) failed: File exists
05/22/15 10:46:03 - ERROR: Could not create "/tmp/i3-theo.toAK7N" for storing the restart layout, layout will be lost.
The first one is from mkdirp() in src/ipc.c and the second one is from
store_restart_layout() in src/util.c.
Notice that I do _not_ get the ``open()'' or ``Could not write restart layout to
...'' error messages, so the layout writing code after line 260 in
store_restart_layout() succeeded and the layout isn't actually lost. Thus,
these error messages are a bit misleading, especially the second one (which is
triggered by the failure of mkdirp()).
POSIX says about `mkdir -p':
``Each dir operand that names an existing directory shall be ignored without
error.''
Therefore, I suggest the following simple patch that makes mkdirp() succeed if
the named file exists and actually is a directory. This silences the second
error as well.