Merge branch 'tablet-tool-scroll' into 'master'

Draft: Add tablet tool axis scroll

See merge request wlroots/wlroots!4598
This commit is contained in:
Louis Goyard 2024-03-16 09:05:15 +00:00
commit e48de3bd3a
9 changed files with 133 additions and 0 deletions

View file

@ -213,6 +213,9 @@ void handle_libinput_event(struct wlr_libinput_backend *backend,
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
handle_tablet_tool_button(event, &dev->tablet);
break;
case LIBINPUT_EVENT_TABLET_TOOL_SCROLL_CONTINUOUS:
handle_tablet_tool_scroll_continuous(event, &dev->tablet);
break;
case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
handle_tablet_pad_button(event, &dev->tablet_pad);
break;

View file

@ -275,3 +275,53 @@ void handle_tablet_tool_button(struct libinput_event *event,
}
wl_signal_emit_mutable(&wlr_tablet->events.button, &wlr_event);
}
void handle_tablet_tool_scroll_continuous(struct libinput_event *event,
struct wlr_tablet *wlr_tablet) {
struct libinput_event_tablet_tool *tevent =
libinput_event_get_tablet_tool_event(event);
struct wlr_libinput_input_device *dev = device_from_tablet(wlr_tablet);
struct tablet_tool *tool =
get_tablet_tool(dev, libinput_event_tablet_tool_get_tool(tevent));
struct wlr_tablet_tool_axis_scroll_event wlr_event = {
.tablet = wlr_tablet,
.tool = &tool->wlr_tool,
.time_msec = usec_to_msec(libinput_event_tablet_tool_get_time_usec(tevent)),
};
switch (libinput_event_tablet_tool_get_axis_source(tevent)) {
case LIBINPUT_TABLET_TOOL_AXIS_SOURCE_CONTINUOUS:
wlr_event.source = WL_POINTER_AXIS_SOURCE_CONTINUOUS;
break;
default:
// FIXME
return;
}
const enum libinput_pointer_axis axes[] = {
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
};
for (size_t i = 0; i < sizeof(axes) / sizeof(axes[0]); ++i) {
if (!libinput_event_tablet_tool_has_axis(tevent, axes[i])) {
continue;
}
switch (axes[i]) {
case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
wlr_event.orientation = WL_POINTER_AXIS_VERTICAL_SCROLL;
break;
case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
wlr_event.orientation = WL_POINTER_AXIS_HORIZONTAL_SCROLL;
break;
}
wlr_event.delta =
libinput_event_tablet_tool_get_scroll_value(tevent, axes[i]);
wlr_event.relative_direction = WL_POINTER_AXIS_RELATIVE_DIRECTION_IDENTICAL;
if (libinput_device_config_scroll_get_natural_scroll_enabled(libinput_event_get_device(event))) {
wlr_event.relative_direction = WL_POINTER_AXIS_RELATIVE_DIRECTION_INVERTED;
}
wl_signal_emit_mutable(&wlr_tablet->events.axis_scroll, &wlr_event);
}
}

View file

@ -124,6 +124,8 @@ void handle_tablet_tool_tip(struct libinput_event *event,
struct wlr_tablet *tablet);
void handle_tablet_tool_button(struct libinput_event *event,
struct wlr_tablet *tablet);
void handle_tablet_tool_scroll_continuous(struct libinput_event *event,
struct wlr_tablet *tablet);
void init_device_tablet_pad(struct wlr_libinput_input_device *dev);
void finish_device_tablet_pad(struct wlr_libinput_input_device *dev);

View file

@ -73,6 +73,7 @@ struct wlr_cursor {
struct wl_signal tablet_tool_proximity;
struct wl_signal tablet_tool_tip;
struct wl_signal tablet_tool_button;
struct wl_signal tablet_tool_axis_scroll;
} events;
void *data;

View file

