aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sway/desktop/output.c19
-rw-r--r--sway/input/seat.c99
2 files changed, 73 insertions, 45 deletions
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index c150270e..a25139b4 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -453,7 +453,7 @@ static void render_container_simple_border_pixel(struct sway_output *output,
453} 453}
454 454
455static void render_container(struct sway_output *output, 455static void render_container(struct sway_output *output,
456 pixman_region32_t *damage, struct sway_container *con); 456 pixman_region32_t *damage, struct sway_container *con, bool parent_focused);
457 457
458/** 458/**
459 * Render a container's children using a L_HORIZ or L_VERT layout. 459 * Render a container's children using a L_HORIZ or L_VERT layout.
@@ -462,7 +462,8 @@ static void render_container(struct sway_output *output,
462 * they'll apply their own borders to their children. 462 * they'll apply their own borders to their children.
463 */ 463 */
464static void render_container_simple(struct sway_output *output, 464static void render_container_simple(struct sway_output *output,
465 pixman_region32_t *damage, struct sway_container *con) { 465 pixman_region32_t *damage, struct sway_container *con,
466 bool parent_focused) {
466 struct sway_seat *seat = input_manager_current_seat(input_manager); 467 struct sway_seat *seat = input_manager_current_seat(input_manager);
467 struct sway_container *focus = seat_get_focus(seat); 468 struct sway_container *focus = seat_get_focus(seat);
468 469
@@ -473,7 +474,7 @@ static void render_container_simple(struct sway_output *output,
473 if (child->sway_view->border != B_NONE) { 474 if (child->sway_view->border != B_NONE) {
474 struct border_colors *colors; 475 struct border_colors *colors;
475 struct wlr_texture *title_texture; 476 struct wlr_texture *title_texture;
476 if (focus == child) { 477 if (focus == child || parent_focused) {
477 colors = &config->border_colors.focused; 478 colors = &config->border_colors.focused;
478 title_texture = child->title_focused; 479 title_texture = child->title_focused;
479 } else if (seat_get_focus_inactive(seat, con) == child) { 480 } else if (seat_get_focus_inactive(seat, con) == child) {
@@ -494,7 +495,8 @@ static void render_container_simple(struct sway_output *output,
494 } 495 }
495 render_view(child->sway_view, output, damage); 496 render_view(child->sway_view, output, damage);
496 } else { 497 } else {
497 render_container(output, damage, child); 498 render_container(output, damage, child,
499 parent_focused || focus == child);
498 } 500 }
499 } 501 }
500} 502}
@@ -516,12 +518,13 @@ static void render_container_stacked(struct sway_output *output,
516} 518}
517 519
518static void render_container(struct sway_output *output, 520static void render_container(struct sway_output *output,
519 pixman_region32_t *damage, struct sway_container *con) { 521 pixman_region32_t *damage, struct sway_container *con,
522 bool parent_focused) {
520 switch (con->layout) { 523 switch (con->layout) {
521 case L_NONE: 524 case L_NONE:
522 case L_HORIZ: 525 case L_HORIZ:
523 case L_VERT: 526 case L_VERT:
524 render_container_simple(output, damage, con); 527 render_container_simple(output, damage, con, parent_focused);
525 break; 528 break;
526 case L_STACKED: 529 case L_STACKED:
527 render_container_stacked(output, damage, con); 530 render_container_stacked(output, damage, con);
@@ -605,7 +608,9 @@ static void render_output(struct sway_output *output, struct timespec *when,
605 render_layer(output, damage, 608 render_layer(output, damage,
606 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]); 609 &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
607 610
608 render_container(output, damage, workspace); 611 struct sway_seat *seat = input_manager_current_seat(input_manager);
612 struct sway_container *focus = seat_get_focus(seat);
613 render_container(output, damage, workspace, focus == workspace);
609 614
610 render_unmanaged(output, damage, 615 render_unmanaged(output, damage,
611 &root_container.sway_root->xwayland_unmanaged); 616 &root_container.sway_root->xwayland_unmanaged);
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
68static 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; 71static 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 */
92static 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`)
483static 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
460void seat_set_focus_warp(struct sway_seat *seat, 496void 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 =