diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt index a40ce928e8..781d759c82 100644 --- a/runtime/doc/ui.txt +++ b/runtime/doc/ui.txt @@ -642,6 +642,13 @@ tabs. purpose it only counts "virtual" or "displayed" lines, so folds only count as one line. + All updates, such as `grid_line`, in a batch affects the new viewport, + despite the fact that `win_viewport` is received after the updates. + Applications implementing, for example, smooth scrolling should take + this into account and keep the grid separated from what's displayed on + the screen and copy it to the viewport destination once `win_viewport` + is received. + ["win_extmark", grid, win, ns_id, mark_id, row, col] ~ Updates the position of an extmark which is currently visible in a window. Only emitted if the mark has the `ui_watched` attribute. diff --git a/src/nvim/window.c b/src/nvim/window.c index 0fe5d68c9e..26c533f2a3 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -987,7 +987,9 @@ void ui_ext_win_position(win_T *wp, bool validate) void ui_ext_win_viewport(win_T *wp) { - if ((wp == curwin || ui_has(kUIMultigrid)) && wp->w_viewport_invalid) { + // NOTE: The win_viewport command is delayed until the next flush when there are pending updates. + // This ensures that the updates and the viewport are sent together. + if ((wp == curwin || ui_has(kUIMultigrid)) && wp->w_viewport_invalid && wp->w_redr_type == 0) { int botline = wp->w_botline; int line_count = wp->w_buffer->b_ml.ml_line_count; if (botline == line_count + 1 && wp->w_empty_rows == 0) {