change codename
[awesome.git] / layouts / tile.c
blobb4d4c1e78f4bf00dc9cf00e4f06cc45cfc383e12
1 /*
2 * tile.c - tile layout
4 * Copyright © 2007-2008 Julien Danjou <julien@danjou.info>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include <stdio.h>
24 #include "screen.h"
25 #include "tag.h"
26 #include "client.h"
27 #include "layouts/tile.h"
28 #include "common/util.h"
30 extern awesome_t globalconf;
32 static void
33 _tile(int screen, const position_t position)
35 /* windows area geometry */
36 int wah = 0, waw = 0, wax = 0, way = 0;
37 /* master size */
38 unsigned int mw = 0, mh = 0;
39 int n, i, masterwin = 0, otherwin = 0;
40 int real_ncol = 1, win_by_col = 1, current_col = 0;
41 int small_ncol, adj_win_by_col;
42 area_t area, geometry = { 0, 0, 0, 0 };
43 client_t *c;
44 tag_t **curtags = tags_get_current(screen);
46 area = screen_area_get(screen,
47 &globalconf.screens[screen].wiboxes,
48 &globalconf.screens[screen].padding,
49 true);
51 for(n = 0, c = globalconf.clients; c; c = c->next)
52 if(IS_TILED(c, screen))
53 n++;
55 wah = area.height;
56 waw = area.width;
57 wax = area.x;
58 way = area.y;
60 masterwin = MIN(n, curtags[0]->nmaster);
62 otherwin = MAX(n - masterwin, 0);
64 if(curtags[0]->nmaster)
65 switch(position)
67 case Right:
68 case Left:
69 mh = masterwin ? wah / masterwin : wah;
70 mw = otherwin ? waw * curtags[0]->mwfact : waw;
71 break;
72 default:
73 mh = otherwin ? wah * curtags[0]->mwfact : wah;
74 mw = masterwin ? waw / masterwin : waw;
75 break;
77 else
78 mh = mw = 0;
80 real_ncol = curtags[0]->ncol > 0 ? MIN(otherwin, curtags[0]->ncol) : MIN(otherwin, 1);
82 for(i = 0, c = globalconf.clients; c; c = c->next)
84 if(!IS_TILED(c, screen))
85 continue;
87 if(i < curtags[0]->nmaster)
89 switch(position)
91 case Right:
92 geometry.y = way + i * mh;
93 geometry.x = wax;
94 break;
95 case Left:
96 geometry.y = way + i * mh;
97 geometry.x = wax + (waw - mw);
98 break;
99 case Top:
100 geometry.x = wax + i * mw;
101 geometry.y = way + (wah - mh);
102 break;
103 case Bottom:
104 default:
105 geometry.x = wax + i * mw;
106 geometry.y = way;
107 break;
108 break;
111 geometry.width = mw - 2 * c->border;
112 geometry.height = mh - 2 * c->border;
114 client_resize(c, geometry, c->honorsizehints);
116 else
118 win_by_col = otherwin / real_ncol;
119 small_ncol = (win_by_col + 1) * real_ncol - otherwin;
120 adj_win_by_col = current_col < small_ncol ? 0 : 1;
122 if((i - curtags[0]->nmaster) &&
123 (i - curtags[0]->nmaster + small_ncol * adj_win_by_col)
124 % (win_by_col + adj_win_by_col) == 0 &&
125 current_col < real_ncol - 1)
126 current_col++;
128 adj_win_by_col = current_col < small_ncol ? 0 : 1;
130 if(position == Right || position == Left)
132 if(otherwin <= real_ncol)
133 geometry.height = wah - 2 * c->border;
134 else
135 geometry.height = (wah / (win_by_col + adj_win_by_col)) -
136 2 * c->border;
138 geometry.width = (waw - mw) / real_ncol - 2 * c->border;
140 if(otherwin <= real_ncol ||
141 (i - curtags[0]->nmaster + small_ncol * adj_win_by_col)
142 % (win_by_col + adj_win_by_col) == 0)
143 geometry.y = way;
144 else
145 geometry.y = way +
146 ((i - curtags[0]->nmaster +
147 small_ncol * adj_win_by_col) %
148 (win_by_col + adj_win_by_col)) *
149 (geometry.height + 2 * c->border);
151 geometry.x = wax + current_col * (geometry.width + 2 * c->border);
153 if(position == Right)
154 geometry.x += mw;
156 else
158 if(otherwin <= real_ncol)
159 geometry.width = waw - 2 * c->border;
160 else
161 geometry.width = (waw / (win_by_col + adj_win_by_col)) -
162 2 * c->border;
164 geometry.height = (wah - mh) / real_ncol - 2 * c->border;
166 if(otherwin <= real_ncol ||
167 (i - curtags[0]->nmaster + small_ncol * adj_win_by_col)
168 % (win_by_col + adj_win_by_col) == 0)
169 geometry.x = wax;
170 else
171 geometry.x = wax +
172 ((i - curtags[0]->nmaster +
173 small_ncol * adj_win_by_col) %
174 (win_by_col + adj_win_by_col)) *
175 (geometry.width + 2 * c->border);
177 geometry.y = way + current_col * (geometry.height + 2 * c->border);
179 if(position == Bottom)
180 geometry.y += mh;
182 client_resize(c, geometry, c->honorsizehints);
184 i++;
187 p_delete(&curtags);
190 void
191 layout_tile(int screen)
193 _tile(screen, Right);
196 void
197 layout_tileleft(int screen)
199 _tile(screen, Left);
202 void
203 layout_tilebottom(int screen)
205 _tile(screen, Bottom);
208 void
209 layout_tiletop(int screen)
211 _tile(screen, Top);
214 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80