tui.c: Send fewer cursor-hide commands to the terminal.

Since #2158 all connected UIs are informed about the busy state of nvim.
This can be used to decide whether to hide or show the cursor (in one
place).

In the TUI, this is tui_flush(). To prevent cursor flashing, the
terminal is always redrawn with an invisible cursor. After that the
cursor is shown if necessary. In the current implementation
a cursor-hide command will always be the first command in the next
redraw, to prevent flashing. This is not necessary.

Instead we start the TUI with a hidden cursor and only need to hide the
cursor in the next redraw, if the cursor was shown in the last redraw.
Otherwise the cursor is still hidden.

So instead of sending every redraw the cursor-hide command, we only need
to send the command while not busy(a state in nvim with low frequency).
This commit is contained in:
oni-link 2015-03-16 21:08:58 +01:00 committed by Thiago de Arruda
parent 293a7dc134
commit a0f2961b4f

View File

@ -108,6 +108,7 @@ void tui_start(void)
data->ut = unibi_dummy();
}
fix_terminfo(data);
unibi_out(ui, unibi_cursor_invisible);
// Enter alternate screen and clear
unibi_out(ui, unibi_enter_ca_mode);
unibi_out(ui, unibi_clear_screen);
@ -530,12 +531,7 @@ static void tui_flush(UI *ui)
unibi_goto(ui, data->row, data->col);
if (!data->busy) {
unibi_out(ui, unibi_cursor_normal);
}
flush_buf(ui);
unibi_out(ui, unibi_cursor_invisible);
}
static void tui_suspend(UI *ui)
@ -789,14 +785,32 @@ end:
static void flush_buf(UI *ui)
{
static uv_write_t req;
static uv_buf_t buf;
uv_write_t req;
uv_buf_t buf[2];
unsigned int buf_count = 1;
TUIData *data = ui->data;
buf.base = data->buf;
buf.len = data->bufpos;
uv_write(&req, (uv_stream_t *)&data->output_handle, &buf, 1, NULL);
buf[0].base = data->buf;
buf[0].len = data->bufpos;
char normal_buf[64];
if (!data->busy) {
// Cannot use unibi_out(ui, unibi_cursor_normal), in case there is not
// enough remaining space in data->buf.
const char *str = unibi_get_str(data->ut, unibi_cursor_normal);
buf[1].base = normal_buf;
buf[1].len = unibi_run(str, data->params, normal_buf, sizeof(normal_buf));
buf_count++;
}
uv_write(&req, (uv_stream_t *)&data->output_handle, buf, buf_count, NULL);
uv_run(data->write_loop, UV_RUN_DEFAULT);
data->bufpos = 0;
if (!data->busy) {
unibi_out(ui, unibi_cursor_invisible);
}
}
static void destroy_screen(TUIData *data)