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.
This helps for windows which are immediately destroyed instead of
unmapped, like when starting i3status | ./foobar | dzen2 -dock
and foobar does not exist (i3status and dzen2 will get a SIGPIPE).
Before this commit, i3 used key bindings in SYNC mode for bindings
like Mode_switch + <a> and replayed the key if the current state
did not include Mode_switch. This had some problems:
1) The WM needed to acknowledge much more key presses than you
actually had bindings for, thus making the system a bit laggy
sometimes.
2) Users of layouts who constantly type in the third level (like
russian layouts) did not get their cyrillic symbols correctly
(they were not replayed right), neither did the keybindings
work in both modes.
So, the current implementation uses the following approach: XKB
provides an event which contains the current state (including
the current level). i3 signs up for this event and upon receival,
it re-maps the bindings using Mode_switch (enables them when the
level goes to the third level and disables them as soon as the
level goes back to normal). This fixes both problems.
This is the foundation to use dzen2 or similar as a complete
replacement for the internal workspaces bar.
A testcase is included, more documentation about the IPC interface
will follow.
Add --force-xinerama when starting i3 to use Xinerama instead of RandR.
This should *ONLY* be done if you have no other choice (nvidia’s
binary driver uses twinview and does not expose the monitor information
through RandR).
This enables compilation with llvm-clang and thus closes ticket #101.
While it makes the code more ugly, I don’t see a beautiful solution
which would enable us to stay with the more elegant solution of
nested functions and still allow compilation with any other compiler
than gcc.
Thanks to Merovius for doing a proof of concept on this one and
being a driving force behind the idea.
Using RandR instead of Xinerama means that we are now able to use
the full potential of the modern way of configuring screens. That
means, i3 now has an idea of the outputs your graphic driver
provides, which allowed us to get rid of the ugly way of detecting
changes in the screen configuration which we used before. Now, your
workspaces should not be confused when changing output modes anymore.
Also, instead of having ugly heuristics to assign your workspaces
to (the screen at position X or the second screen in the list of
screens) you will be able to just specify an output name.
As this change basically touches everything, you should be prepared
for bugs. Please test and report them!
Actually, WM_CLASS contains two null-terminated strings, so we cannot
use asprintf() to get its value but rather use strdup() to get both
of them. Both values are compared when a client is matched against
a wm_class/title combination (for assignments for example).