aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-01-10 12:56:43 +0800
committerGitHub <noreply@github.com>2024-01-10 12:56:43 +0800
commita7550a20e0c3084eacd2b4ede1e6a94f282c2fb8 (patch)
tree6e09de77e58724c4aa7c07f413c69b50ac42b3a8
parentfa17a5ab49dff5a2e4de7bd2faee31f5458993aa (diff)
downloadrneovim-a7550a20e0c3084eacd2b4ede1e6a94f282c2fb8.tar.gz
rneovim-a7550a20e0c3084eacd2b4ede1e6a94f282c2fb8.tar.bz2
rneovim-a7550a20e0c3084eacd2b4ede1e6a94f282c2fb8.zip
fix(pum): handle right-click menu repositioning with multigrid (#26975)
-rw-r--r--src/nvim/popupmenu.c23
-rw-r--r--test/functional/ui/popupmenu_spec.lua65
2 files changed, 78 insertions, 10 deletions
diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c
index f3cc804097..220214c887 100644
--- a/src/nvim/popupmenu.c
+++ b/src/nvim/popupmenu.c
@@ -58,7 +58,8 @@ static bool pum_rl; // true when popupmenu is drawn 'rightleft'
static int pum_anchor_grid; // grid where position is defined
static int pum_row; // top row of pum
-static int pum_col; // left column of pum
+static int pum_col; // left column of pum, right column if 'rightleft'
+static int pum_left_col; // left column of pum, before padding or scrollbar
static bool pum_above; // pum is drawn above cursor line
static bool pum_is_visible = false;
@@ -464,14 +465,14 @@ void pum_redraw(void)
grid_assign_handle(&pum_grid);
- bool moved = ui_comp_put_grid(&pum_grid, pum_row, pum_col - col_off,
+ pum_left_col = pum_col - col_off;
+ bool moved = ui_comp_put_grid(&pum_grid, pum_row, pum_left_col,
pum_height, grid_width, false, true);
bool invalid_grid = moved || pum_invalid;
pum_invalid = false;
must_redraw_pum = false;
- if (!pum_grid.chars
- || pum_grid.rows != pum_height || pum_grid.cols != grid_width) {
+ if (!pum_grid.chars || pum_grid.rows != pum_height || pum_grid.cols != grid_width) {
grid_alloc(&pum_grid, pum_height, grid_width, !invalid_grid, false);
ui_call_grid_resize(pum_grid.handle, pum_grid.cols, pum_grid.rows);
} else if (invalid_grid) {
@@ -480,9 +481,8 @@ void pum_redraw(void)
if (ui_has(kUIMultigrid)) {
const char *anchor = pum_above ? "SW" : "NW";
int row_off = pum_above ? -pum_height : 0;
- ui_call_win_float_pos(pum_grid.handle, -1, cstr_as_string((char *)anchor),
- pum_anchor_grid, pum_row - row_off, pum_col - col_off,
- false, pum_grid.zindex);
+ ui_call_win_float_pos(pum_grid.handle, -1, cstr_as_string((char *)anchor), pum_anchor_grid,
+ pum_row - row_off, pum_left_col, false, pum_grid.zindex);
}
// Never display more than we have
@@ -1160,7 +1160,14 @@ static void pum_position_at_mouse(int min_width)
max_col = MAX(Columns - wp->w_wincol, wp->w_grid.cols);
}
}
- pum_anchor_grid = mouse_grid;
+ if (pum_grid.handle != 0 && mouse_grid == pum_grid.handle) {
+ // Repositioning the menu by right-clicking on itself
+ mouse_grid = pum_anchor_grid;
+ mouse_row += pum_row;
+ mouse_col += pum_left_col;
+ } else {
+ pum_anchor_grid = mouse_grid;
+ }
if (max_row - mouse_row > pum_size) {
// Enough space below the mouse row.
pum_above = false;
diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua
index 67a5f2ef77..da0a68edcb 100644
--- a/test/functional/ui/popupmenu_spec.lua
+++ b/test/functional/ui/popupmenu_spec.lua
@@ -3771,6 +3771,67 @@ describe('builtin popupmenu', function()
]])
end
if multigrid then
+ meths.input_mouse('right', 'press', '', 2, 0, 18)
+ screen:expect {
+ grid = [[
+ ## grid 1
+ [2:--------------------------------]|*5
+ [3:--------------------------------]|
+ ## grid 2
+ ^popup menu test |
+ {1:~ }|*4
+ ## grid 3
+ :let g:menustr = 'bar' |
+ ## grid 4
+ {n: foo }|
+ {n: bar }|
+ {n: baz }|
+ ]],
+ float_pos = {
+ [4] = { { id = -1 }, 'NW', 2, 1, 17, false, 250 },
+ },
+ }
+ else
+ feed('<RightMouse><18,0>')
+ screen:expect([[
+ ^popup menu test |
+ {1:~ }{n: foo }{1: }|
+ {1:~ }{n: bar }{1: }|
+ {1:~ }{n: baz }{1: }|
+ {1:~ }|
+ :let g:menustr = 'bar' |
+ ]])
+ end
+ if multigrid then
+ meths.input_mouse('right', 'press', '', 4, 1, 3)
+ screen:expect({
+ grid = [[
+ ## grid 1
+ [2:--------------------------------]|*5
+ [3:--------------------------------]|
+ ## grid 2
+ ^popup menu test |
+ {1:~ }|*4
+ ## grid 3
+ :let g:menustr = 'bar' |
+ ## grid 4
+ {n: foo }|
+ {n: bar }|
+ {n: baz }|
+ ]],
+ float_pos = { [4] = { { id = -1 }, 'NW', 2, 3, 19, false, 250 } },
+ })
+ else
+ feed('<RightMouse><20,2>')
+ screen:expect([[
+ ^popup menu test |
+ {1:~ }|*2
+ {1:~ }{n: foo }{1: }|
+ {1:~ }{n: bar }{1: }|
+ :let g:menustr = 'b{n: baz } |
+ ]])
+ end
+ if multigrid then
meths.input_mouse('left', 'press', '', 4, 2, 2)
screen:expect({
grid = [[
@@ -3785,7 +3846,7 @@ describe('builtin popupmenu', function()
]],
})
else
- feed('<LeftMouse><22,5>')
+ feed('<LeftMouse><21,5>')
screen:expect([[
^popup menu test |
{1:~ }|*4
@@ -4022,7 +4083,7 @@ describe('builtin popupmenu', function()
]],
})
else
- feed('<LeftMouse><22,3>')
+ feed('<LeftMouse><21,3>')
screen:expect([[
popup menu test |
{1:~ }|