This is done by installing a new check watcher that replaces the main
X11 event handler and calling ev_run with EVRUN_ONCE until the dragging
loop left state DRAGGING.
With this commit, other handlers, most notably the redraw handler for
placeholder windows, get a chance to run when dragging (placeholder!)
windows around.
e.g. pressing Mod1+x when having the following in your configfile:
bindsym Mod1+x some invalid command
will lead to an i3-nagbar instance popping up, offering you to view the
error log (which will contain parser errors from this commit on).
On the rationale of using a custom parser instead of a lex/yacc one, see this
quote from src/commands_parser.c:
We use a hand-written parser instead of lex/yacc because our commands are
easy for humans, not for computers. Thus, it’s quite hard to specify a
context-free grammar for the commands. A PEG grammar would be easier, but
there’s downsides to every PEG parser generator I have come accross so far.
This parser is basically a state machine which looks for literals or strings
and can push either on a stack. After identifying a literal or string, it
will either transition to the current state, to a different state, or call a
function (like cmd_move()).
Special care has been taken that error messages are useful and the code is
well testable (when compiled with -DTEST_PARSER it will output to stdout
instead of actually calling any function).
During the migration phase (I plan to completely switch to this parser before
4.2 will be released), the new parser will parse every command you send to
i3 and save the resulting call stack. Then, the old parser will parse your
input and actually execute the commands. Afterwards, both call stacks will be
compared and any differences will be logged.
The new parser works with 100% of the test suite and produces identical call
stacks.
In order to not depend on X11 just for getting the socket paths, scripts or
other programs can now use i3 --get-socketpath. Since i3 must be present on the
computer anyways, this saves one dependency :).
An example to set all XTerms floating:
for_window [class="XTerm"] mode floating
To make all urxvts use a 1-pixel border:
for_window [class="urxvt"] border 1pixel
A less useful, but rather funny example:
for_window [title="x200: ~/work"] mode floating
The commands are not completely arbitrary. The commands above were tested,
others may need some fixing. Internally, windows are compared against your
criteria (class, title, …) when they are initially managed and whenever one of
the relevant values change. Then, the specified command is run *once* (per
window). It gets prefixed with a criteria to make it match only the specific
window that triggered it. So, if you configure "mode floating", i3 runs
something like '[id="8393923"] mode floating'.
This involves:
• Compiling with xcb-util instead of xcb-{atom,aux} (they merged the libraries)
• Not using xcb-{event,property} anymore (code removed upstream)
• Not using the predefined WINDOW, CARDINEL, … atoms (removed upstream)
• Using the new xcb_icccm_* data types/functions instead of just xcb_*
(for example xcb_icccm_get_wm_hints instead of xcb_get_wm_hints)
Also I refactored the atoms to use x-macros.
Due to lots of cases which were added and added to tree_move(), the function
was not really easy to understand. For this refactoring, I wrote tree_move()
from scratch, thinking about (hopefully) all cases. The testsuite still passes.
The move command also has different parameters now. Instead of the hard to
understand 'before v' stuff, we use 'move [left|right|up|down]'.