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  */
49 bool 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) {
140  gaps.top -= config.gaps.top;
141  }
142  if (mask & GAPS_RIGHT) {
144  }
145  if (mask & GAPS_BOTTOM) {
147  }
148  if (mask & GAPS_LEFT) {
149  gaps.left -= config.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 }
int con_num_visible_children(Con *con)
Returns the number of visible non-floating children of this container.
Definition: con.c:999
int left
Definition: data.h:155
bool resize_find_tiling_participants(Con **current, Con **other, direction_t direction, bool both_sides)
Definition: resize.c:70
Definition: data.h:112
char * name
Definition: data.h:720
#define TAILQ_FIRST(head)
Definition: queue.h:336
struct gaps_t gaps_t
Definition: data.h:50
Con * output_get_content(Con *output)
Returns the output container below the given output container.
Definition: output.c:16
int top
Definition: data.h:152
int right
Definition: data.h:153
smart_gaps_t smart_gaps
struct ws_assignments_head ws_assignments
Definition: main.c:101
bool con_is_leaf(Con *con)
Returns true when this node is a leaf node (has no children)
Definition: con.c:361
enum Con::@18 type
bool gaps_should_inset_con(Con *con, int children)
Definition: gaps.c:49
bool con_has_parent(Con *con, Con *parent)
Checks if the container has the given parent as an actual parent.
Definition: con.c:653
Definition: data.h:150
gaps_t gaps_for_workspace(Con *ws)
Returns the configured gaps for this workspace based on the workspace name, number, and configured workspace gap assignments.
Definition: gaps.c:118
Con * con_inside_floating(Con *con)
Checks if the given container is either floating or inside some floating container.
Definition: con.c:620
gaps_mask_t
Definition: data.h:158
Stores which workspace (by name or number) goes to which output and its gaps config.
Definition: data.h:257
int num
the workspace number, if this Con is of type CT_WORKSPACE and the workspace is not a named workspace ...
Definition: data.h:701
bool gaps_has_adjacent_container(Con *con, direction_t direction)
Definition: gaps.c:90
int inner
Definition: data.h:151
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:347
Con * con_get_workspace(Con *con)
Gets the workspace container this node is on.
Definition: con.c:477
int con_num_children(Con *con)
Returns the number of children of this container.
Definition: con.c:983
Definition: data.h:108
struct Con * croot
Definition: tree.c:12
Definition: data.h:160
gaps_t gaps
direction_t
Definition: data.h:56
bool con_inside_stacked_or_tabbed(Con *con)
Returns true if the container is within any stacked/tabbed split container.
Definition: con.c:2590
int ws_name_to_number(const char *name)
Parses the workspace name as a number.
Definition: util.c:109
layout_t layout
Definition: data.h:783
Con * con_get_fullscreen_con(Con *con, fullscreen_mode_t fullscreen_mode)
Returns the first fullscreen node below this node.
Definition: con.c:525
A &#39;Con&#39; represents everything from the X11 root window down to a single X11 window.
Definition: data.h:671
gaps_mask_t gaps_mask
Definition: data.h:261
#define DLOG(fmt,...)
Definition: libi3.h:105
gaps_t gaps
Only applicable for containers of type CT_WORKSPACE.
Definition: data.h:704
gaps_t calculate_effective_gaps(Con *con)
Calculates the effective gap sizes for a container.
Definition: gaps.c:16
int bottom
Definition: data.h:154
Config config
Definition: config.c:19
void gaps_reapply_workspace_assignments(void)
Re-applies all workspace gap assignments to existing workspaces after reloading the configuration fil...
Definition: gaps.c:160
Definition: data.h:111
struct Con * parent
Definition: data.h:706