diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-05-11 09:13:40 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-05-11 09:20:46 +1000 |
commit | 83e314bf51265ca825eaa78ffaaedeb10621f1b3 (patch) | |
tree | 74018b8596c8a130dae6dbeeca79d0dab9d653ec /sway/input/seat.c | |
parent | Merge pull request #1923 from emersion/full-damage-tracking (diff) | |
download | sway-83e314bf51265ca825eaa78ffaaedeb10621f1b3.tar.gz sway-83e314bf51265ca825eaa78ffaaedeb10621f1b3.tar.zst sway-83e314bf51265ca825eaa78ffaaedeb10621f1b3.zip |
Highlight all child borders when using focus parent
Diffstat (limited to 'sway/input/seat.c')
-rw-r--r-- | sway/input/seat.c | 99 |
1 files changed, 61 insertions, 38 deletions
diff --git a/sway/input/seat.c b/sway/input/seat.c index 2c279ff2..9ac3e6a8 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -65,27 +65,49 @@ static void seat_container_destroy(struct sway_seat_container *seat_con) { | |||
65 | free(seat_con); | 65 | free(seat_con); |
66 | } | 66 | } |
67 | 67 | ||
68 | static void seat_send_focus(struct sway_seat *seat, | 68 | /** |
69 | struct sway_container *con) { | 69 | * Activate all views within this container recursively. |
70 | if (con->type != C_VIEW) { | 70 | */ |
71 | return; | 71 | static void seat_send_activate(struct sway_container *con, |
72 | } | 72 | struct sway_seat *seat) { |
73 | struct sway_view *view = con->sway_view; | 73 | if (con->type == C_VIEW) { |
74 | if (view->type == SWAY_VIEW_XWAYLAND) { | 74 | if (!seat_is_input_allowed(seat, con->sway_view->surface)) { |
75 | struct wlr_xwayland *xwayland = | 75 | wlr_log(L_DEBUG, "Refusing to set focus, input is inhibited"); |
76 | seat->input->server->xwayland; | 76 | return; |
77 | wlr_xwayland_set_seat(xwayland, seat->wlr_seat); | 77 | } |
78 | } | 78 | view_set_activated(con->sway_view, true); |
79 | view_set_activated(view, true); | ||
80 | struct wlr_keyboard *keyboard = | ||
81 | wlr_seat_get_keyboard(seat->wlr_seat); | ||
82 | if (keyboard) { | ||
83 | wlr_seat_keyboard_notify_enter(seat->wlr_seat, | ||
84 | view->surface, keyboard->keycodes, | ||
85 | keyboard->num_keycodes, &keyboard->modifiers); | ||
86 | } else { | 79 | } else { |
87 | wlr_seat_keyboard_notify_enter( | 80 | for (int i = 0; i < con->children->length; ++i) { |
88 | seat->wlr_seat, view->surface, NULL, 0, NULL); | 81 | struct sway_container *child = con->children->items[i]; |
82 | seat_send_activate(child, seat); | ||
83 | } | ||
84 | } | ||
85 | } | ||
86 | |||
87 | /** | ||
88 | * If con is a view, set it as active and enable keyboard input. | ||
89 | * If con is a container, set all child views as active and don't enable | ||
90 | * keyboard input on any. | ||
91 | */ | ||
92 | static void seat_send_focus(struct sway_container *con, | ||
93 | struct sway_seat *seat) { | ||
94 | seat_send_activate(con, seat); | ||
95 | |||
96 | if (con->type == C_VIEW | ||
97 | && seat_is_input_allowed(seat, con->sway_view->surface)) { | ||
98 | if (con->sway_view->type == SWAY_VIEW_XWAYLAND) { | ||
99 | struct wlr_xwayland *xwayland = seat->input->server->xwayland; | ||
100 | wlr_xwayland_set_seat(xwayland, seat->wlr_seat); | ||
101 | } | ||
102 | struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat); | ||
103 | if (keyboard) { | ||
104 | wlr_seat_keyboard_notify_enter(seat->wlr_seat, | ||
105 | con->sway_view->surface, keyboard->keycodes, | ||
106 | keyboard->num_keycodes, &keyboard->modifiers); | ||
107 | } else { | ||
108 | wlr_seat_keyboard_notify_enter( | ||
109 | seat->wlr_seat, con->sway_view->surface, NULL, 0, NULL); | ||
110 | } | ||
89 | } | 111 | } |
90 | } | 112 | } |
91 | 113 | ||
@@ -160,7 +182,7 @@ static void handle_seat_container_destroy(struct wl_listener *listener, | |||
160 | // the structure change might have caused it to move up to the top of | 182 | // the structure change might have caused it to move up to the top of |
161 | // the focus stack without sending focus notifications to the view | 183 | // the focus stack without sending focus notifications to the view |
162 | if (seat_get_focus(seat) == next_focus) { | 184 | if (seat_get_focus(seat) == next_focus) { |
163 | seat_send_focus(seat, next_focus); | 185 | seat_send_focus(next_focus, seat); |
164 | } else { | 186 | } else { |
165 | seat_set_focus(seat, next_focus); | 187 | seat_set_focus(seat, next_focus); |
166 | } | 188 | } |
@@ -457,6 +479,20 @@ bool seat_is_input_allowed(struct sway_seat *seat, | |||
457 | return !seat->exclusive_client || seat->exclusive_client == client; | 479 | return !seat->exclusive_client || seat->exclusive_client == client; |
458 | } | 480 | } |
459 | 481 | ||
482 | // Unfocus the container and any children (eg. when leaving `focus parent`) | ||
483 | static void seat_send_unfocus(struct sway_container *container, | ||
484 | struct sway_seat *seat) { | ||
485 | if (container->type == C_VIEW) { | ||
486 | wlr_seat_keyboard_clear_focus(seat->wlr_seat); | ||
487 | view_set_activated(container->sway_view, false); | ||
488 | } else { | ||
489 | for (int i = 0; i < container->children->length; ++i) { | ||
490 | struct sway_container *child = container->children->items[i]; | ||
491 | seat_send_unfocus(child, seat); | ||
492 | } | ||
493 | } | ||
494 | } | ||
495 | |||
460 | void seat_set_focus_warp(struct sway_seat *seat, | 496 | void seat_set_focus_warp(struct sway_seat *seat, |
461 | struct sway_container *container, bool warp) { | 497 | struct sway_container *container, bool warp) { |
462 | if (seat->focused_layer) { | 498 | if (seat->focused_layer) { |
@@ -521,15 +557,11 @@ void seat_set_focus_warp(struct sway_seat *seat, | |||
521 | wl_list_remove(&seat_con->link); | 557 | wl_list_remove(&seat_con->link); |
522 | wl_list_insert(&seat->focus_stack, &seat_con->link); | 558 | wl_list_insert(&seat->focus_stack, &seat_con->link); |
523 | 559 | ||
524 | if (container->type == C_VIEW && !seat_is_input_allowed( | 560 | if (last_focus) { |
525 | seat, container->sway_view->surface)) { | 561 | seat_send_unfocus(last_focus, seat); |
526 | wlr_log(L_DEBUG, "Refusing to set focus, input is inhibited"); | ||
527 | return; | ||
528 | } | 562 | } |
529 | 563 | ||
530 | if (container->type == C_VIEW) { | 564 | seat_send_focus(container, seat); |
531 | seat_send_focus(seat, container); | ||
532 | } | ||
533 | container_damage_whole(container); | 565 | container_damage_whole(container); |
534 | } | 566 | } |
535 | 567 | ||
@@ -580,12 +612,6 @@ void seat_set_focus_warp(struct sway_seat *seat, | |||
580 | container_damage_whole(last_focus); | 612 | container_damage_whole(last_focus); |
581 | } | 613 | } |
582 | 614 | ||
583 | if (last_focus && last_focus->type == C_VIEW && | ||
584 | !input_manager_has_focus(seat->input, last_focus)) { | ||
585 | struct sway_view *view = last_focus->sway_view; | ||
586 | view_set_activated(view, false); | ||
587 | } | ||
588 | |||
589 | if (last_workspace && last_workspace != new_workspace) { | 615 | if (last_workspace && last_workspace != new_workspace) { |
590 | cursor_send_pointer_motion(seat->cursor, 0); | 616 | cursor_send_pointer_motion(seat->cursor, 0); |
591 | } | 617 | } |
@@ -607,10 +633,7 @@ void seat_set_focus_surface(struct sway_seat *seat, | |||
607 | } | 633 | } |
608 | if (seat->has_focus) { | 634 | if (seat->has_focus) { |
609 | struct sway_container *focus = seat_get_focus(seat); | 635 | struct sway_container *focus = seat_get_focus(seat); |
610 | if (focus->type == C_VIEW) { | 636 | seat_send_unfocus(focus, seat); |
611 | wlr_seat_keyboard_clear_focus(seat->wlr_seat); | ||
612 | view_set_activated(focus->sway_view, false); | ||
613 | } | ||
614 | seat->has_focus = false; | 637 | seat->has_focus = false; |
615 | } | 638 | } |
616 | struct wlr_keyboard *keyboard = | 639 | struct wlr_keyboard *keyboard = |