fix(float): cursor visible in "hidden" floating window #30866

Problem:
Cursor is visible in "hidden" floating window.

Solution:
Hide cursor when curwin is a hidden floating window.
Show cursor after returning to a normal (non-hidden) window.
This commit is contained in:
glepnir
2025-04-23 20:22:43 +08:00
committed by GitHub
parent 70d7979439
commit d4f2b9050d
5 changed files with 225 additions and 3 deletions

View File

@@ -3554,7 +3554,8 @@ nvim_open_win({buffer}, {enter}, {config}) *nvim_open_win()*
the duration of the call. the duration of the call.
• fixed: If true when anchor is NW or SW, the float window • fixed: If true when anchor is NW or SW, the float window
would be kept fixed even if the window would be truncated. would be kept fixed even if the window would be truncated.
• hide: If true the floating window will be hidden. • hide: If true the floating window will be hidden and the
cursor will be invisible when focused on it.
• vertical: Split vertically |:vertical|. • vertical: Split vertically |:vertical|.
• split: Split direction: "left", "right", "above", "below". • split: Split direction: "left", "right", "above", "below".

View File

@@ -1848,7 +1848,8 @@ function vim.api.nvim_open_term(buffer, opts) end
--- the call. --- the call.
--- - fixed: If true when anchor is NW or SW, the float window --- - fixed: If true when anchor is NW or SW, the float window
--- would be kept fixed even if the window would be truncated. --- would be kept fixed even if the window would be truncated.
--- - hide: If true the floating window will be hidden. --- - hide: If true the floating window will be hidden and the cursor will be invisible when
--- focused on it.
--- - vertical: Split vertically `:vertical`. --- - vertical: Split vertically `:vertical`.
--- - split: Split direction: "left", "right", "above", "below". --- - split: Split direction: "left", "right", "above", "below".
--- @return integer # |window-ID|, or 0 on error --- @return integer # |window-ID|, or 0 on error

View File

@@ -201,7 +201,8 @@
/// the call. /// the call.
/// - fixed: If true when anchor is NW or SW, the float window /// - fixed: If true when anchor is NW or SW, the float window
/// would be kept fixed even if the window would be truncated. /// would be kept fixed even if the window would be truncated.
/// - hide: If true the floating window will be hidden. /// - hide: If true the floating window will be hidden and the cursor will be invisible when
/// focused on it.
/// - vertical: Split vertically |:vertical|. /// - vertical: Split vertically |:vertical|.
/// - split: Split direction: "left", "right", "above", "below". /// - split: Split direction: "left", "right", "above", "below".
/// ///

View File

@@ -539,7 +539,21 @@ void ui_flush(void)
if (!ui_active()) { if (!ui_active()) {
return; return;
} }
static bool was_busy = false;
cmdline_ui_flush(); cmdline_ui_flush();
if (State != MODE_CMDLINE && curwin->w_floating && curwin->w_config.hide) {
if (!was_busy) {
ui_call_busy_start();
was_busy = true;
}
} else if (was_busy) {
ui_call_busy_stop();
was_busy = false;
}
win_ui_flush(false); win_ui_flush(false);
msg_ext_ui_flush(); msg_ext_ui_flush();
msg_scroll_flush(); msg_scroll_flush();

View File

@@ -9585,6 +9585,211 @@ describe('float window', function()
| |
]]) ]])
end end
--
-- Cursor visibility:
--
-- Cursor is not visible in a hide=true floating window.
api.nvim_set_current_win(win)
if multigrid then
screen:expect({
grid = [[
## grid 1
[2:----------------------------------------]|*6
[3:----------------------------------------]|
## grid 2
|
{0:~ }|*5
## grid 3
|
## grid 4 (hidden)
{1: }|
{2:~ }|
]], 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] = {
bottom = 0,
left = 0,
right = 0,
top = 0,
win = 1000
},
[4] = {
bottom = 0,
left = 0,
right = 0,
top = 0,
win = 1001
}
}
})
else
screen:expect({
grid = [[
|
{0:~ }|*5
|
]]
})
end
-- Show cursor if cmdline is entered while curwin is a hide=true floating window.
feed(':')
if multigrid then
screen:expect({
grid = [[
## grid 1
[2:----------------------------------------]|*6
[3:----------------------------------------]|
## grid 2
|
{0:~ }|*5
## grid 3
:^ |
## grid 4 (hidden)
{1: }|
{2:~ }|
]], 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] = {
bottom = 0,
left = 0,
right = 0,
top = 0,
win = 1000
},
[4] = {
bottom = 0,
left = 0,
right = 0,
top = 0,
win = 1001
}
}
})
else
screen:expect({
grid = [[
|
{0:~ }|*5
:^ |
]]
})
end
feed('<ESC>')
-- Show cursor after switching to a normal window (hide=false).
api.nvim_set_current_win(cwin)
if multigrid then
screen:expect({
grid = [[
## grid 1
[2:----------------------------------------]|*6
[3:----------------------------------------]|
## grid 2
^ |
{0:~ }|*5
## grid 3
|
## grid 4 (hidden)
{1: }|
{2:~ }|
]], 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] = {
bottom = 0,
left = 0,
right = 0,
top = 0,
win = 1000
},
[4] = {
bottom = 0,
left = 0,
right = 0,
top = 0,
win = 1001
}
}
})
else
screen:expect({
grid = [[
^ |
{0:~ }|*5
|
]]
})
end
api.nvim_set_current_win(win)
local win1 = api.nvim_open_win(buf, false, {relative='editor', width=4, height=4, row=1, col=2})
api.nvim_set_current_win(win1)
if multigrid then
screen:expect({
grid = [[
## grid 1
[2:----------------------------------------]|*6
[3:----------------------------------------]|
## grid 2
|
{0:~ }|*5
## grid 3
|
## grid 4 (hidden)
{1: }|
{2:~ }|
## grid 5
{1:^ }|
{2:~ }|*3
]], float_pos={
[5] = {1002, "NW", 1, 1, 2, true, 50, 1, 1, 2};
}, 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};
[5] = {win = 1002, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0};
}, win_viewport_margins={
[2] = {
bottom = 0,
left = 0,
right = 0,
top = 0,
win = 1000
},
[4] = {
bottom = 0,
left = 0,
right = 0,
top = 0,
win = 1001
},
[5] = {
bottom = 0,
left = 0,
right = 0,
top = 0,
win = 1002
}
}
})
else
screen:expect({
grid = [[
|
{0:~ }{1:^ }{0: }|
{0:~ }{2:~ }{0: }|*3
{0:~ }|
|
]]
})
end
api.nvim_win_close(win1, true)
-- check window jump with hide -- check window jump with hide
feed('<C-W><C-W>') feed('<C-W><C-W>')
-- should keep on current window -- should keep on current window