data_device: don't use grabs

This commit is contained in:
Kirill Primak 2023-07-23 15:22:31 +03:00
parent 41823f3086
commit 1bb781d362
2 changed files with 16 additions and 225 deletions

View file

@ -94,18 +94,7 @@ struct wlr_drag_icon {
void *data; void *data;
}; };
enum wlr_drag_grab_type {
WLR_DRAG_GRAB_KEYBOARD,
WLR_DRAG_GRAB_KEYBOARD_POINTER,
WLR_DRAG_GRAB_KEYBOARD_TOUCH,
};
struct wlr_drag { struct wlr_drag {
enum wlr_drag_grab_type grab_type;
struct wlr_seat_keyboard_grab keyboard_grab;
struct wlr_seat_pointer_grab pointer_grab;
struct wlr_seat_touch_grab touch_grab;
struct wlr_seat *seat; struct wlr_seat *seat;
struct wlr_seat_client *seat_client; struct wlr_seat_client *seat_client;
struct wlr_seat_client *focus_client; struct wlr_seat_client *focus_client;
@ -181,26 +170,11 @@ void wlr_seat_request_start_drag(struct wlr_seat *seat, struct wlr_drag *drag,
struct wlr_surface *origin, uint32_t serial); struct wlr_surface *origin, uint32_t serial);
/** /**
* Starts a drag on the seat. This starts an implicit keyboard grab, but doesn't * Starts a drag on the seat.
* start a pointer or a touch grab.
*/ */
void wlr_seat_start_drag(struct wlr_seat *seat, struct wlr_drag *drag, void wlr_seat_start_drag(struct wlr_seat *seat, struct wlr_drag *drag,
uint32_t serial); uint32_t serial);
/**
* Starts a pointer drag on the seat. This starts implicit keyboard and pointer
* grabs.
*/
void wlr_seat_start_pointer_drag(struct wlr_seat *seat, struct wlr_drag *drag,
uint32_t serial);
/**
* Starts a touch drag on the seat. This starts implicit keyboard and touch
* grabs.
*/
void wlr_seat_start_touch_drag(struct wlr_seat *seat, struct wlr_drag *drag,
uint32_t serial, struct wlr_touch_point *point);
void wlr_seat_drag_enter(struct wlr_seat *seat, struct wlr_surface *surface, void wlr_seat_drag_enter(struct wlr_seat *seat, struct wlr_surface *surface,
double sx, double sy); double sx, double sy);

View file

@ -27,25 +27,6 @@ static void drag_icon_destroy(struct wlr_drag_icon *icon) {
} }
static void drag_destroy(struct wlr_drag *drag) { static void drag_destroy(struct wlr_drag *drag) {
if (drag->cancelling) {
return;
}
drag->cancelling = true;
if (drag->started) {
wlr_seat_keyboard_end_grab(drag->seat);
switch (drag->grab_type) {
case WLR_DRAG_GRAB_KEYBOARD:
break;
case WLR_DRAG_GRAB_KEYBOARD_POINTER:
wlr_seat_pointer_end_grab(drag->seat);
break;
case WLR_DRAG_GRAB_KEYBOARD_TOUCH:
wlr_seat_touch_end_grab(drag->seat);
break;
}
}
if (drag->started) { if (drag->started) {
wlr_seat_drag_clear_focus(drag->seat); wlr_seat_drag_clear_focus(drag->seat);
@ -53,11 +34,8 @@ static void drag_destroy(struct wlr_drag *drag) {
drag->seat->drag = NULL; drag->seat->drag = NULL;
} }
// We issue destroy after ending the grab to allow focus changes. // We wait until after clearing the drag focus to ensure that
// Furthermore, we wait until after clearing the drag focus in order // wl_data_device.leave is sent before emitting the signal.
// to ensure that the wl_data_device.leave is sent before emitting the
// signal. This allows e.g. wl_pointer.enter to be sent in the destroy
// signal handler.
wl_signal_emit_mutable(&drag->events.destroy, drag); wl_signal_emit_mutable(&drag->events.destroy, drag);
if (drag->source) { if (drag->source) {
@ -70,146 +48,6 @@ static void drag_destroy(struct wlr_drag *drag) {
free(drag); free(drag);
} }
static void drag_handle_pointer_enter(struct wlr_seat_pointer_grab *grab,
struct wlr_surface *surface, double sx, double sy) {
wlr_seat_drag_enter(grab->seat, surface, sx, sy);
}
static void drag_handle_pointer_clear_focus(struct wlr_seat_pointer_grab *grab) {
wlr_seat_drag_clear_focus(grab->seat);
}
static void drag_handle_pointer_motion(struct wlr_seat_pointer_grab *grab,
uint32_t time, double sx, double sy) {
wlr_seat_drag_send_motion(grab->seat, time, sx, sy);
}
static void drag_drop(struct wlr_drag *drag, uint32_t time) {
assert(drag->focus_client);
drag->dropped = true;
struct wl_resource *resource;
wl_resource_for_each(resource, &drag->focus_client->data_devices) {
wl_data_device_send_drop(resource);
}
if (drag->source) {
wlr_data_source_dnd_drop(drag->source);
}
struct wlr_drag_drop_event event = {
.drag = drag,
.time = time,
};
wl_signal_emit_mutable(&drag->events.drop, &event);
}
static uint32_t drag_handle_pointer_button(struct wlr_seat_pointer_grab *grab,
uint32_t time, uint32_t button, uint32_t state) {
wlr_seat_drag_drop_and_destroy(grab->seat, time);
return 0;
}
static void drag_handle_pointer_axis(struct wlr_seat_pointer_grab *grab,
uint32_t time, enum wlr_axis_orientation orientation, double value,
int32_t value_discrete, enum wlr_axis_source source) {
// This space is intentionally left blank
}
static void drag_handle_pointer_cancel(struct wlr_seat_pointer_grab *grab) {
struct wlr_drag *drag = grab->data;
drag_destroy(drag);
}
static const struct wlr_pointer_grab_interface
data_device_pointer_drag_interface = {
.enter = drag_handle_pointer_enter,
.clear_focus = drag_handle_pointer_clear_focus,
.motion = drag_handle_pointer_motion,
.button = drag_handle_pointer_button,
.axis = drag_handle_pointer_axis,
.cancel = drag_handle_pointer_cancel,
};
static uint32_t drag_handle_touch_down(struct wlr_seat_touch_grab *grab,
uint32_t time, struct wlr_touch_point *point) {
// eat the event
return 0;
}
static void drag_handle_touch_up(struct wlr_seat_touch_grab *grab,
uint32_t time, struct wlr_touch_point *point) {
struct wlr_drag *drag = grab->data;
if (drag->grab_touch_id != point->touch_id) {
return;
}
wlr_seat_drag_drop_and_destroy(grab->seat, time);
}
static void drag_handle_touch_motion(struct wlr_seat_touch_grab *grab,
uint32_t time, struct wlr_touch_point *point) {
struct wlr_drag *drag = grab->data;
if (drag->grab_touch_id != point->touch_id) {
return;
}
wlr_seat_drag_send_motion(grab->seat, time, point->sx, point->sy);
}
static void drag_handle_touch_enter(struct wlr_seat_touch_grab *grab,
uint32_t time, struct wlr_touch_point *point) {
wlr_seat_drag_enter(grab->seat, point->focus_surface, point->sx, point->sy);
}
static void drag_handle_touch_cancel(struct wlr_seat_touch_grab *grab) {
struct wlr_drag *drag = grab->data;
drag_destroy(drag);
}
static const struct wlr_touch_grab_interface
data_device_touch_drag_interface = {
.down = drag_handle_touch_down,
.up = drag_handle_touch_up,
.motion = drag_handle_touch_motion,
.enter = drag_handle_touch_enter,
.cancel = drag_handle_touch_cancel,
};
static void drag_handle_keyboard_enter(struct wlr_seat_keyboard_grab *grab,
struct wlr_surface *surface, const uint32_t keycodes[], size_t num_keycodes,
const struct wlr_keyboard_modifiers *modifiers) {
// nothing has keyboard focus during drags
}
static void drag_handle_keyboard_clear_focus(struct wlr_seat_keyboard_grab *grab) {
// nothing has keyboard focus during drags
}
static void drag_handle_keyboard_key(struct wlr_seat_keyboard_grab *grab,
uint32_t time, uint32_t key, uint32_t state) {
// no keyboard input during drags
}
static void drag_handle_keyboard_modifiers(struct wlr_seat_keyboard_grab *grab,
const struct wlr_keyboard_modifiers *modifiers) {
//struct wlr_keyboard *keyboard = grab->seat->keyboard_state.keyboard;
// TODO change the dnd action based on what modifier is pressed on the
// keyboard
}
static void drag_handle_keyboard_cancel(struct wlr_seat_keyboard_grab *grab) {
struct wlr_drag *drag = grab->data;
drag_destroy(drag);
}
static const struct wlr_keyboard_grab_interface
data_device_keyboard_drag_interface = {
.enter = drag_handle_keyboard_enter,
.clear_focus = drag_handle_keyboard_clear_focus,
.key = drag_handle_keyboard_key,
.modifiers = drag_handle_keyboard_modifiers,
.cancel = drag_handle_keyboard_cancel,
};
static void drag_handle_icon_destroy(struct wl_listener *listener, void *data) { static void drag_handle_icon_destroy(struct wl_listener *listener, void *data) {
struct wlr_drag *drag = wl_container_of(listener, drag, icon_destroy); struct wlr_drag *drag = wl_container_of(listener, drag, icon_destroy);
drag->icon = NULL; drag->icon = NULL;
@ -297,15 +135,6 @@ struct wlr_drag *wlr_drag_create(struct wlr_seat_client *seat_client,
wl_signal_add(&source->events.destroy, &drag->source_destroy); wl_signal_add(&source->events.destroy, &drag->source_destroy);
} }
drag->pointer_grab.data = drag;
drag->pointer_grab.interface = &data_device_pointer_drag_interface;
drag->touch_grab.data = drag;
drag->touch_grab.interface = &data_device_touch_drag_interface;
drag->keyboard_grab.data = drag;
drag->keyboard_grab.interface = &data_device_keyboard_drag_interface;
return drag; return drag;
} }
@ -341,8 +170,6 @@ void wlr_seat_start_drag(struct wlr_seat *seat, struct wlr_drag *drag,
assert(!drag->started); assert(!drag->started);
drag->started = true; drag->started = true;
wlr_seat_keyboard_start_grab(seat, &drag->keyboard_grab);
seat->drag = drag; seat->drag = drag;
seat->drag_serial = serial; seat->drag_serial = serial;
@ -358,28 +185,6 @@ void wlr_seat_start_drag(struct wlr_seat *seat, struct wlr_drag *drag,
wl_signal_emit_mutable(&seat->events.start_drag, drag); wl_signal_emit_mutable(&seat->events.start_drag, drag);
} }
void wlr_seat_start_pointer_drag(struct wlr_seat *seat, struct wlr_drag *drag,
uint32_t serial) {
drag->grab_type = WLR_DRAG_GRAB_KEYBOARD_POINTER;
wlr_seat_pointer_clear_focus(seat);
wlr_seat_pointer_start_grab(seat, &drag->pointer_grab);
wlr_seat_start_drag(seat, drag, serial);
}
void wlr_seat_start_touch_drag(struct wlr_seat *seat, struct wlr_drag *drag,
uint32_t serial, struct wlr_touch_point *point) {
drag->grab_type = WLR_DRAG_GRAB_KEYBOARD_TOUCH;
drag->grab_touch_id = seat->touch_state.grab_id;
drag->touch_id = point->touch_id;
wlr_seat_touch_start_grab(seat, &drag->touch_grab);
wlr_seat_drag_enter(seat, point->surface, point->sx, point->sy);
wlr_seat_start_drag(seat, drag, serial);
}
void wlr_seat_drag_enter(struct wlr_seat *seat, struct wlr_surface *surface, void wlr_seat_drag_enter(struct wlr_seat *seat, struct wlr_surface *surface,
double sx, double sy) { double sx, double sy) {
struct wlr_drag *drag = seat->drag; struct wlr_drag *drag = seat->drag;
@ -504,7 +309,19 @@ void wlr_seat_drag_drop_and_destroy(struct wlr_seat *seat, uint32_t time_msec) {
if (drag->focus_client != NULL && if (drag->focus_client != NULL &&
drag->source->current_dnd_action != WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE && drag->source->current_dnd_action != WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE &&
drag->source->accepted) { drag->source->accepted) {
drag_drop(drag, time_msec); drag->dropped = true;
struct wl_resource *resource;
wl_resource_for_each(resource, &drag->focus_client->data_devices) {
wl_data_device_send_drop(resource);
}
wlr_data_source_dnd_drop(drag->source);
struct wlr_drag_drop_event event = {
.drag = drag,
.time = time_msec,
};
wl_signal_emit_mutable(&drag->events.drop, &event);
} else if (drag->source->impl->dnd_finish != NULL) { } else if (drag->source->impl->dnd_finish != NULL) {
// This will call drag_destroy() // This will call drag_destroy()
wlr_data_source_destroy(drag->source); wlr_data_source_destroy(drag->source);