diff --git a/src/lib/internal.h b/src/lib/internal.h index 895331d65..b0840e81a 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -458,6 +458,7 @@ typedef struct ncpile { struct ncpile *prev, *next; // circular list size_t crenderlen; // size of crender vector int dimy, dimx; // rows and cols at time of render + int scrolls; // how many real lines need be scrolled at raster sprixel* sprixelcache; // list of sprixels } ncpile; @@ -496,6 +497,7 @@ typedef struct notcurses { ncpalette palette; // 256-indexed palette can be used instead of/with RGB bool palette_damage[NCPALETTESIZE]; unsigned stdio_blocking_save; // was stdio blocking at entry? restore on stop. + uint64_t flags; // copied from notcurses_options } notcurses; // this flag is used internally, by direct mode (which might want @@ -815,7 +817,7 @@ sprite_destroy(const notcurses* nc, const ncpile* p, FILE* out, sprixel* s){ // returns -1 on error, or the number of bytes written. static inline int sprite_draw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out){ -//sprixel_debug(stderr, s); +sprixel_debug(stderr, s); return n->tcache.pixel_draw(p, s, out); } @@ -823,7 +825,7 @@ sprite_draw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out){ // returns -1 on error, or the number of bytes written. static inline int sprite_redraw(const notcurses* n, const ncpile* p, sprixel* s, FILE* out){ -//sprixel_debug(stderr, s); +sprixel_debug(stderr, s); if(s->invalidated == SPRIXEL_MOVED && n->tcache.pixel_move){ return n->tcache.pixel_move(p, s, out); }else{ diff --git a/src/lib/kitty.c b/src/lib/kitty.c index 2704e255c..a52831c9c 100644 --- a/src/lib/kitty.c +++ b/src/lib/kitty.c @@ -599,7 +599,7 @@ int kitty_destroy(const notcurses* nc __attribute__ ((unused)), // ideally, we wouldn't damage our annihilated sprixcells, but if // we're being annihilated only during this cycle, we need to go // ahead and damage it. - r->s.damaged = 1; + // r->s.damaged = 1; } }else{ // need this to damage cells underneath a sprixel we're removing diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index 1f4cf41cc..1044eee60 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -357,6 +357,7 @@ make_ncpile(notcurses* nc, ncplane* n){ ret->crender = NULL; ret->crenderlen = 0; ret->sprixelcache = NULL; + ret->scrolls = 0; } return ret; } @@ -1034,6 +1035,7 @@ notcurses* notcurses_core_init(const notcurses_options* opts, FILE* outfp){ if(outfp == NULL){ outfp = stdout; } + ret->flags = opts->flags; ret->margin_t = opts->margin_t; ret->margin_b = opts->margin_b; ret->margin_l = opts->margin_l; @@ -1237,13 +1239,17 @@ int notcurses_stop(notcurses* nc){ fclose(nc->rstate.mstreamfp); } // if we were not using the alternate screen, our cursor's wherever we last - // wrote. move it to the bottom left of the screen. - if(!get_escape(&nc->tcache, ESCAPE_SMCUP)){ - // if ldimy is 0, we've not yet written anything; leave it untouched - if(nc->lfdimy){ - int targy = nc->lfdimy + nc->margin_t - 1; - // cup is required, no need to test for existence - tty_emit(tiparm(get_escape(&nc->tcache, ESCAPE_CUP), targy, 0), nc->ttyfd); + // wrote. move it to the bottom left of the screen, *unless* + // NCOPTION_PRESERVE_CURSOR was used, in which case it's right where we + // want it (i think?). + if(!(nc->flags & NCOPTION_PRESERVE_CURSOR)){ + if(!get_escape(&nc->tcache, ESCAPE_SMCUP)){ + // if ldimy is 0, we've not yet written anything; leave it untouched + if(nc->lfdimy){ + int targy = nc->lfdimy + nc->margin_t - 1; + // cup is required, no need to test for existence + tty_emit(tiparm(get_escape(&nc->tcache, ESCAPE_CUP), targy, 0), nc->ttyfd); + } } } if(nc->ttyfd >= 0){ @@ -1484,8 +1490,12 @@ nccell_obliterate(ncplane* n, nccell* c){ // increment y by 1 and rotate the framebuffer up one line. x moves to 0. void scroll_down(ncplane* n){ +//fprintf(stderr, "pre-scroll: %d/%d %d/%d log: %d\n", n->y, n->x, n->leny, n->lenx, n->logrow); n->x = 0; if(n->y == n->leny - 1){ + if(n == notcurses_stdplane(ncplane_notcurses(n))){ + ncplane_pile(n)->scrolls++; + } n->logrow = (n->logrow + 1) % n->leny; nccell* row = n->fb + nfbcellidx(n, n->y, 0); for(int clearx = 0 ; clearx < n->lenx ; ++clearx){ diff --git a/src/lib/render.c b/src/lib/render.c index 4b80fdf50..797ae6a63 100644 --- a/src/lib/render.c +++ b/src/lib/render.c @@ -942,6 +942,18 @@ clean_sprixels(notcurses* nc, ncpile* p, FILE* out){ return bytesemitted; } +static int +rasterize_scrolls(ncpile* p, FILE* out){ +//fprintf(stderr, "%d tardies to work off, by far the most in the class\n", p->scrolls); + while(p->scrolls){ + if(fprintf(out, "\n") < 0){ + return -1; + } + --p->scrolls; + } + return 0; +} + // draw any invalidated sprixels. returns -1 on error, number of bytes written // on success. any material underneath them has already been updated. static int64_t @@ -1116,6 +1128,9 @@ notcurses_rasterize_inner(notcurses* nc, ncpile* p, FILE* out, unsigned* asu){ } update_palette(nc, out); //fprintf(stderr, "RASTERIZE CORE\n"); + if(rasterize_scrolls(p, out)){ + return -1; + } if(rasterize_core(nc, p, out, 0)){ return -1; }