diff options
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 { | 
