wlr-seat: pointer grab interface
This commit is contained in:
parent
30eabf38b8
commit
17b134e178
|
@ -24,6 +24,30 @@ struct wlr_seat_handle {
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wlr_seat_pointer_grab;
|
||||||
|
|
||||||
|
struct wlr_pointer_grab_interface {
|
||||||
|
void (*enter)(struct wlr_seat_pointer_grab *grab,
|
||||||
|
struct wlr_surface *surface, double sx, double sy);
|
||||||
|
void (*motion)(struct wlr_seat_pointer_grab *grab, uint32_t time,
|
||||||
|
double sx, double sy);
|
||||||
|
uint32_t (*button)(struct wlr_seat_pointer_grab *grab, uint32_t time,
|
||||||
|
uint32_t button, uint32_t state);
|
||||||
|
void (*axis)(struct wlr_seat_pointer_grab *grab, uint32_t time,
|
||||||
|
enum wlr_axis_orientation orientation, double value);
|
||||||
|
void (*cancel)(struct wlr_seat_pointer_grab *grab);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Passed to `wlr_seat_pointer_start_grab()` to start a grab of the pointer. The
|
||||||
|
* grabber is responsible for handling pointer events for the seat.
|
||||||
|
*/
|
||||||
|
struct wlr_seat_pointer_grab {
|
||||||
|
const struct wlr_pointer_grab_interface *interface;
|
||||||
|
struct wlr_seat *seat;
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
|
||||||
struct wlr_seat_pointer_state {
|
struct wlr_seat_pointer_state {
|
||||||
struct wlr_seat *wlr_seat;
|
struct wlr_seat *wlr_seat;
|
||||||
struct wlr_seat_handle *focused_handle;
|
struct wlr_seat_handle *focused_handle;
|
||||||
|
@ -31,6 +55,9 @@ struct wlr_seat_pointer_state {
|
||||||
|
|
||||||
struct wl_listener surface_destroy;
|
struct wl_listener surface_destroy;
|
||||||
struct wl_listener resource_destroy;
|
struct wl_listener resource_destroy;
|
||||||
|
|
||||||
|
struct wlr_seat_pointer_grab *grab;
|
||||||
|
struct wlr_seat_pointer_grab *default_grab;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_seat_keyboard {
|
struct wlr_seat_keyboard {
|
||||||
|
@ -109,6 +136,8 @@ bool wlr_seat_pointer_surface_has_focus(struct wlr_seat *wlr_seat,
|
||||||
* Send a pointer enter event to the given surface and consider it to be the
|
* Send a pointer enter event to the given surface and consider it to be the
|
||||||
* focused surface for the pointer. This will send a leave event to the last
|
* focused surface for the pointer. This will send a leave event to the last
|
||||||
* surface that was entered. Coordinates for the enter event are surface-local.
|
* surface that was entered. Coordinates for the enter event are surface-local.
|
||||||
|
* Compositor should use `wlr_seat_pointer_notify_enter()` to change pointer
|
||||||
|
* focus to respect pointer grabs.
|
||||||
*/
|
*/
|
||||||
void wlr_seat_pointer_enter(struct wlr_seat *wlr_seat,
|
void wlr_seat_pointer_enter(struct wlr_seat *wlr_seat,
|
||||||
struct wlr_surface *surface, double sx, double sy);
|
struct wlr_surface *surface, double sx, double sy);
|
||||||
|
@ -120,21 +149,71 @@ void wlr_seat_pointer_clear_focus(struct wlr_seat *wlr_seat);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a motion event to the surface with pointer focus. Coordinates for the
|
* Send a motion event to the surface with pointer focus. Coordinates for the
|
||||||
* motion event are surface-local.
|
* motion event are surface-local. Compositors should use
|
||||||
|
* `wlr_seat_pointer_notify_motion()` to send motion events to respect pointer
|
||||||
|
* grabs.
|
||||||
*/
|
*/
|
||||||
void wlr_seat_pointer_send_motion(struct wlr_seat *wlr_seat, uint32_t time,
|
void wlr_seat_pointer_send_motion(struct wlr_seat *wlr_seat, uint32_t time,
|
||||||
double sx, double sy);
|
double sx, double sy);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a button event to the surface with pointer focus. Coordinates for the
|
* Send a button event to the surface with pointer focus. Coordinates for the
|
||||||
* button event are surface-local. Returns the serial.
|
* button event are surface-local. Returns the serial. Compositors should use
|
||||||
|
* `wlr_seat_pointer_notify_button()` to send button events to respect pointer
|
||||||
|
* grabs.
|
||||||
*/
|
*/
|
||||||
uint32_t wlr_seat_pointer_send_button(struct wlr_seat *wlr_seat, uint32_t time,
|
uint32_t wlr_seat_pointer_send_button(struct wlr_seat *wlr_seat, uint32_t time,
|
||||||
uint32_t button, uint32_t state);
|
uint32_t button, uint32_t state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send an axis event to the surface with pointer focus. Compositors should use
|
||||||
|
* `wlr_seat_pointer_notify_axis()` to send axis events to respect pointer
|
||||||
|
* grabs.
|
||||||
|
**/
|
||||||
void wlr_seat_pointer_send_axis(struct wlr_seat *wlr_seat, uint32_t time,
|
void wlr_seat_pointer_send_axis(struct wlr_seat *wlr_seat, uint32_t time,
|
||||||
enum wlr_axis_orientation orientation, double value);
|
enum wlr_axis_orientation orientation, double value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a grab of the pointer of this seat. The grabber is responsible for
|
||||||
|
* handling all pointer events until the grab ends.
|
||||||
|
*/
|
||||||
|
void wlr_seat_pointer_start_grab(struct wlr_seat *wlr_seat,
|
||||||
|
struct wlr_seat_pointer_grab *grab);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End the grab of the pointer of this seat. This reverts the grab back to the
|
||||||
|
* default grab for the pointer.
|
||||||
|
*/
|
||||||
|
void wlr_seat_pointer_end_grab(struct wlr_seat *wlr_seat);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the seat of a pointer enter event to the given surface and request it to be the
|
||||||
|
* focused surface for the pointer. Pass surface-local coordinates where the
|
||||||
|
* enter occurred.
|
||||||
|
*/
|
||||||
|
void wlr_seat_pointer_notify_enter(struct wlr_seat *wlr_seat,
|
||||||
|
struct wlr_surface *surface, double sx, double sy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the seat of motion over the given surface. Pass surface-local
|
||||||
|
* coordinates where the pointer motion occurred.
|
||||||
|
*/
|
||||||
|
void wlr_seat_pointer_notify_motion(struct wlr_seat *wlr_seat, uint32_t time,
|
||||||
|
double sx, double sy);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the seat that a button has been pressed. Returns the serial of the
|
||||||
|
* button press or zero if no button press was sent.
|
||||||
|
*/
|
||||||
|
uint32_t wlr_seat_pointer_notify_button(struct wlr_seat *wlr_seat,
|
||||||
|
uint32_t time, uint32_t button, uint32_t state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the seat of an axis event.
|
||||||
|
*/
|
||||||
|
void wlr_seat_pointer_notify_axis(struct wlr_seat *wlr_seat, uint32_t time,
|
||||||
|
enum wlr_axis_orientation orientation, double value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attaches this keyboard to the seat. Key events from this keyboard will be
|
* Attaches this keyboard to the seat. Key events from this keyboard will be
|
||||||
* propegated to the focused client.
|
* propegated to the focused client.
|
||||||
|
|
|
@ -55,8 +55,8 @@ void cursor_update_position(struct roots_input *input, uint32_t time) {
|
||||||
view = view_at(desktop, input->cursor->x, input->cursor->y, &surface,
|
view = view_at(desktop, input->cursor->x, input->cursor->y, &surface,
|
||||||
&sx, &sy);
|
&sx, &sy);
|
||||||
if (view) {
|
if (view) {
|
||||||
wlr_seat_pointer_enter(input->wl_seat, surface, sx, sy);
|
wlr_seat_pointer_notify_enter(input->wl_seat, surface, sx, sy);
|
||||||
wlr_seat_pointer_send_motion(input->wl_seat, time, sx, sy);
|
wlr_seat_pointer_notify_motion(input->wl_seat, time, sx, sy);
|
||||||
} else {
|
} else {
|
||||||
wlr_seat_pointer_clear_focus(input->wl_seat);
|
wlr_seat_pointer_clear_focus(input->wl_seat);
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ static void handle_cursor_axis(struct wl_listener *listener, void *data) {
|
||||||
struct roots_input *input =
|
struct roots_input *input =
|
||||||
wl_container_of(listener, input, cursor_axis);
|
wl_container_of(listener, input, cursor_axis);
|
||||||
struct wlr_event_pointer_axis *event = data;
|
struct wlr_event_pointer_axis *event = data;
|
||||||
wlr_seat_pointer_send_axis(input->wl_seat, event->time_sec,
|
wlr_seat_pointer_notify_axis(input->wl_seat, event->time_sec,
|
||||||
event->orientation, event->delta);
|
event->orientation, event->delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ static void do_cursor_button_press(struct roots_input *input,
|
||||||
double sx, sy;
|
double sx, sy;
|
||||||
struct roots_view *view = view_at(desktop,
|
struct roots_view *view = view_at(desktop,
|
||||||
input->cursor->x, input->cursor->y, &surface, &sx, &sy);
|
input->cursor->x, input->cursor->y, &surface, &sx, &sy);
|
||||||
uint32_t serial = wlr_seat_pointer_send_button(
|
uint32_t serial = wlr_seat_pointer_notify_button(
|
||||||
input->wl_seat, time, button, state);
|
input->wl_seat, time, button, state);
|
||||||
int i;
|
int i;
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
|
|
@ -173,6 +173,38 @@ static void wl_seat_bind(struct wl_client *wl_client, void *_wlr_seat,
|
||||||
wl_signal_emit(&wlr_seat->events.client_bound, handle);
|
wl_signal_emit(&wlr_seat->events.client_bound, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void default_pointer_enter(struct wlr_seat_pointer_grab *grab,
|
||||||
|
struct wlr_surface *surface, double sx, double sy) {
|
||||||
|
wlr_seat_pointer_enter(grab->seat, surface, sx, sy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void default_pointer_motion(struct wlr_seat_pointer_grab *grab,
|
||||||
|
uint32_t time, double sx, double sy) {
|
||||||
|
wlr_seat_pointer_send_motion(grab->seat, time, sx, sy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t default_pointer_button(struct wlr_seat_pointer_grab *grab,
|
||||||
|
uint32_t time, uint32_t button, uint32_t state) {
|
||||||
|
return wlr_seat_pointer_send_button(grab->seat, time, button, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void default_pointer_axis(struct wlr_seat_pointer_grab *grab,
|
||||||
|
uint32_t time, enum wlr_axis_orientation orientation, double value) {
|
||||||
|
wlr_seat_pointer_send_axis(grab->seat, time, orientation, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void default_pointer_cancel(struct wlr_seat_pointer_grab *grab) {
|
||||||
|
// cannot be cancelled
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wlr_pointer_grab_interface default_pointer_grab_impl = {
|
||||||
|
.enter = default_pointer_enter,
|
||||||
|
.motion = default_pointer_motion,
|
||||||
|
.button = default_pointer_button,
|
||||||
|
.axis = default_pointer_axis,
|
||||||
|
.cancel = default_pointer_cancel,
|
||||||
|
};
|
||||||
|
|
||||||
struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name) {
|
struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name) {
|
||||||
struct wlr_seat *wlr_seat = calloc(1, sizeof(struct wlr_seat));
|
struct wlr_seat *wlr_seat = calloc(1, sizeof(struct wlr_seat));
|
||||||
if (!wlr_seat) {
|
if (!wlr_seat) {
|
||||||
|
@ -183,6 +215,17 @@ struct wlr_seat *wlr_seat_create(struct wl_display *display, const char *name) {
|
||||||
wl_list_init(&wlr_seat->pointer_state.surface_destroy.link);
|
wl_list_init(&wlr_seat->pointer_state.surface_destroy.link);
|
||||||
wl_list_init(&wlr_seat->pointer_state.resource_destroy.link);
|
wl_list_init(&wlr_seat->pointer_state.resource_destroy.link);
|
||||||
|
|
||||||
|
struct wlr_seat_pointer_grab *default_grab =
|
||||||
|
calloc(1, sizeof(struct wlr_seat_pointer_grab));
|
||||||
|
if (!default_grab) {
|
||||||
|
free(wlr_seat);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
default_grab->interface = &default_pointer_grab_impl;
|
||||||
|
default_grab->seat = wlr_seat;
|
||||||
|
wlr_seat->pointer_state.default_grab = default_grab;
|
||||||
|
wlr_seat->pointer_state.grab = default_grab;
|
||||||
|
|
||||||
wlr_seat->keyboard_state.wlr_seat = wlr_seat;
|
wlr_seat->keyboard_state.wlr_seat = wlr_seat;
|
||||||
wl_list_init(&wlr_seat->keyboard_state.resource_destroy.link);
|
wl_list_init(&wlr_seat->keyboard_state.resource_destroy.link);
|
||||||
wl_list_init(
|
wl_list_init(
|
||||||
|
@ -218,6 +261,7 @@ void wlr_seat_destroy(struct wlr_seat *wlr_seat) {
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_global_destroy(wlr_seat->wl_global);
|
wl_global_destroy(wlr_seat->wl_global);
|
||||||
|
free(wlr_seat->pointer_state.default_grab);
|
||||||
free(wlr_seat->data_device);
|
free(wlr_seat->data_device);
|
||||||
free(wlr_seat->name);
|
free(wlr_seat->name);
|
||||||
free(wlr_seat);
|
free(wlr_seat);
|
||||||
|
@ -386,6 +430,42 @@ void wlr_seat_pointer_send_axis(struct wlr_seat *wlr_seat, uint32_t time,
|
||||||
pointer_send_frame(pointer);
|
pointer_send_frame(pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wlr_seat_pointer_start_grab(struct wlr_seat *wlr_seat,
|
||||||
|
struct wlr_seat_pointer_grab *grab) {
|
||||||
|
grab->seat = wlr_seat;
|
||||||
|
wlr_seat->pointer_state.grab = grab;
|
||||||
|
// TODO: replay the last enter
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_seat_pointer_end_grab(struct wlr_seat *wlr_seat) {
|
||||||
|
wlr_seat->pointer_state.grab = wlr_seat->pointer_state.default_grab;
|
||||||
|
// TODO: replay the last enter
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_seat_pointer_notify_enter(struct wlr_seat *wlr_seat,
|
||||||
|
struct wlr_surface *surface, double sx, double sy) {
|
||||||
|
struct wlr_seat_pointer_grab *grab = wlr_seat->pointer_state.grab;
|
||||||
|
grab->interface->enter(grab, surface, sx, sy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_seat_pointer_notify_motion(struct wlr_seat *wlr_seat, uint32_t time,
|
||||||
|
double sx, double sy) {
|
||||||
|
struct wlr_seat_pointer_grab *grab = wlr_seat->pointer_state.grab;
|
||||||
|
grab->interface->motion(grab, time, sx, sy);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t wlr_seat_pointer_notify_button(struct wlr_seat *wlr_seat,
|
||||||
|
uint32_t time, uint32_t button, uint32_t state) {
|
||||||
|
struct wlr_seat_pointer_grab *grab = wlr_seat->pointer_state.grab;
|
||||||
|
return grab->interface->button(grab, time, button, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_seat_pointer_notify_axis(struct wlr_seat *wlr_seat, uint32_t time,
|
||||||
|
enum wlr_axis_orientation orientation, double value) {
|
||||||
|
struct wlr_seat_pointer_grab *grab = wlr_seat->pointer_state.grab;
|
||||||
|
grab->interface->axis(grab, time, orientation, value);
|
||||||
|
}
|
||||||
|
|
||||||
static void keyboard_switch_seat_keyboard(struct wlr_seat_handle *handle,
|
static void keyboard_switch_seat_keyboard(struct wlr_seat_handle *handle,
|
||||||
struct wlr_seat_keyboard *seat_kb) {
|
struct wlr_seat_keyboard *seat_kb) {
|
||||||
if (handle->seat_keyboard == seat_kb) {
|
if (handle->seat_keyboard == seat_kb) {
|
||||||
|
|
Loading…
Reference in New Issue