@ -12,6 +12,7 @@
#include <stdint.h>
#include <wayland-server-core.h>
#include <wlr/types/wlr_input_device.h>
#include <wlr/types/wlr_seat.h>
/*
* Copy+Paste from libinput, but this should neither use libinput, nor
@ -72,6 +73,7 @@ struct wlr_tablet {
struct wl_signal proximity;
struct wl_signal tip;
struct wl_signal button;
struct wl_signal axis_scroll;
} events;
struct wl_array paths; // char *
@ -145,6 +147,16 @@ struct wlr_tablet_tool_button_event {
enum wlr_button_state state;
};
struct wlr_tablet_tool_axis_scroll_event {
struct wlr_tablet *tablet;
struct wlr_tablet_tool *tool;
uint32_t time_msec;
enum wl_pointer_axis_source source;
enum wl_pointer_axis orientation;
enum wl_pointer_axis_relative_direction relative_direction;
double delta;
};
/**
* Get a struct wlr_tablet from a struct wlr_input_device.
*

View file

@ -179,6 +179,11 @@ void wlr_send_tablet_v2_tablet_tool_button(
struct wlr_tablet_v2_tablet_tool *tool, uint32_t button,
enum zwp_tablet_pad_v2_button_state state);
void wlr_send_tablet_v2_tablet_tool_axis_scroll(
struct wlr_tablet_v2_tablet_tool *tool, uint32_t time_msec,
enum wl_pointer_axis orientation, double value,
enum wl_pointer_axis_source source,
enum wl_pointer_axis_relative_direction relative_direction);
void wlr_tablet_v2_tablet_tool_notify_proximity_in(
@ -217,6 +222,12 @@ void wlr_tablet_v2_tablet_tool_notify_button(
struct wlr_tablet_v2_tablet_tool *tool, uint32_t button,
enum zwp_tablet_pad_v2_button_state state);
void wlr_tablet_v2_tablet_tool_notify_scroll(
struct wlr_tablet_v2_tablet_tool *tool, uint32_t time_msec,
enum wl_pointer_axis orientation, double value,
enum wl_pointer_axis_source source,
enum wl_pointer_axis_relative_direction relative_direction);
struct wlr_tablet_tool_v2_grab_interface {
void (*proximity_in)(
@ -246,6 +257,13 @@ struct wlr_tablet_tool_v2_grab_interface {
void (*button)(
struct wlr_tablet_tool_v2_grab *grab, uint32_t button,
enum zwp_tablet_pad_v2_button_state state);
void (*axis_scroll)(
struct wlr_tablet_tool_v2_grab *grab, uint32_t time_msec,
enum wl_pointer_axis orientation, double value,
enum wl_pointer_axis_source source,
enum wl_pointer_axis_relative_direction relative_direction);
void (*cancel)(struct wlr_tablet_tool_v2_grab *grab);
};

View file

@ -490,6 +490,17 @@ void wlr_send_tablet_v2_tablet_tool_button(
}
}
void wlr_send_tablet_v2_tablet_tool_axis_scroll(
struct wlr_tablet_v2_tablet_tool *tool, uint32_t time_msec,
enum wl_pointer_axis orientation, double value,
enum wl_pointer_axis_source source,
enum wl_pointer_axis_relative_direction relative_direction) {
if (tool->current_client) {
zwp_tablet_tool_v2_send_axis_scroll(tool->current_client->resource, time_msec, orientation, value);
queue_tool_frame(tool->current_client);
}
}
void wlr_send_tablet_v2_tablet_tool_wheel(
struct wlr_tablet_v2_tablet_tool *tool, double degrees, int32_t clicks) {
if (tool->current_client) {
@ -616,6 +627,16 @@ void wlr_tablet_v2_tablet_tool_notify_button(
}
}
void wlr_tablet_v2_tablet_tool_notify_scroll(
struct wlr_tablet_v2_tablet_tool *tool, uint32_t time_msec,
enum wl_pointer_axis orientation, double value,
enum wl_pointer_axis_source source,
enum wl_pointer_axis_relative_direction relative_direction) {
if (tool->grab->interface->axis_scroll) {
tool->grab->interface->axis_scroll(tool->grab, time_msec, orientation, value, source, relative_direction);
}
}
void wlr_tablet_tool_v2_start_grab(struct wlr_tablet_v2_tablet_tool *tool,
struct wlr_tablet_tool_v2_grab *grab) {
wlr_tablet_tool_v2_end_grab(tool);
@ -689,6 +710,14 @@ static void default_tool_button(
wlr_send_tablet_v2_tablet_tool_button(grab->tool, button, state);
}
static void default_tool_axis_scroll(struct wlr_tablet_tool_v2_grab *grab,
uint32_t time_msec,
enum wl_pointer_axis orientation, double value,
enum wl_pointer_axis_source source,
enum wl_pointer_axis_relative_direction relative_direction) {
wlr_send_tablet_v2_tablet_tool_axis_scroll(grab->tool, time_msec, orientation, value, source, relative_direction);
}
static void default_tool_cancel(struct wlr_tablet_tool_v2_grab *grab) {
/* Do nothing. Default grab can't be canceled */
}
@ -707,6 +736,7 @@ static const struct wlr_tablet_tool_v2_grab_interface
.wheel = default_tool_wheel,
.proximity_out = default_tool_proximity_out,
.button = default_tool_button,
.axis_scroll = default_tool_axis_scroll,
.cancel = default_tool_cancel,
};

