Add mmsg rename tag IPC message

* Add mmsg rename tag IPC message for renaming tags
This commit is contained in:
Emilia Miki 2026-06-30 02:12:44 +03:00
parent ced800910d
commit c72a083bf6
No known key found for this signature in database
GPG key ID: 73695055BC885C2B
4 changed files with 67 additions and 1 deletions

View file

@ -67,6 +67,17 @@ mmsg watch all-monitors
mmsg watch all-tags
```
### RENAME
| Command | Description |
| :--- | :--- |
| `rename tag <index> <name>` | Renames a tag at runtime. Updates the in-memory config, the ext-workspace-v1 protocol name, and notifies all IPC watchers. The name may contain spaces. |
*Example:*
```bash
mmsg rename tag 1 web
mmsg rename tag 2 my projects
```
### DISPATCH
Allows sending commands to the compositor to alter its state.
* `dispatch <func_name>,[args...] [client,<id>]`

View file

@ -74,6 +74,24 @@ Examples:
.IP \(bu 2
\fBmmsg dispatch movewin,10,100 client,4\fR
.RE
.SS "Rename commands"
.TP
\fBrename tag\fR <index> <name>
Rename a tag at runtime.
\fIindex\fR is the 1-based tag number.
\fIname\fR may contain spaces.
The change is reflected immediately in the ext-workspace-v1 protocol and in all
active IPC watch streams.
Survives \fBreload_config\fR only if also set via \fBtagrule=id:<index>,name:<name>\fR
in the config file.
.br
Example:
.RS
.IP \(bu 2
\fBmmsg rename tag 1 web\fR
.IP \(bu 2
\fBmmsg rename tag 2 my projects\fR
.RE
.SS "Persistent streams (watch)"
\fBWatch\fR commands keep the connection open and continuously output JSON
updates. The initial state is sent immediately, followed by updates whenever

View file

@ -155,6 +155,8 @@ void dwl_ext_workspace_printstatus(Monitor *m) {
wl_list_for_each(w, &workspaces, link) {
if (w && w->m == m) {
wlr_ext_workspace_handle_v1_set_name(w->ext_workspace,
get_name_from_tag(w->tag));
tag_status = get_tag_status(w->tag, m);
if (tag_status == 2) {
wlr_ext_workspace_handle_v1_set_hidden(w->ext_workspace, false);

View file

@ -352,6 +352,41 @@ static void handle_command(int client_fd, const char *cmd_raw) {
return;
}
resp = build_monitor_tags_response(m);
} else if (strncmp(cmd, "rename tag ", 11) == 0) {
char *rest = (char *)(cmd + 11);
char *endptr;
long tag_index = strtol(rest, &endptr, 10);
if (endptr == rest || *endptr != ' ' ||
tag_index < 1 || tag_index > (int)LENGTH(tags)) {
send_static_json(client_fd, "{\"error\":\"usage: rename tag <index> <name>\"}\n");
return;
}
const char *new_name = endptr + 1;
if (*new_name == '\0') {
send_static_json(client_fd, "{\"error\":\"usage: rename tag <index> <name>\"}\n");
return;
}
bool found = false;
for (int i = 0; i < config.tag_rules_count; i++) {
if (config.tag_rules[i].id == (int)tag_index) {
free(config.tag_rules[i].name);
config.tag_rules[i].name = strdup(new_name);
found = true;
break;
}
}
if (!found) {
config.tag_rules = realloc(config.tag_rules,
(config.tag_rules_count + 1) * sizeof(ConfigTagRule));
ConfigTagRule *rule = &config.tag_rules[config.tag_rules_count];
memset(rule, 0, sizeof(ConfigTagRule));
rule->id = (int)tag_index;
rule->name = strdup(new_name);
config.tag_rules_count++;
}
printstatus(IPC_WATCH_ARRANGGE);
resp = cJSON_CreateObject();
cJSON_AddBoolToObject(resp, "success", true);
} else if (strncmp(cmd, "dispatch ", 9) == 0) {
char *dispatch_copy = strdup(cmd_raw + 9);
char *out = dispatch_copy, *ptr = dispatch_copy;
@ -1060,4 +1095,4 @@ void ipc_cleanup(void) {
struct ipc_watch_client *wc, *tmp;
wl_list_for_each_safe(wc, tmp, &watch_clients, link)
ipc_remove_watch_client(wc);
}
}