move gaps-specific logic out of con.c and render.c into gaps.c
This commit is contained in:
committed by
Michael Stapelberg
parent
a5791b2e64
commit
3f400b8ad0
@ -46,6 +46,7 @@
|
|||||||
#include "click.h"
|
#include "click.h"
|
||||||
#include "key_press.h"
|
#include "key_press.h"
|
||||||
#include "floating.h"
|
#include "floating.h"
|
||||||
|
#include "gaps.h"
|
||||||
#include "drag.h"
|
#include "drag.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "handlers.h"
|
#include "handlers.h"
|
||||||
|
@ -525,13 +525,6 @@ void con_set_urgency(Con *con, bool urgent);
|
|||||||
*/
|
*/
|
||||||
char *con_get_tree_representation(Con *con);
|
char *con_get_tree_representation(Con *con);
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the effective gap sizes for a container depending
|
|
||||||
* on whether it is adjacent to the edge of the screen or another
|
|
||||||
* container.
|
|
||||||
*/
|
|
||||||
gaps_t calculate_effective_gaps(Con *con);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* force parent split containers to be redrawn
|
* force parent split containers to be redrawn
|
||||||
*
|
*
|
||||||
|
28
include/gaps.h
Normal file
28
include/gaps.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* vim:ts=4:sw=4:expandtab
|
||||||
|
*
|
||||||
|
* i3 - an improved dynamic tiling window manager
|
||||||
|
* © 2009 Michael Stapelberg and contributors (see also: LICENSE)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "data.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the effective gap sizes for a container.
|
||||||
|
*/
|
||||||
|
gaps_t calculate_effective_gaps(Con *con);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decides whether the container should be inset.
|
||||||
|
*/
|
||||||
|
bool gaps_should_inset_con(Con *con, int children);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns whether the given container has an adjacent container in the
|
||||||
|
* specified direction. In other words, this returns true if and only if
|
||||||
|
* the container is not touching the edge of the screen in that direction.
|
||||||
|
*/
|
||||||
|
bool gaps_has_adjacent_container(Con *con, direction_t direction);
|
@ -389,6 +389,7 @@ i3srcs = [
|
|||||||
'src/ewmh.c',
|
'src/ewmh.c',
|
||||||
'src/fake_outputs.c',
|
'src/fake_outputs.c',
|
||||||
'src/floating.c',
|
'src/floating.c',
|
||||||
|
'src/gaps.c',
|
||||||
'src/handlers.c',
|
'src/handlers.c',
|
||||||
'src/ipc.c',
|
'src/ipc.c',
|
||||||
'src/key_press.c',
|
'src/key_press.c',
|
||||||
|
39
src/con.c
39
src/con.c
@ -2342,45 +2342,6 @@ char *con_get_tree_representation(Con *con) {
|
|||||||
return complete_buf;
|
return complete_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the effective gap sizes for a container.
|
|
||||||
*/
|
|
||||||
gaps_t calculate_effective_gaps(Con *con) {
|
|
||||||
Con *workspace = con_get_workspace(con);
|
|
||||||
if (workspace == NULL)
|
|
||||||
return (gaps_t){0, 0, 0, 0, 0};
|
|
||||||
|
|
||||||
bool one_child = con_num_visible_children(workspace) <= 1 ||
|
|
||||||
(con_num_children(workspace) == 1 &&
|
|
||||||
(TAILQ_FIRST(&(workspace->nodes_head))->layout == L_TABBED ||
|
|
||||||
TAILQ_FIRST(&(workspace->nodes_head))->layout == L_STACKED));
|
|
||||||
|
|
||||||
if (config.smart_gaps == SMART_GAPS_ON && one_child)
|
|
||||||
return (gaps_t){0, 0, 0, 0, 0};
|
|
||||||
|
|
||||||
gaps_t gaps = {
|
|
||||||
.inner = (workspace->gaps.inner + config.gaps.inner) / 2,
|
|
||||||
.top = 0,
|
|
||||||
.right = 0,
|
|
||||||
.bottom = 0,
|
|
||||||
.left = 0};
|
|
||||||
|
|
||||||
if (config.smart_gaps != SMART_GAPS_INVERSE_OUTER || one_child) {
|
|
||||||
gaps.top = workspace->gaps.top + config.gaps.top;
|
|
||||||
gaps.right = workspace->gaps.right + config.gaps.right;
|
|
||||||
gaps.bottom = workspace->gaps.bottom + config.gaps.bottom;
|
|
||||||
gaps.left = workspace->gaps.left + config.gaps.left;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Outer gaps are added on top of inner gaps. */
|
|
||||||
gaps.top += 2 * gaps.inner;
|
|
||||||
gaps.right += 2 * gaps.inner;
|
|
||||||
gaps.bottom += 2 * gaps.inner;
|
|
||||||
gaps.left += 2 * gaps.inner;
|
|
||||||
|
|
||||||
return gaps;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the container's title considering the current title format.
|
* Returns the container's title considering the current title format.
|
||||||
*
|
*
|
||||||
|
106
src/gaps.c
Normal file
106
src/gaps.c
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* vim:ts=4:sw=4:expandtab
|
||||||
|
*
|
||||||
|
* i3 - an improved dynamic tiling window manager
|
||||||
|
* © 2009 Michael Stapelberg and contributors (see also: LICENSE)
|
||||||
|
*
|
||||||
|
* gaps.c: gaps logic: whether to display gaps at all, and how big
|
||||||
|
* they should be.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "all.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the effective gap sizes for a container.
|
||||||
|
*/
|
||||||
|
gaps_t calculate_effective_gaps(Con *con) {
|
||||||
|
Con *workspace = con_get_workspace(con);
|
||||||
|
if (workspace == NULL)
|
||||||
|
return (gaps_t){0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
bool one_child = con_num_visible_children(workspace) <= 1 ||
|
||||||
|
(con_num_children(workspace) == 1 &&
|
||||||
|
(TAILQ_FIRST(&(workspace->nodes_head))->layout == L_TABBED ||
|
||||||
|
TAILQ_FIRST(&(workspace->nodes_head))->layout == L_STACKED));
|
||||||
|
|
||||||
|
if (config.smart_gaps == SMART_GAPS_ON && one_child)
|
||||||
|
return (gaps_t){0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
gaps_t gaps = {
|
||||||
|
.inner = (workspace->gaps.inner + config.gaps.inner) / 2,
|
||||||
|
.top = 0,
|
||||||
|
.right = 0,
|
||||||
|
.bottom = 0,
|
||||||
|
.left = 0};
|
||||||
|
|
||||||
|
if (config.smart_gaps != SMART_GAPS_INVERSE_OUTER || one_child) {
|
||||||
|
gaps.top = workspace->gaps.top + config.gaps.top;
|
||||||
|
gaps.right = workspace->gaps.right + config.gaps.right;
|
||||||
|
gaps.bottom = workspace->gaps.bottom + config.gaps.bottom;
|
||||||
|
gaps.left = workspace->gaps.left + config.gaps.left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Outer gaps are added on top of inner gaps. */
|
||||||
|
gaps.top += 2 * gaps.inner;
|
||||||
|
gaps.right += 2 * gaps.inner;
|
||||||
|
gaps.bottom += 2 * gaps.inner;
|
||||||
|
gaps.left += 2 * gaps.inner;
|
||||||
|
|
||||||
|
return gaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decides whether the container should be inset.
|
||||||
|
*/
|
||||||
|
bool gaps_should_inset_con(Con *con, int children) {
|
||||||
|
/* Inset direct children of the workspace that are leaf containers or
|
||||||
|
stacked/tabbed containers. */
|
||||||
|
if (con->parent != NULL &&
|
||||||
|
con->parent->type == CT_WORKSPACE &&
|
||||||
|
(con_is_leaf(con) ||
|
||||||
|
(con->layout == L_STACKED || con->layout == L_TABBED))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inset direct children of vertical or horizontal split containers at any
|
||||||
|
depth in the tree (only leaf containers, not split containers within
|
||||||
|
split containers, to avoid double insets). */
|
||||||
|
if (con_is_leaf(con) &&
|
||||||
|
con->parent != NULL &&
|
||||||
|
con->parent->type == CT_CON &&
|
||||||
|
(con->parent->layout == L_SPLITH ||
|
||||||
|
con->parent->layout == L_SPLITV)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns whether the given container has an adjacent container in the
|
||||||
|
* specified direction. In other words, this returns true if and only if
|
||||||
|
* the container is not touching the edge of the screen in that direction.
|
||||||
|
*/
|
||||||
|
bool gaps_has_adjacent_container(Con *con, direction_t direction) {
|
||||||
|
Con *workspace = con_get_workspace(con);
|
||||||
|
Con *fullscreen = con_get_fullscreen_con(workspace, CF_GLOBAL);
|
||||||
|
if (fullscreen == NULL)
|
||||||
|
fullscreen = con_get_fullscreen_con(workspace, CF_OUTPUT);
|
||||||
|
|
||||||
|
/* If this container is fullscreen by itself, there's no adjacent container. */
|
||||||
|
if (con == fullscreen)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Con *first = con;
|
||||||
|
Con *second = NULL;
|
||||||
|
bool found_neighbor = resize_find_tiling_participants(&first, &second, direction, false);
|
||||||
|
if (!found_neighbor)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* If we have an adjacent container and nothing is fullscreen, we consider it. */
|
||||||
|
if (fullscreen == NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* For fullscreen containers, only consider the adjacent container if it is also fullscreen. */
|
||||||
|
return con_has_parent(con, fullscreen) && con_has_parent(second, fullscreen);
|
||||||
|
}
|
68
src/render.c
68
src/render.c
@ -20,8 +20,6 @@ static void render_con_split(Con *con, Con *child, render_params *p, int i);
|
|||||||
static void render_con_stacked(Con *con, Con *child, render_params *p, int i);
|
static void render_con_stacked(Con *con, Con *child, render_params *p, int i);
|
||||||
static void render_con_tabbed(Con *con, Con *child, render_params *p, int i);
|
static void render_con_tabbed(Con *con, Con *child, render_params *p, int i);
|
||||||
static void render_con_dockarea(Con *con, Con *child, render_params *p);
|
static void render_con_dockarea(Con *con, Con *child, render_params *p);
|
||||||
bool should_inset_con(Con *con, int children);
|
|
||||||
bool has_adjacent_container(Con *con, direction_t direction);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the height for the decorations
|
* Returns the height for the decorations
|
||||||
@ -51,13 +49,13 @@ void render_con(Con *con) {
|
|||||||
DLOG("Rendering node %p / %s / layout %d / children %d\n", con, con->name,
|
DLOG("Rendering node %p / %s / layout %d / children %d\n", con, con->name,
|
||||||
con->layout, params.children);
|
con->layout, params.children);
|
||||||
|
|
||||||
if (should_inset_con(con, params.children)) {
|
if (gaps_should_inset_con(con, params.children)) {
|
||||||
gaps_t gaps = calculate_effective_gaps(con);
|
gaps_t gaps = calculate_effective_gaps(con);
|
||||||
Rect inset = (Rect){
|
Rect inset = (Rect){
|
||||||
has_adjacent_container(con, D_LEFT) ? gaps.inner : gaps.left,
|
gaps_has_adjacent_container(con, D_LEFT) ? gaps.inner : gaps.left,
|
||||||
has_adjacent_container(con, D_UP) ? gaps.inner : gaps.top,
|
gaps_has_adjacent_container(con, D_UP) ? gaps.inner : gaps.top,
|
||||||
has_adjacent_container(con, D_RIGHT) ? -gaps.inner : -gaps.right,
|
gaps_has_adjacent_container(con, D_RIGHT) ? -gaps.inner : -gaps.right,
|
||||||
has_adjacent_container(con, D_DOWN) ? -gaps.inner : -gaps.bottom};
|
gaps_has_adjacent_container(con, D_DOWN) ? -gaps.inner : -gaps.bottom};
|
||||||
inset.width -= inset.x;
|
inset.width -= inset.x;
|
||||||
inset.height -= inset.y;
|
inset.height -= inset.y;
|
||||||
|
|
||||||
@ -460,59 +458,3 @@ static void render_con_dockarea(Con *con, Con *child, render_params *p) {
|
|||||||
child->deco_rect.height = 0;
|
child->deco_rect.height = 0;
|
||||||
p->y += child->rect.height;
|
p->y += child->rect.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Decides whether the container should be inset.
|
|
||||||
*/
|
|
||||||
bool should_inset_con(Con *con, int children) {
|
|
||||||
/* Inset direct children of the workspace that are leaf containers or
|
|
||||||
stacked/tabbed containers. */
|
|
||||||
if (con->parent != NULL &&
|
|
||||||
con->parent->type == CT_WORKSPACE &&
|
|
||||||
(con_is_leaf(con) ||
|
|
||||||
(con->layout == L_STACKED || con->layout == L_TABBED))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Inset direct children of vertical or horizontal split containers at any
|
|
||||||
depth in the tree (only leaf containers, not split containers within
|
|
||||||
split containers, to avoid double insets). */
|
|
||||||
if (con_is_leaf(con) &&
|
|
||||||
con->parent != NULL &&
|
|
||||||
con->parent->type == CT_CON &&
|
|
||||||
(con->parent->layout == L_SPLITH ||
|
|
||||||
con->parent->layout == L_SPLITV)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns whether the given container has an adjacent container in the
|
|
||||||
* specified direction. In other words, this returns true if and only if
|
|
||||||
* the container is not touching the edge of the screen in that direction.
|
|
||||||
*/
|
|
||||||
bool has_adjacent_container(Con *con, direction_t direction) {
|
|
||||||
Con *workspace = con_get_workspace(con);
|
|
||||||
Con *fullscreen = con_get_fullscreen_con(workspace, CF_GLOBAL);
|
|
||||||
if (fullscreen == NULL)
|
|
||||||
fullscreen = con_get_fullscreen_con(workspace, CF_OUTPUT);
|
|
||||||
|
|
||||||
/* If this container is fullscreen by itself, there's no adjacent container. */
|
|
||||||
if (con == fullscreen)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Con *first = con;
|
|
||||||
Con *second = NULL;
|
|
||||||
bool found_neighbor = resize_find_tiling_participants(&first, &second, direction, false);
|
|
||||||
if (!found_neighbor)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/* If we have an adjacent container and nothing is fullscreen, we consider it. */
|
|
||||||
if (fullscreen == NULL)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/* For fullscreen containers, only consider the adjacent container if it is also fullscreen. */
|
|
||||||
return con_has_parent(con, fullscreen) && con_has_parent(second, fullscreen);
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user