From 7fc3bf660e58ad11908be60d7df048f920e74689 Mon Sep 17 00:00:00 2001 From: Orestis Floros Date: Thu, 21 Mar 2019 23:57:24 +0200 Subject: [PATCH] cmd_focus_output: Avoid assertion crash Happened when the command criteria didn't match any windows. For example: `[con_mark=doesnotexist] focus output left`. --- src/commands.c | 21 +++++++-------------- testcases/t/502-focus-output.t | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/commands.c b/src/commands.c index b7fbce90..3cf5a57c 100644 --- a/src/commands.c +++ b/src/commands.c @@ -1626,24 +1626,18 @@ void cmd_open(I3_CMD) { * */ void cmd_focus_output(I3_CMD, const char *name) { - owindow *current; - - DLOG("name = %s\n", name); - HANDLE_EMPTY_MATCH; - /* get the output */ - Output *current_output = NULL; - Output *output; + if (TAILQ_EMPTY(&owindows)) { + ysuccess(true); + return; + } - TAILQ_FOREACH(current, &owindows, owindows) - current_output = get_output_for_con(current->con); - assert(current_output != NULL); - - output = get_output_from_string(current_output, name); + Output *current_output = get_output_for_con(TAILQ_FIRST(&owindows)->con); + Output *output = get_output_from_string(current_output, name); if (!output) { - yerror("No such output found."); + yerror("Output %s not found.", name); return; } @@ -1658,7 +1652,6 @@ void cmd_focus_output(I3_CMD, const char *name) { workspace_show(ws); cmd_output->needs_tree_render = true; - // XXX: default reply for now, make this a better reply ysuccess(true); } diff --git a/testcases/t/502-focus-output.t b/testcases/t/502-focus-output.t index 01d8db33..118aba16 100644 --- a/testcases/t/502-focus-output.t +++ b/testcases/t/502-focus-output.t @@ -86,4 +86,33 @@ is(focused_output, 'fake-1', 'focus on second output'); cmd 'focus output fake-0'; is(focused_output, 'fake-0', 'focus on first output'); +################################################################################ +# use 'focus output' with command criteria and verify that i3 does not crash +# when they don't match any window +################################################################################ + +is(focused_output, 'fake-0', 'focus on first output'); + +cmd '[con_mark=doesnotexist] focus output right'; +does_i3_live; +is(focused_output, 'fake-0', 'focus remained on first output'); + +################################################################################ +# use 'focus output' with command criteria and verify that focus gets changed +# appropriately +################################################################################ + +is(focused_output, 'fake-0', 'focus on first output'); + +my $window = open_window; + +cmd 'focus output right'; +is(focused_output, 'fake-1', 'focus on second output'); + +cmd '[id= . ' . $window->id . '] focus output right'; +is(focused_output, 'fake-1', 'focus on second output after command with criteria'); + +cmd 'focus output right'; +is(focused_output, 'fake-0', 'focus on first output after command without criteria'); + done_testing;