[PATCH 2/2] window: Only release the widget grab when all buttons are released
Bill Spitzak
spitzak at gmail.com
Mon Jan 23 14:14:42 PST 2012
This looks a little risky, if there is a bug that eats one of the events.
Under X I never did this because of this worry, instead it checked the
button-down state in the shift flags of the event to see if all were
released.
Can't the compositor input send some similar indication? I realize that
a mask of all the buttons might be impractical with modern input
handling, but just a flag that says if any buttons are down other than
the one the event is about would be equally useful.
Neil Roberts wrote:
> This copies the algorithm for keeping track of an implicit grab widget
> when a button is pressed from Wayland. Instead of just tracking a
> single button, Wayland keeps a count of all the mouse buttons that are
> down and only releases the grab when all buttons are released. Without
> this it could lose button release events if a second button is pressed
> and held while the original grab button is held because the grab would
> be lost when the grab button is released. Then the release for the
> second mouse button would go nowhere.
>
> The code makes sure to only release the grab if it there is a grab
> button so that it won't release grabs initiated from window_show_menu.
> ---
> clients/window.c | 12 +++++++++++-
> 1 files changed, 11 insertions(+), 1 deletions(-)
>
> diff --git a/clients/window.c b/clients/window.c
> index 1356c75..fb6b307 100644
> --- a/clients/window.c
> +++ b/clients/window.c
> @@ -164,6 +164,8 @@ struct input {
> struct widget *focus_widget;
> struct widget *grab;
> uint32_t grab_button;
> + /* Number of buttons that are held down */
> + uint32_t button_count;
>
> struct wl_data_device *data_device;
> struct data_offer *drag_offer;
> @@ -1524,6 +1526,11 @@ input_handle_button(void *data,
> struct input *input = data;
> struct widget *widget;
>
> + if (state)
> + input->button_count++;
> + else
> + input->button_count--;
> +
> if (input->focus_widget && input->grab == NULL && state)
> input_grab(input, input->focus_widget, button);
>
> @@ -1534,7 +1541,10 @@ input_handle_button(void *data,
> button, state,
> input->grab->user_data);
>
> - if (input->grab && input->grab_button == button && !state)
> + /* If we were grabbing because of a button press but there are
> + * no longer any buttons being pressed then release the
> + * grab */
> + if (input->grab && input->grab_button != 0 && input->button_count == 0)
> input_ungrab(input, time);
> }
>
More information about the wayland-devel
mailing list