diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | include/border.h | 6 | ||||
-rw-r--r-- | include/focus.h | 1 | ||||
-rw-r--r-- | sway/border.c | 38 | ||||
-rw-r--r-- | sway/commands.c | 26 | ||||
-rw-r--r-- | sway/focus.c | 34 | ||||
-rw-r--r-- | sway/handlers.c | 14 | ||||
-rw-r--r-- | sway/layout.c | 8 |
8 files changed, 81 insertions, 48 deletions
@@ -6,7 +6,7 @@ Read the [FAQ](https://github.com/SirCmpwn/sway/wiki). Join the | |||
6 | [IRC channel](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway on | 6 | [IRC channel](http://webchat.freenode.net/?channels=sway&uio=d4) (#sway on |
7 | irc.freenode.net). | 7 | irc.freenode.net). |
8 | 8 | ||
9 | ![](https://sr.ht/me1j.png) | 9 | [![](https://sr.ht/ICd5.png)](https://sr.ht/ICd5.png) |
10 | 10 | ||
11 | ## Release Signatures | 11 | ## Release Signatures |
12 | 12 | ||
diff --git a/include/border.h b/include/border.h index b629ba46..b72dc5dc 100644 --- a/include/border.h +++ b/include/border.h | |||
@@ -16,8 +16,12 @@ 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); | ||
21 | void map_update_view_border(swayc_t *view, void *data); | 25 | void map_update_view_border(swayc_t *view, void *data); |
22 | int get_font_text_height(const char *font); | 26 | int get_font_text_height(const char *font); |
23 | bool should_hide_top_border(swayc_t *con, double y); | 27 | bool should_hide_top_border(swayc_t *con, double y); |
diff --git a/include/focus.h b/include/focus.h index 236d050b..b532edc2 100644 --- a/include/focus.h +++ b/include/focus.h | |||
@@ -33,7 +33,6 @@ bool set_focused_container_for(swayc_t *ancestor, swayc_t *container); | |||
33 | // and unlocked when they are destroyed | 33 | // and unlocked when they are destroyed |
34 | 34 | ||
35 | extern bool locked_container_focus; | 35 | extern bool locked_container_focus; |
36 | extern bool locked_view_focus; | ||
37 | 36 | ||
38 | // Prevents wss from being destroyed on focus switch | 37 | // Prevents wss from being destroyed on focus switch |
39 | extern bool suspend_workspace_cleanup; | 38 | extern bool suspend_workspace_cleanup; |
diff --git a/sway/border.c b/sway/border.c index c1a62bc6..46343d61 100644 --- a/sway/border.c +++ b/sway/border.c | |||
@@ -201,12 +201,6 @@ static void render_title_bar(swayc_t *view, cairo_t *cr, struct wlc_geometry *b, | |||
201 | } | 201 | } |
202 | } | 202 | } |
203 | 203 | ||
204 | void map_update_view_border(swayc_t *view, void *data) { | ||
205 | if (view->type == C_VIEW) { | ||
206 | update_view_border(view); | ||
207 | } | ||
208 | } | ||
209 | |||
210 | /** | 204 | /** |
211 | * Generate nested container title for tabbed/stacked layouts | 205 | * Generate nested container title for tabbed/stacked layouts |
212 | */ | 206 | */ |
@@ -239,6 +233,10 @@ static char *generate_container_title(swayc_t *container) { | |||
239 | title = generate_container_title(child); | 233 | title = generate_container_title(child); |
240 | } | 234 | } |
241 | 235 | ||
236 | if (!title) { | ||
237 | title = "(null)"; | ||
238 | } | ||
239 | |||
242 | len = strlen(name) + strlen(title) + 1; | 240 | len = strlen(name) + strlen(title) + 1; |
243 | if (i < container->children->length-1) { | 241 | if (i < container->children->length-1) { |
244 | len++; | 242 | len++; |
@@ -293,7 +291,7 @@ void update_tabbed_stacked_titlebars(swayc_t *c, cairo_t *cr, struct wlc_geometr | |||
293 | } | 291 | } |
294 | } | 292 | } |
295 | 293 | ||
296 | void update_view_border(swayc_t *view) { | 294 | static void update_view_border(swayc_t *view) { |
297 | if (!view->visible) { | 295 | if (!view->visible) { |
298 | return; | 296 | return; |
299 | } | 297 | } |
@@ -308,6 +306,9 @@ void update_view_border(swayc_t *view) { | |||
308 | swayc_t *focused = get_focused_view(&root_container); | 306 | swayc_t *focused = get_focused_view(&root_container); |
309 | swayc_t *container = swayc_parent_by_type(view, C_CONTAINER); | 307 | swayc_t *container = swayc_parent_by_type(view, C_CONTAINER); |
310 | swayc_t *focused_inactive = NULL; | 308 | swayc_t *focused_inactive = NULL; |
309 | |||
310 | bool is_child_of_focused = swayc_is_parent_of(get_focused_container(&root_container), view); | ||
311 | |||
311 | if (container) { | 312 | if (container) { |
312 | focused_inactive = swayc_focus_by_type(container, C_VIEW); | 313 | focused_inactive = swayc_focus_by_type(container, C_VIEW); |
313 | } else { | 314 | } else { |
@@ -334,7 +335,7 @@ void update_view_border(swayc_t *view) { | |||
334 | cr = create_border_buffer(view, g, &surface); | 335 | cr = create_border_buffer(view, g, &surface); |
335 | 336 | ||
336 | bool render_top = !should_hide_top_border(view, view->y); | 337 | bool render_top = !should_hide_top_border(view, view->y); |
337 | if (view == focused) { | 338 | if (view == focused || is_child_of_focused) { |
338 | render_borders(view, cr, &config->border_colors.focused, render_top); | 339 | render_borders(view, cr, &config->border_colors.focused, render_top); |
339 | } else { | 340 | } else { |
340 | render_borders(view, cr, &config->border_colors.focused_inactive, render_top); | 341 | render_borders(view, cr, &config->border_colors.focused_inactive, render_top); |
@@ -360,7 +361,7 @@ void update_view_border(swayc_t *view) { | |||
360 | break; | 361 | break; |
361 | } | 362 | } |
362 | 363 | ||
363 | if (focused == view) { | 364 | if (focused == view || is_child_of_focused) { |
364 | render_borders(view, cr, &config->border_colors.focused, true); | 365 | render_borders(view, cr, &config->border_colors.focused, true); |
365 | } else if (focused_inactive == view) { | 366 | } else if (focused_inactive == view) { |
366 | render_borders(view, cr, &config->border_colors.focused_inactive, true); | 367 | render_borders(view, cr, &config->border_colors.focused_inactive, true); |
@@ -375,7 +376,7 @@ void update_view_border(swayc_t *view) { | |||
375 | break; | 376 | break; |
376 | } | 377 | } |
377 | 378 | ||
378 | if (focused == view) { | 379 | if (focused == view || is_child_of_focused) { |
379 | render_borders(view, cr, &config->border_colors.focused, false); | 380 | render_borders(view, cr, &config->border_colors.focused, false); |
380 | render_title_bar(view, cr, &view->border_geometry, | 381 | render_title_bar(view, cr, &view->border_geometry, |
381 | &config->border_colors.focused); | 382 | &config->border_colors.focused); |
@@ -403,6 +404,23 @@ void update_view_border(swayc_t *view) { | |||
403 | } | 404 | } |
404 | } | 405 | } |
405 | 406 | ||
407 | void update_container_border(swayc_t *container) { | ||
408 | if (container->type == C_VIEW) { | ||
409 | update_view_border(container); | ||
410 | return; | ||
411 | } else { | ||
412 | for (int i = 0; i < container->children->length; ++i) { | ||
413 | update_container_border(container->children->items[i]); | ||
414 | } | ||
415 | } | ||
416 | } | ||
417 | |||
418 | void map_update_view_border(swayc_t *view, void *data) { | ||
419 | if (view->type == C_VIEW) { | ||
420 | update_view_border(view); | ||
421 | } | ||
422 | } | ||
423 | |||
406 | void render_view_borders(wlc_handle view) { | 424 | void render_view_borders(wlc_handle view) { |
407 | swayc_t *c = swayc_by_handle(view); | 425 | swayc_t *c = swayc_by_handle(view); |
408 | 426 | ||
diff --git a/sway/commands.c b/sway/commands.c index 28dcc996..f73bd21c 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -2340,7 +2340,7 @@ static struct cmd_results *_do_split(int argc, char **argv, int layout) { | |||
2340 | 2340 | ||
2341 | // update container title if tabbed/stacked | 2341 | // update container title if tabbed/stacked |
2342 | if (swayc_tabbed_stacked_ancestor(focused)) { | 2342 | if (swayc_tabbed_stacked_ancestor(focused)) { |
2343 | update_view_border(focused); | 2343 | update_container_border(focused); |
2344 | swayc_t *output = swayc_parent_by_type(focused, C_OUTPUT); | 2344 | swayc_t *output = swayc_parent_by_type(focused, C_OUTPUT); |
2345 | // schedule render to make changes take effect right away, | 2345 | // schedule render to make changes take effect right away, |
2346 | // otherwise we would have to wait for the view to render, | 2346 | // otherwise we would have to wait for the view to render, |
@@ -2501,6 +2501,30 @@ static struct cmd_results *cmd_fullscreen(int argc, char **argv) { | |||
2501 | swayc_t *workspace = swayc_parent_by_type(container, C_WORKSPACE); | 2501 | swayc_t *workspace = swayc_parent_by_type(container, C_WORKSPACE); |
2502 | bool current = swayc_is_fullscreen(container); | 2502 | bool current = swayc_is_fullscreen(container); |
2503 | wlc_view_set_state(container->handle, WLC_BIT_FULLSCREEN, !current); | 2503 | wlc_view_set_state(container->handle, WLC_BIT_FULLSCREEN, !current); |
2504 | |||
2505 | if (container->is_floating) { | ||
2506 | if (current) { | ||
2507 | // set dimensions back to what they were before we fullscreened this | ||
2508 | container->x = container->cached_geometry.origin.x; | ||
2509 | container->y = container->cached_geometry.origin.y; | ||
2510 | container->width = container->cached_geometry.size.w; | ||
2511 | container->height = container->cached_geometry.size.h; | ||
2512 | } else { | ||
2513 | // cache dimensions so we can reset them after we "unfullscreen" this | ||
2514 | struct wlc_geometry geo = { | ||
2515 | .origin = { | ||
2516 | .x = container->x, | ||
2517 | .y = container->y | ||
2518 | }, | ||
2519 | .size = { | ||
2520 | .w = container->width, | ||
2521 | .h = container->height | ||
2522 | } | ||
2523 | }; | ||
2524 | container->cached_geometry = geo; | ||
2525 | } | ||
2526 | } | ||
2527 | |||
2504 | // Resize workspace if going from fullscreen -> notfullscreen | 2528 | // Resize workspace if going from fullscreen -> notfullscreen |
2505 | // otherwise just resize container | 2529 | // otherwise just resize container |
2506 | if (!current) { | 2530 | if (!current) { |
diff --git a/sway/focus.c b/sway/focus.c index 0f629e1e..6583f802 100644 --- a/sway/focus.c +++ b/sway/focus.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include "border.h" | 10 | #include "border.h" |
11 | 11 | ||
12 | bool locked_container_focus = false; | 12 | bool locked_container_focus = false; |
13 | bool locked_view_focus = false; | ||
14 | bool suspend_workspace_cleanup = false; | 13 | bool suspend_workspace_cleanup = false; |
15 | 14 | ||
16 | // switches parent focus to c. will switch it accordingly | 15 | // switches parent focus to c. will switch it accordingly |
@@ -115,7 +114,7 @@ bool set_focused_container(swayc_t *c) { | |||
115 | 114 | ||
116 | // Get workspace for c, get that workspaces current focused container. | 115 | // Get workspace for c, get that workspaces current focused container. |
117 | swayc_t *workspace = swayc_active_workspace_for(c); | 116 | swayc_t *workspace = swayc_active_workspace_for(c); |
118 | swayc_t *focused = get_focused_view(workspace); | 117 | swayc_t *focused = get_focused_container(workspace); |
119 | 118 | ||
120 | if (swayc_is_fullscreen(focused) && focused != c) { | 119 | if (swayc_is_fullscreen(focused) && focused != c) { |
121 | // if switching to a workspace with a fullscreen view, | 120 | // if switching to a workspace with a fullscreen view, |
@@ -140,37 +139,32 @@ bool set_focused_container(swayc_t *c) { | |||
140 | } | 139 | } |
141 | 140 | ||
142 | // get new focused view and set focus to it. | 141 | // get new focused view and set focus to it. |
143 | p = get_focused_view(c); | 142 | 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 | 143 | // unactivate previous focus |
146 | if (focused->type == C_VIEW) { | 144 | if (focused->type == C_VIEW) { |
147 | wlc_view_set_state(focused->handle, WLC_BIT_ACTIVATED, false); | 145 | wlc_view_set_state(focused->handle, WLC_BIT_ACTIVATED, false); |
148 | update_view_border(focused); | ||
149 | } | 146 | } |
147 | update_container_border(focused); | ||
150 | // activate current focus | 148 | // activate current focus |
151 | if (p->type == C_VIEW) { | 149 | if (c->type == C_VIEW) { |
152 | wlc_view_set_state(p->handle, WLC_BIT_ACTIVATED, true); | 150 | wlc_view_set_state(c->handle, WLC_BIT_ACTIVATED, true); |
153 | // set focus if view_focus is unlocked | 151 | } |
154 | if (!locked_view_focus) { | 152 | // set focus if view_focus is unlocked |
155 | wlc_view_focus(p->handle); | 153 | wlc_view_focus(c->handle); |
156 | if (p->parent->layout != L_TABBED | 154 | if (c->parent->layout != L_TABBED && c->parent->layout != L_STACKED) { |
157 | && p->parent->layout != L_STACKED) { | 155 | update_container_border(c); |
158 | update_view_border(p); | ||
159 | } | ||
160 | } | ||
161 | } | 156 | } |
162 | 157 | ||
163 | // rearrange if parent container is tabbed/stacked | 158 | // rearrange if parent container is tabbed/stacked |
164 | swayc_t *parent = swayc_tabbed_stacked_ancestor(p); | 159 | swayc_t *parent = swayc_tabbed_stacked_ancestor(c); |
165 | if (parent != NULL) { | 160 | if (parent != NULL) { |
166 | arrange_backgrounds(); | 161 | arrange_backgrounds(); |
167 | arrange_windows(parent, -1, -1); | 162 | arrange_windows(parent, -1, -1); |
168 | } | 163 | } |
169 | } else if (p->type == C_WORKSPACE) { | 164 | } else if (c->type == C_WORKSPACE) { |
170 | // remove previous focus if view_focus is unlocked | 165 | // remove previous focus if view_focus is unlocked |
171 | if (!locked_view_focus) { | 166 | update_container_border(c); |
172 | wlc_view_focus(0); | 167 | wlc_view_focus(0); |
173 | } | ||
174 | } | 168 | } |
175 | 169 | ||
176 | if (active_ws != workspace) { | 170 | if (active_ws != workspace) { |
diff --git a/sway/handlers.c b/sway/handlers.c index bdcdcaa4..6d35f8a2 100644 --- a/sway/handlers.c +++ b/sway/handlers.c | |||
@@ -226,7 +226,7 @@ static void handle_output_focused(wlc_handle output, bool focus) { | |||
226 | handle_output_created(output); | 226 | handle_output_created(output); |
227 | } | 227 | } |
228 | if (focus) { | 228 | if (focus) { |
229 | set_focused_container(c); | 229 | set_focused_container(get_focused_container(c)); |
230 | } | 230 | } |
231 | } | 231 | } |
232 | 232 | ||
@@ -343,7 +343,6 @@ static bool handle_view_created(wlc_handle handle) { | |||
343 | // Dmenu keeps viewfocus, but others with this flag don't, for now simulate | 343 | // Dmenu keeps viewfocus, but others with this flag don't, for now simulate |
344 | // dmenu | 344 | // dmenu |
345 | case WLC_BIT_OVERRIDE_REDIRECT: | 345 | case WLC_BIT_OVERRIDE_REDIRECT: |
346 | // locked_view_focus = true; | ||
347 | wlc_view_focus(handle); | 346 | wlc_view_focus(handle); |
348 | wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true); | 347 | wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true); |
349 | wlc_view_bring_to_front(handle); | 348 | wlc_view_bring_to_front(handle); |
@@ -415,7 +414,7 @@ static bool handle_view_created(wlc_handle handle) { | |||
415 | // we were on one workspace, switched to another to add this view, | 414 | // we were on one workspace, switched to another to add this view, |
416 | // now let's return to where we were | 415 | // now let's return to where we were |
417 | workspace_switch(current_ws); | 416 | workspace_switch(current_ws); |
418 | set_focused_container(current_ws->focused); | 417 | set_focused_container(get_focused_container(current_ws)); |
419 | } | 418 | } |
420 | 419 | ||
421 | suspend_workspace_cleanup = false; | 420 | suspend_workspace_cleanup = false; |
@@ -437,7 +436,6 @@ static void handle_view_destroyed(wlc_handle handle) { | |||
437 | // DMENU has this flag, and takes view_focus, but other things with this | 436 | // DMENU has this flag, and takes view_focus, but other things with this |
438 | // flag don't | 437 | // flag don't |
439 | case WLC_BIT_OVERRIDE_REDIRECT: | 438 | case WLC_BIT_OVERRIDE_REDIRECT: |
440 | // locked_view_focus = false; | ||
441 | break; | 439 | break; |
442 | case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED: | 440 | case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED: |
443 | locked_container_focus = false; | 441 | locked_container_focus = false; |
@@ -553,9 +551,9 @@ static void handle_view_properties_updated(wlc_handle view, uint32_t mask) { | |||
553 | swayc_t *p = swayc_tabbed_stacked_ancestor(c); | 551 | swayc_t *p = swayc_tabbed_stacked_ancestor(c); |
554 | if (p) { | 552 | if (p) { |
555 | // TODO: we only got the topmost tabbed/stacked container, update borders of all containers on the path | 553 | // TODO: we only got the topmost tabbed/stacked container, update borders of all containers on the path |
556 | update_view_border(get_focused_view(p)); | 554 | update_container_border(get_focused_view(p)); |
557 | } else if (c->border_type == B_NORMAL) { | 555 | } else if (c->border_type == B_NORMAL) { |
558 | update_view_border(c); | 556 | update_container_border(c); |
559 | } | 557 | } |
560 | ipc_event_window(c, "title"); | 558 | ipc_event_window(c, "title"); |
561 | } | 559 | } |
@@ -646,10 +644,6 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
646 | return EVENT_PASSTHROUGH; | 644 | return EVENT_PASSTHROUGH; |
647 | } | 645 | } |
648 | 646 | ||
649 | if (locked_view_focus && state == WLC_KEY_STATE_PRESSED) { | ||
650 | return EVENT_PASSTHROUGH; | ||
651 | } | ||
652 | |||
653 | // reset pointer mode on keypress | 647 | // reset pointer mode on keypress |
654 | if (state == WLC_KEY_STATE_PRESSED && pointer_state.mode) { | 648 | if (state == WLC_KEY_STATE_PRESSED && pointer_state.mode) { |
655 | pointer_mode_reset(); | 649 | pointer_mode_reset(); |
diff --git a/sway/layout.c b/sway/layout.c index 6502d930..42954ebc 100644 --- a/sway/layout.c +++ b/sway/layout.c | |||
@@ -441,7 +441,7 @@ static void update_border_geometry_floating(swayc_t *c, struct wlc_geometry *geo | |||
441 | c->border_geometry = g; | 441 | c->border_geometry = g; |
442 | *geometry = c->actual_geometry; | 442 | *geometry = c->actual_geometry; |
443 | 443 | ||
444 | update_view_border(c); | 444 | update_container_border(c); |
445 | } | 445 | } |
446 | 446 | ||
447 | void update_layout_geometry(swayc_t *parent, enum swayc_layouts prev_layout) { | 447 | void update_layout_geometry(swayc_t *parent, enum swayc_layouts prev_layout) { |
@@ -688,7 +688,7 @@ void update_geometry(swayc_t *container) { | |||
688 | container->actual_geometry = geometry; | 688 | container->actual_geometry = geometry; |
689 | 689 | ||
690 | if (container->type == C_VIEW) { | 690 | if (container->type == C_VIEW) { |
691 | update_view_border(container); | 691 | update_container_border(container); |
692 | } | 692 | } |
693 | } | 693 | } |
694 | 694 | ||
@@ -867,7 +867,7 @@ static void arrange_windows_r(swayc_t *container, double width, double height) { | |||
867 | // update focused view border last because it may | 867 | // update focused view border last because it may |
868 | // depend on the title bar geometry of its siblings. | 868 | // depend on the title bar geometry of its siblings. |
869 | if (focused && container->children->length > 1) { | 869 | if (focused && container->children->length > 1) { |
870 | update_view_border(focused); | 870 | update_container_border(focused); |
871 | } | 871 | } |
872 | } | 872 | } |
873 | break; | 873 | break; |
@@ -911,7 +911,7 @@ static void arrange_windows_r(swayc_t *container, double width, double height) { | |||
911 | // update focused view border last because it may | 911 | // update focused view border last because it may |
912 | // depend on the title bar geometry of its siblings. | 912 | // depend on the title bar geometry of its siblings. |
913 | if (focused && container->children->length > 1) { | 913 | if (focused && container->children->length > 1) { |
914 | update_view_border(focused); | 914 | update_container_border(focused); |
915 | } | 915 | } |
916 | } | 916 | } |
917 | break; | 917 | break; |