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) { 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;