diff --git a/include/wlr/types/wlr_data_device.h b/include/wlr/types/wlr_data_device.h index b4aa024a..e1e1e516 100644 --- a/include/wlr/types/wlr_data_device.h +++ b/include/wlr/types/wlr_data_device.h @@ -7,6 +7,9 @@ extern const struct wlr_pointer_grab_interface wlr_data_device_pointer_drag_interface; +extern const struct +wlr_keyboard_grab_interface wlr_data_device_keyboard_drag_interface; + struct wlr_data_device_manager { struct wl_global *global; }; @@ -49,6 +52,8 @@ struct wlr_data_source { struct wlr_drag { struct wlr_seat_pointer_grab pointer_grab; + struct wlr_seat_keyboard_grab keyboard_grab; + struct wlr_seat_handle *handle; struct wlr_seat_handle *focus_handle; diff --git a/types/wlr_data_device.c b/types/wlr_data_device.c index 0ee88161..6616c338 100644 --- a/types/wlr_data_device.c +++ b/types/wlr_data_device.c @@ -438,6 +438,7 @@ static void wlr_drag_end(struct wlr_drag *drag) { wlr_drag_set_focus(drag, NULL, 0, 0); wlr_seat_pointer_end_grab(drag->pointer_grab.seat); + wlr_seat_keyboard_end_grab(drag->keyboard_grab.seat); free(drag); } @@ -508,6 +509,36 @@ wlr_pointer_grab_interface wlr_data_device_pointer_drag_interface = { .cancel = pointer_drag_cancel, }; +static void keyboard_drag_enter(struct wlr_seat_keyboard_grab *grab, + struct wlr_surface *surface) { + // nothing has keyboard focus during drags +} + +static void keyboard_drag_key(struct wlr_seat_keyboard_grab *grab, + uint32_t time, uint32_t key, uint32_t state) { + // no keyboard input during drags +} + +static void keyboard_drag_modifiers(struct wlr_seat_keyboard_grab *grab, + uint32_t mods_depressed, uint32_t mods_latched, + uint32_t mods_locked, uint32_t group) { + // TODO change the dnd action based on what modifier is pressed on the + // keyboard +} + +static void keyboard_drag_cancel(struct wlr_seat_keyboard_grab *grab) { + struct wlr_drag *drag = grab->data; + wlr_drag_end(drag); +} + +const struct +wlr_keyboard_grab_interface wlr_data_device_keyboard_drag_interface = { + .enter = keyboard_drag_enter, + .key = keyboard_drag_key, + .modifiers = keyboard_drag_modifiers, + .cancel = keyboard_drag_cancel, +}; + static void drag_handle_icon_destroy(struct wl_listener *listener, void *data) { struct wlr_drag *drag = wl_container_of(listener, drag, icon_destroy); drag->icon = NULL; @@ -545,8 +576,12 @@ static bool seat_handle_start_drag(struct wlr_seat_handle *handle, drag->pointer_grab.data = drag; drag->pointer_grab.interface = &wlr_data_device_pointer_drag_interface; + drag->keyboard_grab.data = drag; + drag->keyboard_grab.interface = &wlr_data_device_keyboard_drag_interface; + wlr_seat_pointer_clear_focus(seat); + wlr_seat_keyboard_start_grab(seat, &drag->keyboard_grab); wlr_seat_pointer_start_grab(seat, &drag->pointer_grab); // TODO keyboard grab diff --git a/types/wlr_seat.c b/types/wlr_seat.c index bad0e5cf..a4721e22 100644 --- a/types/wlr_seat.c +++ b/types/wlr_seat.c @@ -696,9 +696,11 @@ void wlr_seat_keyboard_start_grab(struct wlr_seat *wlr_seat, void wlr_seat_keyboard_end_grab(struct wlr_seat *wlr_seat) { struct wlr_seat_keyboard_grab *grab = wlr_seat->keyboard_state.grab; - wlr_seat->keyboard_state.grab = wlr_seat->keyboard_state.default_grab; - wl_signal_emit(&wlr_seat->events.keyboard_grab_end, grab); + if (grab != wlr_seat->keyboard_state.default_grab) { + wlr_seat->keyboard_state.grab = wlr_seat->keyboard_state.default_grab; + wl_signal_emit(&wlr_seat->events.keyboard_grab_end, grab); + } } static void keyboard_surface_destroy_notify(struct wl_listener *listener,