Skip to content

Commit deaafb2

Browse files
committed
Send individual grids to UIs with event "grid_resize"
The grids get allocated a handle (very naive at the moment) and these handles are sent with every event to the external UIs. Works for one window at the moment. Use neovim/python-gui#36 to test. It currently creates separate windows for each grid. `:sp` seems to work, but `:vs` crashes.
1 parent 200166e commit deaafb2

File tree

6 files changed

+51
-22
lines changed

6 files changed

+51
-22
lines changed

src/nvim/api/ui.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -268,12 +268,12 @@ static void remote_ui_grid_resize(UI *ui, Integer grid,
268268
Integer width, Integer height)
269269
{
270270
Array args = ARRAY_DICT_INIT;
271-
if (ui->ui_ext[kUINewgrid]) {
271+
if (ui->ui_ext[kUIMultigrid]) {
272272
ADD(args, INTEGER_OBJ(grid));
273273
}
274274
ADD(args, INTEGER_OBJ(width));
275275
ADD(args, INTEGER_OBJ(height));
276-
const char *name = ui->ui_ext[kUINewgrid] ? "grid_resize" : "resize";
276+
const char *name = ui->ui_ext[kUIMultigrid] ? "grid_resize" : "resize";
277277
push_call(ui, name, args);
278278
}
279279

src/nvim/screen.c

+36-14
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,14 @@ StlClickDefinition *tab_page_click_defs = NULL;
128128

129129
long tab_page_click_defs_size = 0;
130130

131+
/// The last handle that was assigned to a ScreenGrid. 1 is reserved for
132+
/// the default_grid.
133+
/// TODO(utkarshme): Numbers can be recycled after grid destruction.
134+
static int last_handle = 1;
135+
136+
/// Whether to call "ui_call_grid_resize" in win_grid_alloc
137+
static int send_grid_resize;
138+
131139
#ifdef INCLUDE_GENERATED_DECLARATIONS
132140
# include "screen.c.generated.h"
133141
#endif
@@ -422,6 +430,7 @@ void update_screen(int type)
422430
win_redr_status(wp, true); // any popup menu will be redrawn below
423431
}
424432
}
433+
send_grid_resize = false;
425434
end_search_hl();
426435
// May need to redraw the popup menu.
427436
if (pum_drawn()) {
@@ -661,7 +670,7 @@ static void win_update(win_T *wp)
661670

662671
type = wp->w_redr_type;
663672

664-
window_grid_alloc(wp, false);
673+
win_grid_alloc(wp, false);
665674

666675
if (type == NOT_VALID) {
667676
wp->w_redr_status = TRUE;
@@ -2235,7 +2244,7 @@ win_line (
22352244
row = startrow;
22362245

22372246
// allocate window grid if not already
2238-
window_grid_alloc(wp, true);
2247+
win_grid_alloc(wp, true);
22392248

22402249
/*
22412250
* To speed up the loop below, set extra_check when there is linebreak,
@@ -5849,18 +5858,28 @@ int screen_valid(int doclear)
58495858
/// (re)allocate a window grid if size changed
58505859
/// If "doclear" is true, clear the screen if resized.
58515860
// TODO(utkarshme): Think of a better name, place
5852-
void window_grid_alloc(win_T *wp, int doclear)
5861+
void win_grid_alloc(win_T *wp, int doclear)
58535862
{
5854-
if (wp->w_grid.ScreenLines != NULL
5855-
&& wp->w_grid.Rows == wp->w_height
5856-
&& wp->w_grid.Columns == wp->w_width) {
5857-
return;
5858-
}
5863+
if (wp->w_grid.ScreenLines == NULL
5864+
|| wp->w_grid.Rows != wp->w_height
5865+
|| wp->w_grid.Columns != wp->w_width) {
5866+
grid_alloc(&wp->w_grid, wp->w_height, wp->w_width, doclear);
5867+
5868+
// only assign a grid handle if not already
5869+
if (wp->w_grid.handle == 0) {
5870+
wp->w_grid.handle = ++last_handle;
5871+
}
5872+
5873+
wp->w_grid.OffsetRow = wp->w_winrow;
5874+
wp->w_grid.OffsetColumn = wp->w_wincol;
58595875

5860-
grid_alloc(&wp->w_grid, wp->w_height, wp->w_width, doclear);
5876+
wp->w_grid.was_resized = true;
5877+
}
58615878

5862-
wp->w_grid.OffsetRow = wp->w_winrow;
5863-
wp->w_grid.OffsetColumn = wp->w_wincol;
5879+
if (send_grid_resize || wp->w_grid.was_resized) {
5880+
ui_call_grid_resize(wp->w_grid.handle, wp->w_grid.Columns, wp->w_grid.Rows);
5881+
wp->w_grid.was_resized = false;
5882+
}
58645883
}
58655884

58665885
/*
@@ -5954,6 +5973,7 @@ void screenalloc(bool doclear)
59545973

59555974
default_grid.OffsetRow = 0;
59565975
default_grid.OffsetColumn = 0;
5976+
default_grid.handle = 1;
59575977

59585978
must_redraw = CLEAR; /* need to clear the screen later */
59595979
if (doclear)
@@ -5978,7 +5998,7 @@ void screenalloc(bool doclear)
59785998
void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy)
59795999
{
59806000
int new_row, old_row;
5981-
ScreenGrid new = { 0 };
6001+
ScreenGrid new = *grid;
59826002

59836003
size_t ncells = (size_t)((rows+1) * columns);
59846004
new.ScreenLines = xmalloc(ncells * sizeof(schar_T));
@@ -6265,7 +6285,7 @@ int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end,
62656285
}
62666286
}
62676287

6268-
ui_call_grid_scroll(1, row, end, col, col+width, -line_count, 0);
6288+
ui_call_grid_scroll(grid->handle, row, end, col, col+width, -line_count, 0);
62696289

62706290
return OK;
62716291
}
@@ -6317,7 +6337,7 @@ int grid_del_lines(ScreenGrid *grid, int row, int line_count, int end,
63176337
}
63186338
}
63196339

