- 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.