toplevel-icon: implement OSC-1, CSI 20/21/22/23 t

* The toplevel icon is now set to the app-id, unless "overridden" by
  OSC-1 or OSC-0.
* Implemented OSC-1
* OSC-0 extended to also set the icon
* Implemented CSI 20 t - report window icon
* Implemented CSI 21 t - report window title
* Implemented CSI 22 ; 1 t - push window icon
* Implemented CS 23 ; 1 t - pop window icon
* Extended CSI 22/23 ; 0 t to also push/pop the icon
* Verify app-id set by OSC-176 is valid UTF-8
* Verify icon set by OSC-0/1 is valid UTF-8
This commit is contained in:
Daniel Eklöf 2024-09-10 18:53:38 +02:00
parent 3f8a1fc85b
commit 97ec375c67
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
10 changed files with 220 additions and 32 deletions

31
csi.c
View file

@ -1249,8 +1249,6 @@ csi_dispatch(struct terminal *term, uint8_t final)
case 8: LOG_WARN("unimplemented: resize window in chars"); break;
case 9: LOG_WARN("unimplemented: maximize/unmaximize window"); break;
case 10: LOG_WARN("unimplemented: to/from full screen"); break;
case 20: LOG_WARN("unimplemented: report icon label"); break;
case 21: LOG_WARN("unimplemented: report window title"); break;
case 24: LOG_WARN("unimplemented: resize window (DECSLPP)"); break;
case 11: /* report if window is iconified */
@ -1354,6 +1352,24 @@ csi_dispatch(struct terminal *term, uint8_t final)
break;
}
case 20: {
const char *icon = term_icon(term);
char reply[3 + strlen(icon) + 2 + 1];
int chars = xsnprintf(
reply, sizeof(reply), "\033]L%s\033\\", icon);
term_to_slave(term, reply, chars);
break;
}
case 21: {
char reply[3 + strlen(term->window_title) + 2 + 1];
int chars = xsnprintf(
reply, sizeof(reply), "\033]l%s\033\\", term->window_title);
term_to_slave(term, reply, chars);
break;
}
case 22: { /* push window title */
/* 0 - icon + title, 1 - icon, 2 - title */
unsigned what = vt_param_get(term, 1, 0);
@ -1361,6 +1377,10 @@ csi_dispatch(struct terminal *term, uint8_t final)
tll_push_back(
term->window_title_stack, xstrdup(term->window_title));
}
if (what == 0 || what == 1) {
tll_push_back(
term->window_icon_stack, xstrdup(term->window_icon));
}
break;
}
@ -1374,6 +1394,13 @@ csi_dispatch(struct terminal *term, uint8_t final)
free(title);
}
}
if (what == 0 || what == 1) {
if (tll_length(term->window_icon_stack) > 0) {
char *icon = tll_pop_back(term->window_icon_stack);
term_set_icon(term, icon);
free(icon);
}
}
break;
}