Compare commits

...

5 Commits

Author SHA1 Message Date
Orestis Floros
1cc2548027
271-for_window_tilingfloating: Fix flaky test (#6509)
Floating assignments run based on the _I3_FLOATING_WINDOW property which
means we have to go through X11 first.
2025-10-07 17:37:04 +02:00
Orestis Floros
45bfae0fc8
assignments: Avoid crash when using for_window reload (#6508)
Note: Found with [bugfinder](https://github.com/stanek-michal/bugfinder)
2025-10-07 17:36:09 +02:00
Orestis Floros
0d47ec22a9
randr: Avoid use-after-free in RandR <= 1.4 (#6506)
Before the xcb_randr_get_crtc_info() call fails, `new` has been already
added to `outputs with `TAILQ_INSERT_TAIL(&outputs, new, outputs);`.

Note: Found with [bugfinder](https://github.com/stanek-michal/bugfinder)
2025-10-07 17:34:57 +02:00
Orestis Floros
389cf064e6
randr: Fix memleak (#6505)
`sasprintf` always allocates `oname` but it is only conditionally freed.

Note: Found with [bugfinder](https://github.com/stanek-michal/bugfinder)
2025-10-07 17:33:07 +02:00
Orestis Floros
b3329fbb02
tiling_drag: Fix crash when performing tree_move (#6503)
tree_move calls tree_flatten which can destroy redundant containers.

An example reproduction would be V[H[a V[b]]] where V[b] is focused
(parent of b) and a is moved away using the DT_PARENT target.

Note: Found with [bugfinder](https://github.com/stanek-michal/bugfinder)
2025-10-07 17:32:15 +02:00
7 changed files with 50 additions and 6 deletions

View File

@ -0,0 +1 @@
fix crash when a container parent is focused and a tiling drag causes it to be killed

View File

@ -0,0 +1 @@
fix crash when using for_window [...] reload

View File

@ -18,6 +18,7 @@ void run_assignments(i3Window *window) {
DLOG("Checking if any assignments match this window\n");
bool needs_tree_render = false;
const Assignment *old_first_assignment = TAILQ_FIRST(&assignments);
/* Check if any assignments match */
Assignment *current;
@ -59,6 +60,14 @@ void run_assignments(i3Window *window) {
}
command_result_free(result);
/* Prevent crash: if the assigned command included a reload, the
* assignments array was re-initialized, which will lead to a SEGFAULT
* if we continue.
*/
if (old_first_assignment != TAILQ_FIRST(&assignments)) {
break;
}
}
/* If any of the commands required re-rendering, we will do that now. */

View File

@ -660,9 +660,8 @@ static bool randr_query_outputs_15(void) {
struct output_name *output_name = scalloc(1, sizeof(struct output_name));
output_name->name = sstrdup(oname);
SLIST_INSERT_HEAD(&new->names_head, output_name, names);
} else {
free(oname);
}
free(oname);
}
FREE(info);
}
@ -757,12 +756,10 @@ static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id,
return;
}
xcb_randr_get_crtc_info_cookie_t icookie;
icookie = xcb_randr_get_crtc_info(conn, output->crtc, cts);
const xcb_randr_get_crtc_info_cookie_t icookie = xcb_randr_get_crtc_info(conn, output->crtc, cts);
if ((crtc = xcb_randr_get_crtc_info_reply(conn, icookie, NULL)) == NULL) {
DLOG("Skipping output %s: could not get CRTC (%p)\n",
output_primary_name(new), crtc);
free(new);
return;
}

View File

@ -389,7 +389,7 @@ void tiling_drag(Con *con, xcb_button_press_event_t *event, bool use_threshold)
/* tree_move can change the focus */
Con *old_focus = focused;
tree_move(con, direction);
if (focused != old_focus) {
if (focused != old_focus && con_exists(old_focus)) {
con_activate(old_focus);
}
break;

View File

@ -56,6 +56,7 @@ is_deeply($nodes[0]->{nodes}[0]->{marks}, [ 'floating', 'floating_auto' ], "mark
cmd '[id=' . $A->{id} . '] floating enable';
cmd '[id=' . $B->{id} . '] floating disable';
sync_with_i3; # Assignments run based on the _I3_FLOATING_WINDOW property. No sync is race-y.
@nodes = @{get_ws($tmp)->{nodes}};
cmp_ok(@nodes, '==', 1, 'one tiling container on this workspace');
@ -75,6 +76,7 @@ is_deeply($nodes[0]->{nodes}[0]->{marks}, [ 'tiling_auto', 'floating', 'floating
# Use 'mark' to clear old marks
cmd '[id=' . $A->{id} . '] mark A, floating disable';
cmd '[id=' . $B->{id} . '] mark B, floating enable';
sync_with_i3;
@nodes = @{get_ws($tmp)->{nodes}};
cmp_ok(@nodes, '==', 1, 'one tiling container on this workspace');
@ -115,6 +117,7 @@ is_deeply($nodes[0]->{nodes}[0]->{marks}, [ 'floating' ], "mark set for 'floatin
cmd '[tiling_from="auto" con_mark="tiling"] mark --add tiling_auto';
cmd '[floating_from="auto" con_mark="floating"] mark --add floating_auto';
sync_with_i3;
@nodes = @{get_ws($tmp)->{nodes}};
cmp_ok(@nodes, '==', 1, 'one tiling container on this workspace');

View File

@ -0,0 +1,33 @@
#!perl
# vim:ts=4:sw=4:expandtab
#
# Please read the following documents before working on tests:
# • https://build.i3wm.org/docs/testsuite.html
# (or docs/testsuite)
#
# • https://build.i3wm.org/docs/lib-i3test.html
# (alternatively: perldoc ./testcases/lib/i3test.pm)
#
# • https://build.i3wm.org/docs/ipc.html
# (or docs/ipc)
#
# • https://i3wm.org/downloads/modern_perl_a4.pdf
# (unless you are already familiar with Perl)
#
# This test ensures that i3 does not crash when a for_window rule triggers a
# 'reload' command.
# Bug still in: 4.24-12-gab6a75a6
use i3test i3_config => <<'EOT';
font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
for_window [class="special"] reload
EOT
my $window = open_window(
wm_class => 'special',
);
does_i3_live;
done_testing;