summaryrefslogtreecommitdiffstats
path: root/screen.c
diff options
context:
space:
mode:
authornicm <nicm>2019-03-20 19:19:11 +0000
committernicm <nicm>2019-03-20 19:19:11 +0000
commit9ee1a8f7014dedaa701594ea847a4da98a07073d (patch)
tree6e3bb2259235507f8526ba487066636b25621e43 /screen.c
parented962e76129d499012bee92617620d3703245482 (diff)
Improve cursor positioning after reflow by storing the position as an
offset into the entire history before reflow and restoring it aftewards.
Diffstat (limited to 'screen.c')
-rw-r--r--screen.c58
1 files changed, 27 insertions, 31 deletions
diff --git a/screen.c b/screen.c
index 75d9d09d..92eb31de 100644
--- a/screen.c
+++ b/screen.c
@@ -48,7 +48,6 @@ struct screen_title_entry {
};
TAILQ_HEAD(screen_titles, screen_title_entry);
-static void screen_resize_x(struct screen *, u_int);
static void screen_resize_y(struct screen *, u_int);
static void screen_reflow(struct screen *, u_int);
@@ -207,13 +206,7 @@ screen_resize(struct screen *s, u_int sx, u_int sy, int reflow)
sy = 1;
if (sx != screen_size_x(s)) {
- screen_resize_x(s, sx);
-
- /*
- * It is unclear what should happen to tabs on resize. xterm
- * seems to try and maintain them, rxvt resets them. Resetting
- * is simpler and more reliable so let's do that.
- */
+ s->grid->sx = sx;
screen_reset_tabs(s);
} else
reflow = 0;
@@ -226,28 +219,6 @@ screen_resize(struct screen *s, u_int sx, u_int sy, int reflow)
}
static void
-screen_resize_x(struct screen *s, u_int sx)
-{
- struct grid *gd = s->grid;
-
- if (sx == 0)
- fatalx("zero size");
-
- /*
- * Treat resizing horizontally simply: just ensure the cursor is
- * on-screen and change the size. Don't bother to truncate any lines -
- * then the data should be accessible if the size is then increased.
- *
- * The only potential wrinkle is if UTF-8 double-width characters are
- * left in the last column, but UTF-8 terminals should deal with this
- * sanely.
- */
- if (s->cx >= sx)
- s->cx = sx - 1;
- gd->sx = sx;
-}
-
-static void
screen_resize_y(struct screen *s, u_int sy)
{
struct grid *gd = s->grid;
@@ -493,5 +464,30 @@ screen_select_cell(struct screen *s, struct grid_cell *dst,
static void
screen_reflow(struct screen *s, u_int new_x)
{
- grid_reflow(s->grid, new_x, &s->cy);
+ u_int offset, cx = s->cx, cy = s->grid->hsize + s->cy;
+ struct timeval start, tv;
+
+ gettimeofday(&start, NULL);
+
+ offset = grid_to_offset(s->grid, cx, cy);
+ log_debug("%s: cursor %u,%u offset is %u", __func__, cx, cy, offset);
+
+ grid_reflow(s->grid, new_x);
+
+ grid_from_offset(s->grid, offset, &cx, &cy);
+ log_debug("%s: new cursor is %u,%u", __func__, cx, cy);
+
+ if (cy >= s->grid->hsize) {
+ s->cx = cx;
+ s->cy = cy - s->grid->hsize;
+ } else {
+ s->cx = 0;
+ s->cy = 0;
+ }
+
+ gettimeofday(&tv, NULL);
+ timersub(&tv, &start, &tv);
+
+ log_debug("%s: reflow took %llu.%06u seconds", __func__,
+ (unsigned long long)tv.tv_sec, (u_int)tv.tv_usec);
}