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