Make 'unmark' aware of matched windows.
This patch allows using 'unmark' on matched windows. The old behavior of applying it to all windows if no criteria were specified is kept. relates to #2014
This commit is contained in:
parent
7a77c5f0bb
commit
9537ada5ad
|
@ -2132,11 +2132,19 @@ unmark <identifier>
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
|
|
||||||
*Example (in a terminal)*:
|
*Example (in a terminal)*:
|
||||||
------------------------------
|
---------------------------------------------------------
|
||||||
$ i3-msg mark irssi
|
# marks the focused container
|
||||||
$ i3-msg '[con_mark="irssi"] focus'
|
mark irssi
|
||||||
$ i3-msg unmark irssi
|
|
||||||
------------------------------
|
# focus the container with the mark "irssi"
|
||||||
|
'[con_mark="irssi"] focus'
|
||||||
|
|
||||||
|
# remove the mark "irssi" from whichever container has it
|
||||||
|
unmark irssi
|
||||||
|
|
||||||
|
# remove all marks on all firefox windows
|
||||||
|
[class="(?i)firefox"] unmark
|
||||||
|
---------------------------------------------------------
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
TODO: make i3-input replace %s
|
TODO: make i3-input replace %s
|
||||||
|
|
|
@ -166,12 +166,14 @@ void con_mark_toggle(Con *con, const char *mark, mark_mode_t mode);
|
||||||
*/
|
*/
|
||||||
void con_mark(Con *con, const char *mark, mark_mode_t mode);
|
void con_mark(Con *con, const char *mark, mark_mode_t mode);
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* If mark is NULL, this removes all existing marks.
|
* Removes marks from containers.
|
||||||
|
* If con is NULL, all containers are considered.
|
||||||
|
* If name is NULL, this removes all existing marks.
|
||||||
* Otherwise, it will only remove the given mark (if it is present).
|
* Otherwise, it will only remove the given mark (if it is present).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void con_unmark(const char *mark);
|
void con_unmark(Con *con, const char *name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the first container below 'con' which wants to swallow this window
|
* Returns the first container below 'con' which wants to swallow this window
|
||||||
|
|
|
@ -1040,7 +1040,14 @@ void cmd_mark(I3_CMD, const char *mark, const char *mode, const char *toggle) {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void cmd_unmark(I3_CMD, const char *mark) {
|
void cmd_unmark(I3_CMD, const char *mark) {
|
||||||
con_unmark(mark);
|
if (match_is_empty(current_match)) {
|
||||||
|
con_unmark(NULL, mark);
|
||||||
|
} else {
|
||||||
|
owindow *current;
|
||||||
|
TAILQ_FOREACH(current, &owindows, owindows) {
|
||||||
|
con_unmark(current->con, mark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cmd_output->needs_tree_render = true;
|
cmd_output->needs_tree_render = true;
|
||||||
// XXX: default reply for now, make this a better reply
|
// XXX: default reply for now, make this a better reply
|
||||||
|
|
59
src/con.c
59
src/con.c
|
@ -545,7 +545,7 @@ void con_mark_toggle(Con *con, const char *mark, mark_mode_t mode) {
|
||||||
DLOG("Toggling mark \"%s\" on con = %p.\n", mark, con);
|
DLOG("Toggling mark \"%s\" on con = %p.\n", mark, con);
|
||||||
|
|
||||||
if (con_has_mark(con, mark)) {
|
if (con_has_mark(con, mark)) {
|
||||||
con_unmark(mark);
|
con_unmark(con, mark);
|
||||||
} else {
|
} else {
|
||||||
con_mark(con, mark, mode);
|
con_mark(con, mark, mode);
|
||||||
}
|
}
|
||||||
|
@ -559,13 +559,13 @@ void con_mark(Con *con, const char *mark, mark_mode_t mode) {
|
||||||
assert(con != NULL);
|
assert(con != NULL);
|
||||||
DLOG("Setting mark \"%s\" on con = %p.\n", mark, con);
|
DLOG("Setting mark \"%s\" on con = %p.\n", mark, con);
|
||||||
|
|
||||||
con_unmark(mark);
|
con_unmark(NULL, mark);
|
||||||
if (mode == MM_REPLACE) {
|
if (mode == MM_REPLACE) {
|
||||||
DLOG("Removing all existing marks on con = %p.\n", con);
|
DLOG("Removing all existing marks on con = %p.\n", con);
|
||||||
|
|
||||||
mark_t *current;
|
mark_t *current;
|
||||||
TAILQ_FOREACH(current, &(con->marks_head), marks) {
|
TAILQ_FOREACH(current, &(con->marks_head), marks) {
|
||||||
con_unmark(current->name);
|
con_unmark(con, current->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,47 +577,52 @@ void con_mark(Con *con, const char *mark, mark_mode_t mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If mark is NULL, this removes all existing marks.
|
* Removes marks from containers.
|
||||||
|
* If con is NULL, all containers are considered.
|
||||||
|
* If name is NULL, this removes all existing marks.
|
||||||
* Otherwise, it will only remove the given mark (if it is present).
|
* Otherwise, it will only remove the given mark (if it is present).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void con_unmark(const char *mark) {
|
void con_unmark(Con *con, const char *name) {
|
||||||
Con *con;
|
Con *current;
|
||||||
if (mark == NULL) {
|
if (name == NULL) {
|
||||||
DLOG("Unmarking all containers.\n");
|
DLOG("Unmarking all containers.\n");
|
||||||
TAILQ_FOREACH(con, &all_cons, all_cons) {
|
TAILQ_FOREACH(current, &all_cons, all_cons) {
|
||||||
if (TAILQ_EMPTY(&(con->marks_head)))
|
if (con != NULL && current != con)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mark_t *current;
|
if (TAILQ_EMPTY(&(current->marks_head)))
|
||||||
while (!TAILQ_EMPTY(&(con->marks_head))) {
|
continue;
|
||||||
current = TAILQ_FIRST(&(con->marks_head));
|
|
||||||
FREE(current->name);
|
mark_t *mark;
|
||||||
TAILQ_REMOVE(&(con->marks_head), current, marks);
|
while (!TAILQ_EMPTY(&(current->marks_head))) {
|
||||||
FREE(current);
|
mark = TAILQ_FIRST(&(current->marks_head));
|
||||||
|
FREE(mark->name);
|
||||||
|
TAILQ_REMOVE(&(current->marks_head), mark, marks);
|
||||||
|
FREE(mark);
|
||||||
}
|
}
|
||||||
|
|
||||||
con->mark_changed = true;
|
current->mark_changed = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DLOG("Removing mark \"%s\".\n", mark);
|
DLOG("Removing mark \"%s\".\n", name);
|
||||||
con = con_by_mark(mark);
|
current = (con == NULL) ? con_by_mark(name) : con;
|
||||||
if (con == NULL) {
|
if (current == NULL) {
|
||||||
DLOG("No container found with this mark, so there is nothing to do.\n");
|
DLOG("No container found with this mark, so there is nothing to do.\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DLOG("Found mark on con = %p. Removing it now.\n", con);
|
DLOG("Found mark on con = %p. Removing it now.\n", current);
|
||||||
con->mark_changed = true;
|
current->mark_changed = true;
|
||||||
|
|
||||||
mark_t *current;
|
mark_t *mark;
|
||||||
TAILQ_FOREACH(current, &(con->marks_head), marks) {
|
TAILQ_FOREACH(mark, &(current->marks_head), marks) {
|
||||||
if (strcmp(current->name, mark) != 0)
|
if (strcmp(mark->name, name) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
FREE(current->name);
|
FREE(mark->name);
|
||||||
TAILQ_REMOVE(&(con->marks_head), current, marks);
|
TAILQ_REMOVE(&(current->marks_head), mark, marks);
|
||||||
FREE(current);
|
FREE(mark);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue