diff options
author | Tony Crisci <tony@dubstepdish.com> | 2016-07-31 18:10:33 -0400 |
---|---|---|
committer | Tony Crisci <tony@dubstepdish.com> | 2016-07-31 18:10:33 -0400 |
commit | f78d07d39bb4e401920efb1396cb85d9cadd8adf (patch) | |
tree | 2c53f09455cebea9bf5af0eb5bfaff7858b37efe | |
parent | Merge pull request #808 from zandrmartin/document-kill-command (diff) | |
download | sway-f78d07d39bb4e401920efb1396cb85d9cadd8adf.tar.gz sway-f78d07d39bb4e401920efb1396cb85d9cadd8adf.tar.zst sway-f78d07d39bb4e401920efb1396cb85d9cadd8adf.zip |
Implement focus handling for containers
The previous implementation of focus handling assumed that only views can be
focused. Containers can also be focused with a command like `focus parent` or
`focus child`.
Change `set_focused_container()` to handle the case of the given container
being a container with children and update borders accordingly.
-rw-r--r-- | include/border.h | 5 | ||||
-rw-r--r-- | sway/border.c | 20 | ||||
-rw-r--r-- | sway/focus.c | 29 |
3 files changed, 36 insertions, 18 deletions
diff --git a/include/border.h b/include/border.h index b629ba46..b61b0f8a 100644 --- a/include/border.h +++ b/include/border.h | |||
@@ -16,6 +16,11 @@ struct border { | |||
16 | */ | 16 | */ |
17 | void border_clear(struct border *border); | 17 | void border_clear(struct border *border); |
18 | 18 | ||
19 | /** | ||
20 | * Recursively update all of the borders within a container. | ||
21 | */ | ||
22 | void update_container_border(swayc_t *container); | ||
23 | |||
19 | void render_view_borders(wlc_handle view); | 24 | void render_view_borders(wlc_handle view); |
20 | void update_view_border(swayc_t *view); | 25 | void update_view_border(swayc_t *view); |
21 | void map_update_view_border(swayc_t *view, void *data); | 26 | void map_update_view_border(swayc_t *view, void *data); |
diff --git a/sway/border.c b/sway/border.c index c1a62bc6..c3e1004a 100644 --- a/sway/border.c +++ b/sway/border.c | |||
@@ -308,6 +308,9 @@ void update_view_border(swayc_t *view) { | |||
308 | swayc_t *focused = get_focused_view(&root_container); | 308 | swayc_t *focused = get_focused_view(&root_container); |
309 | swayc_t *container = swayc_parent_by_type(view, C_CONTAINER); | 309 | swayc_t *container = swayc_parent_by_type(view, C_CONTAINER); |
310 | swayc_t *focused_inactive = NULL; | 310 | swayc_t *focused_inactive = NULL; |
311 | |||
312 | bool is_child_of_focused = swayc_is_parent_of(get_focused_container(&root_container), view); | ||
313 | |||
311 | if (container) { | 314 | if (container) { |
312 | focused_inactive = swayc_focus_by_type(container, C_VIEW); | 315 | focused_inactive = swayc_focus_by_type(container, C_VIEW); |
313 | } else { | 316 | } else { |
@@ -334,7 +337,7 @@ void update_view_border(swayc_t *view) { | |||
334 | cr = create_border_buffer(view, g, &surface); | 337 | cr = create_border_buffer(view, g, &surface); |
335 | 338 | ||
336 | bool render_top = !should_hide_top_border(view, view->y); | 339 | bool render_top = !should_hide_top_border(view, view->y); |
337 | if (view == focused) { | 340 | if (view == focused || is_child_of_focused) { |
338 | render_borders(view, cr, &config->border_colors.focused, render_top); | 341 | render_borders(view, cr, &config->border_colors.focused, render_top); |
339 | } else { | 342 | } else { |
340 | render_borders(view, cr, &config->border_colors.focused_inactive, render_top); | 343 | render_borders(view, cr, &config->border_colors.focused_inactive, render_top); |
@@ -360,7 +363,7 @@ void update_view_border(swayc_t *view) { | |||
360 | break; | 363 | break; |
361 | } | 364 | } |
362 | 365 | ||
363 | if (focused == view) { | 366 | if (focused == view || is_child_of_focused) { |
364 | render_borders(view, cr, &config->border_colors.focused, true); | 367 | render_borders(view, cr, &config->border_colors.focused, true); |
365 | } else if (focused_inactive == view) { | 368 | } else if (focused_inactive == view) { |
366 | render_borders(view, cr, &config->border_colors.focused_inactive, true); | 369 | render_borders(view, cr, &config->border_colors.focused_inactive, true); |
@@ -375,7 +378,7 @@ void update_view_border(swayc_t *view) { | |||
375 | break; | 378 | break; |
376 | } | 379 | } |
377 | 380 | ||
378 | if (focused == view) { | 381 | if (focused == view || is_child_of_focused) { |
379 | render_borders(view, cr, &config->border_colors.focused, false); | 382 | render_borders(view, cr, &config->border_colors.focused, false); |
380 | render_title_bar(view, cr, &view->border_geometry, | 383 | render_title_bar(view, cr, &view->border_geometry, |
381 | &config->border_colors.focused); | 384 | &config->border_colors.focused); |
@@ -403,6 +406,17 @@ void update_view_border(swayc_t *view) { | |||
403 | } | 406 | } |
404 | } | 407 | } |
405 | 408 | ||
409 | void update_container_border(swayc_t *container) { | ||
410 | if (container->type == C_VIEW) { | ||
411 | update_view_border(container); | ||
412 | return; | ||
413 | } else { | ||
414 | for (int i = 0; i < container->children->length; ++i) { | ||
415 | update_container_border(container->children->items[i]); | ||
416 | } | ||
417 | } | ||
418 | } | ||
419 | |||
406 | void render_view_borders(wlc_handle view) { | 420 | void render_view_borders(wlc_handle view) { |
407 | swayc_t *c = swayc_by_handle(view); | 421 | swayc_t *c = swayc_by_handle(view); |
408 | 422 | ||
diff --git a/sway/focus.c b/sway/focus.c index 0f629e1e..576a5e9b 100644 --- a/sway/focus.c +++ b/sway/focus.c | |||
@@ -115,7 +115,7 @@ bool set_focused_container(swayc_t *c) { | |||
115 | 115 | ||
116 | // Get workspace for c, get that workspaces current focused container. | 116 | // Get workspace for c, get that workspaces current focused container. |
117 | swayc_t *workspace = swayc_active_workspace_for(c); | 117 | swayc_t *workspace = swayc_active_workspace_for(c); |
118 | swayc_t *focused = get_focused_view(workspace); | 118 | swayc_t *focused = get_focused_container(workspace); |
119 | 119 | ||
120 | if (swayc_is_fullscreen(focused) && focused != c) { | 120 | if (swayc_is_fullscreen(focused) && focused != c) { |
121 | // if switching to a workspace with a fullscreen view, | 121 | // if switching to a workspace with a fullscreen view, |
@@ -140,33 +140,32 @@ bool set_focused_container(swayc_t *c) { | |||
140 | } | 140 | } |
141 | 141 | ||
142 | // get new focused view and set focus to it. | 142 | // get new focused view and set focus to it. |
143 | p = get_focused_view(c); | 143 | if (c->type == C_CONTAINER || (c->type == C_VIEW && !(wlc_view_get_type(p->handle) & WLC_BIT_POPUP))) { |
144 | if (p->type == C_VIEW && !(wlc_view_get_type(p->handle) & WLC_BIT_POPUP)) { | ||
145 | // unactivate previous focus | 144 | // unactivate previous focus |
146 | if (focused->type == C_VIEW) { | 145 | if (focused->type == C_VIEW) { |
147 | wlc_view_set_state(focused->handle, WLC_BIT_ACTIVATED, false); | 146 | wlc_view_set_state(focused->handle, WLC_BIT_ACTIVATED, false); |
148 | update_view_border(focused); | ||
149 | } | 147 | } |
148 | update_container_border(focused); | ||
150 | // activate current focus | 149 | // activate current focus |
151 | if (p->type == C_VIEW) { | 150 | if (c->type == C_VIEW) { |
152 | wlc_view_set_state(p->handle, WLC_BIT_ACTIVATED, true); | 151 | wlc_view_set_state(c->handle, WLC_BIT_ACTIVATED, true); |
153 | // set focus if view_focus is unlocked | 152 | } |
154 | if (!locked_view_focus) { | 153 | // set focus if view_focus is unlocked |
155 | wlc_view_focus(p->handle); | 154 | if (!locked_view_focus) { |
156 | if (p->parent->layout != L_TABBED | 155 | wlc_view_focus(c->handle); |
157 | && p->parent->layout != L_STACKED) { | 156 | if (c->parent->layout != L_TABBED |
158 | update_view_border(p); | 157 | && c->parent->layout != L_STACKED) { |
159 | } | 158 | update_container_border(c); |
160 | } | 159 | } |
161 | } | 160 | } |
162 | 161 | ||
163 | // rearrange if parent container is tabbed/stacked | 162 | // rearrange if parent container is tabbed/stacked |
164 | swayc_t *parent = swayc_tabbed_stacked_ancestor(p); | 163 | swayc_t *parent = swayc_tabbed_stacked_ancestor(c); |
165 | if (parent != NULL) { | 164 | if (parent != NULL) { |
166 | arrange_backgrounds(); | 165 | arrange_backgrounds(); |
167 | arrange_windows(parent, -1, -1); | 166 | arrange_windows(parent, -1, -1); |
168 | } | 167 | } |
169 | } else if (p->type == C_WORKSPACE) { | 168 | } else if (c->type == C_WORKSPACE) { |
170 | // remove previous focus if view_focus is unlocked | 169 | // remove previous focus if view_focus is unlocked |
171 | if (!locked_view_focus) { | 170 | if (!locked_view_focus) { |
172 | wlc_view_focus(0); | 171 | wlc_view_focus(0); |