implement unmark command

This commit is contained in:
koebi 2013-07-16 00:33:14 +02:00 committed by Michael Stapelberg
parent 35aec2f038
commit 88671986f4
7 changed files with 127 additions and 7 deletions

View File

@ -458,9 +458,8 @@ JSON dump:
=== MARKS reply === MARKS reply
The reply consists of a single array of strings for each container that has a The reply consists of a single array of strings for each container that has a
mark. The order of that array is undefined. If more than one container has the mark. A mark can only be set on one container, so the array is unique.
same mark, it will be represented multiple times in the reply (the array The order of that array is undefined.
contents are not unique).
If no window has a mark the response will be the empty array []. If no window has a mark the response will be the empty array [].

View File

@ -1679,9 +1679,10 @@ bindsym $mod+a [class="urxvt" title="VIM"] focus
This feature is like the jump feature: It allows you to directly jump to a This feature is like the jump feature: It allows you to directly jump to a
specific window (this means switching to the appropriate workspace and setting specific window (this means switching to the appropriate workspace and setting
focus to the windows). However, you can directly mark a specific window with focus to the windows). However, you can directly mark a specific window with
an arbitrary label and use it afterwards. You do not need to ensure that your an arbitrary label and use it afterwards. You can unmark the label in the same
windows have unique classes or titles, and you do not need to change your way, using the unmark command. If you don't specify a label, unmark removes all
configuration file. marks. You do not need to ensure that your windows have unique classes or
titles, and you do not need to change your configuration file.
As the command needs to include the label with which you want to mark the As the command needs to include the label with which you want to mark the
window, you cannot simply bind it to a key. +i3-input+ is a tool created window, you cannot simply bind it to a key. +i3-input+ is a tool created
@ -1692,12 +1693,14 @@ can also prefix this command and display a custom prompt for the input dialog.
------------------------------ ------------------------------
mark identifier mark identifier
[con_mark="identifier"] focus [con_mark="identifier"] focus
unmark identifier
------------------------------ ------------------------------
*Example (in a terminal)*: *Example (in a terminal)*:
------------------------------ ------------------------------
$ i3-msg mark irssi $ i3-msg mark irssi
$ i3-msg '[con_mark="irssi"] focus' $ i3-msg '[con_mark="irssi"] focus'
$ i3-msg unmark irssi
------------------------------ ------------------------------
/////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////

View File

@ -115,6 +115,12 @@ void cmd_workspace_name(I3_CMD, char *name);
*/ */
void cmd_mark(I3_CMD, char *mark); void cmd_mark(I3_CMD, char *mark);
/**
* Implementation of 'unmark [mark]'
*
*/
void cmd_unmark(I3_CMD, char *mark);
/** /**
* Implementation of 'mode <string>'. * Implementation of 'mode <string>'.
* *

View File

@ -32,6 +32,7 @@ state INITIAL:
'split' -> SPLIT 'split' -> SPLIT
'floating' -> FLOATING 'floating' -> FLOATING
'mark' -> MARK 'mark' -> MARK
'unmark' -> UNMARK
'resize' -> RESIZE 'resize' -> RESIZE
'rename' -> RENAME 'rename' -> RENAME
'nop' -> NOP 'nop' -> NOP
@ -177,6 +178,13 @@ state MARK:
mark = string mark = string
-> call cmd_mark($mark) -> call cmd_mark($mark)
# unmark [mark]
state UNMARK:
end
-> call cmd_unmark($mark)
mark = string
-> call cmd_unmark($mark)
# resize # resize
state RESIZE: state RESIZE:
way = 'grow', 'shrink' way = 'grow', 'shrink'

View File

@ -1031,6 +1031,31 @@ void cmd_mark(I3_CMD, char *mark) {
ysuccess(true); ysuccess(true);
} }
/*
* Implementation of 'unmark [mark]'
*
*/
void cmd_unmark(I3_CMD, char *mark) {
if (mark == NULL) {
Con *con;
TAILQ_FOREACH(con, &all_cons, all_cons) {
FREE(con->mark);
}
DLOG("removed all window marks");
} else {
Con *con;
TAILQ_FOREACH(con, &all_cons, all_cons) {
if (con->mark && strcmp(con->mark, mark) == 0)
FREE(con->mark);
}
DLOG("removed window mark %s\n", mark);
}
cmd_output->needs_tree_render = true;
// XXX: default reply for now, make this a better reply
ysuccess(true);
}
/* /*
* Implementation of 'mode <string>'. * Implementation of 'mode <string>'.
* *

View File

@ -144,7 +144,7 @@ is(parser_calls("\nworkspace test"),
################################################################################ ################################################################################
is(parser_calls('unknown_literal'), is(parser_calls('unknown_literal'),
"ERROR: Expected one of these tokens: <end>, '[', 'move', 'exec', 'exit', 'restart', 'reload', 'shmlog', 'debuglog', 'border', 'layout', 'append_layout', 'workspace', 'focus', 'kill', 'open', 'fullscreen', 'split', 'floating', 'mark', 'resize', 'rename', 'nop', 'scratchpad', 'mode', 'bar'\n" . "ERROR: Expected one of these tokens: <end>, '[', 'move', 'exec', 'exit', 'restart', 'reload', 'shmlog', 'debuglog', 'border', 'layout', 'append_layout', 'workspace', 'focus', 'kill', 'open', 'fullscreen', 'split', 'floating', 'mark', 'unmark', 'resize', 'rename', 'nop', 'scratchpad', 'mode', 'bar'\n" .
"ERROR: Your command: unknown_literal\n" . "ERROR: Your command: unknown_literal\n" .
"ERROR: ^^^^^^^^^^^^^^^", "ERROR: ^^^^^^^^^^^^^^^",
'error for unknown literal ok'); 'error for unknown literal ok');

View File

@ -0,0 +1,79 @@
#!perl
# vim:ts=4:sw=4:expandtab
#
# Please read the following documents before working on tests:
# • http://build.i3wm.org/docs/testsuite.html
# (or docs/testsuite)
#
# • http://build.i3wm.org/docs/lib-i3test.html
# (alternatively: perldoc ./testcases/lib/i3test.pm)
#
# • http://build.i3wm.org/docs/ipc.html
# (or docs/ipc)
#
# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
# (unless you are already familiar with Perl)
#
# checks if mark and unmark work correctly
use i3test;
sub get_marks {
return i3(get_socket_path())->get_marks->recv;
}
##############################################################
# 1: check that there are no marks set yet
##############################################################
my $tmp = fresh_workspace;
cmd 'split h';
is_deeply(get_marks(), [], 'no marks set yet');
##############################################################
# 2: mark a con, check that it's marked, unmark it, check that
##############################################################
my $one = open_window;
cmd 'mark foo';
is_deeply(get_marks(), ["foo"], 'mark foo set');
cmd 'unmark foo';
is_deeply(get_marks(), [], 'mark foo removed');
##############################################################
# 3: mark three cons, check that they are marked
# unmark one con, check that it's unmarked
# unmark all cons, check that they are unmarked
##############################################################
my $left = open_window;
my $middle = open_window;
my $right = open_window;
cmd 'mark right';
cmd 'focus left';
cmd 'mark middle';
cmd 'focus left';
cmd 'mark left';
#
# get_marks replys an array of marks, whose order is undefined,
# so we use sort to be able to compare the output
#
is_deeply(sort(get_marks()), ["left","middle","right"], 'all three marks set');
cmd 'unmark right';
is_deeply(sort(get_marks()), ["left","middle"], 'mark right removed');
cmd 'unmark';
is_deeply(get_marks(), [], 'all marks removed');
done_testing;