diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt index b8d47923ca..5f217c5537 100644 --- a/runtime/doc/ui.txt +++ b/runtime/doc/ui.txt @@ -656,6 +656,11 @@ tabs. the screen and copy it to the viewport destination once `win_viewport` is received. +["win_viewport_margins", grid, win, top, bottom, left, right] ~ + Indicates the margins of a window grid which are _not_ part of the + viewport as indicated by the `win_viewport` event. This happens + e.g. in the presence of 'winbar' and floating window borders. + ["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/api/ui_events.in.h b/src/nvim/api/ui_events.in.h index c2f02c34f8..2bd8792d71 100644 --- a/src/nvim/api/ui_events.in.h +++ b/src/nvim/api/ui_events.in.h @@ -118,6 +118,10 @@ void win_viewport(Integer grid, Window win, Integer topline, Integer botline, In Integer curcol, Integer line_count, Integer scroll_delta) FUNC_API_SINCE(7) FUNC_API_CLIENT_IGNORE; +void win_viewport_margins(Integer grid, Window win, Integer top, Integer bottom, Integer left, + Integer right) + FUNC_API_SINCE(12) FUNC_API_CLIENT_IGNORE; + void win_extmark(Integer grid, Window win, Integer ns_id, Integer mark_id, Integer row, Integer col) FUNC_API_SINCE(10) FUNC_API_REMOTE_ONLY; diff --git a/src/nvim/window.c b/src/nvim/window.c index c9c2124730..6d85e088b5 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -6744,6 +6744,13 @@ void win_set_inner_size(win_T *wp, bool valid_cursor) wp->w_width_outer = (wp->w_width_inner + win_border_width(wp)); wp->w_winrow_off = wp->w_border_adj[0] + wp->w_winbar_height; wp->w_wincol_off = wp->w_border_adj[3]; + + if (ui_has(kUIMultigrid)) { + ui_call_win_viewport_margins(wp->w_grid_alloc.handle, wp->handle, + wp->w_winrow_off, wp->w_border_adj[2], + wp->w_wincol_off, wp->w_border_adj[1]); + } + wp->w_redr_status = true; } diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index 361ea3e778..e83f3ff57e 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -1536,7 +1536,12 @@ describe('float window', function() }, win_viewport={ [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; - }} + }, + win_viewport_margins={ + [2] = {win = 1000, top = 0, bottom = 0, left = 0, right = 0}; + [4] = {win = 1001, top = 1, bottom = 1, left = 1, right = 1}; + } + } else screen:expect{grid=[[ ^ | @@ -1736,7 +1741,12 @@ describe('float window', function() }, win_viewport={ [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; - }} + }, + win_viewport_margins={ + [2] = {win = 1000, top = 0, bottom = 0, left = 0, right = 0}; + [4] = {win = 1001, top = 0, bottom = 0, left = 1, right = 1}; + } + } else screen:expect{grid=[[ ^ | @@ -1769,6 +1779,10 @@ describe('float window', function() }, win_viewport={ [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + }, + win_viewport_margins={ + [2] = {win = 1000, top = 0, bottom = 0, left = 0, right = 0}; + [4] = {win = 1001, top = 1, bottom = 1, left = 0, right = 0}; }} else screen:expect{grid=[[ @@ -1814,6 +1828,10 @@ describe('float window', function() }, win_viewport={ [2] = {win = 1000, topline = 0, botline = 6, curline = 5, curcol = 0, linecount = 6, sum_scroll_delta = 0}; [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0}; + }, + win_viewport_margins={ + [2] = {win = 1000, top = 0, bottom = 0, left = 0, right = 0}; + [4] = {win = 1001, top = 0, bottom = 1, left = 0, right = 1}; }} else screen:expect{grid=[[ @@ -8361,6 +8379,10 @@ describe('float window', function() }, win_viewport={ [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + }, + win_viewport_margins={ + [2] = {win = 1000, top = 0, bottom = 0, left = 0, right = 0}; + [4] = {win = 1001, top = 2, bottom = 1, left = 1, right = 1}; }} else screen:expect{grid=[[ diff --git a/test/functional/ui/multigrid_spec.lua b/test/functional/ui/multigrid_spec.lua index 4b11a881ed..bb490546f6 100644 --- a/test/functional/ui/multigrid_spec.lua +++ b/test/functional/ui/multigrid_spec.lua @@ -2354,6 +2354,9 @@ describe('ext_multigrid', function() ]], win_viewport={ [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + }, win_viewport_margins={ + [2] = {win = 1000, top = 0, bottom = 0, left = 0, right = 0}; + [4] = {win = 1001, top = 0, bottom = 0, left = 0, right = 0}; }} -- XXX: hack to get notifications. Could use next_msg() also. @@ -2384,6 +2387,9 @@ describe('ext_multigrid', function() ]], win_viewport={ [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + }, win_viewport_margins={ + [2] = {win = 1000, top = 0, bottom = 0, left = 0, right = 0}; + [4] = {win = 1001, top = 1, bottom = 0, left = 0, right = 0}; }} eq({}, win_pos) @@ -2406,6 +2412,9 @@ describe('ext_multigrid', function() ]], win_viewport={ [2] = {win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; [4] = {win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0}; + }, win_viewport_margins={ + [2] = {win = 1000, top = 0, bottom = 0, left = 0, right = 0}; + [4] = {win = 1001, top = 0, bottom = 0, left = 0, right = 0}; }} eq({}, win_pos) end) diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua index d741b440c5..ee9334a9fe 100644 --- a/test/functional/ui/screen.lua +++ b/test/functional/ui/screen.lua @@ -204,6 +204,7 @@ function Screen.new(width, height) wildmenu_selected = nil, win_position = {}, win_viewport = {}, + win_viewport_margins = {}, float_pos = {}, msg_grid = nil, msg_grid_pos = nil, @@ -337,6 +338,7 @@ local ext_keys = { 'ruler', 'float_pos', 'win_viewport', + 'win_viewport_margins', } local expect_keys = { @@ -621,6 +623,9 @@ screen:redraw_debug() to show all intermediate screen states.]] if expected.win_viewport == nil then extstate.win_viewport = nil end + if expected.win_viewport_margins == nil then + extstate.win_viewport_margins = nil + end if expected.float_pos then expected.float_pos = deepcopy(expected.float_pos) @@ -993,6 +998,7 @@ function Screen:_handle_grid_destroy(grid) if self._options.ext_multigrid then self.win_position[grid] = nil self.win_viewport[grid] = nil + self.win_viewport_margins[grid] = nil end end @@ -1048,6 +1054,16 @@ function Screen:_handle_win_viewport( } end +function Screen:_handle_win_viewport_margins(grid, win, top, bottom, left, right) + self.win_viewport_margins[grid] = { + win = win, + top = top, + bottom = bottom, + left = left, + right = right, + } +end + function Screen:_handle_win_float_pos(grid, ...) self.win_position[grid] = nil self.float_pos[grid] = { ... } @@ -1466,6 +1482,8 @@ function Screen:_extstate_repr(attr_state) end local win_viewport = (next(self.win_viewport) and self.win_viewport) or nil + local win_viewport_margins = (next(self.win_viewport_margins) and self.win_viewport_margins) + or nil return { popupmenu = self.popupmenu, @@ -1480,6 +1498,7 @@ function Screen:_extstate_repr(attr_state) msg_history = msg_history, float_pos = self.float_pos, win_viewport = win_viewport, + win_viewport_margins = win_viewport_margins, } end