input: reset mouse button click counter when mouse moves

As described in #883, creating a block selection (with ctrl+BTN_LEFT),
then *quickly* (within 300ms from) creating a new one, will, in fact,
_not_ create a new block selection, but a ‘select-word-whitespace’
selection (ctrl+BTN_LEFT-2).

A similar effect can be seen with plain selections (BTN_LEFT). Click
and drag to make a selection, but *release*, and make a new selection
within 300ms from the initial button press, and the new selection is
suddenly a word-based selection.

This happens because triggering a binding does *not* reset the button
click counter.

So, shouldn’t we just do that?

No, because we rely on this behavior to handle single-, double- and
triple-click actions. If we were to reset the button click handler,
then we’d have to instead delay triggering the first action with
300ms, which would make things appear laggy. If we don’t do this, it
would be impossible to double- and triple-click, since the
single-click action would keep resetting the click counter.

This patch takes a slightly different approach; we reset the click
counter when the mouse has moved “too much”. For now, “too much” is
when the cursor has moved to a different cell.

This way, single-, double- and triple-clicks continue to work as
before. But, creating actual selections, and then quickly releasing
and starting a new selection produces the expected results.

Closes #883
This commit is contained in:
Daniel Eklöf 2022-01-12 15:38:32 +01:00
parent 29c31054a1
commit e853c7139e
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 10 additions and 0 deletions

View file

@ -82,6 +82,9 @@
* Failure to launch when `exec(3):ed with an empty argv.
* Pasting from the primary clipboard (mouse middle clicking) did not
reset the scrollback view to the bottom.
* Wrong mouse binding triggered when doing two mouse selections in
very quick (< 300ms) succession
(https://codeberg.org/dnkl/foot/issues/883).
### Security

View file

@ -2046,6 +2046,13 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer,
bool cursor_is_on_new_cell
= old_col != seat->mouse.col || old_row != seat->mouse.row;
if (cursor_is_on_new_cell) {
/* Prevent multiple/different mouse bindings from
* triggering if the mouse has moved too much (to
* another cell) */
seat->mouse.count = 0;
}
/* Cursor is inside the grid, i.e. *not* in the margins */
const bool cursor_is_on_grid = seat->mouse.col >= 0 && seat->mouse.row >= 0;