diff --git a/I3_VERSION b/I3_VERSION index 7cf2ba0d3..60f610c03 100644 --- a/I3_VERSION +++ b/I3_VERSION @@ -1 +1 @@ -4.18-non-git +4.18.1-non-git diff --git a/Makefile.am b/Makefile.am index 59eba84a8..d62b2f53f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -118,7 +118,7 @@ EXTRA_DIST = \ I3_VERSION \ LICENSE \ PACKAGE-MAINTAINER \ - RELEASE-NOTES-4.18 \ + RELEASE-NOTES-4.18.1 \ generate-command-parser.pl \ parser-specs/commands.spec \ parser-specs/config.spec \ diff --git a/RELEASE-NOTES-4.18 b/RELEASE-NOTES-4.18 deleted file mode 100644 index 4396ee1bf..000000000 --- a/RELEASE-NOTES-4.18 +++ /dev/null @@ -1,71 +0,0 @@ - - ┌────────────────────────────┐ - │ Release notes for i3 v4.18 │ - └────────────────────────────┘ - -This is i3 v4.18. This version is considered stable. All users of i3 are -strongly encouraged to upgrade. - - ┌────────────────────────────┐ - │ Changes in i3 v4.18 │ - └────────────────────────────┘ - - • docs/ipc: document fullscreen_mode in GET_TREE reply - • docs/ipc: document marks field in GET_TREE reply - • docs/ipc: document window_type in GET_TREE reply - • docs/ipc: improve documentation for window_properties - • docs/userguide: clarify commands/config directive wording - • layout saving: remanage window after property updates (e.g. titles) - • get_first_output: prefer primary output (e.g. when moving disabled outputs) - • ipc: add window_type to nodes - • ipc: add container id to nodes - • allow dragging active titles for all container types (e.g. floating+tabbed) - • allow dragging inactive titles after a 10px threshold - • make tray icon order deterministic (sorted by class/instance) - • implement focus next|prev - • implement focus next|prev sibling - • implement focus_wrapping workspace - • exit with exit code 0 on --help - • exec command: respect command criteria - - ┌────────────────────────────┐ - │ Bugfixes │ - └────────────────────────────┘ - - • build: fix lcov support - • build: use AC_REPLACE_FUNCS, drop bundled memmem - • build: fix building with -fno-common (for gcc 10) - • build: configure: deal with git worktree checkouts, where .git is a file - • docs/userguide: fix link to pango markup - • docs/userguide: add missing manipulating_layout anchor - • docs/userguide: fix IPC socket location - • i3-nagbar: make debug log visible - • i3-nagbar: fix small memory leaks - • i3bar: fix small memory leaks - • move workspace to output: don’t create duplicate numbered workspace - • correctly select output when pointer query fails - • fix moving windows to scratchpad when using marks - • fix startup workspace selection when workspace command uses options - • do not try to center floating window on itself (fixes xterm placement) - • fix “move window to ” when target is a workspace - • correctly activate windows behind a fullscreen window - • fix back-and-forth after renaming workspaces - • keep focus when moving container to marked workspace - • do not show scratchpad windows upon move to position command - • reparent windows to their current position when unmanaging - (fixes dock clients unexpectedly moving to different output) - • fix crash when moving containers - • scratchpad_move: un-fullscreen correct container - • avoid crash when nc->window is NULL - - ┌────────────────────────────┐ - │ Thanks! │ - └────────────────────────────┘ - -Thanks for testing, bugfixes, discussions and everything I forgot go out to: - - acheronfail, Albert Safin, Antoine, Benjamin Dopplinger, Brian Ashworth, - Damien Cassou, Daniele Varrazzo, David Shen, Erwin J. van Eijk, Ingo Bürk, - Iskustvo, izzel, Konst Mayer, Orestis Floros, Yury Ignatev - --- Michael Stapelberg, 2020-02-17 diff --git a/RELEASE-NOTES-4.18.1 b/RELEASE-NOTES-4.18.1 new file mode 100644 index 000000000..c05180f8d --- /dev/null +++ b/RELEASE-NOTES-4.18.1 @@ -0,0 +1,32 @@ + + ┌──────────────────────────────┐ + │ Release notes for i3 v4.18.1 │ + └──────────────────────────────┘ + +This is i3 v4.18.1. This version is considered stable. All users of i3 are +strongly encouraged to upgrade. + +This is a bugfix release for v4.18. + + ┌────────────────────────────┐ + │ Bugfixes │ + └────────────────────────────┘ + + • Move parent nodes in scratchpad correctly + • i3bar: Call cont_child() more liberally + • Fix load_layout crash when floating node doesn't have CT_FLOATING_CON parent + • Fix SEGFAULT when i3bar receives invalid input + • Revert "floating_reposition: avoid extra tree_render" + • Call tree_render if floating move changes workspace + • Update EWMH properties on workspace move + • cmd_focus_sibling: Fix crash on workspace level + + ┌────────────────────────────┐ + │ Thanks! │ + └────────────────────────────┘ + +Thanks for testing, bugfixes, discussions and everything I forgot go out to: + + Heman Gandhi, Orestis Floros + +-- Michael Stapelberg, 2020-04-22 diff --git a/configure.ac b/configure.ac index dda934823..fe34d6b26 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Run autoreconf -fi to generate a configure script from this file. AC_PREREQ([2.69]) -AC_INIT([i3], [4.18], [https://github.com/i3/i3/issues]) +AC_INIT([i3], [4.18.1], [https://github.com/i3/i3/issues]) # For AX_EXTEND_SRCDIR AX_ENABLE_BUILDDIR AM_INIT_AUTOMAKE([foreign subdir-objects -Wall no-dist-gzip dist-bzip2]) diff --git a/debian/changelog b/debian/changelog index e89df1f44..059fa327d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -26,7 +26,6 @@ i3-wm (4.16.1-1) unstable; urgency=medium * New upstream release. ->>>>>>> vanilla/next -- Michael Stapelberg Sun, 27 Jan 2019 16:45:11 +0100 i3-wm (4.16-1) unstable; urgency=medium diff --git a/i3bar/src/child.c b/i3bar/src/child.c index 83ee26b41..85206ac34 100644 --- a/i3bar/src/child.c +++ b/i3bar/src/child.c @@ -194,6 +194,11 @@ static int stdin_map_key(void *context, const unsigned char *key, size_t len) { static int stdin_boolean(void *context, int val) { parser_ctx *ctx = context; + + if (!ctx->last_map_key) { + return 0; + } + if (strcasecmp(ctx->last_map_key, "urgent") == 0) { ctx->block.urgent = val; return 1; @@ -208,6 +213,11 @@ static int stdin_boolean(void *context, int val) { static int stdin_string(void *context, const unsigned char *val, size_t len) { parser_ctx *ctx = context; + + if (!ctx->last_map_key) { + return 0; + } + if (strcasecmp(ctx->last_map_key, "full_text") == 0) { ctx->block.full_text = i3string_from_markup_with_length((const char *)val, len); return 1; @@ -260,6 +270,11 @@ static int stdin_string(void *context, const unsigned char *val, size_t len) { static int stdin_integer(void *context, long long val) { parser_ctx *ctx = context; + + if (!ctx->last_map_key) { + return 0; + } + if (strcasecmp(ctx->last_map_key, "min_width") == 0) { ctx->block.min_width = (uint32_t)val; return 1; diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index 1ecae1144..0880cb819 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -677,9 +677,6 @@ static void handle_visibility_notify(xcb_visibility_notify_event_t *event) { continue; } if (output->bar.id == event->window) { - if (output->visible == visible) { - return; - } output->visible = visible; } num_visible += output->visible; @@ -687,10 +684,7 @@ static void handle_visibility_notify(xcb_visibility_notify_event_t *event) { if (num_visible == 0) { stop_child(); - } else if (num_visible == visible) { - /* Wake the child only when transitioning from 0 to 1 visible bar. - * We cannot transition from 0 to 2 or more visible bars at once since - * visibility events are delivered to each window separately */ + } else { cont_child(); } } diff --git a/src/commands.c b/src/commands.c index 496316b66..9f6309a55 100644 --- a/src/commands.c +++ b/src/commands.c @@ -1299,7 +1299,16 @@ void cmd_focus_sibling(I3_CMD, const char *direction_str) { } Con *next = get_tree_next_sibling(current->con, direction); if (next) { - con_activate(next); + if (next->type == CT_WORKSPACE) { + /* On the workspace level, we need to make sure that the + * workspace change happens properly. However, workspace_show + * descends focus so we also have to put focus on the workspace + * itself to maintain consistency. See #3997. */ + workspace_show(next); + con_focus(next); + } else { + con_activate(next); + } } } @@ -1517,7 +1526,7 @@ void cmd_move_direction(I3_CMD, const char *direction_str, long move_px) { break; } - floating_reposition(current->con->parent, newrect); + cmd_output->needs_tree_render = floating_reposition(current->con->parent, newrect); } else { tree_move(current->con, direction); cmd_output->needs_tree_render = true; diff --git a/src/floating.c b/src/floating.c index 117160b5f..ba2074074 100644 --- a/src/floating.c +++ b/src/floating.c @@ -745,16 +745,13 @@ bool floating_reposition(Con *con, Rect newrect) { con->rect = newrect; - bool reassigned = floating_maybe_reassign_ws(con); + floating_maybe_reassign_ws(con); /* If this is a scratchpad window, don't auto center it from now on. */ if (con->scratchpad_state == SCRATCHPAD_FRESH) con->scratchpad_state = SCRATCHPAD_CHANGED; - /* Workspace change will already result in a tree_render. */ - if (!reassigned) { - tree_render(); - } + tree_render(); return true; } diff --git a/src/load_layout.c b/src/load_layout.c index 063cb2e5c..f61e6877e 100644 --- a/src/load_layout.c +++ b/src/load_layout.c @@ -171,6 +171,19 @@ static int json_end_map(void *ctx) { con_attach(json_node, json_node->parent, true); LOG("Creating window\n"); x_con_init(json_node); + + /* Fix erroneous JSON input regarding floating containers to avoid + * crashing, see #3901. */ + const int old_floating_mode = json_node->floating; + if (old_floating_mode >= FLOATING_AUTO_ON && json_node->parent->type != CT_FLOATING_CON) { + LOG("Fixing floating node without CT_FLOATING_CON parent\n"); + + /* Force floating_enable to work */ + json_node->floating = FLOATING_AUTO_OFF; + floating_enable(json_node, false); + json_node->floating = old_floating_mode; + } + json_node = json_node->parent; incomplete--; DLOG("incomplete = %d\n", incomplete); diff --git a/src/scratchpad.c b/src/scratchpad.c index 261a8bfde..cce4c0bfc 100644 --- a/src/scratchpad.c +++ b/src/scratchpad.c @@ -138,7 +138,7 @@ bool scratchpad_show(Con *con) { floating->scratchpad_state != SCRATCHPAD_NONE) { DLOG("Found a visible scratchpad window on another workspace,\n"); DLOG("moving it to this workspace: con = %p\n", walk_con); - con_move_to_workspace(walk_con, focused_ws, true, false, false); + con_move_to_workspace(floating, focused_ws, true, false, false); con_activate(con_descend_focused(walk_con)); return true; } diff --git a/src/workspace.c b/src/workspace.c index d4dcaed3b..74982f37c 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -1069,6 +1069,8 @@ void workspace_move_to_output(Con *ws, Output *output) { workspace_show(ws); } + ewmh_update_desktop_properties(); + if (!previously_visible_ws) { return; } diff --git a/testcases/t/185-scratchpad.t b/testcases/t/185-scratchpad.t index bffdf74a3..0cd9ac3b1 100644 --- a/testcases/t/185-scratchpad.t +++ b/testcases/t/185-scratchpad.t @@ -548,5 +548,31 @@ is ($x->input_focus, $second->id, 'moving scratchpad window does not show it'); cmd '[id=' . $first->id . '] move position center'; is ($x->input_focus, $second->id, 'centering scratchpad window does not show it'); +################################################################################### +# Verify that a scratchpad container with child containers that was open in +# another workspace is moved to the current workspace (with all its children) +# after a scratchpad show. +################################################################################ + +kill_all_windows; +open_window; +open_window; +# This is to dodge the edge case were the whole workspace is moved +# window-by-window into the scratchpad. +cmd 'layout tabbed'; +cmd 'focus parent'; +cmd 'move to scratchpad'; +$ws = fresh_workspace; +cmd 'scratchpad show'; +# Case 1: a parent node in the scratchpad does not lose children +# Note on the layout: there should be a floating tabbed container, which is +# represented as follows: +# [workspace object] -> [floating_nodes] -> [tabbed node container] -> [the 2 children we expect] +is(scalar @{get_ws($ws)->{floating_nodes}->[0]->{nodes}->[0]->{nodes}}, 2, 'both windows moved from scratchpad to this workspace'); + +# Case 2: a parent node in the scratchpad from another workspace does not lose children +$ws = fresh_workspace; +cmd 'scratchpad show'; +is(scalar @{get_ws($ws)->{floating_nodes}->[0]->{nodes}->[0]->{nodes}}, 2, 'both windows moved from scratchpad focused on other workspace to this workspace'); done_testing; diff --git a/testcases/t/215-layout-restore-crash.t b/testcases/t/215-layout-restore-crash.t index 0306425a8..d9fcd54a7 100644 --- a/testcases/t/215-layout-restore-crash.t +++ b/testcases/t/215-layout-restore-crash.t @@ -212,7 +212,7 @@ subtest 'issue 2755' => sub { EOT $fh->flush; $reply = cmd "append_layout $filename"; - ok(!$reply->[0]->{success}, 'IPC reply indicated success'); + ok(!$reply->[0]->{success}, 'IPC reply did not indicate success'); does_i3_live; @@ -276,5 +276,49 @@ does_i3_live; close($fh); +################################################################################ +# Issue with floating key being set, without proper parent +# See #3901 +################################################################################ +subtest 'issue 3901' => sub { + kill_all_windows; + $ws = fresh_workspace; + is(scalar @{get_ws($ws)->{floating_nodes}}, 0, 'No floating nodes yet'); + + ($fh, $filename) = tempfile(UNLINK => 1); + print $fh <<'EOT'; +// vim:ts=4:sw=4:et +{ + "border": "pixel", + "current_border_width": 1, + "floating": "auto_on", // crashes: user_on, auto_on, no crash: user_off, auto_off + "geometry": { + "height": 400, + "width": 300, + "x": 820, + "y": 350 + }, + "name": "Click me to crash", + "percent": 0.5, // still crashes if this field is absent + "swallows": [ + { + "class": "^this doesn't matter as long as it doesn't match a new window$" + } + ], + "type": "con" +} + +EOT + $fh->flush; + $reply = cmd "append_layout $filename"; + ok($reply->[0]->{success}, 'IPC reply indicated success'); + + cmd '[floating] focus'; + is(scalar @{get_ws($ws)->{floating_nodes}}, 1, 'one floating node on this ws'); + + does_i3_live; + + close($fh); +}; done_testing; diff --git a/testcases/t/307-focus-next-prev.t b/testcases/t/307-focus-next-prev.t index c7f06589f..4f8a8ecd2 100644 --- a/testcases/t/307-focus-next-prev.t +++ b/testcases/t/307-focus-next-prev.t @@ -69,4 +69,16 @@ cmp_tree( cmd 'focus parent, focus next sibling'; }); +# See #3997 +cmd 'workspace 2'; +open_window; +cmd 'workspace 1'; +open_window; +cmd 'focus parent, focus parent, focus next sibling, focus prev sibling'; +does_i3_live; +is(focused_ws, '1', 'Back and forth between workspaces'); + +cmd 'focus parent, focus parent, focus next sibling'; +is(focused_ws, '2', "Workspace 2 focused with 'focus next sibling'"); + done_testing; diff --git a/testcases/t/521-ewmh-desktop-viewport.t b/testcases/t/521-ewmh-desktop-viewport.t index 5ede140d3..a41193674 100644 --- a/testcases/t/521-ewmh-desktop-viewport.t +++ b/testcases/t/521-ewmh-desktop-viewport.t @@ -50,7 +50,10 @@ sub get_desktop_viewport { return unpack ("L$len", $reply->{value}); } -# initialize the workspaces +################################################################################ +# Initialize the workspaces +################################################################################ + cmd 'workspace 1'; cmd 'workspace 0'; @@ -60,6 +63,10 @@ my @desktop_viewport = get_desktop_viewport; is_deeply(\@desktop_viewport, \@expected_viewport, '_NET_DESKTOP_VIEWPORT should be an array of x/y coordinate pairs for the upper left corner of the respective outputs of the workspaces'); +################################################################################ +# Create workspace +################################################################################ + cmd 'workspace 0'; open_window; cmd 'workspace 3'; @@ -70,6 +77,10 @@ cmd 'workspace 3'; is_deeply(\@desktop_viewport, \@expected_viewport, 'it should be updated when a new workspace appears'); +################################################################################ +# Rename workspace +################################################################################ + cmd 'rename workspace 3 to 2'; @expected_viewport = (0, 0, 0, 0, 1024, 0); @@ -78,6 +89,10 @@ cmd 'rename workspace 3 to 2'; is_deeply(\@desktop_viewport, \@expected_viewport, 'it should stay up to date when a workspace is renamed'); +################################################################################ +# Empty workspace +################################################################################ + cmd 'workspace 0'; @expected_viewport = (0, 0, 1024, 0); @@ -86,4 +101,20 @@ cmd 'workspace 0'; is_deeply(\@desktop_viewport, \@expected_viewport, 'it should be updated when a workspace is emptied'); +################################################################################ +# Move workspace +# See #4001 +################################################################################ + +# Keep workspace 1 open to have 3 workspaces in total +cmd 'workspace 1'; +open_window; +cmd 'workspace 0, move workspace to output right'; +@expected_viewport = (0, 0, 1024, 0, 1024, 0); +@desktop_viewport = get_desktop_viewport; +is_deeply(\@desktop_viewport, \@expected_viewport, + 'it should be updated when a workspace is moved'); + +################################################################################ + done_testing;