diff --git a/src/lib/direct.c b/src/lib/direct.c index 4a4216f56..ff7e65999 100644 --- a/src/lib/direct.c +++ b/src/lib/direct.c @@ -636,6 +636,9 @@ ncdirect_stop_minimal(void* vnc){ ret = -1; } if(nc->ctermfd >= 0){ + if(nc->tcache.pixel_shutdown){ + ret |= nc->tcache.pixel_shutdown(nc->ctermfd); + } if(nc->tcache.cnorm && tty_emit(nc->tcache.cnorm, nc->ctermfd)){ ret = -1; } diff --git a/src/lib/internal.h b/src/lib/internal.h index 8196d2511..d3bae40aa 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -363,8 +363,9 @@ typedef struct tinfo { // means leaving out the pixels (and likely resizes the string). for kitty, // this means dialing down their alpha to 0 (in equivalent space). int (*pixel_cell_wipe)(const struct notcurses* nc, sprixel* s, int y, int x); - int (*pixel_init)(int fd); + int (*pixel_init)(int fd); // called when support is detected int (*pixel_draw)(const struct notcurses* n, const struct ncpile* p, sprixel* s, FILE* out); + int (*pixel_shutdown)(int fd); // called during context shutdown bool bitmap_supported; // do we support bitmaps (post pixel_query_done)? bool sprixel_cursor_hack; // do sprixels reset the cursor? (mlterm) bool pixel_query_done; // have we yet performed pixel query? @@ -848,6 +849,8 @@ int sprite_kitty_init(int fd); int sprite_sixel_init(int fd); int sprite_init(const notcurses* nc); void sprixel_invalidate(sprixel* s); +int kitty_shutdown(int fd); +int sixel_shutdown(int fd); sprixel* sprixel_by_id(const notcurses* nc, uint32_t id); static inline void diff --git a/src/lib/kitty.c b/src/lib/kitty.c index 4e728a660..bfc704f1e 100644 --- a/src/lib/kitty.c +++ b/src/lib/kitty.c @@ -379,3 +379,10 @@ int kitty_draw(const notcurses* nc, const ncpile* p, sprixel* s, FILE* out){ int sprite_kitty_init(int fd){ return tty_emit("\e_Ga=d\e\\", fd); } + +int kitty_shutdown(int fd){ + // FIXME need to close off any open kitty bitmap emission, or we will + // lock up the terminal + (void)fd; + return 0; +} diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index 37a72d630..b63dfd569 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -67,6 +67,9 @@ notcurses_stop_minimal(void* vnc){ // be sure to write the restoration sequences *prior* to running rmcup, as // they apply to the screen (alternate or otherwise) we're actually using. if(nc->ttyfd >= 0){ + if(nc->tcache.pixel_shutdown){ + ret |= nc->tcache.pixel_shutdown(nc->ttyfd); + } ret |= reset_term_attributes(nc); if(nc->tcache.rmcup && tty_emit(nc->tcache.rmcup, nc->ttyfd)){ ret = -1; diff --git a/src/lib/sixel.c b/src/lib/sixel.c index 13ff8cffd..42bed3f07 100644 --- a/src/lib/sixel.c +++ b/src/lib/sixel.c @@ -535,6 +535,7 @@ int sixel_draw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out){ } int sprite_sixel_init(int fd){ +fprintf(stderr, "ARP?\n"); // \e[?8452: DECSDM private "sixel scrolling" mode keeps the sixel from // scrolling, but puts it at the current cursor location (as opposed to // the upper left corner of the screen). @@ -553,3 +554,8 @@ int sixel_wipe(const notcurses* nc, sprixel* s, int ycell, int xcell){ change_p2(s->glyph, SIXEL_P2_TRANS); return -1; } + +int sixel_shutdown(int fd){ +fprintf(stderr, "ERP?\n"); + return tty_emit("\e[?80;8452l", fd); +} diff --git a/src/lib/terminfo.c b/src/lib/terminfo.c index 28dd444a8..198b18ecd 100644 --- a/src/lib/terminfo.c +++ b/src/lib/terminfo.c @@ -65,6 +65,7 @@ apply_term_heuristics(tinfo* ti, const char* termname){ ti->pixel_destroy = sprite_kitty_annihilate; ti->pixel_init = sprite_kitty_init; ti->pixel_draw = kitty_draw; + ti->pixel_shutdown = kitty_shutdown; set_pixel_blitter(kitty_blit); }else if(strstr(termname, "alacritty")){ ti->alacritty_sixel_hack = true; @@ -339,6 +340,7 @@ setup_sixel(tinfo* ti){ ti->sixel_maxy = 4096; ti->pixel_destroy = sixel_delete; ti->pixel_cell_wipe = sixel_wipe; + ti->pixel_shutdown = sixel_shutdown; } // query for Sixel support