diff --git a/include/sway/config.h b/include/sway/config.h index 46dd4ffe4..660245c1e 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -283,6 +283,12 @@ struct side_gaps { int left; }; +enum smart_gaps_mode { + SMART_GAPS_OFF, + SMART_GAPS_ON, + SMART_GAPS_INVERSE_OUTER, +}; + /** * Stores configuration for a workspace, regardless of whether the workspace * exists. @@ -512,7 +518,7 @@ struct sway_config { bool tiling_drag; int tiling_drag_threshold; - bool smart_gaps; + enum smart_gaps_mode smart_gaps; int gaps_inner; struct side_gaps gaps_outer; diff --git a/sway/commands/smart_gaps.c b/sway/commands/smart_gaps.c index b27f9ccde..a6d165dc3 100644 --- a/sway/commands/smart_gaps.c +++ b/sway/commands/smart_gaps.c @@ -15,7 +15,12 @@ struct cmd_results *cmd_smart_gaps(int argc, char **argv) { return error; } - config->smart_gaps = parse_boolean(argv[0], config->smart_gaps); + if (strcmp(argv[0], "inverse_outer") == 0) { + config->smart_gaps = SMART_GAPS_INVERSE_OUTER; + } else { + config->smart_gaps = parse_boolean(argv[0], config->smart_gaps) + ? SMART_GAPS_ON : SMART_GAPS_OFF; + } arrange_root(); diff --git a/sway/config.c b/sway/config.c index e3daacda4..358372124 100644 --- a/sway/config.c +++ b/sway/config.c @@ -266,7 +266,7 @@ static void config_defaults(struct sway_config *config) { config->tiling_drag = true; config->tiling_drag_threshold = 9; - config->smart_gaps = false; + config->smart_gaps = SMART_GAPS_OFF; config->gaps_inner = 0; config->gaps_outer.top = 0; config->gaps_outer.right = 0; diff --git a/sway/sway.5.scd b/sway/sway.5.scd index e8d3d6066..ec34a56ca 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd @@ -692,9 +692,10 @@ The default colors are: borders will only be enabled if the workspace has more than one visible child and gaps equal to zero. -*smart_gaps* on|off +*smart_gaps* on|off|toggle|inverse_outer If smart_gaps are _on_ gaps will only be enabled if a workspace has more - than one child. + than one child. If smart_gaps are _inverse_outer_ outer gaps will only + be enabled if a workspace has exactly one child. *mark* --add|--replace [--toggle] Marks are arbitrary labels that can be used to identify certain windows and diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 8dd7789dc..e3ff15131 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -844,24 +844,36 @@ struct sway_container *workspace_insert_tiling(struct sway_workspace *workspace, return con; } +bool workspace_has_single_visible_container(struct sway_workspace *ws) { + struct sway_seat *seat = input_manager_get_default_seat(); + struct sway_container *focus = + seat_get_focus_inactive_tiling(seat, ws); + if (focus && !focus->view) { + focus = seat_get_focus_inactive_view(seat, &focus->node); + } + return (focus && focus->view && view_ancestor_is_only_visible(focus->view)); +} + void workspace_add_gaps(struct sway_workspace *ws) { - if (config->smart_gaps) { - struct sway_seat *seat = input_manager_get_default_seat(); - struct sway_container *focus = - seat_get_focus_inactive_tiling(seat, ws); - if (focus && !focus->view) { - focus = seat_get_focus_inactive_view(seat, &focus->node); - } - if (focus && focus->view && view_ancestor_is_only_visible(focus->view)) { - ws->current_gaps.top = 0; - ws->current_gaps.right = 0; - ws->current_gaps.bottom = 0; - ws->current_gaps.left = 0; - return; - } + if (config->smart_gaps == SMART_GAPS_ON + && workspace_has_single_visible_container(ws)) { + ws->current_gaps.top = 0; + ws->current_gaps.right = 0; + ws->current_gaps.bottom = 0; + ws->current_gaps.left = 0; + return; + } + + if (config->smart_gaps == SMART_GAPS_INVERSE_OUTER + && !workspace_has_single_visible_container(ws)) { + ws->current_gaps.top = 0; + ws->current_gaps.right = 0; + ws->current_gaps.bottom = 0; + ws->current_gaps.left = 0; + } else { + ws->current_gaps = ws->gaps_outer; } - ws->current_gaps = ws->gaps_outer; // Add inner gaps and make sure we don't turn out negative ws->current_gaps.top = fmax(0, ws->current_gaps.top + ws->gaps_inner); ws->current_gaps.right = fmax(0, ws->current_gaps.right + ws->gaps_inner);