To reproduce (in HEAD):
In a tmux window running the shell, type "seq 1 100", letting the output
scroll the screen (if you've got more than 100 lines on your term, then
give a higher value to seq's second arg).
...
97
98
99
100
micah$
Enter copy-mode, leaving the cursor still at the last line, and scroll
up a line, using Ctrl-Up, K, or C-y. Instead of the prompt scrolling off
the screen, it will remain where it is, and all the lines above it will
scroll:
...
98
99
micah$
hit C-y (or whatever) again. You'll see:
...
97
98
100
(Note the missing "99".) In each case, the bottom line is displaying the
line _after_ the proper one, which is not visible.
Cause:
The culprit is in this snippet from window_cursor_copy_up(), in
window-copy.c, which takes effect _after_ the actual scroll (which
writes the proper line):
if (scroll_only)
window_copy_redraw_lines(wp, data->cy, 2);
(For me, this is on line 1090.) When data->cy is the last line,
window_copy_redraw_lines will first redraw the final line again, and
then, attempt to "redraw" the next line down. It'll fail to advance the
cursor (since screen_write_cursormove() detects this problem), so just
write the next line over the proper last line.
While I can see what the problem is, I'm not yet comfortable enough with
the code to be sure of the solution. It's not entirely clear to me why
this redraw happens at all (though the CVS log mentions an end-of-line
marker "$"). It's equally unclear to me whether this should be handled
at the point of call to window_copy_redraw_lines() (to limit the third
argument in the event we're at the end), within
window_copy_redraw_lines() to exit the loop when we're past the last
line, or within window_copy_write_line() to return early when copying
the last line is detected. I suspect the first option is the most
cumbersome, as it could potentially require every caller to first check
and adjust the number of lines; the second option seems reasonable, and
perhaps the third should be done just in case it's missed by a different
caller? The patch I've attached does both of those, in case that's how
you want to go with this.
--
Micah J. Cowan
http://micah.cowan.name/
Index: window-copy.c
===================================================================
--- window-copy.c.orig
+++ window-copy.c
@@ -706,6 +706,8 @@
"%s: %s", data->inputprompt, data->inputstr);
screen_write_cursormove(ctx, 0, last);
screen_write_puts(ctx, &gc, "%s", hdr);
+ } else if (py > last) {
+ return;
} else
size = 0;
@@ -734,11 +736,17 @@
window_copy_redraw_lines(struct window_pane *wp, u_int py, u_int ny)
{
struct window_copy_mode_data *data = wp->modedata;
+ struct screen *s = &data->screen;
struct screen_write_ctx ctx;
u_int i;
+ size_t limit;
+
+ limit = screen_size_y(s);
+ if (py + ny < limit)
+ limit = py + ny;
screen_write_start(&ctx, wp, NULL);
- for (i = py; i < py + ny; i++)
+ for (i = py; i < limit; i++)
window_copy_write_line(wp, &ctx, i);
screen_write_cursormove(&ctx, data->cx, data->cy);
screen_write_stop(&ctx);
------------------------------------------------------------------------------
Throughout its 18-year history, RSA Conference consistently attracts the
world's best and brightest in the field, creating opportunities for Conference
attendees to learn about information security's most important issues through
interactions with peers, luminaries and emerging and established companies.
http://p.sf.net/sfu/rsaconf-dev2dev
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users