2 * placement.c - client placement management
4 * Copyright © 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 "placement.h"
27 extern AwesomeConf globalconf
;
29 name_func_link_t FloatingPlacementList
[] =
31 { "smart", placement_smart
},
32 { "under_mouse", placement_under_mouse
},
37 placement_fix_offscreen(area_t geometry
, int screen
, int border
)
39 area_t screen_geometry
;
41 screen_geometry
= screen_get_area(screen
,
42 globalconf
.screens
[screen
].statusbar
,
43 &globalconf
.screens
[screen
].padding
);
46 if(AREA_RIGHT(geometry
) > AREA_RIGHT(screen_geometry
))
47 geometry
.x
= screen_geometry
.x
+ screen_geometry
.width
- (geometry
.width
+ 2 * border
);
48 else if(AREA_LEFT(geometry
) < AREA_LEFT(screen_geometry
))
49 geometry
.x
= screen_geometry
.x
;
51 if(AREA_BOTTOM(geometry
) > AREA_BOTTOM(screen_geometry
))
52 geometry
.y
= screen_geometry
.y
+ screen_geometry
.height
- (geometry
.height
+ 2 * border
);
53 else if(AREA_TOP(geometry
) < AREA_TOP(screen_geometry
))
54 geometry
.y
= screen_geometry
.y
;
59 /** Compute smart coordinates for a client window
60 * \param geometry current/requested client geometry
61 * \param screen screen used
62 * \return new geometry
65 placement_smart(Client
*c
)
68 area_t newgeometry
= { 0, 0, 0, 0, NULL
, NULL
};
69 area_t
*screen_geometry
, *arealist
= NULL
, *r
;
72 screen_geometry
= p_new(area_t
, 1);
74 *screen_geometry
= screen_get_area(c
->screen
,
75 globalconf
.screens
[c
->screen
].statusbar
,
76 &globalconf
.screens
[c
->screen
].padding
);
78 area_list_push(&arealist
, screen_geometry
);
80 for(client
= globalconf
.clients
; client
; client
= client
->next
)
81 if(client_isvisible(client
, c
->screen
))
83 newgeometry
= client
->f_geometry
;
84 newgeometry
.width
+= 2 * client
->border
;
85 newgeometry
.height
+= 2 * client
->border
;
86 newgeometry
= titlebar_geometry_add(&client
->titlebar
, newgeometry
);
87 area_list_remove(&arealist
, &newgeometry
);
90 newgeometry
.x
= c
->f_geometry
.x
;
91 newgeometry
.y
= c
->f_geometry
.y
;
92 newgeometry
.width
= 0;
93 newgeometry
.height
= 0;
95 for(r
= arealist
; r
; r
= r
->next
)
96 if(r
->width
>= c
->f_geometry
.width
&& r
->height
>= c
->f_geometry
.height
97 && r
->width
* r
->height
> newgeometry
.width
* newgeometry
.height
)
103 /* we did not found a space with enough space for our size:
104 * just take the biggest available and go in */
106 for(r
= arealist
; r
; r
= r
->next
)
107 if(r
->width
* r
->height
> newgeometry
.width
* newgeometry
.height
)
110 /* restore height and width */
111 newgeometry
.width
= c
->f_geometry
.width
;
112 newgeometry
.height
= c
->f_geometry
.height
;
114 newgeometry
= titlebar_geometry_add(&c
->titlebar
, newgeometry
);
115 newgeometry
= placement_fix_offscreen(newgeometry
, c
->screen
, c
->border
);
116 newgeometry
= titlebar_geometry_remove(&c
->titlebar
, newgeometry
);
118 area_list_wipe(&arealist
);
124 placement_under_mouse(Client
*c
)
129 area_t finalgeometry
= c
->f_geometry
;
131 if(XQueryPointer(globalconf
.display
, RootWindow(globalconf
.display
, c
->phys_screen
),
132 &dummy
, &dummy
, &x
, &y
, &d
, &d
, &m
))
134 finalgeometry
.x
= x
- c
->f_geometry
.width
/ 2;
135 finalgeometry
.y
= y
- c
->f_geometry
.height
/ 2;
138 finalgeometry
= titlebar_geometry_add(&c
->titlebar
, finalgeometry
);
139 finalgeometry
= placement_fix_offscreen(finalgeometry
, c
->screen
, c
->border
);
140 finalgeometry
= titlebar_geometry_remove(&c
->titlebar
, finalgeometry
);
142 return finalgeometry
;
144 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80