luaa: add support for meta __ipairs
[awesome.git] / layouts / tile.c
blob6fb6d3b61f42e9c795fb9ebd332da9a88540673d
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 area_t area, geometry = { 0, 0, 0, 0 };
42 client_t *c;
43 tag_t **curtags = tags_get_current(screen);
45 area = screen_area_get(screen,
46 &globalconf.screens[screen].wiboxes,
47 &globalconf.screens[screen].padding,
48 true);
50 for(n = 0, c = globalconf.clients; c; c = c->next)
51 if(IS_TILED(c, screen))
52 n++;
54 wah = area.height;
55 waw = area.width;
56 wax = area.x;
57 way = area.y;
59 masterwin = MIN(n, curtags[0]->nmaster);
61 otherwin = MAX(n - masterwin, 0);
63 if(curtags[0]->nmaster)
64 switch(position)
66 case Right:
67 case Left:
68 mh = masterwin ? wah / masterwin : wah;
69 mw = otherwin ? waw * curtags[0]->mwfact : waw;
70 break;
71 default:
72 mh = otherwin ? wah * curtags[0]->mwfact : wah;
73 mw = masterwin ? waw / masterwin : waw;
74 break;
76 else
77 mh = mw = 0;
79 real_ncol = curtags[0]->ncol > 0 ? MIN(otherwin, curtags[0]->ncol) : MIN(otherwin, 1);
81 for(i = 0, c = globalconf.clients; c; c = c->next)
83 if(!IS_TILED(c, screen))
84 continue;
86 if(i < curtags[0]->nmaster)
88 switch(position)
90 case Right:
91 geometry.y = way + i * mh;
92 geometry.x = wax;
93 break;
94 case Left:
95 geometry.y = way + i * mh;
96 geometry.x = wax + (waw - mw);
97 break;
98 case Top:
99 geometry.x = wax + i * mw;
100 geometry.y = way + (wah - mh);
101 break;
102 case Bottom:
103 default:
104 geometry.x = wax + i * mw;
105 geometry.y = way;
106 break;
107 break;
110 geometry.width = mw - 2 * c->border;
111 geometry.height = mh - 2 * c->border;
113 client_resize(c, geometry, c->honorsizehints);
115 else
117 if(real_ncol)
118 win_by_col = otherwin / real_ncol;
120 if((i - curtags[0]->nmaster)
121 && (i - curtags[0]->nmaster) % win_by_col == 0
122 && current_col < real_ncol - 1)
123 current_col++;
125 if(current_col == real_ncol - 1)
126 win_by_col += otherwin % real_ncol;
128 if(position == Right || position == Left)
130 if(otherwin <= real_ncol)
131 geometry.height = wah - 2 * c->border;
132 else
133 geometry.height = (wah / win_by_col) - 2 * c->border;
135 geometry.width = (waw - mw) / real_ncol - 2 * c->border;
137 if(i == curtags[0]->nmaster || otherwin <= real_ncol || (i - curtags[0]->nmaster) % win_by_col == 0)
138 geometry.y = way;
139 else
140 geometry.y = way + ((i - curtags[0]->nmaster) % win_by_col) * (geometry.height + 2 * c->border);
142 geometry.x = wax + current_col * (geometry.width + 2 * c->border);
144 if(position == Right)
145 geometry.x += mw;
147 else
149 if(otherwin <= real_ncol)
150 geometry.width = waw - 2 * c->border;
151 else
152 geometry.width = (waw / win_by_col) - 2 * c->border;
154 geometry.height = (wah - mh) / real_ncol - 2 * c->border;
156 if(i == curtags[0]->nmaster || otherwin <= real_ncol || (i - curtags[0]->nmaster) % win_by_col == 0)
157 geometry.x = wax;
158 else
159 geometry.x = wax + ((i - curtags[0]->nmaster) % win_by_col) * (geometry.width + 2 * c->border);
161 geometry.y = way + current_col * (geometry.height + 2 * c->border);
163 if(position == Bottom)
164 geometry.y += mh;
166 client_resize(c, geometry, c->honorsizehints);
168 i++;
171 p_delete(&curtags);
174 void
175 layout_tile(int screen)
177 _tile(screen, Right);
180 void
181 layout_tileleft(int screen)
183 _tile(screen, Left);
186 void
187 layout_tilebottom(int screen)
189 _tile(screen, Bottom);
192 void
193 layout_tiletop(int screen)
195 _tile(screen, Top);
198 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80