The testcase is changed because it was actually incorrect. Easy to
verify because:
> _NET_CURRENT_DESKTOP
> …
> The index of the current desktop. This is always an integer between 0
> and _NET_NUMBER_OF_DESKTOPS - 1.
Fixes#3696.
Also updates the viewports.
Finally, fixes an issue with _NET_CURRENT_DESKTOP not being updated
after a workspace rename. Example:
- workspaces 1, 2, 3
- rename workspace 1 to 5
- All workspaces changed their index but _NET_CURRENT_DESKTOP was not
updated
Closes#3635.
Probably the bug can still happen when a tree_close_internal happens
inside a workspace_show but modifying the code to avoid them seems to
not be worth it.
- The result from con_get_output was always not NULL because
con_get_output asserts so
- get_output_by_name should always be able to get an output from the
corresponding container
- workspace_move_to_output doesn't return bool anymore since it can't
fail
Fixes#3595
Like the issue mentions:
> instead of the newly created workspace (not referenced by variable
> here) the `"init"` event is fired with the current workspace (`ws`).
Plus, there was another issue where duplicate workspace init events
where being sent because of workspace_get().
304-ipc-workspace-init.t: Subtest "move workspace to output" fails with
current next.
Fixes#3631
No event was being sent here:
2d6e09a66a/src/randr.c (L487)
533-randr15.t: I confirmed that SKIP still works if the xrandr command
fails.
Added test fails with current next.
This fixes a crash produced with the following config:
# i3 config file (v4)
workspace 1 output $screen1
workspace 2 output $screen2
exec --no-startup-id "i3-msg workspace 1, open && i3-msg workspace 2 && xrandr --output $screen2 --off && xrandr --output $screen1 --auto --output $screen2 --auto --right-of $screen1 "
Which results in:
ERROR: AddressSanitizer: heap-use-after-free on address …
READ of size 8 at 0x614000001f48 thread T0
#0 0x5563df6e73a8 in init_ws_for_output i3/src/randr.c:468
#1 0x5563df6ef3b4 in randr_query_outputs i3/src/randr.c:940
#2 0x5563df68dbe1 in handle_screen_change i3/src/handlers.c:450
… is located 264 bytes inside of 448-byte region …
freed by thread T0 here:
#1 0x5563df634b0a in con_free i3/src/con.c:96
#2 0x5563df7151e6 in tree_close_internal i3/src/tree.c:344
#3 0x5563df7280fe in workspace_show i3/src/workspace.c:499
#4 0x5563df6e7315 in init_ws_for_output i3/src/randr.c:457
#5 0x5563df6ef3b4 in randr_query_outputs i3/src/randr.c:940
#6 0x5563df68dbe1 in handle_screen_change i3/src/handlers.c:450
Which is similar to #3228, #3248.
This commit makes multiple changes in tree_close_internal. I didn't
split them because they are not completely independent.
- Remove force_set_focus parameter
This parameter was always set to `false` throughout the code base except
for one case where it was set to `(con == focused)`, when killing a
floating con's parent (the one with type CT_FLOATING_CON). But this case
is not needed anymore since the special handling of CT_FLOATING_CONs in
con_next_focused was removed in #2941.
- Assume that con_next_focused does not returned a container of type
CT_DOCKAREA. This is reasonable since con_next_focused uses the
focus_head stack and has special handling of CT_DOCKAREA containers.
- Remove is_mapped
This variable was only used in the if block towards the end of
tree_close_internal. Ignoring the, now removed, dockarea code and the
use of force_set_focus this block performed only one useful action:
focus the `next` container when `con == focused`. `con == focused` was a
necessary and sufficient condition for the con_activate call:
if `con != focused` we could reach the inner if blocks because of the
other conditions but would never focus another container. If `con ==
focused` then all other conditions would be irrelevant.
- Remove special handling of floating containers
Since the `next` focused container is calculated through the parent for
floating containers, I moved this code to con_next_focused.
Also, because of the removal of force_set_focus, it appears that we can
call con_on_remove_child for floating containers as well.
This prohibits the usage of workspaces assigned to other outputs in
create_workspace_on_output.
Eg, with config:
workspace 1 output fake-0
workspace 2 output fake-0
and 2 screens workspace 2 would be used for the second screen even
though it is assigned to the first one.
Also introduces a test for workspace assignments that includes the case
described above and some tests that don't fail in the next branch.
This also replaces code in create_workspace_on_output() that is
theoretically more efficient but:
1. It isn't a huge difference since it depends on the number of outputs,
that shouldn't be high.
2. get_assigned_output will be modified and used for #555, then its
logic should be followed in create_workspace_on_output() too.
Another note for create_workspace_on_output: if assigned is not NULL the
condition (assigned != output->con) should never be false, ie if there
is an assigned output to this name, it isn't the current one. This
happens because the current callers check for assignments before calling
create_workspace_on_output().
Currently when renaming outputs, an output assignment of "left" will
cause the workspace to move left. Treat this assignment as a proper name
instead (even though it is unlikely an output will be named "left").
Move logic for determining output to move to out of
`workspace_move_to_output`
Add test for ignoring direcionality during rename.
Fixes#3208.
From comment:
https://github.com/i3/i3/issues/2990#issuecomment-368345169
To easily reproduce:
1. Open 2 floating windows
2. Focus (with `focus_follows_mouse`) the one behind
3. Move the mouse to the other workspace
4. Move the mouse inside the previous workspace (without it even
touching a window)
The bug triggers when _workspace_show calls tree_close_internal and
old == old_focus. Ie, when the old workspace was empty and needs to be
closed but then is accessed as output_push_sticky_windows's argument:
Breakpoint 1, output_push_sticky_windows (to_focus=0x55555589c8a0) at ../../i3/src/output.c:102
102 con_move_to_workspace(current, visible_ws, true, false, current != to_focus->parent);
(gdb) print con_exists(to_focus)
$1 = false
The access violation can also be prevented by checking if
con_exists(old_focus) but it shouldn't be necessary: the old_focus
container can only be killed when it is an empty workspace.
With --enable-sanitizers this causes i3 to exit but with
--disable-sanitizers the access violation doesn't reliably cause a crash
and the con_move_to_workspace call continues with:
(gdb) print current != to_focus->parent
$2 = 1
Since current->type is CT_FLOATING_CON and to_focus->type is
CT_WORKSPACE, in this specific case ignore_focus would always be true.
So, in this case, passing NULL instead of old_focus to
output_push_sticky_windows doesn't change the behaviour of i3.
Fixes#3075.
Currently simply returns output->name, but this will make it easier to
change how output names are stored in the following commits.
Also replace reading output->name with invocations of
output_primary_name. Code which writes output->name is unchanged. Done
using a mostly mechanical replacement of output->name to
output_primary_name(output).
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 patch correctly determines the previously focused workspace on the
target output when moving a workspace to another output. Before, we used
nodes_head for this, which will not actually return the previously focused
workspace, but just the first workspace on that output. Hence, we now use
focus_head instead.
This bug was introduced all the way back in 1e143fea when the feature of
moving workspaces to another output was first implemented.
fixes#2229
We already claim _NET_WM_DESKTOP support in _NET_SUPPORTED since around 2009,
but haven't actually done anything with it. However, especially pagers like
gnome-panel rely on this property to be updated and many tools, like GTK, want
to use the corresponding client messages to make a window sticky, move it
around etc.
This patch implements full support according to the EWMH spec. This means:
* We set the property on all windows when managing it.
* We keep the property updated on all windows at all times.
* We read and respect the property upon managing a window if it was set before
mapping the window.
* We react to client messages for it.
* We remove the property on withdrawn windows.
Note that the special value 0xFFFFFFFF, according to the spec, means that the
window shall be shown on all workspaces. We do this by making it sticky and
float it. This shows it on all workspaces at least on the output it is on.
Furthermore, the spec gives us the freedom to ignore _NET_WM_DESKTOP when
managing a window if we have good reason to. In our case, we give window
swallowing a higher priority since the user would likely expect that and we
want to keep placeholder windows only around for as long as we have to.
However, we do prioritize this property over, for example, startup
notifications.
fixes#2153fixes#1507fixes#938
It should be clear for callers of this function that this is an internal
function that skips certain validations which might be important. Therefore
we make it clear that this is an internal function by renaming it.
relates to #1761
See the issue #1798 (http://github.com/i3/i3/issues/1798).
+workspace_next+ as-is cycles through either numbered or named workspaces,
but when it reaches the last numbered/named workspace, it only looks for
named workspaces. This commit changes it: look for named workspaces after
exhausting numbered ones, but also for numbered ones after exhausting
named ones.
Also add a test case 528-workspace-next-prev.t (numbered workspaces and named
workspaces on 2 outputs) for testing this.
This commit also reworks the way focusing sticky windows is prevented by not focusing them temporarily at all, but preventing the focus in the first place.
The comment immediately following implied that this was the intended
behaviour. Not doing so means that compound commands that both move a
window to a new workspace as well as do something that depends on the
workspace's geometry (e.g. 'move position center' or 'floating enable'
on a tiled window) would use the workspace's calloc'd 0x0+0x0 geometry.