Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Touch support #143

Draft
wants to merge 3 commits into
base: wayland
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions include/wayland-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ typedef struct {
uint32_t layer_height;
} wayland_stuff;

#define MAX_TOUCHPOINTS 10

struct _wayland_seat {
wayland_stuff *context;
uint32_t global_name;
Expand All @@ -99,6 +101,11 @@ struct _wayland_seat {
uint32_t pointer_serial;
struct wl_keyboard *keyboard;
struct wl_pointer *pointer;
struct wl_touch *touch;
struct {
int32_t x, start_y, move_y;
uint32_t start_time, move_time;
} touches[MAX_TOUCHPOINTS];

#ifdef HAVE_WAYLAND_CURSOR_SHAPE
struct wp_cursor_shape_device_v1 *cursor_shape_device;
Expand Down
114 changes: 114 additions & 0 deletions source/wayland/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,100 @@ static const struct wl_keyboard_listener wayland_keyboard_listener = {
.repeat_info = wayland_keyboard_repeat_info,
};

static void wayland_touch_down(void *data, struct wl_touch *wl_touch,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation is a bit inconsistent with the rest of the file.

Could you please run clang-format on the lines you've added?

uint32_t serial, uint32_t time, struct wl_surface *wl_surface,
int32_t id, wl_fixed_t surface_x, wl_fixed_t surface_y) {
wayland_seat *self = data;
if (id >= MAX_TOUCHPOINTS) {
return;
}
self->touches[id].x = wl_fixed_to_int(surface_x);
self->touches[id].start_y = self->touches[id].move_y = wl_fixed_to_int(surface_y);
self->touches[id].start_time = self->touches[id].move_time = time;
RofiViewState *state = rofi_view_get_active();

if (state == NULL) {
return;
}
rofi_view_handle_mouse_motion(state, self->touches[id].x, self->touches[id].start_y,
FALSE);
}

static void wayland_touch_up(void *data, struct wl_touch *wl_touch,
uint32_t serial, uint32_t time, int32_t id) {
wayland_seat *self = data;
if (id >= MAX_TOUCHPOINTS) {
return;
}
gboolean has_moved = self->touches[id].start_time != self->touches[id].move_time;
if (has_moved) {
return;
}
RofiViewState *state = rofi_view_get_active();

if (state == NULL) {
return;
}
int key = KEY_ENTER;
if (time - self->touches[id].start_time > 200) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe define this 200 as a constant with a proper name at the top of this function?

key = KEY_ESC;
}
nk_bindings_seat_handle_key(wayland->bindings_seat, NULL,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on some rofi launches, this doesn't work (i.e. if it doesn't work, it won't magically fix itself if you click multiple times). TODO figure out why

key + 8,
NK_BINDINGS_KEY_STATE_PRESS);
rofi_view_maybe_update(state);
}

static int32_t y_offset_to_line_offset(int32_t y_offset) {
static const int32_t line_height = 20;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, this "20" is some kind of hard-coded sensitivity?

It is fine for now but maybe add a TODO comment like "TODO: make sensitivity parametrizable"

return -(y_offset / line_height);
}

static void wayland_touch_motion(void *data, struct wl_touch *wl_touch,
uint32_t time, int32_t id, wl_fixed_t surface_x, wl_fixed_t surface_y) {
wayland_seat *self = data;
if (id >= MAX_TOUCHPOINTS) {
return;
}
RofiViewState *state = rofi_view_get_active();

if (state == NULL) {
return;
}
int32_t x = wl_fixed_to_int(surface_x);
int32_t y = wl_fixed_to_int(surface_y);

int last_pos = y_offset_to_line_offset(self->touches[id].move_y - self->touches[id].start_y);
int cur_pos = y_offset_to_line_offset(y - self->touches[id].start_y);

if (cur_pos != last_pos) {
nk_bindings_seat_handle_scroll(wayland->bindings_seat, NULL,
NK_BINDINGS_SCROLL_AXIS_VERTICAL,
cur_pos - last_pos);
self->touches[id].x = x;
self->touches[id].move_y = y;
self->touches[id].move_time = time;
rofi_view_maybe_update(state);
}
}

static void wayland_touch_frame(void *data, struct wl_touch *wl_touch) { }
static void wayland_touch_cancel(void *data, struct wl_touch *wl_touch) { }
static void wayland_touch_shape(void *data, struct wl_touch *wl_touch,
int32_t id, wl_fixed_t major, wl_fixed_t minor) { }
static void wayland_touch_orientation(void *data, struct wl_touch *wl_touch,
int32_t id, wl_fixed_t orientation) { }

static const struct wl_touch_listener wayland_touch_listener = {
.down = wayland_touch_down,
.up = wayland_touch_up,
.motion = wayland_touch_motion,
.frame = wayland_touch_frame,
.cancel = wayland_touch_cancel,
.shape = wayland_touch_shape,
.orientation = wayland_touch_orientation,
};

static gboolean wayland_cursor_reload_theme(guint scale);

static void wayland_cursor_set_image(int i) {
Expand Down Expand Up @@ -1081,9 +1175,20 @@ static void wayland_pointer_release(wayland_seat *self) {
self->pointer = NULL;
}

static void wayland_touch_release(wayland_seat *self) {
if (self->touch == NULL) {
return;
}

wl_touch_release(self->touch);

self->touch = NULL;
}

static void wayland_seat_release(wayland_seat *self) {
wayland_keyboard_release(self);
wayland_pointer_release(self);
wayland_touch_release(self);

wl_seat_release(self->seat);

Expand Down Expand Up @@ -1113,6 +1218,15 @@ static void wayland_seat_capabilities(void *data, struct wl_seat *seat,
wayland_pointer_release(self);
}

if ((capabilities & WL_SEAT_CAPABILITY_TOUCH) &&
(self->touch == NULL)) {
self->touch = wl_seat_get_touch(self->seat);
wl_touch_add_listener(self->touch, &wayland_touch_listener, self);
} else if ((!(capabilities & WL_SEAT_CAPABILITY_TOUCH)) &&
(self->touch != NULL)) {
wayland_touch_release(self);
}

if (wayland->data_device_manager != NULL) {
self->data_device = wl_data_device_manager_get_data_device(
wayland->data_device_manager, seat);
Expand Down
Loading