Add mouse emulation for touch devices (#2277)

This commit is contained in:
Simon Long 2024-10-29 19:22:01 +00:00 committed by GitHub
parent 4d3efb4339
commit 45a9bd95e7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 24 additions and 3 deletions

View file

@ -690,7 +690,7 @@ extending outward from the snapped edge.
## TOUCH ## TOUCH
``` ```
<touch deviceName="" mapToOutput="" /> <touch deviceName="" mapToOutput="" mouseEmulation="no"/>
``` ```
*<touch deviceName="" />* *<touch deviceName="" />*
@ -704,6 +704,10 @@ extending outward from the snapped edge.
Direct cursor movement to a specified output. If the compositor is Direct cursor movement to a specified output. If the compositor is
running in nested mode, this does not take effect. running in nested mode, this does not take effect.
*<touch mouseEmulation="" />*
If mouseEmulation is enabled, all touch up/down/motion events are
translated to mouse button and motion events.
## TABLET ## TABLET
``` ```

View file

@ -537,8 +537,11 @@
Direct cursor movement to a specified output. If the compositor is Direct cursor movement to a specified output. If the compositor is
running in nested mode, this does not take effect. running in nested mode, this does not take effect.
If mouseEmulation is enabled, all touch up/down/motion events are
translated to mouse button and motion events.
--> -->
<touch deviceName="" mapToOutput="" /> <touch deviceName="" mapToOutput="" mouseEmulation="no"/>
<!-- <!--
The tablet cursor movement can be restricted to a single output. The tablet cursor movement can be restricted to a single output.

View file

@ -8,6 +8,7 @@
struct touch_config_entry { struct touch_config_entry {
char *device_name; char *device_name;
char *output_name; char *output_name;
bool force_mouse_emulation;
struct wl_list link; /* struct rcxml.touch_configs */ struct wl_list link; /* struct rcxml.touch_configs */
}; };

View file

@ -633,6 +633,8 @@ fill_touch(char *nodename, char *content)
current_touch->device_name = xstrdup(content); current_touch->device_name = xstrdup(content);
} else if (!strcasecmp(nodename, "mapToOutput.touch")) { } else if (!strcasecmp(nodename, "mapToOutput.touch")) {
current_touch->output_name = xstrdup(content); current_touch->output_name = xstrdup(content);
} else if (!strcasecmp(nodename, "mouseEmulation.touch")) {
set_bool(content, &current_touch->force_mouse_emulation);
} else { } else {
wlr_log(WLR_ERROR, "Unexpected data in touch parser: %s=\"%s\"", wlr_log(WLR_ERROR, "Unexpected data in touch parser: %s=\"%s\"",
nodename, content); nodename, content);

View file

@ -24,6 +24,17 @@ static struct wlr_surface*
touch_get_coords(struct seat *seat, struct wlr_touch *touch, double x, double y, touch_get_coords(struct seat *seat, struct wlr_touch *touch, double x, double y,
double *x_offset, double *y_offset) double *x_offset, double *y_offset)
{ {
/*
* Do not return a surface when mouse emulation is enforced. Not
* having a surface will trigger the fallback to cursor move/button
* emulation in the touch signal handlers.
*/
struct touch_config_entry *config_entry =
touch_find_config_for_device(touch->base.name);
if (config_entry && config_entry->force_mouse_emulation) {
return NULL;
}
/* Convert coordinates: first [0, 1] => layout, then layout => surface */ /* Convert coordinates: first [0, 1] => layout, then layout => surface */
double lx, ly; double lx, ly;
wlr_cursor_absolute_to_layout_coords(seat->cursor, &touch->base, wlr_cursor_absolute_to_layout_coords(seat->cursor, &touch->base,
@ -93,7 +104,7 @@ handle_touch_down(struct wl_listener *listener, void *data)
/* Compute layout => surface offset and save for this touch point */ /* Compute layout => surface offset and save for this touch point */
struct touch_point *touch_point = znew(*touch_point); struct touch_point *touch_point = znew(*touch_point);
double x_offset, y_offset; double x_offset = 0.0, y_offset = 0.0;
touch_point->surface = touch_get_coords(seat, event->touch, touch_point->surface = touch_get_coords(seat, event->touch,
event->x, event->y, &x_offset, &y_offset); event->x, event->y, &x_offset, &y_offset);
touch_point->touch_id = event->touch_id; touch_point->touch_id = event->touch_id;