UI: add "compositor" layer to merge grids for TUI use in a correct way

Initially we will use this for the popupmenu, floating windows will
follow soon

NB: writedelay + compositor is weird, we need more flexible
redraw introspection.
This commit is contained in:
Björn Linse
2018-02-03 20:11:31 +01:00
parent 894f6bee54
commit 31cbd34d97
15 changed files with 583 additions and 112 deletions

View File

@@ -110,6 +110,7 @@
#include "nvim/syntax.h"
#include "nvim/terminal.h"
#include "nvim/ui.h"
#include "nvim/ui_compositor.h"
#include "nvim/undo.h"
#include "nvim/version.h"
#include "nvim/window.h"
@@ -153,6 +154,8 @@ static bool highlights_invalid = false;
static bool conceal_cursor_used = false;
static bool floats_invalid = false;
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "screen.c.generated.h"
#endif
@@ -453,17 +456,20 @@ void update_screen(int type)
/* redraw status line after the window to minimize cursor movement */
if (wp->w_redr_status) {
win_redr_status(wp, true); // any popup menu will be redrawn below
win_redr_status(wp);
}
}
send_grid_resize = false;
highlights_invalid = false;
end_search_hl();
// May need to redraw the popup menu.
if (pum_drawn()) {
if (pum_drawn() && floats_invalid) {
pum_redraw();
}
send_grid_resize = false;
highlights_invalid = false;
floats_invalid = false;
/* Reset b_mod_set flags. Going through all windows is probably faster
* than going through all buffers (there could be many buffers). */
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
@@ -4287,7 +4293,7 @@ win_line (
/// screen positions.
static void screen_adjust_grid(ScreenGrid **grid, int *row_off, int *col_off)
{
if (!ui_is_external(kUIMultigrid) && *grid != &default_grid) {
if (!(*grid)->chars && *grid != &default_grid) {
*row_off += (*grid)->row_offset;
*col_off += (*grid)->col_offset;
*grid = &default_grid;
@@ -4537,7 +4543,7 @@ void redraw_statuslines(void)
{
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
if (wp->w_redr_status) {
win_redr_status(wp, false);
win_redr_status(wp);
}
}
if (redraw_tabline)
@@ -4808,7 +4814,7 @@ win_redr_status_matches (
/// If inversion is possible we use it. Else '=' characters are used.
/// If "ignore_pum" is true, also redraw statusline when the popup menu is
/// displayed.
static void win_redr_status(win_T *wp, int ignore_pum)
static void win_redr_status(win_T *wp)
{
int row;
char_u *p;
@@ -4831,7 +4837,7 @@ static void win_redr_status(win_T *wp, int ignore_pum)
if (wp->w_status_height == 0) {
// no status line, can only be last window
redraw_cmdline = true;
} else if (!redrawing() || (!ignore_pum && pum_drawn())) {
} else if (!redrawing()) {
// Don't redraw right now, do it later. Don't update status line when
// popup menu is visible and may be drawn over it
wp->w_redr_status = true;
@@ -5454,10 +5460,10 @@ void grid_puts_len(ScreenGrid *grid, char_u *text, int textlen, int row,
grid->chars[off + 1][0] = 0;
grid->attrs[off + 1] = attr;
}
if (put_dirty_first == -1) {
if (put_dirty_first == -1 || col < put_dirty_first) {
put_dirty_first = col;
}
put_dirty_last = col+mbyte_cells;
put_dirty_last = MAX(put_dirty_last, col+mbyte_cells);
}
off += mbyte_cells;
@@ -5864,7 +5870,7 @@ void grid_fill(ScreenGrid *grid, int start_row, int end_row, int start_col,
if (dirty_last > dirty_first) {
// TODO(bfredl): support a cleared suffix even with a batched line?
if (put_dirty_row == row) {
if (put_dirty_first == -1) {
if (put_dirty_first == -1 || dirty_first < put_dirty_first) {
put_dirty_first = dirty_first;
}
put_dirty_last = MAX(put_dirty_last, dirty_last);
@@ -6030,6 +6036,10 @@ retry:
*/
++RedrawingDisabled;
// win_new_shellsize will recompute floats posititon, but tell the
// compositor to now redraw them yet
ui_comp_invalidate_screen();
win_new_shellsize(); /* fit the windows in the new sized shell */
comp_col(); /* recompute columns for shown command and ruler */
@@ -6188,6 +6198,7 @@ static void screenclear2(void)
default_grid.line_wraps[i] = false;
}
floats_invalid = true;
ui_call_grid_clear(1); // clear the display
clear_cmdline = false;
mode_displayed = false;
@@ -6218,7 +6229,7 @@ static void grid_clear_line(ScreenGrid *grid, unsigned off, int width,
(void)memset(grid->attrs + off, fill, (size_t)width * sizeof(sattr_T));
}
static void grid_invalidate(ScreenGrid *grid)
void grid_invalidate(ScreenGrid *grid)
{
(void)memset(grid->attrs, -1, grid->Rows * grid->Columns * sizeof(sattr_T));
}
@@ -6916,11 +6927,6 @@ void showruler(int always)
{
if (!always && !redrawing())
return;
if (pum_drawn()) {
// Don't redraw right now, do it later.
curwin->w_redr_status = true;
return;
}
if ((*p_stl != NUL || *curwin->w_p_stl != NUL) && curwin->w_status_height) {
redraw_custom_statusline(curwin);
} else {
@@ -6955,10 +6961,6 @@ static void win_redr_ruler(win_T *wp, int always)
if (wp == lastwin && lastwin->w_status_height == 0)
if (edit_submode != NULL)
return;
// Don't draw the ruler when the popup menu is visible, it may overlap.
if (pum_drawn()) {
return;
}
if (*p_ruf) {
int save_called_emsg = called_emsg;