aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/input/seat.h6
-rw-r--r--sway/input/seat.c38
2 files changed, 44 insertions, 0 deletions
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h
index 37de1223..2256fff1 100644
--- a/include/sway/input/seat.h
+++ b/include/sway/input/seat.h
@@ -64,6 +64,12 @@ struct sway_drag_icon {
64 struct wl_listener destroy; 64 struct wl_listener destroy;
65}; 65};
66 66
67struct sway_drag {
68 struct sway_seat *seat;
69 struct wlr_drag *wlr_drag;
70 struct wl_listener destroy;
71};
72
67struct sway_seat { 73struct sway_seat {
68 struct wlr_seat *wlr_seat; 74 struct wlr_seat *wlr_seat;
69 struct sway_cursor *cursor; 75 struct sway_cursor *cursor;
diff --git a/sway/input/seat.c b/sway/input/seat.c
index aa56394a..a54bc2e7 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -402,6 +402,31 @@ static void drag_icon_handle_destroy(struct wl_listener *listener, void *data) {
402 free(icon); 402 free(icon);
403} 403}
404 404
405static void drag_handle_destroy(struct wl_listener *listener, void *data) {
406 struct sway_drag *drag = wl_container_of(listener, drag, destroy);
407
408 // Focus enter isn't sent during drag, so refocus the focused node, layer
409 // surface or unmanaged surface.
410 struct sway_seat *seat = drag->seat;
411 struct sway_node *focus = seat_get_focus(seat);
412 if (focus) {
413 seat_set_focus(seat, NULL);
414 seat_set_focus(seat, focus);
415 } else if (seat->focused_layer) {
416 struct wlr_layer_surface_v1 *layer = seat->focused_layer;
417 seat_set_focus_layer(seat, NULL);
418 seat_set_focus_layer(seat, layer);
419 } else {
420 struct wlr_surface *unmanaged = seat->wlr_seat->keyboard_state.focused_surface;
421 seat_set_focus_surface(seat, NULL, false);
422 seat_set_focus_surface(seat, unmanaged, false);
423 }
424
425 drag->wlr_drag->data = NULL;
426 wl_list_remove(&drag->destroy.link);
427 free(drag);
428}
429
405static void handle_request_start_drag(struct wl_listener *listener, 430static void handle_request_start_drag(struct wl_listener *listener,
406 void *data) { 431 void *data) {
407 struct sway_seat *seat = wl_container_of(listener, seat, request_start_drag); 432 struct sway_seat *seat = wl_container_of(listener, seat, request_start_drag);
@@ -431,6 +456,19 @@ static void handle_request_start_drag(struct wl_listener *listener,
431static void handle_start_drag(struct wl_listener *listener, void *data) { 456static void handle_start_drag(struct wl_listener *listener, void *data) {
432 struct sway_seat *seat = wl_container_of(listener, seat, start_drag); 457 struct sway_seat *seat = wl_container_of(listener, seat, start_drag);
433 struct wlr_drag *wlr_drag = data; 458 struct wlr_drag *wlr_drag = data;
459
460 struct sway_drag *drag = calloc(1, sizeof(struct sway_drag));
461 if (drag == NULL) {
462 sway_log(SWAY_ERROR, "Allocation failed");
463 return;
464 }
465 drag->seat = seat;
466 drag->wlr_drag = wlr_drag;
467 wlr_drag->data = drag;
468
469 drag->destroy.notify = drag_handle_destroy;
470 wl_signal_add(&wlr_drag->events.destroy, &drag->destroy);
471
434 struct wlr_drag_icon *wlr_drag_icon = wlr_drag->icon; 472 struct wlr_drag_icon *wlr_drag_icon = wlr_drag->icon;
435 if (wlr_drag_icon == NULL) { 473 if (wlr_drag_icon == NULL) {
436 return; 474 return;