We had way too many calls to wrefresh() which copies the named
window to the physical terminal screen. This slows down the display
considerably, especially on slow machines.
It is more efficient to perform the copy only once per scheduler
iteration. So this commit adds a flag "needs_update" to struct
gui_window, and all callers to wrefresh() are changed to call
refresh_window() instead. This new function is much cheaper since it
only turns on the needs_update flag but does nothing else.
In input_post_select() we check which windows have the flag set and
repaint those windows using wnoutrefresh() and then doupdate(). This
two-step approach is described in the curs_refresh(3X) man page as
more efficient then calling wrefresh() for each window separately
since it avoids alternating calls to wnoutrefresh() and doupdate().
static struct gui_window {
WINDOW *win;
static struct gui_window {
WINDOW *win;
} top, bot, sb, in, sep;
#define RINGBUFFER_SIZE 512
} top, bot, sb, in, sep;
#define RINGBUFFER_SIZE 512
+static void refresh_window(struct gui_window *gw)
+{
+ gw->needs_update = true;
+}
+
+static bool window_update_needed(void)
+{
+ return top.needs_update || bot.needs_update || sb.needs_update ||
+ in.needs_update || sep.needs_update;
+}
+
__printf_2_3 static void print_in_bar(int color, const char *fmt,...)
{
char *msg;
__printf_2_3 static void print_in_bar(int color, const char *fmt,...)
{
char *msg;
wmove(in.win, 0, 0);
align_str(in.win, msg, get_num_cols(&in), LEFT);
free(msg);
wmove(in.win, 0, 0);
align_str(in.win, msg, get_num_cols(&in), LEFT);
free(msg);
}
static void print_status_bar(void)
}
static void print_status_bar(void)
waddstr(bot.win, rbe->msg);
}
out:
waddstr(bot.win, rbe->msg);
}
out:
}
static void rb_add_entry(int color, char *msg)
}
static void rb_add_entry(int color, char *msg)
xvasprintf(&msg, fmt, ap);
va_end(ap);
rb_add_entry(color, msg);
xvasprintf(&msg, fmt, ap);
va_end(ap);
rb_add_entry(color, msg);
}
static int add_output_line(char *line, void *data)
}
static int add_output_line(char *line, void *data)
if (bytes > 0 && msg[bytes - 1] == '\n')
msg[bytes - 1] = '\0'; /* cut trailing newline */
rb_add_entry(color, msg);
if (bytes > 0 && msg[bytes - 1] == '\n')
msg[bytes - 1] = '\0'; /* cut trailing newline */
rb_add_entry(color, msg);
} else if (exec_pid <= 0) /* no external command running */
vfprintf(stderr, fmt, ap);
va_end(ap);
} else if (exec_pid <= 0) /* no external command running */
vfprintf(stderr, fmt, ap);
va_end(ap);
return;
tmp = make_message("%s%s%s", d.prefix, c, d.postfix);
wmove(top.win, d.y * top_lines / 100, d.x * COLS / 100);
return;
tmp = make_message("%s%s%s", d.prefix, c, d.postfix);
wmove(top.win, d.y * top_lines / 100, d.x * COLS / 100);
wattron(top.win, COLOR_PAIR(i + 1));
align_str(top.win, tmp, d.len * COLS / 100, d.align);
free(tmp);
wattron(top.win, COLOR_PAIR(i + 1));
align_str(top.win, tmp, d.len * COLS / 100, d.align);
free(tmp);
}
static int update_item(int item_num, char *buf)
}
static int update_item(int item_num, char *buf)
ct->cbo[i] = for_each_line(ct->flags[i], ct->command_buf[i],
ct->cbo[i], add_output_line, &i);
if (sz != ct->cbo[i]) { /* at least one line found */
ct->cbo[i] = for_each_line(ct->flags[i], ct->command_buf[i],
ct->cbo[i], add_output_line, &i);
if (sz != ct->cbo[i]) { /* at least one line found */
ct->flags[i] = 0;
}
if (ret < 0 || exec_pid == 0) {
ct->flags[i] = 0;
}
if (ret < 0 || exec_pid == 0) {
{
if (exec_status() != EXEC_XCMD)
para_fd_set(STDIN_FILENO, &s->rfds, &s->max_fileno);
{
if (exec_status() != EXEC_XCMD)
para_fd_set(STDIN_FILENO, &s->rfds, &s->max_fileno);
+ if (window_update_needed())
+ sched_min_delay(s);
}
/* read from command pipe and print data to bot window */
}
/* read from command pipe and print data to bot window */
if (exs == EXEC_XCMD)
return 0;
if (exs == EXEC_XCMD)
return 0;
+ if (window_update_needed()) {
+ if (top.needs_update)
+ assert(wnoutrefresh(top.win) == OK);
+ if (bot.needs_update)
+ assert(wnoutrefresh(bot.win) == OK);
+ if (sep.needs_update)
+ assert(wnoutrefresh(sep.win) == OK);
+ if (sb.needs_update)
+ assert(wnoutrefresh(sb.win) == OK);
+ if (in.needs_update)
+ assert(wnoutrefresh(in.win) == OK);
+ doupdate();
+ top.needs_update = bot.needs_update = sb.needs_update =
+ in.needs_update = sep.needs_update = false;
+ }
ret = wgetch(top.win);
if (ret == ERR || ret == KEY_RESIZE)
return 0;
ret = wgetch(top.win);
if (ret == ERR || ret == KEY_RESIZE)
return 0;
wmove(bot.win, bot_lines - rbe_lines, 0);
wattron(bot.win, COLOR_PAIR(rbe->color));
waddstr(bot.win, rbe->msg);
wmove(bot.win, bot_lines - rbe_lines, 0);
wattron(bot.win, COLOR_PAIR(rbe->color));
waddstr(bot.win, rbe->msg);
print_scroll_msg();
return;
err_out:
print_scroll_msg();
return;
err_out: