aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Hixson <mujo@sdf.org>2022-12-28 14:52:06 -0800
committerRandy Palamar <palamar@ualberta.ca>2023-08-01 09:56:53 -0600
commitd1f2c277f8594ee7221d820cac5f90eec103feb3 (patch)
tree8d64e20ca9f1a0623ba02d043b271cbdee816426
parent32e20a2df0fc5d0f61c8292d3f6241476a356476 (diff)
downloadvis-d1f2c277f8594ee7221d820cac5f90eec103feb3.tar.gz
vis-d1f2c277f8594ee7221d820cac5f90eec103feb3.tar.xz
Prevent flickering in curses
Reading from curs_refresh(3X) from curses, calling doupdate() repeatedly will cause 'several bursts of output to the screen'. wnoutrefresh() has the smarts to only copy the changed lines to the copied virtual screen, but doupdate() does not. There have been several bug reports related to flickering but all seems to be inconsistenly reproducible due to different terminal buffering behavior. See #1032, #327 Unfortunately, when I am using a slow display, I still notice flickering, so this commit changes the routines for opening new windows and splitting windows to wait until the last change is finished before calling doupdate().
-rw-r--r--ui-terminal-curses.c3
-rw-r--r--ui-terminal.c8
-rw-r--r--ui.h1
-rw-r--r--vis.c8
-rw-r--r--vis.h7
5 files changed, 26 insertions, 1 deletions
diff --git a/ui-terminal-curses.c b/ui-terminal-curses.c
index 93f729e..e9f726b 100644
--- a/ui-terminal-curses.c
+++ b/ui-terminal-curses.c
@@ -230,7 +230,8 @@ static void ui_curses_blit(UiTerm *tui) {
}
}
wnoutrefresh(stdscr);
- doupdate();
+ if (tui->doupdate)
+ doupdate();
}
static void ui_curses_clear(UiTerm *tui) {
diff --git a/ui-terminal.c b/ui-terminal.c
index f3b9f04..27afb26 100644
--- a/ui-terminal.c
+++ b/ui-terminal.c
@@ -48,6 +48,7 @@ typedef struct {
CellStyle *styles; /* each window has UI_STYLE_MAX different style definitions */
size_t cells_size; /* #bytes allocated for 2D grid (grows only) */
Cell *cells; /* 2D grid of cells, at least as large as current terminal size */
+ bool doupdate; /* Whether to update the screen after refreshing contents */
} UiTerm;
struct UiTermWin {
@@ -347,6 +348,11 @@ static void ui_arrange(Ui *ui, enum UiLayout layout) {
}
}
+static void ui_doupdates(Ui *ui, bool doupdate) {
+ UiTerm *tui = (UiTerm*)ui;
+ tui->doupdate = doupdate;
+}
+
static void ui_draw(Ui *ui) {
debug("ui-draw\n");
UiTerm *tui = (UiTerm*)ui;
@@ -684,6 +690,7 @@ Ui *ui_term_new(void) {
}
tui->styles_size = styles_size;
tui->styles = styles;
+ tui->doupdate = true;
Ui *ui = (Ui*)tui;
*ui = (Ui) {
.init = ui_init,
@@ -699,6 +706,7 @@ Ui *ui_term_new(void) {
.draw = ui_draw,
.redraw = ui_redraw,
.arrange = ui_arrange,
+ .doupdates = ui_doupdates,
.die = ui_die,
.info = ui_info,
.info_hide = ui_info_hide,
diff --git a/ui.h b/ui.h
index 94b45f5..42cdbda 100644
--- a/ui.h
+++ b/ui.h
@@ -98,6 +98,7 @@ struct Ui {
void (*redraw)(Ui*);
void (*suspend)(Ui*);
void (*resume)(Ui*);
+ void (*doupdates)(Ui*, bool);
bool (*getkey)(Ui*, TermKeyKey*);
void (*terminal_save)(Ui*, bool fscr);
void (*terminal_restore)(Ui*);
diff --git a/vis.c b/vis.c
index 0ffbd39..d374d39 100644
--- a/vis.c
+++ b/vis.c
@@ -529,6 +529,7 @@ bool vis_window_reload(Win *win) {
}
bool vis_window_split(Win *original) {
+ vis_doupdates(original->vis, false);
Win *win = window_new_file(original->vis, original->file, UI_OPTION_STATUSBAR);
if (!win)
return false;
@@ -541,6 +542,7 @@ bool vis_window_split(Win *original) {
win->file = original->file;
view_options_set(win->view, view_options_get(original->view));
view_cursor_to(win->view, view_cursor_get(original->view));
+ vis_doupdates(win->vis, true);
return true;
}
@@ -599,15 +601,21 @@ void vis_resume(Vis *vis) {
vis->ui->resume(vis->ui);
}
+void vis_doupdates(Vis *vis, bool doupdate) {
+ vis->ui->doupdates(vis->ui, doupdate);
+}
+
bool vis_window_new(Vis *vis, const char *filename) {
File *file = file_new(vis, filename);
if (!file)
return false;
+ vis_doupdates(vis, false);
Win *win = window_new_file(vis, file, UI_OPTION_STATUSBAR|UI_OPTION_SYMBOL_EOF);
if (!win) {
file_free(vis, file);
return false;
}
+ vis_doupdates(vis, true);
return true;
}
diff --git a/vis.h b/vis.h
index f8c5680..ae059b4 100644
--- a/vis.h
+++ b/vis.h
@@ -144,6 +144,13 @@ void vis_suspend(Vis*);
*/
void vis_resume(Vis*);
/**
+ * Set doupdate flag.
+ * @rst
+ * .. note:: Prevent flickering in curses by delaying window updates.
+ * @endrst
+ */
+void vis_doupdates(Vis*, bool);
+/**
* Inform the editor core that a signal occurred.
* @return Whether the signal was handled.
* @rst