mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-02-04 04:40:25 +01:00
touchpad: hook up sendevents configuration
We may be in the middle of a software button click or a tap, so make sure we go back to the device-neutral state by unwinding. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
49e630376b
commit
45a7edb3fb
5 changed files with 125 additions and 5 deletions
|
|
@ -484,6 +484,16 @@ tp_process_button(struct tp_dispatch *tp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
tp_release_all_buttons(struct tp_dispatch *tp,
|
||||
uint64_t time)
|
||||
{
|
||||
if (tp->buttons.state) {
|
||||
tp->buttons.state = 0;
|
||||
tp->queued |= TOUCHPAD_EVENT_BUTTON_RELEASE;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
tp_init_buttons(struct tp_dispatch *tp,
|
||||
struct evdev_device *device)
|
||||
|
|
|
|||
|
|
@ -693,3 +693,9 @@ tp_destroy_tap(struct tp_dispatch *tp)
|
|||
{
|
||||
libinput_timer_cancel(&tp->tap.timer);
|
||||
}
|
||||
|
||||
void
|
||||
tp_release_all_taps(struct tp_dispatch *tp, uint64_t now)
|
||||
{
|
||||
tp_tap_handle_timeout(now, tp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -641,6 +641,41 @@ tp_destroy(struct evdev_dispatch *dispatch)
|
|||
free(tp);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_suspend(struct tp_dispatch *tp, struct evdev_device *device)
|
||||
{
|
||||
uint64_t now = libinput_now(tp->device->base.seat->libinput);
|
||||
struct tp_touch *t;
|
||||
|
||||
/* Unroll the touchpad state.
|
||||
* Release buttons first. If tp is a clickpad, the button event
|
||||
* must come before the touch up. If it isn't, the order doesn't
|
||||
* matter anyway
|
||||
*
|
||||
* Then cancel all timeouts on the taps, triggering the last set
|
||||
* of events.
|
||||
*
|
||||
* Then lift all touches so the touchpad is in a neutral state.
|
||||
*
|
||||
*/
|
||||
tp_release_all_buttons(tp, now);
|
||||
tp_release_all_taps(tp, now);
|
||||
|
||||
tp_for_each_touch(tp, t) {
|
||||
tp_end_touch(tp, t, now);
|
||||
}
|
||||
|
||||
tp_handle_state(tp, now);
|
||||
|
||||
evdev_device_suspend(device);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_resume(struct tp_dispatch *tp, struct evdev_device *device)
|
||||
{
|
||||
evdev_device_resume(device);
|
||||
}
|
||||
|
||||
static struct evdev_dispatch_interface tp_interface = {
|
||||
tp_process,
|
||||
tp_destroy
|
||||
|
|
@ -836,6 +871,54 @@ tp_init(struct tp_dispatch *tp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
tp_sendevents_get_modes(struct libinput_device *device)
|
||||
{
|
||||
return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED |
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
|
||||
}
|
||||
|
||||
static enum libinput_config_status
|
||||
tp_sendevents_set_mode(struct libinput_device *device,
|
||||
enum libinput_config_send_events_mode mode)
|
||||
{
|
||||
struct evdev_device *evdev = (struct evdev_device*)device;
|
||||
struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
|
||||
|
||||
if (mode == tp->sendevents.current_mode)
|
||||
return LIBINPUT_CONFIG_STATUS_SUCCESS;
|
||||
|
||||
switch(mode) {
|
||||
case LIBINPUT_CONFIG_SEND_EVENTS_ENABLED:
|
||||
tp_resume(tp, evdev);
|
||||
break;
|
||||
case LIBINPUT_CONFIG_SEND_EVENTS_DISABLED:
|
||||
tp_suspend(tp, evdev);
|
||||
break;
|
||||
default:
|
||||
return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
tp->sendevents.current_mode = mode;
|
||||
|
||||
return LIBINPUT_CONFIG_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum libinput_config_send_events_mode
|
||||
tp_sendevents_get_mode(struct libinput_device *device)
|
||||
{
|
||||
struct evdev_device *evdev = (struct evdev_device*)device;
|
||||
struct tp_dispatch *dispatch = (struct tp_dispatch*)evdev->dispatch;
|
||||
|
||||
return dispatch->sendevents.current_mode;
|
||||
}
|
||||
|
||||
static enum libinput_config_send_events_mode
|
||||
tp_sendevents_get_default_mode(struct libinput_device *device)
|
||||
{
|
||||
return LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
|
||||
}
|
||||
|
||||
struct evdev_dispatch *
|
||||
evdev_mt_touchpad_create(struct evdev_device *device)
|
||||
{
|
||||
|
|
@ -850,5 +933,13 @@ evdev_mt_touchpad_create(struct evdev_device *device)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
device->base.config.sendevents = &tp->sendevents.config;
|
||||
|
||||
tp->sendevents.current_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
|
||||
tp->sendevents.config.get_modes = tp_sendevents_get_modes;
|
||||
tp->sendevents.config.set_mode = tp_sendevents_set_mode;
|
||||
tp->sendevents.config.get_mode = tp_sendevents_get_mode;
|
||||
tp->sendevents.config.get_default_mode = tp_sendevents_get_default_mode;
|
||||
|
||||
return &tp->base;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -217,6 +217,11 @@ struct tp_dispatch {
|
|||
int32_t right_edge;
|
||||
int32_t left_edge;
|
||||
} palm;
|
||||
|
||||
struct {
|
||||
struct libinput_device_config_send_events config;
|
||||
enum libinput_config_send_events_mode current_mode;
|
||||
} sendevents;
|
||||
};
|
||||
|
||||
#define tp_for_each_touch(_tp, _t) \
|
||||
|
|
@ -248,6 +253,10 @@ tp_process_button(struct tp_dispatch *tp,
|
|||
const struct input_event *e,
|
||||
uint64_t time);
|
||||
|
||||
void
|
||||
tp_release_all_buttons(struct tp_dispatch *tp,
|
||||
uint64_t time);
|
||||
|
||||
int
|
||||
tp_post_button_events(struct tp_dispatch *tp, uint64_t time);
|
||||
|
||||
|
|
@ -260,4 +269,8 @@ tp_button_touch_active(struct tp_dispatch *tp, struct tp_touch *t);
|
|||
bool
|
||||
tp_button_is_inside_softbutton_area(struct tp_dispatch *tp, struct tp_touch *t);
|
||||
|
||||
void
|
||||
tp_release_all_taps(struct tp_dispatch *tp,
|
||||
uint64_t time);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -262,12 +262,12 @@ END_TEST
|
|||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
litest_add("device:sendevents", device_sendevents_config, LITEST_ANY, LITEST_TOUCHPAD);
|
||||
litest_add("device:sendevents", device_sendevents_config_default, LITEST_ANY, LITEST_TOUCHPAD);
|
||||
litest_add("device:sendevents", device_disable, LITEST_POINTER, LITEST_TOUCHPAD);
|
||||
litest_add("device:sendevents", device_sendevents_config, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("device:sendevents", device_sendevents_config_default, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("device:sendevents", device_disable, LITEST_POINTER, LITEST_ANY);
|
||||
litest_add("device:sendevents", device_disable_events_pending, LITEST_POINTER, LITEST_TOUCHPAD);
|
||||
litest_add("device:sendevents", device_double_disable, LITEST_ANY, LITEST_TOUCHPAD);
|
||||
litest_add("device:sendevents", device_double_enable, LITEST_ANY, LITEST_TOUCHPAD);
|
||||
litest_add("device:sendevents", device_double_disable, LITEST_ANY, LITEST_ANY);
|
||||
litest_add("device:sendevents", device_double_enable, LITEST_ANY, LITEST_ANY);
|
||||
litest_add_no_device("device:sendevents", device_reenable_syspath_changed);
|
||||
litest_add_no_device("device:sendevents", device_reenable_device_removed);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue