commands: (rename) check workspace number
Patch status: rejected
Patch by Vivien Didelot
Long description:
Without this patch, you can rename a workspace with a number which is already in use, which makes the navigation a bit inconsistent (for instance workspace next_on_output won't work as expected). For example, assuming you have a workspace 1, you can actually rename another workspace to "1: foo", but will have issue switching to it. This patch updates the cmd_rename_workspace() function to check the workspace number and forbid using a number already used by a workspace different than the target. Signed-off-by: Vivien Didelot <vivien.didelot@gmail.com>
To apply this patch, use:
curl http://cr.i3wm.org/patch/245/raw.patch | git am
b/src/commands.c
| 25 |
@@ -1856,6 +1856,7 @@ void cmd_rename_workspace(I3_CMD, char *old_name, char *new_name) {
|
| 26 |
LOG("Renaming current workspace to \"%s\"\n", new_name);
|
| 27 |
} |
| 28 |
|
| 29 |
+ /* Define the target workspace. */ |
| 30 |
Con *output, *workspace = NULL; |
| 31 |
if (old_name) {
|
| 32 |
TAILQ_FOREACH(output, &(croot->nodes_head), nodes) |
| 33 |
@@ -1869,10 +1870,11 @@ void cmd_rename_workspace(I3_CMD, char *old_name, char *new_name) {
|
| 34 |
// TODO: we should include the old workspace name here and use yajl for |
| 35 |
// generating the reply. |
| 36 |
// TODO: better error message |
| 37 |
- yerror("Old workspace not found");
|
| 38 |
+ yerror("Target workspace not found");
|
| 39 |
return; |
| 40 |
} |
| 41 |
|
| 42 |
+ /* Verify the full name is not already used. */ |
| 43 |
Con *check_dest = NULL; |
| 44 |
TAILQ_FOREACH(output, &(croot->nodes_head), nodes) |
| 45 |
GREP_FIRST(check_dest, output_get_content(output), |
| 46 |
@@ -1886,18 +1888,32 @@ void cmd_rename_workspace(I3_CMD, char *old_name, char *new_name) {
|
| 47 |
return; |
| 48 |
} |
| 49 |
|
| 50 |
- /* Change the name and try to parse it as a number. */ |
| 51 |
- FREE(workspace->name); |
| 52 |
- workspace->name = sstrdup(new_name); |
| 53 |
+ /* Parse and check the workspace number. */ |
| 54 |
char *endptr = NULL; |
| 55 |
long parsed_num = strtol(new_name, &endptr, 10); |
| 56 |
if (parsed_num == LONG_MIN || |
| 57 |
parsed_num == LONG_MAX || |
| 58 |
parsed_num < 0 || |
| 59 |
endptr == new_name) |
| 60 |
- workspace->num = -1; |
| 61 |
- else workspace->num = parsed_num; |
| 62 |
- LOG("num = %d\n", workspace->num);
|
| 63 |
+ parsed_num = -1; |
| 64 |
+ LOG("num = %ld\n", parsed_num);
|
| 65 |
+ if (parsed_num != -1) {
|
| 66 |
+ Con *ws = NULL; |
| 67 |
+ TAILQ_FOREACH(output, &(croot->nodes_head), nodes) |
| 68 |
+ GREP_FIRST(ws, output_get_content(output), |
| 69 |
+ child->num == parsed_num); |
| 70 |
+ |
| 71 |
+ /* It is ok to rename a workspace with its actual number. */ |
| 72 |
+ if (ws && ws != workspace) {
|
| 73 |
+ yerror("Workspace number already in use");
|
| 74 |
+ return; |
| 75 |
+ } |
| 76 |
+ } |
| 77 |
+ |
| 78 |
+ /* Finally change the name and the number. */ |
| 79 |
+ FREE(workspace->name); |
| 80 |
+ workspace->name = sstrdup(new_name); |
| 81 |
+ workspace->num = parsed_num; |
| 82 |
|
| 83 |
/* By re-attaching, the sort order will be correct afterwards. */ |
| 84 |
Con *previously_focused = focused; |