input: rework mouse button/motion handling

Store a list of currently pressed buttons, and which surface they
belong to (i.e. which surface that received the press).

Then, in motion events (with a button pressed, aka drag operations),
send the event to the “original” surface (that received the press).

Also send release events to the originating surface.

This means a surface receiving a press will always receive a
corresponding release. And no one will receive a release event without
a corresponding press event.

Motion events with a button pressed will *always* use the *first*
button that was pressed. I.e. if you press a button, start dragging,
and then press another button, we keep generating motion events for
the *first* button.
This commit is contained in:
Daniel Eklöf 2020-12-12 19:05:24 +01:00
parent a1a0b489ee
commit ff96ce1e91
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
4 changed files with 145 additions and 115 deletions

View file

@ -131,6 +131,13 @@ struct wl_primary {
uint32_t serial;
};
/* Maps a mouse button to its "owning" surface */
struct button_tracker {
int button;
int surf_kind; /* TODO: this is really an "enum term_surface" */
bool send_to_client; /* Only valid when surface is the main grid surface */
};
struct seat {
struct wayland *wayl;
struct wl_seat *wl_seat;
@ -201,23 +208,13 @@ struct seat {
int y;
int col;
int row;
int button;
/*
* Button to send in motion events to the client. This is
* always the *first* button pressed on the grid. If multiple
* buttons are pressed, the first button is still the one used
* in motion events.
*
* A non-zero value of this *also* indicates that the client
* should receive events even if the pointer is outside the
* grid.
*/
int button_for_motion_events;
bool consumed; /* True if a button press was consumed - i.e. if a binding claimed it */
/* Mouse buttons currently being pressed, and their "owning" surfaces */
tll(struct button_tracker) buttons;
/* Double- and triple click state */
int count;
int last_button;
int last_released_button;
struct timeval last_time;
/* We used a discrete axis event in the current pointer frame */