diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index d0db43c588663b..54785fcb3e82e1 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -270,6 +270,10 @@ static void remote_ui_grid_resize(UI *ui, Integer grid, Array args = ARRAY_DICT_INIT; if (ui->ui_ext[kUINewgrid]) { ADD(args, INTEGER_OBJ(grid)); + } else if (grid != 1) { + // calling grid_resize with a grid other than the global when + // the remote ui is not managing grids should not send the event + return; } ADD(args, INTEGER_OBJ(width)); ADD(args, INTEGER_OBJ(height)); diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 8cba3521a8061d..e56b6150ede61e 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -128,6 +128,14 @@ StlClickDefinition *tab_page_click_defs = NULL; long tab_page_click_defs_size = 0; +/// The last handle that was assigned to a ScreenGrid. 1 is reserved for +/// the default_grid. +/// TODO(utkarshme): Numbers can be recycled after grid destruction. +static int last_handle = 1; + +/// Whether to call "ui_call_grid_resize" in win_grid_alloc +static int send_grid_resize; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "screen.c.generated.h" #endif @@ -422,6 +430,7 @@ void update_screen(int type) win_redr_status(wp); } } + send_grid_resize = false; end_search_hl(); // May need to redraw the popup menu. if (pum_drawn()) { @@ -661,7 +670,7 @@ static void win_update(win_T *wp) type = wp->w_redr_type; - window_grid_alloc(wp, false); + win_grid_alloc(wp, false); if (type == NOT_VALID) { wp->w_redr_status = TRUE; @@ -2228,7 +2237,7 @@ win_line ( row = startrow; // allocate window grid if not already - window_grid_alloc(wp, true); + win_grid_alloc(wp, true); /* * To speed up the loop below, set extra_check when there is linebreak, @@ -5838,18 +5847,28 @@ int screen_valid(int doclear) /// (re)allocate a window grid if size changed /// If "doclear" is true, clear the screen if resized. // TODO(utkarshme): Think of a better name, place -void window_grid_alloc(win_T *wp, int doclear) +void win_grid_alloc(win_T *wp, int doclear) { - if (wp->w_grid.ScreenLines != NULL - && wp->w_grid.Rows == wp->w_height - && wp->w_grid.Columns == wp->w_width) { - return; - } + if (wp->w_grid.ScreenLines == NULL + || wp->w_grid.Rows != wp->w_height + || wp->w_grid.Columns != wp->w_width) { + grid_alloc(&wp->w_grid, wp->w_height, wp->w_width, doclear); + + // only assign a grid handle if not already + if (wp->w_grid.handle == 0) { + wp->w_grid.handle = ++last_handle; + } + + wp->w_grid.OffsetRow = wp->w_winrow; + wp->w_grid.OffsetColumn = wp->w_wincol; - grid_alloc(&wp->w_grid, wp->w_height, wp->w_width, doclear); + wp->w_grid.was_resized = true; + } - wp->w_grid.OffsetRow = wp->w_winrow; - wp->w_grid.OffsetColumn = wp->w_wincol; + if (send_grid_resize || wp->w_grid.was_resized) { + ui_call_grid_resize(wp->w_grid.handle, wp->w_grid.Columns, wp->w_grid.Rows); + wp->w_grid.was_resized = false; + } } /* @@ -5943,6 +5962,7 @@ void screenalloc(bool doclear) default_grid.OffsetRow = 0; default_grid.OffsetColumn = 0; + default_grid.handle = 1; must_redraw = CLEAR; /* need to clear the screen later */ if (doclear) @@ -5967,7 +5987,7 @@ void screenalloc(bool doclear) void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy) { int new_row, old_row; - ScreenGrid new = { 0 }; + ScreenGrid new = *grid; size_t ncells = (size_t)((rows+1) * columns); new.ScreenLines = xmalloc(ncells * sizeof(schar_T)); @@ -6254,7 +6274,7 @@ int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end, } } - ui_call_grid_scroll(1, row, end, col, col+width, -line_count, 0); + ui_call_grid_scroll(grid->handle, row, end, col, col+width, -line_count, 0); return OK; } @@ -6306,7 +6326,7 @@ int grid_del_lines(ScreenGrid *grid, int row, int line_count, int end, } } - ui_call_grid_scroll(1, row, end, col, col+width, line_count, 0); + ui_call_grid_scroll(grid->handle, row, end, col, col+width, line_count, 0); return OK; } @@ -7059,6 +7079,8 @@ void screen_resize(int width, int height) default_grid.Rows = screen_Rows; default_grid.Columns = screen_Columns; + send_grid_resize = true; + /* The window layout used to be adjusted here, but it now happens in * screenalloc() (also invoked from screenclear()). That is because the * "busy" check above may skip this, but not screenalloc(). */ diff --git a/src/nvim/types.h b/src/nvim/types.h index 2e6735e99dc55b..1bba8de9bb5f5d 100644 --- a/src/nvim/types.h +++ b/src/nvim/types.h @@ -39,6 +39,8 @@ typedef struct { // offsets for the grid relative to the screen int OffsetRow; int OffsetColumn; + + int was_resized; } ScreenGrid; #endif // NVIM_TYPES_H diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 816e88b0d78bc3..425ed1a1dda292 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -317,10 +317,13 @@ void ui_set_ext_option(UI *ui, UIExtension ext, bool active) void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol, int clearattr) { size_t off = grid->LineOffset[row] + (size_t)startcol; - UI_CALL(raw_line, 1, grid->OffsetRow + row, grid->OffsetColumn + startcol, - grid->OffsetColumn + endcol, grid->OffsetColumn + clearcol, - clearattr, (const schar_T *)grid->ScreenLines + off, - (const schar_T *)grid->ScreenAttrs + off); + int row_off = ui_is_external(kUIMultigrid) ? 0 : grid->OffsetRow; + int col_off = ui_is_external(kUIMultigrid) ? 0 : grid->OffsetColumn; + + UI_CALL(raw_line, grid->handle, row_off + row, col_off + startcol, + col_off + endcol, col_off + clearcol, clearattr, + (const schar_T *)grid->ScreenLines + off, + (const sattr_T *)grid->ScreenAttrs + off); if (p_wd) { // 'writedelay': flush & delay each time. int old_row = row, old_col = col; diff --git a/src/nvim/ui.h b/src/nvim/ui.h index 584d8a77c6cd68..f50865b03b176c 100644 --- a/src/nvim/ui.h +++ b/src/nvim/ui.h @@ -16,6 +16,7 @@ typedef enum { kUIWildmenu, #define kUIGlobalCount (kUIWildmenu+1) kUINewgrid, + kUIMultigrid, kUIHlState, kUIExtCount, } UIExtension; @@ -26,6 +27,7 @@ EXTERN const char *ui_ext_names[] INIT(= { "ext_tabline", "ext_wildmenu", "ext_newgrid", + "ext_multigrid", "ext_hlstate", }); diff --git a/src/nvim/window.c b/src/nvim/window.c index 218536713c48df..08bad82b178d0f 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4222,7 +4222,7 @@ void win_setheight_win(int height, win_T *win) } frame_setheight(win->w_frame, height + win->w_status_height); - window_grid_alloc(win, false); + win_grid_alloc(win, false); /* recompute the window positions */ row = win_comp_pos(); @@ -4419,7 +4419,7 @@ void win_setwidth_win(int width, win_T *wp) } frame_setwidth(wp->w_frame, width + wp->w_vsep_width); - window_grid_alloc(wp, false); + win_grid_alloc(wp, false); /* recompute the window positions */ (void)win_comp_pos();