aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/seat.c
diff options
context:
space:
mode:
authorLibravatar Tony Crisci <tony@dubstepdish.com>2018-03-31 15:22:10 -0400
committerLibravatar Tony Crisci <tony@dubstepdish.com>2018-03-31 15:38:59 -0400
commit6f7b33e6919b2a8467ea1638ee56ac0232408793 (patch)
tree400a88da660080c18c463edff127fa1e27a719c2 /sway/input/seat.c
parentreap container parent on destroy (diff)
downloadsway-6f7b33e6919b2a8467ea1638ee56ac0232408793.tar.gz
sway-6f7b33e6919b2a8467ea1638ee56ac0232408793.tar.zst
sway-6f7b33e6919b2a8467ea1638ee56ac0232408793.zip
handle container destroy in the seat
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r--sway/input/seat.c104
1 files changed, 72 insertions, 32 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c
index e0fd314a..e3d53cb6 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -27,6 +27,7 @@ static void seat_device_destroy(struct sway_seat_device *seat_device) {
27} 27}
28 28
29void sway_seat_destroy(struct sway_seat *seat) { 29void sway_seat_destroy(struct sway_seat *seat) {
30 // TODO destroy seat containers
30 struct sway_seat_device *seat_device, *next; 31 struct sway_seat_device *seat_device, *next;
31 wl_list_for_each_safe(seat_device, next, &seat->devices, link) { 32 wl_list_for_each_safe(seat_device, next, &seat->devices, link) {
32 seat_device_destroy(seat_device); 33 seat_device_destroy(seat_device);
@@ -36,30 +37,57 @@ void sway_seat_destroy(struct sway_seat *seat) {
36 wlr_seat_destroy(seat->wlr_seat); 37 wlr_seat_destroy(seat->wlr_seat);
37} 38}
38 39
40static struct sway_seat_container *seat_container_from_container(
41 struct sway_seat *seat, struct sway_container *con);
42
43static void seat_container_destroy(struct sway_seat_container *seat_con) {
44 struct sway_container *con = seat_con->container;
45 struct sway_container *child = NULL;
46
47 if (con->children != NULL) {
48 for (int i = 0; i < con->children->length; ++i) {
49 child = con->children->items[i];
50 struct sway_seat_container *seat_child =
51 seat_container_from_container(seat_con->seat, child);
52 seat_container_destroy(seat_child);
53 }
54 }
55
56 wl_list_remove(&seat_con->destroy.link);
57 wl_list_remove(&seat_con->link);
58 free(seat_con);
59}
60
39static void handle_seat_container_destroy(struct wl_listener *listener, 61static void handle_seat_container_destroy(struct wl_listener *listener,
40 void *data) { 62 void *data) {
41 struct sway_seat_container *seat_con = 63 struct sway_seat_container *seat_con =
42 wl_container_of(listener, seat_con, destroy); 64 wl_container_of(listener, seat_con, destroy);
43 struct sway_seat *seat = seat_con->seat; 65 struct sway_seat *seat = seat_con->seat;
44 struct sway_container *con = seat_con->container; 66 struct sway_container *con = seat_con->container;
67 struct sway_container *parent = con->parent;
68 struct sway_container *focus = sway_seat_get_focus(seat);
45 69
46 bool is_focus = (sway_seat_get_focus(seat) == con); 70 // TODO handle workspace switch in the seat?
71 bool set_focus =
72 (focus == con || container_has_child(con, focus)) &&
73 con->type != C_WORKSPACE;
47 74
48 wl_list_remove(&seat_con->link); 75 seat_container_destroy(seat_con);
49 76
50 if (is_focus) { 77 if (set_focus && con->type != C_WORKSPACE) {
51 // pick next focus 78 struct sway_container *next_focus = NULL;
52 sway_seat_set_focus(seat, NULL); 79 while (next_focus == NULL) {
53 struct sway_container *next = sway_seat_get_focus_inactive(seat, con->parent); 80 next_focus = sway_seat_get_focus_by_type(seat, parent, C_VIEW);
54 if (next == NULL) { 81 parent = parent->parent;
55 next = con->parent;
56 }
57 sway_seat_set_focus(seat, next);
58 }
59 82
60 wl_list_remove(&seat_con->destroy.link); 83 if (next_focus == NULL && parent->type == C_WORKSPACE) {
84 next_focus = parent;
85 break;
86 }
87 }
61 88
62 free(seat_con); 89 sway_seat_set_focus(seat, next_focus);
90 }
63} 91}
64 92
65static struct sway_seat_container *seat_container_from_container( 93static struct sway_seat_container *seat_container_from_container(
@@ -293,11 +321,37 @@ void sway_seat_configure_xcursor(struct sway_seat *seat) {
293 seat->cursor->cursor->y); 321 seat->cursor->cursor->y);
294} 322}
295 323
324static void seat_send_focus(struct sway_seat *seat,
325 struct sway_container *con) {
326 if (con->type != C_VIEW) {
327 return;
328 }
329 struct sway_view *view = con->sway_view;
330 if (view->type == SWAY_XWAYLAND_VIEW) {
331 struct wlr_xwayland *xwayland =
332 seat->input->server->xwayland;
333 wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
334 }
335 view_set_activated(view, true);
336 struct wlr_keyboard *keyboard =
337 wlr_seat_get_keyboard(seat->wlr_seat);
338 if (keyboard) {
339 wlr_seat_keyboard_notify_enter(seat->wlr_seat,
340 view->surface, keyboard->keycodes,
341 keyboard->num_keycodes, &keyboard->modifiers);
342 } else {
343 wlr_seat_keyboard_notify_enter(
344 seat->wlr_seat, view->surface, NULL, 0, NULL);
345 }
346
347}
348
296void sway_seat_set_focus_warp(struct sway_seat *seat, 349void sway_seat_set_focus_warp(struct sway_seat *seat,
297 struct sway_container *container, bool warp) { 350 struct sway_container *container, bool warp) {
298 struct sway_container *last_focus = sway_seat_get_focus(seat); 351 struct sway_container *last_focus = sway_seat_get_focus(seat);
299 352
300 if (container && last_focus == container) { 353 if (container && last_focus == container) {
354 seat_send_focus(seat, container);
301 return; 355 return;
302 } 356 }
303 357
@@ -312,23 +366,7 @@ void sway_seat_set_focus_warp(struct sway_seat *seat,
312 wl_list_insert(&seat->focus_stack, &seat_con->link); 366 wl_list_insert(&seat->focus_stack, &seat_con->link);
313 367
314 if (container->type == C_VIEW) { 368 if (container->type == C_VIEW) {
315 struct sway_view *view = container->sway_view; 369 seat_send_focus(seat, container);
316 view_set_activated(view, true);
317 if (view->type == SWAY_XWAYLAND_VIEW) {
318 struct wlr_xwayland *xwayland =
319 seat->input->server->xwayland;
320 wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
321 }
322 struct wlr_keyboard *keyboard =
323 wlr_seat_get_keyboard(seat->wlr_seat);
324 if (keyboard) {
325 wlr_seat_keyboard_notify_enter(seat->wlr_seat,
326 view->surface, keyboard->keycodes,
327 keyboard->num_keycodes, &keyboard->modifiers);
328 } else {
329 wlr_seat_keyboard_notify_enter(
330 seat->wlr_seat, view->surface, NULL, 0, NULL);
331 }
332 } 370 }
333 } 371 }
334 372
@@ -378,7 +416,8 @@ void sway_seat_set_focus(struct sway_seat *seat,
378 sway_seat_set_focus_warp(seat, container, true); 416 sway_seat_set_focus_warp(seat, container, true);
379} 417}
380 418
381struct sway_container *sway_seat_get_focus_inactive(struct sway_seat *seat, struct sway_container *container) { 419struct sway_container *sway_seat_get_focus_inactive(struct sway_seat *seat,
420 struct sway_container *container) {
382 return sway_seat_get_focus_by_type(seat, container, C_TYPES); 421 return sway_seat_get_focus_by_type(seat, container, C_TYPES);
383} 422}
384 423
@@ -401,7 +440,8 @@ struct sway_container *sway_seat_get_focus_by_type(struct sway_seat *seat,
401 } 440 }
402 441
403 while (parent) { 442 while (parent) {
404 if (parent == container && (type == C_TYPES || current->container->type == type)) { 443 if (parent == container && (type == C_TYPES ||
444 current->container->type == type)) {
405 return current->container; 445 return current->container;
406 } 446 }
407 parent = parent->parent; 447 parent = parent->parent;