Skip to content

Commit fe14bf3

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 8c93a3e commit fe14bf3

File tree

5 files changed

+57
-27
lines changed

5 files changed

+57
-27
lines changed

src/nvim/api/ui.c

+4
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,10 @@ static void remote_ui_grid_resize(UI *ui, Integer grid,
267267
Array args = ARRAY_DICT_INIT;
268268
if (ui->ui_ext[kUINewgrid]) {
269269
ADD(args, INTEGER_OBJ(grid));
270+
} else if (grid != 1) {
271+
// calling grid_resize with a grid other than the global when
272+
// the remote ui is not managing grids should not send the event
273+
return;
270274
}
271275
ADD(args, INTEGER_OBJ(width));
272276
ADD(args, INTEGER_OBJ(height));

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
@@ -421,6 +429,7 @@ void update_screen(int type)
421429
win_redr_status(wp);
422430
}
423431
}
432+
send_grid_resize = false;
424433
end_search_hl();
425434
// May need to redraw the popup menu.
426435
if (pum_drawn()) {
@@ -653,7 +662,7 @@ static void win_update(win_T *wp)
653662

654663
type = wp->w_redr_type;
655664

656-
window_grid_alloc(wp, false);
665+
win_grid_alloc(wp, false);
657666

658667
if (type == NOT_VALID) {
659668
wp->w_redr_status = TRUE;
@@ -2219,7 +2228,7 @@ win_line (
22192228
row = startrow;
22202229

22212230
// allocate window grid if not already
2222-
window_grid_alloc(wp, true);
2231+
win_grid_alloc(wp, true);
22232232

22242233
/*
22252234
* To speed up the loop below, set extra_check when there is linebreak,
@@ -5808,18 +5817,28 @@ int screen_valid(int doclear)
58085817
/// (re)allocate a window grid if size changed
58095818
/// If "doclear" is true, clear the screen if resized.
58105819
// TODO(utkarshme): Think of a better name, place
5811-
void window_grid_alloc(win_T *wp, int doclear)
5820+
void win_grid_alloc(win_T *wp, int doclear)
58125821
{
5813-
if (wp->w_grid.ScreenLines != NULL
5814-
&& wp->w_grid.Rows == wp->w_height
5815-
&& wp->w_grid.Columns == wp->w_width) {
5816-
return;
5817-
}
5822+
if (wp->w_grid.ScreenLines == NULL
5823+
|| wp->w_grid.Rows != wp->w_height
5824+
|| wp->w_grid.Columns != wp->w_width) {
5825+
grid_alloc(&wp->w_grid, wp->w_height, wp->w_width, doclear);
5826+
5827+
// only assign a grid handle if not already
5828+
if (wp->w_grid.handle == 0) {
5829+
wp->w_grid.handle = ++last_handle;
5830+
}
5831+
5832+
wp->w_grid.OffsetRow = wp->w_winrow;
5833+
wp->w_grid.OffsetColumn = wp->w_wincol;
58185834

5819-
grid_alloc(&wp->w_grid, wp->w_height, wp->w_width, doclear);
5835+
wp->w_grid.was_resized = true;
5836+
}
58205837

5821-
wp->w_grid.OffsetRow = wp->w_winrow;
5822-
wp->w_grid.OffsetColumn = wp->w_wincol;
5838+
if (send_grid_resize || wp->w_grid.was_resized) {
5839+
ui_call_grid_resize(wp->w_grid.handle, wp->w_grid.Columns, wp->w_grid.Rows);
5840+
wp->w_grid.was_resized = false;
5841+
}
58235842
}
58245843

58255844
/*
@@ -5913,6 +5932,7 @@ void screenalloc(bool doclear)
59135932

59145933
default_grid.OffsetRow = 0;
59155934
default_grid.OffsetColumn = 0;
5935+
default_grid.handle = 1;
59165936

59175937
must_redraw = CLEAR; /* need to clear the screen later */
59185938
if (doclear)
@@ -5937,7 +5957,7 @@ void screenalloc(bool doclear)
59375957
void grid_alloc(ScreenGrid *grid, int rows, int columns, bool copy)
59385958
{
59395959
int new_row, old_row;
5940-
ScreenGrid new = { 0 };
5960+
ScreenGrid new = *grid;
59415961

59425962
size_t ncells = (size_t)((rows+1) * columns);
59435963
new.ScreenLines = xmalloc(ncells * sizeof(schar_T));
@@ -6224,7 +6244,7 @@ int grid_ins_lines(ScreenGrid *grid, int row, int line_count, int end,
62246244
}
62256245
}
62266246

6227-
ui_call_grid_scroll(1, row, end, col, col+width, -line_count, 0);
6247+
ui_call_grid_scroll(grid->handle, row, end, col, col+width, -line_count, 0);
62286248

62296249
return OK;
62306250
}
@@ -6276,7 +6296,7 @@ int grid_del_lines(ScreenGrid *grid, int row, int line_count, int end,
62766296
}
62776297
}
62786298

6279-
ui_call_grid_scroll(1, row, end, col, col+width, line_count, 0);
6299+
ui_call_grid_scroll(grid->handle, row, end, col, col+width, line_count, 0);
62806300

62816301
return OK;
62826302
}
@@ -7019,6 +7039,8 @@ void screen_resize(int width, int height)
70197039
default_grid.Rows = screen_Rows;
70207040
default_grid.Columns = screen_Columns;
70217041