6320-
ui_call_grid_scroll(1, row, end, col, col+width, line_count, 0);
6340+
ui_call_grid_scroll(grid->handle, row, end, col, col+width, line_count, 0);
63216341

63226342
return OK;
63236343
}
@@ -7070,6 +7090,8 @@ void screen_resize(int width, int height)
70707090
default_grid.Rows = screen_Rows;
70717091
default_grid.Columns = screen_Columns;
70727092

7093+
send_grid_resize = true;
7094+
70737095
/* The window layout used to be adjusted here, but it now happens in
70747096
* screenalloc() (also invoked from screenclear()). That is because the
70757097
* "busy" check above may skip this, but not screenalloc(). */

src/nvim/types.h

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ typedef struct {
3939
// offsets for the grid relative to the screen
4040
int OffsetRow;
4141
int OffsetColumn;
42+
43+
int was_resized;
4244
} ScreenGrid;
4345

4446
#endif // NVIM_TYPES_H

src/nvim/ui.c

+7-4
Original file line numberDiff line numberDiff line change
@@ -318,10 +318,13 @@ void ui_set_ext_option(UI *ui, UIExtension ext, bool active)
318318
void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol, int clearattr)
319319
{
320320
size_t off = grid->LineOffset[row] + (size_t)startcol;
321-
UI_CALL(raw_line, 1, grid->OffsetRow + row, grid->OffsetColumn + startcol,
322-
grid->OffsetColumn + endcol, grid->OffsetColumn + clearcol,
323-
clearattr, (const schar_T *)grid->ScreenLines + off,
324-
(const schar_T *)grid->ScreenAttrs + off);
321+
int row_off = ui_is_external(kUIMultigrid) ? 0 : grid->OffsetRow;
322+
int col_off = ui_is_external(kUIMultigrid) ? 0 : grid->OffsetColumn;
323+
324+
UI_CALL(raw_line, grid->handle, row_off + row, col_off + startcol,
325+
col_off + endcol, col_off + clearcol, clearattr,
326+
(const schar_T *)grid->ScreenLines + off,
327+
(const sattr_T *)grid->ScreenAttrs + off);
325328

326329
if (p_wd) { // 'writedelay': flush & delay each time.
327330
int old_row = row, old_col = col;

src/nvim/ui.h

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ typedef enum {
1616
kUIWildmenu,
1717
#define kUIGlobalCount (kUIWildmenu+1)
1818
kUINewgrid,
19+
kUIMultigrid,
1920
kUIHlState,
2021
kUIExtCount,
2122
} UIExtension;
@@ -26,6 +27,7 @@ EXTERN const char *ui_ext_names[] INIT(= {
2627
"ext_tabline",
2728
"ext_wildmenu",
2829
"ext_newgrid",
30+
"ext_multigrid",
2931
"ext_hlstate",
3032
});
3133

src/nvim/window.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -4235,7 +4235,7 @@ void win_setheight_win(int height, win_T *win)
42354235
}
42364236

42374237
frame_setheight(win->w_frame, height + win->w_status_height);
4238-
window_grid_alloc(win, false);
4238+
win_grid_alloc(win, false);
42394239

42404240
/* recompute the window positions */
42414241
row = win_comp_pos();
@@ -4432,7 +4432,7 @@ void win_setwidth_win(int width, win_T *wp)
44324432
}
44334433

44344434
frame_setwidth(wp->w_frame, width + wp->w_vsep_width);
4435-
window_grid_alloc(wp, false);
4435+
win_grid_alloc(wp, false);
44364436

44374437
/* recompute the window positions */
44384438
(void)win_comp_pos();

0 commit comments

Comments
 (0)