commit 1999c4cdc11c530be272d192c5b435a95cb6ba3b
parent dd18ab169128a5bb620c04089eff78ee83ed14a5
Author: fredizzimo <fsundvik@gmail.com>
Date: Sat, 26 Apr 2025 23:39:12 +0300
fix: screenchar()/screenstring() with multigrid #32494
Problem:
- When multigrid is enabled, screenchar()/screenstring() functions return wrong
results. See https://github.com/neovide/neovide/issues/2569
- `screenstring()` executed via RPC in child Nvim process, doesn't recognize
floating windows.
Solution:
In ui_comp_get_grid_at_coord(), also iterate window grids.
Diffstat:
2 files changed, 52 insertions(+), 33 deletions(-)
diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c
@@ -333,6 +333,14 @@ ScreenGrid *ui_comp_get_grid_at_coord(int row, int col)
return grid;
}
}
+
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ ScreenGrid *grid = &wp->w_grid_alloc;
+ if (row >= grid->comp_row && row < grid->comp_row + grid->rows
+ && col >= grid->comp_col && col < grid->comp_col + grid->cols) {
+ return grid;
+ }
+ }
return &default_grid;
}
diff --git a/test/functional/vimscript/screenchar_spec.lua b/test/functional/vimscript/screenchar_spec.lua
@@ -1,5 +1,6 @@
local t = require('test.testutil')
local n = require('test.functional.testnvim')()
+local Screen = require('test.functional.ui.screen')
local clear, eq, neq = n.clear, t.eq, t.neq
local command, api, fn = n.command, n.api, n.fn
@@ -30,42 +31,52 @@ local setup_floating_windows = function()
end
describe('screenchar() and family respect floating windows', function()
- before_each(function()
- clear()
- -- These commands result into visible text `aabc`.
- -- `aab` - from floating windows, `c` - from text in regular window.
- api.nvim_buf_set_lines(0, 0, -1, true, { 'cccc' })
- setup_floating_windows()
- end)
+ local function with_ext_multigrid(multigrid)
+ before_each(function()
+ clear()
+ Screen.new(40, 7, { ext_multigrid = multigrid })
+ -- These commands result into visible text `aabc`.
+ -- `aab` - from floating windows, `c` - from text in regular window.
+ api.nvim_buf_set_lines(0, 0, -1, true, { 'cccc' })
+ setup_floating_windows()
+ end)
- it('screenattr()', function()
- local attr_1 = fn.screenattr(1, 1)
- local attr_2 = fn.screenattr(1, 2)
- local attr_3 = fn.screenattr(1, 3)
- local attr_4 = fn.screenattr(1, 4)
- eq(attr_1, attr_2)
- eq(attr_1, attr_3)
- neq(attr_1, attr_4)
- end)
+ it('screenattr()', function()
+ local attr_1 = fn.screenattr(1, 1)
+ local attr_2 = fn.screenattr(1, 2)
+ local attr_3 = fn.screenattr(1, 3)
+ local attr_4 = fn.screenattr(1, 4)
+ eq(attr_1, attr_2)
+ eq(attr_1, attr_3)
+ neq(attr_1, attr_4)
+ end)
- it('screenchar()', function()
- eq(97, fn.screenchar(1, 1))
- eq(97, fn.screenchar(1, 2))
- eq(98, fn.screenchar(1, 3))
- eq(99, fn.screenchar(1, 4))
- end)
+ it('screenchar()', function()
+ eq(97, fn.screenchar(1, 1))
+ eq(97, fn.screenchar(1, 2))
+ eq(98, fn.screenchar(1, 3))
+ eq(99, fn.screenchar(1, 4))
+ end)
- it('screenchars()', function()
- eq({ 97 }, fn.screenchars(1, 1))
- eq({ 97 }, fn.screenchars(1, 2))
- eq({ 98 }, fn.screenchars(1, 3))
- eq({ 99 }, fn.screenchars(1, 4))
- end)
+ it('screenchars()', function()
+ eq({ 97 }, fn.screenchars(1, 1))
+ eq({ 97 }, fn.screenchars(1, 2))
+ eq({ 98 }, fn.screenchars(1, 3))
+ eq({ 99 }, fn.screenchars(1, 4))
+ end)
+
+ it('screenstring()', function()
+ eq('a', fn.screenstring(1, 1))
+ eq('a', fn.screenstring(1, 2))
+ eq('b', fn.screenstring(1, 3))
+ eq('c', fn.screenstring(1, 4))
+ end)
+ end
- it('screenstring()', function()
- eq('a', fn.screenstring(1, 1))
- eq('a', fn.screenstring(1, 2))
- eq('b', fn.screenstring(1, 3))
- eq('c', fn.screenstring(1, 4))
+ describe('with ext_multigrid', function()
+ with_ext_multigrid(true)
+ end)
+ describe('without ext_multigrid', function()
+ with_ext_multigrid(false)
end)
end)