mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	fix(pum): don't select item when clicking to the left/right (#30967)
Problem:  Selecting an item in the right-click menu when clicking to the
          left/right of it is confusing, especially in a UI that doesn't
          support 'mousemoveevent'.
Solution: Don't select an item when clicking to the left/right of the
          right-click menu.
			
			
This commit is contained in:
		| @@ -1358,14 +1358,15 @@ static void pum_select_mouse_pos(void) | |||||||
|   if (mouse_grid == pum_grid.handle) { |   if (mouse_grid == pum_grid.handle) { | ||||||
|     pum_selected = mouse_row; |     pum_selected = mouse_row; | ||||||
|     return; |     return; | ||||||
|   } else if (mouse_grid != pum_anchor_grid) { |   } else if (mouse_grid != pum_anchor_grid || mouse_col < pum_grid.comp_col | ||||||
|  |              || mouse_col >= pum_grid.comp_col + pum_grid.comp_width) { | ||||||
|     pum_selected = -1; |     pum_selected = -1; | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   int idx = mouse_row - pum_row; |   int idx = mouse_row - pum_grid.comp_row; | ||||||
|  |  | ||||||
|   if (idx < 0 || idx >= pum_height) { |   if (idx < 0 || idx >= pum_grid.comp_height) { | ||||||
|     pum_selected = -1; |     pum_selected = -1; | ||||||
|   } else if (*pum_array[idx].pum_text != NUL) { |   } else if (*pum_array[idx].pum_text != NUL) { | ||||||
|     pum_selected = idx; |     pum_selected = idx; | ||||||
|   | |||||||
| @@ -4506,9 +4506,10 @@ describe('builtin popupmenu', function() | |||||||
|           :let g:menustr = 'foo'          | |           :let g:menustr = 'foo'          | | ||||||
|         ]]) |         ]]) | ||||||
|       end |       end | ||||||
|  |       local no_menu_screen ---@type string|test.function.ui.screen.Expect | ||||||
|       if multigrid then |       if multigrid then | ||||||
|         api.nvim_input_mouse('left', 'press', '', 4, 1, 2) |         api.nvim_input_mouse('left', 'press', '', 4, 1, 2) | ||||||
|         screen:expect({ |         no_menu_screen = { | ||||||
|           grid = [[ |           grid = [[ | ||||||
|         ## grid 1 |         ## grid 1 | ||||||
|           [2:--------------------------------]|*2 |           [2:--------------------------------]|*2 | ||||||
| @@ -4527,19 +4528,88 @@ describe('builtin popupmenu', function() | |||||||
|           {2:WINBAR          }| |           {2:WINBAR          }| | ||||||
|           ^popup menu test | |           ^popup menu test | | ||||||
|         ]], |         ]], | ||||||
|         }) |         } | ||||||
|       else |       else | ||||||
|         feed('<LeftMouse><31,2>') |         feed('<LeftMouse><31,2>') | ||||||
|         screen:expect([[ |         no_menu_screen = { | ||||||
|  |           grid = [[ | ||||||
|           popup menu test                 | |           popup menu test                 | | ||||||
|           {1:~                               }| |           {1:~                               }| | ||||||
|           {3:[No Name] [+]                   }| |           {3:[No Name] [+]                   }| | ||||||
|           popup menu test│{2:WINBAR          }| |           popup menu test│{2:WINBAR          }| | ||||||
|           {1:~              }│^popup menu test | |           {1:~              }│^popup menu test | | ||||||
|           :let g:menustr = 'bar'          | |           :let g:menustr = 'bar'          | | ||||||
|         ]]) |         ]], | ||||||
|  |         } | ||||||
|       end |       end | ||||||
|  |       screen:expect(no_menu_screen) | ||||||
|       eq('bar', api.nvim_get_var('menustr')) |       eq('bar', api.nvim_get_var('menustr')) | ||||||
|  |  | ||||||
|  |       local no_sel_screen ---@type string|test.function.ui.screen.Expect | ||||||
|  |       if multigrid then | ||||||
|  |         no_sel_screen = { | ||||||
|  |           grid = [[ | ||||||
|  |         ## grid 1 | ||||||
|  |           [2:--------------------------------]|*2 | ||||||
|  |           {3:[No Name] [+]                   }| | ||||||
|  |           [5:---------------]│[6:----------------]|*2 | ||||||
|  |           [3:--------------------------------]| | ||||||
|  |         ## grid 2 | ||||||
|  |           popup menu test                 | | ||||||
|  |           {1:~                               }| | ||||||
|  |         ## grid 3 | ||||||
|  |           :let g:menustr = 'bar'          | | ||||||
|  |         ## grid 4 | ||||||
|  |           {n: foo }| | ||||||
|  |           {n: bar }| | ||||||
|  |           {n: baz }| | ||||||
|  |         ## grid 5 | ||||||
|  |           popup menu test| | ||||||
|  |           {1:~              }| | ||||||
|  |         ## grid 6 | ||||||
|  |           {2:WINBAR          }| | ||||||
|  |           ^popup menu test | | ||||||
|  |         ]], | ||||||
|  |           float_pos = { [4] = { -1, 'NW', 1, 1, 19, false, 250 } }, | ||||||
|  |         } | ||||||
|  |       else | ||||||
|  |         no_sel_screen = { | ||||||
|  |           grid = [[ | ||||||
|  |           popup menu test                 | | ||||||
|  |           {1:~                  }{n: foo }{1:        }| | ||||||
|  |           {3:[No Name] [+]      }{n: bar }{3:        }| | ||||||
|  |           popup menu test│{2:WIN}{n: baz }{2:        }| | ||||||
|  |           {1:~              }│^popup menu test | | ||||||
|  |           :let g:menustr = 'bar'          | | ||||||
|  |         ]], | ||||||
|  |         } | ||||||
|  |       end | ||||||
|  |       local sel_screens = {} ---@type (string|test.function.ui.screen.Expect)[] | ||||||
|  |       for i, s in ipairs({ 'foo', 'bar', 'baz' }) do | ||||||
|  |         local sel_screen = vim.deepcopy(no_sel_screen) | ||||||
|  |         local grid = assert(sel_screen.grid) | ||||||
|  |         grid = grid:gsub(vim.pesc(('{n: %s }'):format(s)), ('{s: %s }'):format(s)) | ||||||
|  |         sel_screen.grid = grid | ||||||
|  |         sel_screens[i] = sel_screen | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       command([[let g:menustr = '']]) | ||||||
|  |       local g = multigrid and 1 or 0 | ||||||
|  |       api.nvim_input_mouse('right', 'press', '', g, 0, 20) | ||||||
|  |       screen:expect(no_sel_screen) | ||||||
|  |       api.nvim_input_mouse('move', '', '', g, 1, 19) | ||||||
|  |       screen:expect(sel_screens[1]) | ||||||
|  |       api.nvim_input_mouse('move', '', '', g, 1, 18) | ||||||
|  |       screen:expect(no_sel_screen) | ||||||
|  |       api.nvim_input_mouse('move', '', '', g, 2, 23) | ||||||
|  |       screen:expect(sel_screens[2]) | ||||||
|  |       api.nvim_input_mouse('move', '', '', g, 2, 24) | ||||||
|  |       screen:expect(no_sel_screen) | ||||||
|  |       api.nvim_input_mouse('move', '', '', g, 3, 19) | ||||||
|  |       screen:expect(sel_screens[3]) | ||||||
|  |       api.nvim_input_mouse('left', 'press', '', g, 3, 18) | ||||||
|  |       screen:expect(no_menu_screen) | ||||||
|  |       eq('', api.nvim_get_var('menustr')) | ||||||
|     end) |     end) | ||||||
|  |  | ||||||
|     if not multigrid then |     if not multigrid then | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 zeertzjq
					zeertzjq