simplicity. Also look at tcflow(3). Currently, for smooth scrolling to
work with screen(1)/tmux(1), the status bar must be disabled or configured
to be at the top.
+ An early test used input flow control by temporarily stopping to read. This
+ was not kept, but it may be necessary in some circumstances to avoid sudden
+ jumps. Was restored in a different way, may need improvement.
- Check termios(4) IMAXBEL and queue size, also reported by stty(1).
This may allow to tweak interactive performance when a lot of application
output happens.
static Time lastexpose = -1;
static int inputsleepskip = 0;
+static bool scrollblocked = false;
+static int blockedchar = '\0';
if (state->cursor_disabled_ticks != 0)
rbufsize = 1;
+ /*
+ * If we stopped reading to control flow because of
+ * scroll in progress while detecting another
+ * character causing scrolling, simulate its
+ * reception and unblock once scrolling stopped.
+ */
+ if (scrollblocked &&
+ state->smoothscroll_offset == 0) {
+ scrollblocked = false;
+ *ttys->rbuf = blockedchar;
+ size = 1;
+ goto process;
+ }
+
+ /*
+ * Avoid reading more data if blocked because of
+ * scrolling.
+ */
+ if (scrollblocked)
+ continue;
+
/* Finally read from the application tty(4) */
if ((size = read(ttys->ptyfd, ttys->rbuf, rbufsize))
== -1 && errno != EAGAIN && errno != EINTR) {
break;
}
+ /*
+ * If scrolling is in progress and we receive another
+ * character necessitating imminent scrolling,
+ * temporarily stop input until scrolling ends.
+ * Remember the character to simulate reading when
+ * resuming.
+ */
+ if ((state->smoothscroll_offset > 0 && size == 1) &&
+ (*ttys->rbuf == '\n' ||
+ state->cursor_x == cfg_text_width - 1)) {
+ scrollblocked = true;
+ blockedchar = *ttys->rbuf;
+ continue;
+ }
+
+process:
/* Emulate terminal and update screen */
for (i = 0; i < size; i++)
state_emul_printc(state, ttys->rbuf[i]);