With this commit, the "default" layout is replaced by the splith and
splitv layouts. splith is equivalent to default with orientation
horizontal and splitv is equivalent to default with orientation
vertical.
The "split h" and "split v" commands continue to work as before, they
split the current container and you will end up in a split container
with layout splith (after "split h") or splitv (after "split v").
To change a splith container into a splitv container, use either "layout
splitv" or "layout toggle split". The latter command is used in the
default config as mod+l (previously "layout default"). In case you have
"layout default" in your config file, it is recommended to just replace
it by "layout toggle split", which will work as "layout default" did
before when pressing it once, but toggle between horizontal/vertical
when pressing it repeatedly.
The rationale behind this commit is that it’s cleaner to have all
parameters that influence how windows are rendered in the layout itself
rather than having a special parameter in combination with only one
layout. This enables us to change existing split containers in all cases
without breaking existing features (see ticket #464). Also, users should
feel more confident about whether they are actually splitting or just
changing an existing split container now.
As a nice side-effect, this commit brings back the "layout toggle"
feature we once had in i3 version 3 (see the userguide).
AFAIK, it is safe to use in-place restart to upgrade into versions
after this commit (switching to an older version will break your layout,
though).
Fixes#464
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).
This is now restricted according to the already defined fullscreen
focus constraints. Test case 157 was removed, as we don't prevent
level up/down in fullscreen anymore. Those commands are properly
tested in fullscreen by test case 156.
Fixes: #612
Basically, a focus change can't escape a fullscreen container. The
only exception is per-output fullscreen containers, as you should
be able to focus a container in a different workspace in this case.
This is an improvement on 4eab046e, now considering the difference
between global and per-output fullscreen and taking the tree
structure into account to determine what escaping the fullscreen
container means. It only affects targeted focus commands in the
form "for_window [...] focus", but it lays the foundation for
forthcoming fixes to all other focus commands.
See also:
http://article.gmane.org/gmane.linux.kernel/1268792
The C compiler will handle (void) as "no arguments" and () as "variadic
function" (equivalent to (...)) which might lead to subtle errors, such
as the one which was fixed with commit 0ea64ae4.
Initially I thought using the second precision time() function is good enough,
but to make t/113-urgent.t considerably faster (>2s vs. 0.08s), we put in a
little more effort and use gettimeofday. Otherwise, this test blocks the whole
testsuite from completing much faster on modern machines :).
This change has two implications:
1) tree_render() will now be called precisely once for input which consists of
multiple commands (like "focus left; focus right"). Also, the caller of
parse_command() has to call it. This makes us able to fix tickets such as
ticket #608 (where multiple tree_render() calls are noticable).
2) The output of a command is now a JSON array of return values of the
individual subcommands. In the case of "focus left; focus right", this is:
[{"success":true}, {"success":true}]
While this is incompatible with what i3 returned before, the return value of
commands was undocumented and therefore not subject to our API stability.
You need to specify the --enable-32bit-visual flag when starting i3. This is
done because everything feels sluggish on my system when using a 32 bit visual
instead of a 24 bit visual. Fast > fancy.
Currently it supports the following options:
"oldest": match the first window that triggered an urgent event
"latest": match the last window that triggered an urgent event
This re-introduces borders around the workspace buttons in i3bar.
No additional pixels will be consumed (you will not lose any space for your
windows).
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.
After a reload, the drawing parameters for the decorations might
have changed, so we need to invalidate the cache and force a redraw
of the currently visible decorations. Also, don't leak the previous
font when reloading by freeing it before parsing the config.
Abstracted draw_text and predict_text_width into libi3. Use
predict_text_width from libi3 in i3 too. This required tracking
xcb_connection in a xcb_connection_t *conn variable that libi3
expects to be available in i3bar.
Also prints out useful stuff:
CORE DUMPS: You are running a development version of i3, so coredumps were
automatically enabled (ulimit -c unlimited).
CORE DUMPS: Your current working directory is "/home/michael/i3".
CORE DUMPS: Your core_pattern is: /tmp/%e.core.%p
i3 (tree) version 4.0.2-479-g26ab2ac (2011-11-08, branch "next") starting
This does not affect child processes of i3.
The intention of this change is to make debugging easier – it’s one less thing
users of the development version have to worry about when trying to help with
debugging.
Also, the API changed a bit. There are two functions now, both assume you
already got the keysyms (which is the case for i3 and i3-config-wizard),
one gets the modifier mapping for you (aio_get_mod_mask_for) while the other
assumes you also got that. No roundtrips are required for the latter.
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 :).
This is mainly useful for the testsuite. The tests can wait until i3 processed
all X11 events and then continue. This eliminates sleep() calls which leads to
a more robust and faster testsuite.
The configuration option does the same as the commandline parameter, except
it can be easily set by the user (e.g. you are using KDM and can't start a
session through ~/.xsession).
Signed-off-by: Michael Walle <michael@walle.cc>
- Introduce warp_to static variable in x.c that stores the coordinates
to warp to as a Rect.
- Add x_set_warp_to function to set this variable. Use in _tree_next,
workspace_show, and con_move_to_workspace.
- In x_push_chanages, if warp_to is set, then call xcb_warp_pointer_rect
and then reset it to NULL.
This fixes all know bugs for pointer warping for me.
Modify _tree_next() so that when we reach the workspace container:
1. Find the next corresponding output (screen) using the added
get_output_next().
2. If there is another output, find the visible workspace.
3. Call workspace_show on found workspace.
4. Find the appropriate window to focus (leftmost/rightmost, etc.) using
con_descend_direction, and then focus it.
I've only tested on horizontal monitors (left/right).
Generally, the traversal goes: numbered workspaces in order, and then
named workspaces in the order in which they appear in the tree.
Example:
Output 1: Output 2:
1 3 D C 2 4 B A
Traversal: 1, 2, 3, 4, D, C, B, A, 1, ...
Note, after the numbered workspaces, we traverse the named workspaces
from output 1, and then output 2, etc.
This fixes a race where we created cursors on the Xlib connection, flushed,
then used the cursor on the XCB connection. Even though we flushed, the X
server did not process the requests yet and therefore returned a BadCursor
error.
This bugfix uses the Xlib connection for setting the root window cursor which
will ensure that the requests are properly serialized.
An easy test for this (on my machine) is the following ~/.xsession:
xsetroot -cursor_name cross
exec i3
If you see a cross cursor instead of the pointer, the race happens. You’ll see
a error_code=6 error in your ~/.xsession-errors.
These errors can happen because a DestroyWindow request by a client will
trigger an UnmapNotify, then a DestroyNotify. We cannot distinguish this
UnmapNotify from an UnmapNotify not followed by a DestroyNotify, so we just try
to send the ReparentWindow / ChangeProperty and ignore the errors, if any.
Think of the following layout:
-------------
| tab | |
| con | win |
| | |
-------------
The tabbed container on the left has two children. Assume you have focused the
second/right child in the tabbed container. i3 used to focus the first/left
container of the tabbed container when using 'focus right' (it wrapped focus).
With this commit, the default behaviour is to instead focus the window on the
right of the screen.
The intention is to make focus switching more intuitive, especially with tabbed
containers supporting 'focus left'/'focus right' in tree. You should end up
using less 'focus parent' :).
You can force the old behaviour with 'force_focus_wrapping true' in your
config.
Code coverage is 62.5% with this commit.
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'.
Use 'kill window' to kill a specific window (for example only one specific
popup), use 'kill client' to kill the whole application (or X11 connection to
be specific).
When a tabbed container had more than one child and at least the first one
supported WM_DELETE, i3 entered an endless loop when killing that tabbed
container. This was due to tree_close only sending WM_DELETE without actually
removing the child, while the loop in tree_close assumed that with every call
of tree_close one child would be removed.
Actually, commit 1c5adc6c35 commented out code
without ever fixing it. I think this was responsible for the 'workspace
switching sometimes does not work' bug. My observations:
Had it again today and analyzed a log of it. Looks like after unmapping the
windows on one workspace (in my case: chromium, eclipse, urxvt, focus on
eclipse) we get UnmapNotify events for chromium and eclipse, but then we get an
EnterNotify for the terminal (due to unmapping the other windows and therefore
mapping the terminal under the cursor), only afterwards the UnmapNotify
follows.
So, there are two things wrong with that:
• We handle EnterNotifys for unmapped windows
• Unmapping windows sometimes works in a sequence, sometimes the sequence gets
split. Not sure why (if unmapping can take longer for some windows or if our
syncing is wrong -- but i checked the latter briefly and it looks correct).
Maybe GrabServer helps?
• We don’t ignore EnterNotify events caused by UnmapNotifies. We used to, but
then there was a different problem and we decided to solve the EnterNotify
problem in another way, which actually never happened (commit
1c5adc6c35).
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]'.
Instead, we attach them to their workspace when toggling back to tiling. This
makes more sense; afterall, floating clients are always directly below a
CT_WORKSPACE container.
The file is now created in /tmp using the process PID and the
username of the user running i3. The restart state file is only
loaded when restarting (the --restart option is appended to the
command line prior to the restart). That means that renaming the
old state file with the ".old" extension is no longer needed.
This "--restart" switch is supposed to be only used by i3. The
"-L" switch can be used to load a layout (and not delete it
afterwards). We unlink the state file after we load it so that
we don't keep cruft in /tmp or try to restart from an old config
file if restart_state is set.
Quote from the source:
When the container type is CT_WORKSPACE, the user wants to change the
whole workspace into stacked/tabbed mode. To do this and still allow
intuitive operations (like level-up and then opening a new window), we
need to create a new split container. */
Numbered workspaces (workspaces with a name containing only digits) will be
inserted in the correct order now. Named workspaces are always sorted after
numbered workspaces and in the order of creation.
This fixes the bug which caused floating windows to be visible even when
switching to a different workspace.
Instead of ignoring a specific sequence, we now set an ignore_unmap counter for
each container. (So, should containers be closed too early or stay open even if
they should be closed, we probably need to have a closer look at the counter.
At the moment, it is increased by one on reparenting and unmapping (for
workspace changes) and decremented by one on each UnmapNotify event).
This system is better because a sequence does not describe a single unmap or
reparent request but a request to X11 on the network layer -- which can contain
multiple requests.
The implementation works like this:
Containers can have a 'sticky-group' attribute. Imagine two different
containers (on two different workspaces) which have the same sticky-group.
Now you open a window in the first container. When you switch to the
other workspace, the window will be re-assigned to the other container.
An obvious problem which is not covered with the code at the moment is
having two containers with the same sticky-group visible at the same time.