diff options
-rw-r--r-- | include/sway/input/seat.h | 6 | ||||
-rw-r--r-- | sway/input/seat.c | 38 |
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 | ||
67 | struct sway_drag { | ||
68 | struct sway_seat *seat; | ||
69 | struct wlr_drag *wlr_drag; | ||
70 | struct wl_listener destroy; | ||
71 | }; | ||
72 | |||
67 | struct sway_seat { | 73 | struct 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 | ||
405 | static 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 | |||
405 | static void handle_request_start_drag(struct wl_listener *listener, | 430 | static 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, | |||
431 | static void handle_start_drag(struct wl_listener *listener, void *data) { | 456 | static 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; |