From 089c415cb236512add6c29372e26640ff401d39b Mon Sep 17 00:00:00 2001 From: tianrking <10758833+tianrking@users.noreply.github.com> Date: Tue, 28 Jul 2026 19:32:35 +0800 Subject: [PATCH] fix(floatwin): relative='cursor' may use outdated cursor position #40768 Problem: Cursor-relative floats can use stale screen coordinates after a cursor move is restored without a redraw. Solution: Validate the current cursor before converting cursor-relative coordinates. Co-authored-by: zeertzjq --- src/nvim/winfloat.c | 1 + test/functional/ui/float_spec.lua | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/nvim/winfloat.c b/src/nvim/winfloat.c index 6992a7e71d..b5b15e1c9b 100644 --- a/src/nvim/winfloat.c +++ b/src/nvim/winfloat.c @@ -202,6 +202,7 @@ void win_config_float(win_T *wp, WinConfig fconfig) wp->w_height = MAX(fconfig.height, 1); if (fconfig.relative == kFloatRelativeCursor) { + validate_cursor(curwin); fconfig.relative = kFloatRelativeWindow; fconfig.row += curwin->w_wrow; fconfig.col += curwin->w_wcol; diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index 827c5066b8..ce59c22690 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -357,12 +357,23 @@ describe('float window', function() it('opened with correct position relative to the cursor', function() local pos = exec_lua([[ + local lines = {} + for _ = 1, 100 do lines[#lines + 1] = 'foo' end + vim.api.nvim_buf_set_lines(0, 0, -1, false, lines) + vim.api.nvim_win_set_cursor(0, { 50, 0 }) + vim.cmd('normal! zz') + + local view = vim.fn.winsaveview() + vim.api.nvim_win_set_cursor(0, { 1, 0 }) + vim.fn.winrestview(view) + local bufnr = vim.api.nvim_create_buf(false, true) local opts = { width = 10, height = 10, col = 7, row = 9, relative = 'cursor', style = 'minimal' } local win_id = vim.api.nvim_open_win(bufnr, false, opts) - return vim.api.nvim_win_get_position(win_id) + return { vim.api.nvim_win_get_position(win_id), vim.fn.winline() - 1 } ]]) - eq({ 9, 7 }, { pos[1], pos[2] }) + eq(pos[2] + 9, pos[1][1]) + eq(7, pos[1][2]) end) it('opened with correct position relative to another window', function()