scrolling: fix issues with the beacon

Add a few comments on how it works
This commit is contained in:
Boris Faure 2016-11-20 18:23:56 +01:00
parent 5b34e2ba67
commit c47b0c39d5
2 changed files with 51 additions and 33 deletions

View File

@ -845,21 +845,18 @@ termpty_backscroll_adjust(Termpty *ty, int *scroll)
Termsave *ts; Termsave *ts;
ts = BACKLOG_ROW_GET(ty, backlog_y); ts = BACKLOG_ROW_GET(ty, backlog_y);
if (*scroll <= screen_y)
{
return;
}
if (!ts->cells || backlog_y >= (int)ty->backsize) if (!ts->cells || backlog_y >= (int)ty->backsize)
{ {
*scroll = ty->backlog_beacon.screen_y; *scroll = ty->backlog_beacon.screen_y;
return; return;
} }
nb_lines = (ts->w == 0) ? 1 : (ts->w + ty->w - 1) / ty->w; nb_lines = (ts->w == 0) ? 1 : (ts->w + ty->w - 1) / ty->w;
ty->backlog_beacon.screen_y = screen_y; ty->backlog_beacon.screen_y = screen_y;
ty->backlog_beacon.backlog_y = backlog_y; ty->backlog_beacon.backlog_y = backlog_y;
screen_y += nb_lines; screen_y += nb_lines;
backlog_y++; backlog_y++;
if (*scroll <= screen_y)
return;
} }
} }
@ -868,50 +865,69 @@ _termpty_cellrow_from_beacon_get(Termpty *ty, int requested_y, ssize_t *wret)
{ {
int backlog_y = ty->backlog_beacon.backlog_y; int backlog_y = ty->backlog_beacon.backlog_y;
int screen_y = ty->backlog_beacon.screen_y; int screen_y = ty->backlog_beacon.screen_y;
Eina_Bool going_forward = EINA_TRUE; Termsave *ts;
int nb_lines;
requested_y = -requested_y; requested_y = -requested_y;
/* check if going from 0,0 is faster than using the beacon */ /* check if going from 0,0 is faster than using the beacon */
if (screen_y - requested_y > requested_y) if (screen_y - requested_y > requested_y)
{ {
backlog_y = 1; ty->backlog_beacon.backlog_y = 0;
screen_y = 1; ty->backlog_beacon.screen_y = 0;
} }
while (42) {
Termsave *ts;
int nb_lines;
/* going upward */
while (requested_y >= screen_y)
{
ts = BACKLOG_ROW_GET(ty, backlog_y); ts = BACKLOG_ROW_GET(ty, backlog_y);
if (!ts->cells) if (!ts->cells || backlog_y >= (int)ty->backsize)
return NULL;
nb_lines = (ts->w == 0) ? 1 : (ts->w + ty->w - 1) / ty->w;
if (!going_forward) {
screen_y -= nb_lines;
}
if ((screen_y <= requested_y) && (requested_y < screen_y + nb_lines))
{ {
int delta = screen_y + nb_lines - 1 - requested_y; return NULL;
}
nb_lines = (ts->w == 0) ? 1 : (ts->w + ty->w - 1) / ty->w;
ty->backlog_beacon.screen_y = screen_y;
ty->backlog_beacon.backlog_y = backlog_y;
if ((screen_y - nb_lines < requested_y) && (requested_y <= screen_y))
{
/* found the line */
int delta = screen_y - requested_y;
*wret = ts->w - delta * ty->w; *wret = ts->w - delta * ty->w;
if (*wret > ts->w) if (*wret > ts->w)
*wret = ts->w; *wret = ts->w;
ty->backlog_beacon.screen_y = screen_y;
ty->backlog_beacon.backlog_y = backlog_y;
return &ts->cells[delta * ty->w]; return &ts->cells[delta * ty->w];
} }
screen_y += nb_lines;
backlog_y++;
}
/* else, going downward */
while (requested_y <= screen_y)
{
ts = BACKLOG_ROW_GET(ty, backlog_y);
if (!ts->cells)
{
return NULL;
}
nb_lines = (ts->w == 0) ? 1 : (ts->w + ty->w - 1) / ty->w;
if (requested_y > screen_y) ty->backlog_beacon.screen_y = screen_y;
ty->backlog_beacon.backlog_y = backlog_y;
if ((screen_y - nb_lines < requested_y) && (requested_y <= screen_y))
{ {
screen_y += nb_lines; /* found the line */
backlog_y++; int delta = screen_y - requested_y;
*wret = ts->w - delta * ty->w;
if (*wret > ts->w)
*wret = ts->w;
return &ts->cells[delta * ty->w];
} }
else screen_y -= nb_lines;
{ backlog_y--;
backlog_y--; }
going_forward = EINA_FALSE;
}
}
return NULL; return NULL;
} }
@ -1165,8 +1181,8 @@ termpty_resize(Termpty *ty, int new_w, int new_h)
termpty_backlog_unlock(); termpty_backlog_unlock();
ty->backlog_beacon.backlog_y = 1; ty->backlog_beacon.backlog_y = 0;
ty->backlog_beacon.screen_y = 1; ty->backlog_beacon.screen_y = 0;
return; return;

View File

@ -96,6 +96,8 @@ struct _Termpty
unsigned char oldbuf[4]; unsigned char oldbuf[4];
Termsave *back; Termsave *back;
size_t backsize, backpos; size_t backsize, backpos;
/* this beacon in the backlog tells about the top line in screen
* coordinates that maps to a line in the backlog */
struct { struct {
int screen_y; int screen_y;
int backlog_y; int backlog_y;