diff --git a/src/bin/termpty.h b/src/bin/termpty.h index 0dba23e0..533c1a7e 100644 --- a/src/bin/termpty.h +++ b/src/bin/termpty.h @@ -13,6 +13,7 @@ typedef struct _Termblock Termblock; typedef struct _Termexp Termexp; typedef struct _Termpty Termpty; typedef struct _Termlink Term_Link; +typedef struct _TitleIconElem TitleIconElem; #define COL_DEF 0 #define COL_BLACK 1 @@ -212,6 +213,7 @@ struct _Termpty uint8_t *bitmap; uint32_t size; } hl; + TitleIconElem *title_icon_stack; }; struct _Termcell diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c index 8dcecb21..243b8c36 100644 --- a/src/bin/termptyesc.c +++ b/src/bin/termptyesc.c @@ -3075,6 +3075,100 @@ _handle_resize_by_chars(Termpty *ty, Eina_Unicode **ptr) #endif } +struct _TitleIconElem { + const char *title; + const char *icon; + struct _TitleIconElem *next; +}; + +static void +_title_icon_stack_push(Termpty *ty, Eina_Unicode **p) +{ + int arg = _csi_arg_get(ty, p); + TitleIconElem *elem = calloc(sizeof(*elem), 1); + + if (!elem) + return; + + + switch (arg) + { + case -ESC_ARG_ERROR: + free(elem); + return; + case -ESC_ARG_NO_VALUE: + EINA_FALLTHROUGH; + case 0: + elem->title = eina_stringshare_ref(ty->prop.title); + elem->icon = eina_stringshare_ref(ty->prop.icon); + break; + case 1: + elem->icon = eina_stringshare_ref(ty->prop.icon); + break; + case 2: + elem->title = eina_stringshare_ref(ty->prop.title); + break; + default: + break; + } + if (!elem->title) + elem->title = ty->title_icon_stack ? + eina_stringshare_ref(ty->title_icon_stack->title) : + eina_stringshare_ref(ty->prop.title); + if (!elem->icon) + elem->icon = ty->title_icon_stack ? + eina_stringshare_ref(ty->title_icon_stack->icon) : + eina_stringshare_ref(ty->prop.icon); + elem->next = ty->title_icon_stack; + ty->title_icon_stack = elem; +} + +static void +_title_icon_stack_pop(Termpty *ty, Eina_Unicode **p) +{ + int arg = _csi_arg_get(ty, p); + TitleIconElem *elem = ty->title_icon_stack; + + if (!elem) + return; + + switch (arg) + { + case -ESC_ARG_ERROR: + return; + case -ESC_ARG_NO_VALUE: + EINA_FALLTHROUGH; + case 0: + eina_stringshare_del(ty->prop.icon); + ty->prop.icon = eina_stringshare_ref(elem->icon); + if (ty->cb.set_icon.func) + ty->cb.set_icon.func(ty->cb.set_icon.data); + eina_stringshare_del(ty->prop.title); + ty->prop.title = eina_stringshare_ref(elem->title); + if (ty->cb.set_title.func) + ty->cb.set_title.func(ty->cb.set_title.data); + break; + case 1: + eina_stringshare_del(ty->prop.icon); + ty->prop.icon = eina_stringshare_ref(elem->icon); + if (ty->cb.set_icon.func) + ty->cb.set_icon.func(ty->cb.set_icon.data); + break; + case 2: + eina_stringshare_del(ty->prop.title); + ty->prop.title = eina_stringshare_ref(elem->title); + if (ty->cb.set_title.func) + ty->cb.set_title.func(ty->cb.set_title.data); + break; + default: + break; + } + eina_stringshare_del(elem->icon); + eina_stringshare_del(elem->title); + ty->title_icon_stack = elem->next; + free(elem); +} + static void _handle_window_manipulation(Termpty *ty, Eina_Unicode **ptr) { @@ -3089,6 +3183,12 @@ _handle_window_manipulation(Termpty *ty, Eina_Unicode **ptr) case 8: _handle_resize_by_chars(ty, &b); break; + case 22: + _title_icon_stack_push(ty, &b); + break; + case 23: + _title_icon_stack_pop(ty, &b); + break; default: // many others WRN("unhandled window manipulation %d", arg); diff --git a/tests/tests.results b/tests/tests.results index 1c6c915f..4ffcddbd 100644 --- a/tests/tests.results +++ b/tests/tests.results @@ -123,3 +123,6 @@ link_detection.sh bbe87a849586e8b922f26ad5d88146dc selection_with_tabs.sh 23557497a8f28ca246048bb2443b3dab selection_empty_lines.sh 7a90d9bfde9e9fb7f067f6c08eac57ff osc-invalid.sh 0acecbe16bb3b257745787c40affdb90 +title_icon_stack_simple.sh 9231de4459dbb52d0ffab6f33fc386a0 +title_icon_stack_unset.sh d2ebe2295eb036d9612209490f8aa7f9 +title_icon_stack_default.sh d2ebe2295eb036d9612209490f8aa7f9 diff --git a/tests/title_icon_stack_default.sh b/tests/title_icon_stack_default.sh new file mode 100755 index 00000000..b225efa6 --- /dev/null +++ b/tests/title_icon_stack_default.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +# fill space with E +printf '\033#8' +#set color +printf '\033[46;31;3m' + +#pop none +printf '\033[23;0t' + +# set title + icon +printf '\033]0;alpha\007' + +# save both (default case) +printf '\033[22t' + +# restack last elem +printf '\033[22;3t' + +# set again title + icon +printf '\033]0;bravo\007' + +# pop both (default case) +printf '\033[23t' + +# set again title + icon +printf '\033]0;charlie\007' + + +# pop both (default case) +printf '\033[23t' + +# pop none (default case) +printf '\033[23t' diff --git a/tests/title_icon_stack_simple.sh b/tests/title_icon_stack_simple.sh new file mode 100755 index 00000000..58937cf1 --- /dev/null +++ b/tests/title_icon_stack_simple.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +# fill space with E +printf '\033#8' +#set color +printf '\033[46;31;3m' + +# set title + icon +printf '\033]0;alpha\007' + +# save both +printf '\033[22;0t' + +# set again title + icon +printf '\033]0;bravo\007' + +# save both +printf '\033[22;0t' + +# set again title + icon +printf '\033]0;charlie\007' + +# pop title (bravo) +printf '\033[23;2t' + +# set again icon +printf '\033]1;delta\007' + +# pop icon (alpha) +printf '\033[23;1t' diff --git a/tests/title_icon_stack_unset.sh b/tests/title_icon_stack_unset.sh new file mode 100755 index 00000000..b33922cf --- /dev/null +++ b/tests/title_icon_stack_unset.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +# fill space with E +printf '\033#8' +#set color +printf '\033[46;31;3m' + +# set title + icon +printf '\033]0;alpha\007' + +# save title +printf '\033[22;2t' + +# set again title + icon +printf '\033]0;bravo\007' + +# save icon +printf '\033[22;1t' + +# set again title + icon +printf '\033]0;charlie\007' + +# pop title +printf '\033[23;2t' + +# set again icon +printf '\033]1;delta\007' + +# pop icon +printf '\033[23;1t'