7042+
send_grid_resize = true;
7043+
70227044
// TODO(bfredl): update default colors when they changed, NOT on resize.
70237045
ui_default_colors_set();
70247046

src/nvim/types.h

+5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ typedef char_u schar_T[(MAX_MCO+1) * 4 + 1];
2323
typedef int16_t sattr_T;
2424

2525
// TODO(bfredl): find me a good home
26+
typedef unsigned int GridHandle;
2627
typedef struct {
28+
GridHandle handle;
29+
2730
schar_T *ScreenLines;
2831
sattr_T *ScreenAttrs;
2932
unsigned *LineOffset;
@@ -36,6 +39,8 @@ typedef struct {
3639
// offsets for the grid relative to the screen
3740
int OffsetRow;
3841
int OffsetColumn;
42+
43+
int was_resized;
3944
} ScreenGrid;
4045

4146
#endif // NVIM_TYPES_H

src/nvim/ui.c

+10-11
Original file line numberDiff line numberDiff line change
@@ -314,17 +314,16 @@ void ui_set_ext_option(UI *ui, UIExtension ext, bool active)
314314

315315
void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol, int clearattr)
316316
{
317-
size_t off = grid->LineOffset[row] + (size_t)startcol;
318-
319-
UI_CALL(raw_line, 1,
320-
grid->OffsetRow + row,
321-
grid->OffsetColumn + startcol,
322-
grid->OffsetColumn + endcol,
323-
grid->OffsetColumn + clearcol,
324-
clearattr,
325-
grid->ScreenLines + off,
326-
grid->ScreenAttrs + off);
327-
317+
size_t off = grid->LineOffset[row] + (size_t)startcol;
318+
int row_off = ui_is_external(kUIMultigrid) ? 0 : grid->OffsetRow;
319+
int col_off = ui_is_external(kUIMultigrid) ? 0 : grid->OffsetColumn;
320+
321+
UI_CALL(raw_line, grid->handle,
322+
row_off + row,
323+
col_off + startcol,
324+
col_off + endcol,
325+
col_off + clearcol,
326+
clearattr, grid->ScreenLines + off, grid->ScreenAttrs + off);
328327
if (p_wd) { // 'writedelay': flush & delay each time.
329328
ui_flush();
330329
uint64_t wd = (uint64_t)labs(p_wd);

src/nvim/window.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -4222,7 +4222,7 @@ void win_setheight_win(int height, win_T *win)
42224222
}
42234223

42244224
frame_setheight(win->w_frame, height + win->w_status_height);
4225-
window_grid_alloc(win, false);
4225+
win_grid_alloc(win, false);
42264226

42274227
/* recompute the window positions */
42284228
row = win_comp_pos();
@@ -4419,7 +4419,7 @@ void win_setwidth_win(int width, win_T *wp)
44194419
}
44204420

44214421
frame_setwidth(wp->w_frame, width + wp->w_vsep_width);
4422-
window_grid_alloc(wp, false);
4422+
win_grid_alloc(wp, false);
44234423

44244424
/* recompute the window positions */
44254425
(void)win_comp_pos();

0 commit comments

Comments
 (0)