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 | |
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
-rw-r--r-- | sway/desktop/output.c | 19 | ||||
-rw-r--r-- | sway/input/seat.c | 99 |
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 | ||
455 | static void render_container(struct sway_output *output, | 455 | static 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 | */ |
464 | static void render_container_simple(struct sway_output *output, | 464 | static 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 | ||
518 | static void render_container(struct sway_output *output, | 520 | static 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 | ||
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 = |