Fix various bug with smart/mouse floating placement

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2008-03-17 19:26:28 +01:00
parent 94a83c84b6
commit 1acc6ec8f6
3 changed files with 48 additions and 54 deletions

View File

@ -388,23 +388,7 @@ client_manage(Window w, XWindowAttributes *wa, int screen)
titlebar_init(c); titlebar_init(c);
if(!(flags & (USPosition | PPosition))) if(!(flags & (USPosition | PPosition)))
{ c->f_geometry = globalconf.screens[c->screen].floating_placement(c);
c->f_geometry = globalconf.screens[c->screen].floating_placement(c->f_geometry,
c->border,
c->screen);
/* remove effects of the titlebar */
switch(c->titlebar.position)
{
case Top:
c->f_geometry.y += c->titlebar.sw->geometry.height;
break;
case Left:
c->f_geometry.x += c->titlebar.sw->geometry.width;
break;
default:
break;
}
}
XSelectInput(globalconf.display, w, StructureNotifyMask | PropertyChangeMask | EnterWindowMask); XSelectInput(globalconf.display, w, StructureNotifyMask | PropertyChangeMask | EnterWindowMask);

View File

@ -35,24 +35,24 @@ name_func_link_t FloatingPlacementList[] =
static area_t static area_t
placement_fix_offscreen(area_t geometry, int screen, int border) placement_fix_offscreen(area_t geometry, int screen, int border)
{ {
area_t screen_geometry, newgeometry = geometry; area_t screen_geometry;
screen_geometry = screen_get_area(screen, screen_geometry = screen_get_area(screen,
globalconf.screens[screen].statusbar, globalconf.screens[screen].statusbar,
&globalconf.screens[screen].padding); &globalconf.screens[screen].padding);
/* fix offscreen */ /* fix offscreen */
if(AREA_RIGHT(newgeometry) > AREA_RIGHT(screen_geometry)) if(AREA_RIGHT(geometry) > AREA_RIGHT(screen_geometry))
newgeometry.x = screen_geometry.x + screen_geometry.width - (newgeometry.width + 2 * border); geometry.x = screen_geometry.x + screen_geometry.width - (geometry.width + 2 * border);
else if(AREA_LEFT(newgeometry) < AREA_LEFT(screen_geometry)) else if(AREA_LEFT(geometry) < AREA_LEFT(screen_geometry))
newgeometry.x = screen_geometry.x; geometry.x = screen_geometry.x;
if(AREA_BOTTOM(newgeometry) > AREA_BOTTOM(screen_geometry)) if(AREA_BOTTOM(geometry) > AREA_BOTTOM(screen_geometry))
newgeometry.y = screen_geometry.y + screen_geometry.height - (newgeometry.height + 2 * border); geometry.y = screen_geometry.y + screen_geometry.height - (geometry.height + 2 * border);
else if(AREA_TOP(newgeometry) < AREA_TOP(screen_geometry)) else if(AREA_TOP(geometry) < AREA_TOP(screen_geometry))
newgeometry.y = screen_geometry.y; geometry.y = screen_geometry.y;
return newgeometry; return geometry;
} }
static area_t static area_t
@ -63,14 +63,12 @@ placement_geometry_add_titlebar(Titlebar *t, area_t geometry)
switch(t->position) switch(t->position)
{ {
default:
break;
case Top: case Top:
geometry.y -= t->sw->geometry.height; geometry.y -= t->sw->geometry.height;
geometry.height += t->sw->geometry.height; geometry.height += t->sw->geometry.height;
break; break;
case Bottom: case Bottom:
geometry.y += t->sw->geometry.height; geometry.height += t->sw->geometry.height;
break; break;
case Left: case Left:
geometry.x -= t->sw->geometry.width; geometry.x -= t->sw->geometry.width;
@ -79,6 +77,8 @@ placement_geometry_add_titlebar(Titlebar *t, area_t geometry)
case Right: case Right:
geometry.width += t->sw->geometry.width; geometry.width += t->sw->geometry.width;
break; break;
default:
break;
} }
return geometry; return geometry;
@ -90,38 +90,38 @@ placement_geometry_add_titlebar(Titlebar *t, area_t geometry)
* \return new geometry * \return new geometry
*/ */
area_t area_t
placement_smart(area_t geometry, int border, int screen) placement_smart(Client *c)
{ {
Client *c; Client *client;
area_t newgeometry = { 0, 0, 0, 0, NULL, NULL }; area_t newgeometry = { 0, 0, 0, 0, NULL, NULL };
area_t *screen_geometry, *arealist = NULL, *r; area_t *screen_geometry, *arealist = NULL, *r;
Bool found = False; Bool found = False;
screen_geometry = p_new(area_t, 1); screen_geometry = p_new(area_t, 1);
*screen_geometry = screen_get_area(screen, *screen_geometry = screen_get_area(c->screen,
globalconf.screens[screen].statusbar, globalconf.screens[c->screen].statusbar,
&globalconf.screens[screen].padding); &globalconf.screens[c->screen].padding);
area_list_push(&arealist, screen_geometry); area_list_push(&arealist, screen_geometry);
for(c = globalconf.clients; c; c = c->next) for(client = globalconf.clients; client; client = client->next)
if(client_isvisible(c, screen)) if(client_isvisible(client, c->screen))
{ {
newgeometry = c->f_geometry; newgeometry = client->f_geometry;
newgeometry.width += 2 * c->border; newgeometry.width += 2 * client->border;
newgeometry.height += 2 * c->border; newgeometry.height += 2 * client->border;
newgeometry = placement_geometry_add_titlebar(&c->titlebar, newgeometry); newgeometry = placement_geometry_add_titlebar(&client->titlebar, newgeometry);
area_list_remove(&arealist, &newgeometry); area_list_remove(&arealist, &newgeometry);
} }
newgeometry.x = geometry.x; newgeometry.x = c->f_geometry.x;
newgeometry.y = geometry.y; newgeometry.y = c->f_geometry.y;
newgeometry.width = 0; newgeometry.width = 0;
newgeometry.height = 0; newgeometry.height = 0;
for(r = arealist; r; r = r->next) for(r = arealist; r; r = r->next)
if(r->width >= geometry.width && r->height >= geometry.height if(r->width >= c->f_geometry.width && r->height >= c->f_geometry.height
&& r->width * r->height > newgeometry.width * newgeometry.height) && r->width * r->height > newgeometry.width * newgeometry.height)
{ {
found = True; found = True;
@ -136,10 +136,15 @@ placement_smart(area_t geometry, int border, int screen)
newgeometry = *r; newgeometry = *r;
/* restore height and width */ /* restore height and width */
newgeometry.width = geometry.width; newgeometry.width = c->f_geometry.width;
newgeometry.height = geometry.height; newgeometry.height = c->f_geometry.height;
newgeometry = placement_fix_offscreen(newgeometry, screen, border); newgeometry = placement_geometry_add_titlebar(&c->titlebar, newgeometry);
newgeometry = placement_fix_offscreen(newgeometry, c->screen, c->border);
/* restore height and width again */
newgeometry.width = c->f_geometry.width;
newgeometry.height = c->f_geometry.height;
area_list_wipe(&arealist); area_list_wipe(&arealist);
@ -147,21 +152,26 @@ placement_smart(area_t geometry, int border, int screen)
} }
area_t area_t
placement_under_mouse(area_t geometry, int border, int screen) placement_under_mouse(Client *c)
{ {
Window dummy; Window dummy;
unsigned int m; unsigned int m;
int x, y, d; int x, y, d;
area_t finalgeometry = geometry; area_t finalgeometry = c->f_geometry;
if(XQueryPointer(globalconf.display, RootWindow(globalconf.display, get_phys_screen(screen)), if(XQueryPointer(globalconf.display, RootWindow(globalconf.display, get_phys_screen(c->screen)),
&dummy, &dummy, &x, &y, &d, &d, &m)) &dummy, &dummy, &x, &y, &d, &d, &m))
{ {
finalgeometry.x = x - geometry.width / 2; finalgeometry.x = x - c->f_geometry.width / 2;
finalgeometry.y = y - geometry.height / 2; finalgeometry.y = y - c->f_geometry.height / 2;
} }
finalgeometry = placement_fix_offscreen(finalgeometry, screen, border); finalgeometry = placement_geometry_add_titlebar(&c->titlebar, finalgeometry);
finalgeometry = placement_fix_offscreen(finalgeometry, c->screen, c->border);
/* restore height and width */
finalgeometry.height = c->f_geometry.height;
finalgeometry.width = c->f_geometry.width;
return finalgeometry; return finalgeometry;
} }

View File

@ -261,7 +261,7 @@ typedef struct
int right; int right;
} Padding; } Padding;
typedef area_t (FloatingPlacement)(area_t, int, int); typedef area_t (FloatingPlacement)(Client *);
typedef struct typedef struct
{ {
/** Titlebar default parameters */ /** Titlebar default parameters */