View file

@ -50,6 +50,7 @@ struct wlr_cursor_device {
struct wl_listener tablet_tool_proximity;
struct wl_listener tablet_tool_tip;
struct wl_listener tablet_tool_button;
struct wl_listener tablet_tool_axis_scroll;
struct wl_listener destroy;
};
@ -142,6 +143,7 @@ struct wlr_cursor *wlr_cursor_create(void) {
wl_signal_init(&cur->events.tablet_tool_tip);
wl_signal_init(&cur->events.tablet_tool_axis);
wl_signal_init(&cur->events.tablet_tool_button);
wl_signal_init(&cur->events.tablet_tool_axis_scroll);
wl_signal_init(&cur->events.tablet_tool_proximity);
wl_list_init(&cur->state->surface_destroy.link);
@ -212,6 +214,7 @@ static void cursor_device_destroy(struct wlr_cursor_device *c_device) {
wl_list_remove(&c_device->tablet_tool_proximity.link);
wl_list_remove(&c_device->tablet_tool_tip.link);
wl_list_remove(&c_device->tablet_tool_button.link);
wl_list_remove(&c_device->tablet_tool_axis_scroll.link);
break;
default:
abort(); // unreachable
@ -921,6 +924,15 @@ static void handle_tablet_tool_button(struct wl_listener *listener,
wl_signal_emit_mutable(&device->cursor->events.tablet_tool_button, event);
}
static void handle_tablet_tool_axis_scroll(struct wl_listener *listener,
void *data) {
struct wlr_tablet_tool_axis_scroll_event *event = data;
struct wlr_cursor_device *device;
device = wl_container_of(listener, device, tablet_tool_axis_scroll);
wl_signal_emit_mutable(&device->cursor->events.tablet_tool_axis_scroll, event);
}
static void handle_tablet_tool_proximity(struct wl_listener *listener,
void *data) {
struct wlr_tablet_tool_proximity_event *event = data;
@ -1036,6 +1048,10 @@ static struct wlr_cursor_device *cursor_device_create(
wl_signal_add(&tablet->events.button, &c_device->tablet_tool_button);
c_device->tablet_tool_button.notify = handle_tablet_tool_button;
wl_signal_add(&tablet->events.axis_scroll,
&c_device->tablet_tool_axis_scroll);
c_device->tablet_tool_axis_scroll.notify = handle_tablet_tool_axis_scroll;
break;
default:

View file

@ -24,6 +24,7 @@ void wlr_tablet_init(struct wlr_tablet *tablet,
wl_signal_init(&tablet->events.proximity);
wl_signal_init(&tablet->events.tip);
wl_signal_init(&tablet->events.button);
wl_signal_init(&tablet->events.axis_scroll);
wl_array_init(&tablet->paths);
}