i3
gaps.c
Go to the documentation of this file.
1/*
2 * vim:ts=4:sw=4:expandtab
3 *
4 * i3 - an improved dynamic tiling window manager
5 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
6 *
7 * gaps.c: gaps logic: whether to display gaps at all, and how big
8 * they should be.
9 *
10 */
11#include "all.h"
12
17 Con *workspace = con_get_workspace(con);
18 if (workspace == NULL)
19 return (gaps_t){0, 0, 0, 0, 0};
20
21 bool one_child = con_num_visible_children(workspace) <= 1 ||
22 (con_num_children(workspace) == 1 &&
23 (TAILQ_FIRST(&(workspace->nodes_head))->layout == L_TABBED ||
24 TAILQ_FIRST(&(workspace->nodes_head))->layout == L_STACKED));
25
26 if (config.smart_gaps == SMART_GAPS_ON && one_child)
27 return (gaps_t){0, 0, 0, 0, 0};
28
29 gaps_t gaps = {
30 .inner = (workspace->gaps.inner + config.gaps.inner),
31 .top = 0,
32 .right = 0,
33 .bottom = 0,
34 .left = 0};
35
36 if (config.smart_gaps != SMART_GAPS_INVERSE_OUTER || one_child) {
37 gaps.top = workspace->gaps.top + config.gaps.top;
38 gaps.right = workspace->gaps.right + config.gaps.right;
39 gaps.bottom = workspace->gaps.bottom + config.gaps.bottom;
40 gaps.left = workspace->gaps.left + config.gaps.left;
41 }
42
43 return gaps;
44}
45
46/*
47 * Decides whether the container should be inset.
48 */
49bool gaps_should_inset_con(Con *con, int children) {
50 /* No parent? None of the conditionals below can be true. */
51 if (con->parent == NULL) {
52 return false;
53 }
54
55 /* Floating split containers should never have gaps inside them. */
56 if (con_inside_floating(con)) {
57 return false;
58 }
59
60 const bool leaf_or_stacked_tabbed =
61 con_is_leaf(con) ||
62 (con->layout == L_STACKED || con->layout == L_TABBED);
63
64 /* Inset direct children of the workspace that are leaf containers or
65 stacked/tabbed containers. */
66 if (leaf_or_stacked_tabbed &&
67 con->parent->type == CT_WORKSPACE) {
68 return true;
69 }
70
71 /* Inset direct children of vertical or horizontal split containers at any
72 depth in the tree. Do not inset as soon as any parent is a stacked or
73 tabbed container, to avoid double insets. */
74 if (leaf_or_stacked_tabbed &&
76 con->parent->type == CT_CON &&
77 (con->parent->layout == L_SPLITH ||
78 con->parent->layout == L_SPLITV)) {
79 return true;
80 }
81
82 return false;
83}
84
85/*
86 * Returns whether the given container has an adjacent container in the
87 * specified direction. In other words, this returns true if and only if
88 * the container is not touching the edge of the screen in that direction.
89 */
91 Con *workspace = con_get_workspace(con);
92 Con *fullscreen = con_get_fullscreen_con(workspace, CF_GLOBAL);
93 if (fullscreen == NULL)
94 fullscreen = con_get_fullscreen_con(workspace, CF_OUTPUT);
95
96 /* If this container is fullscreen by itself, there's no adjacent container. */
97 if (con == fullscreen)
98 return false;
99
100 Con *first = con;
101 Con *second = NULL;
102 bool found_neighbor = resize_find_tiling_participants(&first, &second, direction, false);
103 if (!found_neighbor)
104 return false;
105
106 /* If we have an adjacent container and nothing is fullscreen, we consider it. */
107 if (fullscreen == NULL)
108 return true;
109
110 /* For fullscreen containers, only consider the adjacent container if it is also fullscreen. */
111 return con_has_parent(con, fullscreen) && con_has_parent(second, fullscreen);
112}
113
114/*
115 * Returns the configured gaps for this workspace based on the workspace name,
116 * number, and configured workspace gap assignments.
117 */
119 gaps_t gaps = (gaps_t){0, 0, 0, 0, 0};
120 gaps_mask_t mask = 0;
121 struct Workspace_Assignment *assignment;
123 if (strcmp(assignment->name, ws->name) == 0) {
124 gaps = assignment->gaps;
125 mask = assignment->gaps_mask;
126 break;
127 } else if (ws->num != -1 && name_is_digits(assignment->name) && ws_name_to_number(assignment->name) == ws->num) {
128 gaps = assignment->gaps;
129 mask = assignment->gaps_mask;
130 }
131 }
132 if (mask == 0) {
133 return gaps;
134 }
135
136 if (mask & GAPS_INNER) {
138 }
139 if (mask & GAPS_TOP) {
141 }
142 if (mask & GAPS_RIGHT) {
144 }
145 if (mask & GAPS_BOTTOM) {
147 }
148 if (mask & GAPS_LEFT) {
150 }
151
152 return gaps;
153}
154
155/*
156 * Re-applies all workspace gap assignments to existing workspaces after
157 * reloading the configuration file.
158 *
159 */
161 Con *output, *workspace = NULL;
162 TAILQ_FOREACH (output, &(croot->nodes_head), nodes) {
163 Con *content = output_get_content(output);
164 TAILQ_FOREACH (workspace, &(content->nodes_head), nodes) {
165 DLOG("updating gap assignments for workspace %s\n", workspace->name);
166 workspace->gaps = gaps_for_workspace(workspace);
167 }
168 }
169}
struct ws_assignments_head ws_assignments
Definition main.c:101
int ws_name_to_number(const char *name)
Parses the workspace name as a number.
Definition util.c:109
struct Con * croot
Definition tree.c:12
bool resize_find_tiling_participants(Con **current, Con **other, direction_t direction, bool both_sides)
Definition resize.c:70
Con * output_get_content(Con *output)
Returns the output container below the given output container.
Definition output.c:16
void gaps_reapply_workspace_assignments(void)
Re-applies all workspace gap assignments to existing workspaces after reloading the configuration fil...
Definition gaps.c:160
gaps_t calculate_effective_gaps(Con *con)
Calculates the effective gap sizes for a container.
Definition gaps.c:16
bool gaps_has_adjacent_container(Con *con, direction_t direction)
Definition gaps.c:90
bool gaps_should_inset_con(Con *con, int children)
Definition gaps.c:49
gaps_t gaps_for_workspace(Con *ws)
Returns the configured gaps for this workspace based on the workspace name, number,...
Definition gaps.c:118
Config config
Definition config.c:19
Con * con_get_fullscreen_con(Con *con, fullscreen_mode_t fullscreen_mode)
Returns the first fullscreen node below this node.
Definition con.c:525
bool con_inside_stacked_or_tabbed(Con *con)
Returns true if the container is within any stacked/tabbed split container.
Definition con.c:2590
Con * con_get_workspace(Con *con)
Gets the workspace container this node is on.
Definition con.c:477
int con_num_visible_children(Con *con)
Returns the number of visible non-floating children of this container.
Definition con.c:999
Con * con_inside_floating(Con *con)
Checks if the given container is either floating or inside some floating container.
Definition con.c:620
bool con_is_leaf(Con *con)
Returns true when this node is a leaf node (has no children)
Definition con.c:361
int con_num_children(Con *con)
Returns the number of children of this container.
Definition con.c:983
bool con_has_parent(Con *con, Con *parent)
Checks if the container has the given parent as an actual parent.
Definition con.c:653
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:347
#define TAILQ_FIRST(head)
Definition queue.h:336
#define DLOG(fmt,...)
Definition libi3.h:105
@ SMART_GAPS_INVERSE_OUTER
Definition data.h:90
@ SMART_GAPS_ON
Definition data.h:89
gaps_mask_t
Definition data.h:158
@ GAPS_LEFT
Definition data.h:163
@ GAPS_RIGHT
Definition data.h:161
@ GAPS_INNER
Definition data.h:159
@ GAPS_BOTTOM
Definition data.h:162
@ GAPS_TOP
Definition data.h:160
@ L_STACKED
Definition data.h:107
@ L_TABBED
Definition data.h:108
@ L_SPLITH
Definition data.h:112
@ L_SPLITV
Definition data.h:111
@ CF_OUTPUT
Definition data.h:634
@ CF_GLOBAL
Definition data.h:635
direction_t
Definition data.h:56
gaps_t gaps
smart_gaps_t smart_gaps
Definition data.h:150
int inner
Definition data.h:151
int left
Definition data.h:155
int right
Definition data.h:153
int top
Definition data.h:152
int bottom
Definition data.h:154
Stores which workspace (by name or number) goes to which output and its gaps config.
Definition data.h:239
gaps_mask_t gaps_mask
Definition data.h:243
A 'Con' represents everything from the X11 root window down to a single X11 window.
Definition data.h:647
struct Con * parent
Definition data.h:682
enum Con::@18 type
gaps_t gaps
Only applicable for containers of type CT_WORKSPACE.
Definition data.h:680
layout_t layout
Definition data.h:759
int num
the workspace number, if this Con is of type CT_WORKSPACE and the workspace is not a named workspace ...
Definition data.h:677
char * name
Definition data.h:696