2 * ion/ioncore/float-placement.c
4 * Copyright (c) Tuomo Valkonen 1999-2007.
6 * Ion is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
16 #include "float-placement.h"
19 WFloatPlacement ioncore_placement_method=PLACEMENT_LRUD;
22 static void random_placement(WRectangle box, WRectangle *g)
26 g->x=box.x+(box.w<=0 ? 0 : rand()%box.w);
27 g->y=box.y+(box.h<=0 ? 0 : rand()%box.h);
31 static void ggeom(WRegion *reg, WRectangle *geom)
33 *geom=REGION_GEOM(reg);
37 static bool st_filt(WStacking *st, void *lvl)
39 uint level=*(uint*)lvl;
41 return (st->reg!=NULL &&
42 REGION_IS_MAPPED(st->reg) &&
47 #define FOR_ALL_STACKING_NODES(VAR, WS, LVL, TMP) \
48 for(stacking_iter_init(&(TMP), group_get_stacking(ws), \
50 VAR=stacking_iter_nodes(&(TMP)); \
52 VAR=stacking_iter_nodes(&(TMP)))
55 #define IGNORE_ST(ST, WS) ((ST)->reg==NULL || (ST)==(WS)->bottom)
58 static WRegion* is_occupied(WGroup *ws, uint level, const WRectangle *r)
64 FOR_ALL_STACKING_NODES(st, ws, level, tmp){
82 static int next_least_x(WGroup *ws, uint level, int x)
85 int retx=REGION_GEOM(ws).x+REGION_GEOM(ws).w;
89 FOR_ALL_STACKING_NODES(st, ws, level, tmp){
92 if(p.x+p.w>x && p.x+p.w<retx)
101 static int next_lowest_y(WGroup *ws, uint level, int y)
104 int rety=REGION_GEOM(ws).y+REGION_GEOM(ws).h;
105 WStackingIterTmp tmp;
108 FOR_ALL_STACKING_NODES(st, ws, level, tmp){
111 if(p.y+p.h>y && p.y+p.h<rety)
119 static bool tiling_placement(WGroup *ws, uint level, WRectangle *g)
129 maxx=REGION_GEOM(ws).x+REGION_GEOM(ws).w;
130 maxy=REGION_GEOM(ws).y+REGION_GEOM(ws).h;
132 if(ioncore_placement_method==PLACEMENT_UDLR){
134 p=is_occupied(ws, level, &r);
135 while(p!=NULL && r.y+r.h<maxy){
138 p=is_occupied(ws, level, &r);
140 if(r.y+r.h<maxy && r.x+r.w<maxx){
145 r.x=next_least_x(ws, level, r.x);
151 p=is_occupied(ws, level, &r);
152 while(p!=NULL && r.x+r.w<maxx){
155 p=is_occupied(ws, level, &r);
157 if(r.y+r.h<maxy && r.x+r.w<maxx){
162 r.y=next_lowest_y(ws, level, r.y);
173 void group_calc_placement(WGroup *ws, uint level, WRectangle *geom)
175 if(ioncore_placement_method!=PLACEMENT_RANDOM){
176 if(tiling_placement(ws, level, geom))
179 random_placement(REGION_GEOM(ws), geom);