From 506dd7252a8c70785650640c8db9595f152137ed Mon Sep 17 00:00:00 2001 From: Sean Dewar <6256228+seandewar@users.noreply.github.com> Date: Wed, 4 Feb 2026 22:43:21 +0000 Subject: [PATCH] fix(ui): remember cursor shape when obscured #37704 Problem: a2b92a5efbb4159d15311f015bb270f80de42e3a is regressive if the ui_mode_idx set by ui_cursor_shape differs from what ui_flush later sets it to. (e.g: if mode changes between both calls) Solution: Don't overwrite ui_mode_idx to obscure the cursor so that we don't forget what shape was last set by ui_cursor_shape. May not be needed, but does fix a potential regression. (and makes it easier to set ui_mode_idx to something other than cursor_get_mode_idx's retval in other places, if that's ever wanted) --- src/nvim/ui.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 8ae16dd399..27521610e5 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -571,17 +571,6 @@ void ui_flush(void) // by nvim core, not the compositor) win_ui_flush(false); } - - // Show "empty box" (underline style) cursor if behind a floatwin. - if (!(State & MODE_CMDLINE)) { - bool cursor_obscured = ui_cursor_is_behind_floatwin(); - int new_idx = cursor_obscured ? SHAPE_IDX_R : cursor_get_mode_idx(); - if (ui_mode_idx != new_idx) { - ui_mode_idx = new_idx; - pending_mode_update = true; - } - } - if (pending_mode_info_update) { Arena arena = ARENA_EMPTY; Array style = mode_style_array(&arena); @@ -590,11 +579,18 @@ void ui_flush(void) arena_mem_free(arena_finish(&arena)); pending_mode_info_update = false; } - if (pending_mode_update && !starting) { - char *full_name = shape_table[ui_mode_idx].full_name; - ui_call_mode_change(cstr_as_string(full_name), ui_mode_idx); + + static bool cursor_was_obscured = false; + bool cursor_obscured = ui_cursor_is_behind_floatwin(); + if ((cursor_obscured != cursor_was_obscured || pending_mode_update) && !starting) { + // Show "empty box" (underline style) cursor instead if behind a floatwin. + int idx = cursor_obscured ? SHAPE_IDX_R : ui_mode_idx; + char *full_name = shape_table[idx].full_name; + ui_call_mode_change(cstr_as_string(full_name), idx); pending_mode_update = false; + cursor_was_obscured = cursor_obscured; } + if (pending_has_mouse != has_mouse) { (has_mouse ? ui_call_mouse_on : ui_call_mouse_off)(); pending_has_mouse = has_mouse; @@ -689,7 +685,7 @@ void ui_cursor_shape(void) /// @return true if cursor is obscured by a float with higher zindex static bool ui_cursor_is_behind_floatwin(void) { - if (!ui_comp_should_draw()) { + if ((State & MODE_CMDLINE) || !ui_comp_should_draw()) { return false; }