Merge pull request #1599 from Airblader/feature-toggle-mark
Added a --toggle switch to the mark command
This commit is contained in:
commit
a99d5463ad
|
@ -1857,9 +1857,13 @@ window, you cannot simply bind it to a key. +i3-input+ is a tool created
|
||||||
for this purpose: It lets you input a command and sends the command to i3. It
|
for this purpose: It lets you input a command and sends the command to i3. It
|
||||||
can also prefix this command and display a custom prompt for the input dialog.
|
can also prefix this command and display a custom prompt for the input dialog.
|
||||||
|
|
||||||
|
The additional +--toggle+ option will remove the mark if the window already has
|
||||||
|
this mark, add it if the window has none or replace the current mark if it has
|
||||||
|
another mark.
|
||||||
|
|
||||||
*Syntax*:
|
*Syntax*:
|
||||||
------------------------------
|
------------------------------
|
||||||
mark identifier
|
mark [--toggle] identifier
|
||||||
[con_mark="identifier"] focus
|
[con_mark="identifier"] focus
|
||||||
unmark identifier
|
unmark identifier
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
|
@ -109,10 +109,10 @@ void cmd_workspace_back_and_forth(I3_CMD);
|
||||||
void cmd_workspace_name(I3_CMD, char *name);
|
void cmd_workspace_name(I3_CMD, char *name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of 'mark <mark>'
|
* Implementation of 'mark [--toggle] <mark>'
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void cmd_mark(I3_CMD, char *mark);
|
void cmd_mark(I3_CMD, char *mark, char *toggle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of 'unmark [mark]'
|
* Implementation of 'unmark [mark]'
|
||||||
|
|
|
@ -189,10 +189,12 @@ state FLOATING:
|
||||||
floating = 'enable', 'disable', 'toggle'
|
floating = 'enable', 'disable', 'toggle'
|
||||||
-> call cmd_floating($floating)
|
-> call cmd_floating($floating)
|
||||||
|
|
||||||
# mark <mark>
|
# mark [--toggle] <mark>
|
||||||
state MARK:
|
state MARK:
|
||||||
|
toggle = '--toggle'
|
||||||
|
->
|
||||||
mark = string
|
mark = string
|
||||||
-> call cmd_mark($mark)
|
-> call cmd_mark($mark, $toggle)
|
||||||
|
|
||||||
# unmark [mark]
|
# unmark [mark]
|
||||||
state UNMARK:
|
state UNMARK:
|
||||||
|
|
|
@ -1037,26 +1037,41 @@ void cmd_workspace_name(I3_CMD, char *name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Implementation of 'mark <mark>'
|
* Implementation of 'mark [--toggle] <mark>'
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void cmd_mark(I3_CMD, char *mark) {
|
void cmd_mark(I3_CMD, char *mark, char *toggle) {
|
||||||
DLOG("Clearing all windows which have that mark first\n");
|
|
||||||
|
|
||||||
Con *con;
|
|
||||||
TAILQ_FOREACH(con, &all_cons, all_cons) {
|
|
||||||
if (con->mark && strcmp(con->mark, mark) == 0)
|
|
||||||
FREE(con->mark);
|
|
||||||
}
|
|
||||||
|
|
||||||
DLOG("marking window with str %s\n", mark);
|
|
||||||
owindow *current;
|
|
||||||
|
|
||||||
HANDLE_EMPTY_MATCH;
|
HANDLE_EMPTY_MATCH;
|
||||||
|
|
||||||
|
owindow *current;
|
||||||
TAILQ_FOREACH(current, &owindows, owindows) {
|
TAILQ_FOREACH(current, &owindows, owindows) {
|
||||||
DLOG("matching: %p / %s\n", current->con, current->con->name);
|
DLOG("matching: %p / %s\n", current->con, current->con->name);
|
||||||
current->con->mark = sstrdup(mark);
|
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)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (con->mark && strcmp(con->mark, mark) == 0)
|
||||||
|
FREE(con->mark);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_output->needs_tree_render = true;
|
cmd_output->needs_tree_render = true;
|
||||||
|
|
|
@ -16,11 +16,19 @@
|
||||||
#
|
#
|
||||||
# checks if mark and unmark work correctly
|
# checks if mark and unmark work correctly
|
||||||
use i3test;
|
use i3test;
|
||||||
|
use List::Util qw(first);
|
||||||
|
|
||||||
sub get_marks {
|
sub get_marks {
|
||||||
return i3(get_socket_path())->get_marks->recv;
|
return i3(get_socket_path())->get_marks->recv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub get_mark_for_window_on_workspace {
|
||||||
|
my ($ws, $con) = @_;
|
||||||
|
|
||||||
|
my $current = first { $_->{window} == $con->{id} } @{get_ws_content($ws)};
|
||||||
|
return $current->{mark};
|
||||||
|
}
|
||||||
|
|
||||||
##############################################################
|
##############################################################
|
||||||
# 1: check that there are no marks set yet
|
# 1: check that there are no marks set yet
|
||||||
##############################################################
|
##############################################################
|
||||||
|
@ -76,4 +84,61 @@ cmd 'unmark';
|
||||||
|
|
||||||
is_deeply(get_marks(), [], 'all marks removed');
|
is_deeply(get_marks(), [], 'all marks removed');
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# 4: mark a con, use same mark to mark another con,
|
||||||
|
# check that only the latter is marked
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
my $first = open_window;
|
||||||
|
my $second = open_window;
|
||||||
|
|
||||||
|
cmd 'mark important';
|
||||||
|
cmd 'focus left';
|
||||||
|
cmd 'mark important';
|
||||||
|
|
||||||
|
is(get_mark_for_window_on_workspace($tmp, $first), 'important', 'first container now has the mark');
|
||||||
|
ok(!get_mark_for_window_on_workspace($tmp, $second), 'second container lost the mark');
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# 5: mark a con, toggle the mark, check that the mark is gone
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
my $con = open_window;
|
||||||
|
cmd 'mark important';
|
||||||
|
cmd 'mark --toggle important';
|
||||||
|
ok(!get_mark_for_window_on_workspace($tmp, $con), 'container no longer has the mark');
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# 6: toggle a mark on an unmarked con, check it is marked
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
my $con = open_window;
|
||||||
|
cmd 'mark --toggle important';
|
||||||
|
is(get_mark_for_window_on_workspace($tmp, $con), 'important', 'container now has the mark');
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# 7: mark a con, toggle a different mark, check it is marked
|
||||||
|
# with the new mark
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
my $con = open_window;
|
||||||
|
cmd 'mark boring';
|
||||||
|
cmd 'mark --toggle important';
|
||||||
|
is(get_mark_for_window_on_workspace($tmp, $con), 'important', 'container has the most recent mark');
|
||||||
|
|
||||||
|
##############################################################
|
||||||
|
# 8: mark a con, toggle the mark on another con,
|
||||||
|
# check only the latter has the mark
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
my $first = open_window;
|
||||||
|
my $second = open_window;
|
||||||
|
|
||||||
|
cmd 'mark important';
|
||||||
|
cmd 'focus left';
|
||||||
|
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');
|
||||||
|
|
||||||
done_testing;
|
done_testing;
|
||||||
|
|
Loading…
Reference in New Issue