Orestis Floros [Sat, 9 Dec 2017 20:17:48 +0000 (22:17 +0200)]
Prevent access of freed workspace in _workspace_show
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.
Orestis Floros [Sat, 9 Dec 2017 17:56:54 +0000 (19:56 +0200)]
migrate_config: scalloc converted config
Prevents a false-positive error eg with config file:
set $mod Mod4
bindsym $mod+h split h
bindsym $mod+v split v
ERROR: CONFIG: Expected one of these tokens: <end>, '#', 'set ', ...
ERROR: CONFIG: Line 8: status_command i3status
ERROR: CONFIG: Line 9: }
ERROR: CONFIG: Line 10: <BE><BE><BE><BE><BE><BE>
Orestis Floros [Sat, 9 Dec 2017 13:35:05 +0000 (15:35 +0200)]
floating_maybe_reassign_ws: show workspace before focusing
With this change i3 will correctly switch to the focused workspace.
This fixes bug with moving floating windows with 'move <direction>' or by dragging like _NET_CURRENT_DESKTOP not getting updated or 'workspace back_and_forth' not working.
Orestis Floros [Fri, 8 Dec 2017 00:23:15 +0000 (02:23 +0200)]
Add '--release' flag for bindsym in the bar block
i3bar's handle_button is modified to also handle XCB_BUTTON_RELEASE
events. During these button release events, only custom commands are
checked to avoid sending multiple workspace ipc messages.
The way this patch is implemented will allow to assign a custom command
for both the press and release of the same button:
bar {
...
bindsym buttonX exec command1
bindsym --release buttonX exec command2
}
Daniel Mueller [Wed, 29 Nov 2017 07:29:47 +0000 (23:29 -0800)]
Perform proper cleanup for signals with 'Term' action (#3057)
Issue #3049 describes a case where terminating i3 by means of SIGTERM
causes it to leak the runtime directory and all its contents. There are
multiple issues at play: first, any cleanup handlers registered via
atexit are never invoked when a signal terminates the program (see
atexit(3)). Hence, the log SHM log cleanup performed in i3_exit is not
invoked in that case. Second, compared to the shutdown path for the
'exit' command, we do not unlink the UNIX domain socket we create,
causing it to be leaked as well. Third, a handler for SIGTERM is not
registered at all despite handle_signal claiming to be the handler for
all 'Term' signals.
This change addresses all three problems and results in a graceful exit
including cleanup to happen when we receive a signal with the default
action 'Term'. It addresses issue #3049.
Daniel Mueller [Fri, 17 Nov 2017 14:58:12 +0000 (06:58 -0800)]
i3bar: replace magic numbers with more meaningful constructs
In i3bar/src/config.c we compare string lengths agains magic numbers.
This change replaces those numbers with the lengths of the strings they
represent.
The userguide still mentions an old 'goto' command which no longer
exists and will be ignored silently (when used in the i3 config) or
causes an error to be reported (when invoked from the command line).
This change updates the userguide to correct this problem. In addition
to that it also updates the i3-input command shown to no longer use the
deprecated -p flag but -F instead.
Previously, we used ev_check watchers, which are executed at the beginning of an
event loop iteration.
This was problematic if one of the handlers happened to fill the XCB event
queue, e.g. by reading a reply from X11 and an event happened in the meantime.
In that situation, we would hand control to the event loop, entirely ignoring
the pending event. This would manifest itself as a 1-minute hang,
reproducible (sometimes) in the i3 testsuite.
issue #2790 describes an instance of this issue in i3bar, and we fixed that by
changing the watcher priority to run last. Handling events in xcb_prepare_cb has
the same effect, as ev_prepare watchers are run just before the event loop goes
to sleep.
We need to set dont_map => 1 on the sync window to prevent an endless loop.
Further, t/219-ipc-window-focus.t made assumptions about windows being named
incrementally, and that assumption is broken by the sync window opened by the
first sync_with_i3 call from open_window, so use the more reliable ->name.
_NET_ACTIVE_WINDOW: invalidate focus to force SetInputFocus call (#3027)
The sender of the _NET_ACTIVE_WINDOW client message might know better when to
set focus than i3, as i3 does not know about unmanaged (override_redirect=1)
windows.
hwangcc23 [Sun, 6 Aug 2017 15:08:05 +0000 (23:08 +0800)]
Add regression tests for #2846
1). Add one regression test in 167-workspace_layout.t:
- Get a fresh workspace
- Set the layout to something
- Create windows
- Try to switch to another layout
- Check if successful
- Repeat for all 12 possible transitions
2). Add another regression test in 167-workspace_layout.t:
- Check that the command 'layout toggle split' works regardless of
what layout we're using
Fix compilation warnings on all Debian architectures. (#3007)
stbuf.st_size is of type off_t, which the standard defines as “extended signed
integral type”¹, and for which there is no correct printf format string. Hence,
we need to cast it into a hopefully-large-enough type (ugh) and use the
corresponding format string. In our case, int64_t should do it, as config files
really shouldn’t be anywhere close to those numbers.
① http://pubs.opengroup.org/onlinepubs/007908799/xsh/systypes.h.html
Use con_descend_focused for workspaces in _tree_next
This way, when changing focus between outputs, the directional focus
command will focus the focused window within the parent container that
is next in the given direction.
Previously, the next window of the given direction was focused which is
Inconsistent with changing focus inside the same output.
Merge "force_focus_wrapping" option into "focus_wrapping force"
Allow enabling forced focus wrapping by specifying "focus_wrapping
force" in i3's configuration. This syntax supersedes the previous
"force_focus_wrapping yes" one, which remains available for backwards
compatibility.
This fixes a crash that occurs when disabling floating for a container
while it is being moved or resized.
@Deiz describes the problem:
> It occurs because the command that disables floating runs before the
event loop. So, the window is tiled, its floating parent is destroyed,
but then a key event is handled which causes the position/size of the
now-destroyed parent to be modified.
canonicalize_output_name allowed the "primary" special output name to
be canonicalized, thus converting it to the name of whatever output
was the primary output at the time. This caused settings
(specifically, i3bar output and tray_output settings) to be stored as
specific output names, instead of the intended special names whose
referred output may change as the system's configuration (i.e. current
primary output) changes.
Add a check to canonicalize_output_name to return the name as-is if it
is the special name "primary".
fake_outputs: Allow designating a fake output as primary
Allow appending 'P' to the fake output specification to set the
created output's "primary" flag, to allow writing test cases that
depend on the presence of a primary output.
fake_outputs_init would unconditionally increase the string read
pointer variable (walk) by one character more than the number of
characters that have been read, to skip past the character delimiting
records (a comma). However, when the input string was not terminated
by a comma, it would cause the function to read past the null
terminator instead.
Avoid this by explicitly checking for the expected delimiter.
fake_outputs: Use %n format specifier instead of sprintf
fake_outputs_init used a sprintf invocation with a throw-away buffer
to estimate how many characters the sscanf invocation consumed. This
was unnecessary, and also potentially incorrect, as differences
between the read and formatted strings (such as leading zeros) could
lead to fake_outputs_init to lose its track.
Instead, use the %n format specifier which allows saving the number of
characters consumed by sscanf so far. %n is part of C99.