From 43204b43fdab6a1949169c0d5ee3a91247a379bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20B=C3=BCrk?= Date: Tue, 31 Mar 2015 20:45:37 +0200 Subject: [PATCH 1/2] Added a testcase for #1614 --- testcases/lib/i3test.pm | 2 +- testcases/t/210-mark-unmark.t | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/testcases/lib/i3test.pm b/testcases/lib/i3test.pm index c149cbd1..ac1a26ca 100644 --- a/testcases/lib/i3test.pm +++ b/testcases/lib/i3test.pm @@ -606,7 +606,7 @@ sub get_dock_clients { =head2 cmd($command) -Sends the specified command to i3. +Sends the specified command to i3 and returns the output. my $ws = unused_workspace; cmd "workspace $ws"; diff --git a/testcases/t/210-mark-unmark.t b/testcases/t/210-mark-unmark.t index 0083547f..99fc92c8 100644 --- a/testcases/t/210-mark-unmark.t +++ b/testcases/t/210-mark-unmark.t @@ -141,4 +141,21 @@ cmd 'mark --toggle important'; is(get_mark_for_window_on_workspace($tmp, $first), 'important', 'left container has the mark now'); ok(!get_mark_for_window_on_workspace($tmp, $second), 'second containr no longer has the mark'); +############################################################## +# 9: try to mark two cons with the same mark and check that +# it fails +############################################################## + +my $first = open_window(wm_class => 'iamnotunique'); +my $second = open_window(wm_class => 'iamnotunique'); + +my $result = cmd "[instance=iamnotunique] mark important"; + +is($result->[0]->{success}, 0, 'command was unsuccessful'); +is($result->[0]->{error}, 'A mark must not be put onto more than one window', 'correct error is returned'); +ok(!get_mark_for_window_on_workspace($tmp, $first), 'first container is not marked'); +ok(!get_mark_for_window_on_workspace($tmp, $second), 'second containr is not marked'); + +############################################################## + done_testing; From 2e4fac61d2b6ec488bc476230655baaa12fc394e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20B=C3=BCrk?= Date: Tue, 31 Mar 2015 20:47:22 +0200 Subject: [PATCH 2/2] Only mark a window if only one window is matched We only support unique marks, so looping over all matched windows must be prevented. If more than one window is matched, we reject it with an error message. fixes #1614 --- src/commands.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/commands.c b/src/commands.c index dc60e974..79071d6b 100644 --- a/src/commands.c +++ b/src/commands.c @@ -1043,32 +1043,34 @@ void cmd_workspace_name(I3_CMD, char *name) { void cmd_mark(I3_CMD, char *mark, char *toggle) { HANDLE_EMPTY_MATCH; - owindow *current; - TAILQ_FOREACH(current, &owindows, owindows) { - DLOG("matching: %p / %s\n", current->con, current->con->name); - current->con->mark_changed = true; - if (toggle != NULL && current->con->mark && strcmp(current->con->mark, mark) == 0) { - DLOG("removing window mark %s\n", mark); - FREE(current->con->mark); - } else { - DLOG("marking window with str %s\n", mark); - FREE(current->con->mark); - current->con->mark = sstrdup(mark); - } + owindow *current = TAILQ_FIRST(&owindows); + if (current == NULL) { + ysuccess(false); + return; + } + + /* Marks must be unique, i.e., no two windows must have the same mark. */ + if (current != TAILQ_LAST(&owindows, owindows_head)) { + yerror("A mark must not be put onto more than one window"); + return; + } + + DLOG("matching: %p / %s\n", current->con, current->con->name); + current->con->mark_changed = true; + if (toggle != NULL && current->con->mark && strcmp(current->con->mark, mark) == 0) { + DLOG("removing window mark %s\n", mark); + FREE(current->con->mark); + } else { + DLOG("marking window with str %s\n", mark); + FREE(current->con->mark); + current->con->mark = sstrdup(mark); } DLOG("Clearing all non-matched windows with this mark\n"); Con *con; TAILQ_FOREACH(con, &all_cons, all_cons) { - /* Skip matched windows, we took care of them already. */ - bool matched = false; - TAILQ_FOREACH(current, &owindows, owindows) { - if (current->con == con) { - matched = true; - break; - } - } - if (matched) + /* Skip matched window, we took care of it already. */ + if (current->con == con) continue; if (con->mark && strcmp(con->mark, mark) == 0) {