diff options
author | Famiu Haque <famiuhaque@protonmail.com> | 2022-07-15 22:15:02 +0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-15 09:15:02 -0700 |
commit | 6645f59832682e9a3623c2b1e45369529bef201a (patch) | |
tree | c0635d300fbf6c64d05f9380b6ce3999736c0d8f /src | |
parent | 5c49129c5e334a9c7da253499cd9aa19358d4ac9 (diff) | |
download | rneovim-6645f59832682e9a3623c2b1e45369529bef201a.tar.gz rneovim-6645f59832682e9a3623c2b1e45369529bef201a.tar.bz2 rneovim-6645f59832682e9a3623c2b1e45369529bef201a.zip |
fix: right-click in clickable statusline #19252
Problem:
1. Right-click does not work in statusline unless you left-click first (to focus
the statusline).
2. Modifier (e.g. shift+rightclick) does not work in statusline.
Solution:
Make clickable statusline sections receive right-clicks regardless of whether
the statusline is focused.
Closes #18994
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/mouse.c | 102 |
1 files changed, 68 insertions, 34 deletions
diff --git a/src/nvim/mouse.c b/src/nvim/mouse.c index 2ea108d3df..a4a521fa80 100644 --- a/src/nvim/mouse.c +++ b/src/nvim/mouse.c @@ -128,8 +128,10 @@ bool is_mouse_key(int c) /// @param which_button MOUSE_LEFT, MOUSE_RIGHT, MOUSE_MIDDLE int jump_to_mouse(int flags, bool *inclusive, int which_button) { - static int on_status_line = 0; // #lines below bottom of window - static int on_sep_line = 0; // on separator right of window + static int status_line_offset = 0; // #lines offset from status line + static int sep_line_offset = 0; // #cols offset from sep line + static bool on_status_line = false; + static bool on_sep_line = false; static bool on_winbar = false; static int prev_row = -1; static int prev_col = -1; @@ -144,6 +146,7 @@ int jump_to_mouse(int flags, bool *inclusive, int which_button) int col = mouse_col; int grid = mouse_grid; int fdc = 0; + bool keep_focus = flags & MOUSE_FOCUS; mouse_past_bottom = false; mouse_past_eol = false; @@ -164,10 +167,10 @@ int jump_to_mouse(int flags, bool *inclusive, int which_button) retnomove: // before moving the cursor for a left click which is NOT in a status // line, stop Visual mode - if (on_status_line) { + if (status_line_offset) { return IN_STATUS_LINE; } - if (on_sep_line) { + if (sep_line_offset) { return IN_SEP_LINE; } if (on_winbar) { @@ -189,49 +192,78 @@ retnomove: old_curwin = curwin; old_cursor = curwin->w_cursor; - if (!(flags & MOUSE_FOCUS)) { - if (row < 0 || col < 0) { // check if it makes sense - return IN_UNKNOWN; + if (row < 0 || col < 0) { // check if it makes sense + return IN_UNKNOWN; + } + + // find the window where the row is in + wp = mouse_find_win(&grid, &row, &col); + if (wp == NULL) { + return IN_UNKNOWN; + } + + on_status_line = (grid == DEFAULT_GRID_HANDLE && row + wp->w_winbar_height >= wp->w_height) + ? row + wp->w_winbar_height - wp->w_height + 1 == 1 + : false; + + on_winbar = (row == -1) + ? wp->w_winbar_height != 0 + : false; + + on_sep_line = grid == DEFAULT_GRID_HANDLE && col >= wp->w_width + ? col - wp->w_width + 1 == 1 + : false; + + // The rightmost character of the status line might be a vertical + // separator character if there is no connecting window to the right. + if (on_status_line && on_sep_line) { + if (stl_connected(wp)) { + on_sep_line = false; + } else { + on_status_line = false; } + } - // find the window where the row is in - wp = mouse_find_win(&grid, &row, &col); - if (wp == NULL) { - return IN_UNKNOWN; + if (keep_focus) { + // If we can't change focus, set the value of row, col and grid back to absolute values + // since the values relative to the window are only used when keep_focus is false + row = mouse_row; + col = mouse_col; + grid = mouse_grid; + } + + if (!keep_focus) { + if (on_winbar) { + return IN_OTHER_WIN | MOUSE_WINBAR; } + fdc = win_fdccol_count(wp); dragwin = NULL; - if (row == -1) { - on_winbar = wp->w_winbar_height != 0; - return IN_OTHER_WIN | (on_winbar ? MOUSE_WINBAR : 0); - } - on_winbar = false; - // winpos and height may change in win_enter()! if (grid == DEFAULT_GRID_HANDLE && row + wp->w_winbar_height >= wp->w_height) { // In (or below) status line - on_status_line = row + wp->w_winbar_height - wp->w_height + 1; + status_line_offset = row + wp->w_winbar_height - wp->w_height + 1; dragwin = wp; } else { - on_status_line = 0; + status_line_offset = 0; } if (grid == DEFAULT_GRID_HANDLE && col >= wp->w_width) { // In separator line - on_sep_line = col - wp->w_width + 1; + sep_line_offset = col - wp->w_width + 1; dragwin = wp; } else { - on_sep_line = 0; + sep_line_offset = 0; } // The rightmost character of the status line might be a vertical // separator character if there is no connecting window to the right. - if (on_status_line && on_sep_line) { + if (status_line_offset && sep_line_offset) { if (stl_connected(wp)) { - on_sep_line = 0; + sep_line_offset = 0; } else { - on_status_line = 0; + status_line_offset = 0; } } @@ -239,8 +271,8 @@ retnomove: // click, stop Visual mode. if (VIsual_active && (wp->w_buffer != curwin->w_buffer - || (!on_status_line - && !on_sep_line + || (!status_line_offset + && !sep_line_offset && (wp->w_p_rl ? col < wp->w_width_inner - fdc : col >= fdc + (cmdwin_type == 0 && wp == curwin ? 0 : 1)) @@ -251,7 +283,7 @@ retnomove: if (cmdwin_type != 0 && wp != curwin) { // A click outside the command-line window: Use modeless // selection if possible. Allow dragging the status lines. - on_sep_line = 0; + sep_line_offset = 0; row = 0; col += wp->w_wincol; wp = curwin; @@ -266,7 +298,7 @@ retnomove: if (curwin != old_curwin) { set_mouse_topline(curwin); } - if (on_status_line) { // In (or below) status line + if (status_line_offset) { // In (or below) status line // Don't use start_arrow() if we're in the same window if (curwin == old_curwin) { return IN_STATUS_LINE; @@ -274,7 +306,7 @@ retnomove: return IN_STATUS_LINE | CURSOR_MOVED; } } - if (on_sep_line) { // In (or below) status line + if (sep_line_offset) { // In (or below) status line // Don't use start_arrow() if we're in the same window if (curwin == old_curwin) { return IN_SEP_LINE; @@ -284,25 +316,27 @@ retnomove: } curwin->w_cursor.lnum = curwin->w_topline; - } else if (on_status_line) { + } else if (status_line_offset) { if (which_button == MOUSE_LEFT && dragwin != NULL) { // Drag the status line count = row - dragwin->w_winrow - dragwin->w_height + 1 - - on_status_line; + - status_line_offset; win_drag_status_line(dragwin, count); did_drag |= count; } return IN_STATUS_LINE; // Cursor didn't move - } else if (on_sep_line && which_button == MOUSE_LEFT) { + } else if (sep_line_offset && which_button == MOUSE_LEFT) { if (dragwin != NULL) { // Drag the separator column count = col - dragwin->w_wincol - dragwin->w_width + 1 - - on_sep_line; + - sep_line_offset; win_drag_vsep_line(dragwin, count); did_drag |= count; } return IN_SEP_LINE; // Cursor didn't move - } else if (on_winbar) { + } else if (on_status_line && which_button == MOUSE_RIGHT) { + return IN_STATUS_LINE; + } else if (on_winbar && which_button == MOUSE_RIGHT) { // After a click on the window bar don't start Visual mode. return IN_OTHER_WIN | MOUSE_WINBAR; } else { |