diff options
author | bfredl <bjorn.linse@gmail.com> | 2024-03-28 15:27:32 +0100 |
---|---|---|
committer | bfredl <bjorn.linse@gmail.com> | 2024-03-29 08:15:28 +0100 |
commit | 2e4e12756a697d4767ec294e1f268384395e7a7f (patch) | |
tree | 5dc431001eefa5e4dc26651eea1e7c1dcd093f76 | |
parent | e2224a7933b6e30ab6efb0b7ad4e3f26da57c226 (diff) | |
download | rneovim-2e4e12756a697d4767ec294e1f268384395e7a7f.tar.gz rneovim-2e4e12756a697d4767ec294e1f268384395e7a7f.tar.bz2 rneovim-2e4e12756a697d4767ec294e1f268384395e7a7f.zip |
feat(ui): indicate margins for the area used by win_viewport
Problem: using win_viewport for implementing smooth scrolling in an external
UI might run into problems when winbar or borders is used, as there is
no indication that the entire grid is not used for scrolled buffer text.
Solution: add `win_viewport_margins` event.
-rw-r--r-- | runtime/doc/ui.txt | 5 | ||||
-rw-r--r-- | src/nvim/api/ui_events.in.h | 4 | ||||
-rw-r--r-- | src/nvim/window.c | 7 | ||||
-rw-r--r-- | test/functional/ui/float_spec.lua | 26 | ||||
-rw-r--r-- | test/functional/ui/multigrid_spec.lua | 9 | ||||
-rw-r--r-- | test/functional/ui/screen.lua | 19 |
6 files changed, 68 insertions, 2 deletions
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 |