Repository: neovim/neovim
File: src/nvim/ui.c (C)

Code before:
    return;
  }

  static bool was_busy = false;

  if (!(State & MODE_CMDLINE)) {
    if (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;
      }

      int crow = curwin->w_winrow + curwin->w_wrow;
      int ccol = curwin->w_wincol + curwin->w_wcol;
      ScreenGrid *top_grid = ui_comp_get_grid_at_coord(crow, ccol);
      win_T *wp = (top_grid && top_grid != &curwin->w_grid_alloc && top_grid != &default_grid)
                  ? get_win_by_grid_handle(top_grid->handle) : NULL;

      int cur_z = curwin->w_floating ? curwin->w_config.zindex : 0;
      bool cursor_obscured = wp && wp->w_floating && !wp->w_config.hide
                             && wp->w_config.zindex > cur_z;
      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;
      }
    }
  } else if (was_busy) {
    ui_call_busy_stop();
    was_busy = false;
  }

  win_ui_flush(false);
  // Avoid flushing callbacks expected to change text during textlock.
  if (textlock == 0 && expr_map_lock == 0) {
    cmdline_ui_flush();
    msg_ext_ui_flush();
  }
  msg_scroll_flush();

  if (pending_cursor_update) {
    ui_call_grid_cursor_goto(cursor_grid_handle, cursor_row, cursor_col);
    pending_cursor_update = false;
    // The cursor move might change the composition order,
    // so flush again to update the windows that changed
    // TODO(bfredl): refactor the flow of information so that win_ui_flush()

Review comment (suggestion):
Hmm, I'm not totally sure (and I don't have a repro for this), but until `ui_ext_win_position` is called (via `win_ui_flush`), maybe it's possible for a hidden float's grid to still be in `layers`? If that happens, the cursor may be considered unobscured despite being behind another non-hidden float that's behind the hidden float.

Might want to move cursor visibility handling until after the `win_ui_flush`es below this stuff?
That should also mean the check for `w_config.hide` can be removed.

Code after:
    return;
  }

  static bool was_busy = false;

  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);
  // Avoid flushing callbacks expected to change text during textlock.
  if (textlock == 0 && expr_map_lock == 0) {
    cmdline_ui_flush();
    msg_ext_ui_flush();
  }
  msg_scroll_flush();

  if (pending_cursor_update) {
    ui_call_grid_cursor_goto(cursor_grid_handle, cursor_row, cursor_col);
    pending_cursor_update = false;
    // The cursor move might change the composition order,
    // so flush again to update the windows that changed
    // TODO(bfredl): refactor the flow of information so that win_ui_flush()
    // only is called once. (as order state is exposed, it should be owned
    // 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);
    bool enabled = (*p_guicursor != NUL);
    ui_call_mode_info_set(enabled, style);
    arena_mem_free(arena_finish(&arena));
    pending_mode_info_update = false;