ALL: Improve client structure

This commit is contained in:
Martin Duquesnoy
2008-10-18 17:38:11 +02:00
parent f061810390
commit 31765c6165
6 changed files with 113 additions and 80 deletions

View File

@@ -191,9 +191,12 @@ client_hide(Client *c)
if(!c)
return;
XMoveWindow(dpy, c->win, c->x, c->y+mh*2);
XMoveWindow(dpy, c->win, c->geo.x, c->geo.y + sgeo.height*2);
if(conf.ttbarheight)
bar_moveresize(c->tbar, c->x, c->y+mh*2, c->w, c->h);
bar_moveresize(c->tbar,
c->geo.x,
c->geo.y + sgeo.height*2,
c->geo.width, c->geo.height);
setwinstate(c->win, IconicState);
c->hide = True;
@@ -258,16 +261,16 @@ client_manage(Window w, XWindowAttributes *wa)
c = emalloc(1, sizeof(Client));
c->win = w;
c->x = wa->x;
c->y = wa->y + conf.ttbarheight + barheight;
c->w = wa->width;
c->h = wa->height - conf.ttbarheight-1;
c->geo.x = wa->x;
c->geo.y = wa->y + conf.ttbarheight + barheight;
c->geo.width = wa->width;
c->geo.height = wa->height - conf.ttbarheight;
c->tag = seltag;
/* Create titlebar */
if(conf.ttbarheight)
c->tbar = bar_create(c->x, c->y - conf.ttbarheight,
c->w, conf.ttbarheight, conf.borderheight,
c->tbar = bar_create(c->geo.x, c->geo.y - conf.ttbarheight,
c->geo.width, conf.ttbarheight, conf.borderheight,
conf.colors.bar, True);
XConfigureWindow(dpy, w, CWBorderWidth, &winc);
@@ -287,7 +290,7 @@ client_manage(Window w, XWindowAttributes *wa)
raiseclient(c);
client_attach(c);
client_moveresize(c, c->x, c->y, c->w, c->h, True);
client_moveresize(c, c->geo, True);
mapclient(c);
setwinstate(c->win, NormalState);
client_focus(c);
@@ -297,63 +300,64 @@ client_manage(Window w, XWindowAttributes *wa)
}
void
client_moveresize(Client *c, int x, int y, int w, int h, bool r)
client_moveresize(Client *c, XRectangle geo, bool r)
{
Bool d;
if(!c)
return;
/* Resize hints {{{ */
if(r)
{
/* minimum possible */
if (w < 1)
w = 1;
if (h < 1)
h = 1;
if (geo.width < 1)
geo.width = 1;
if (geo.height < 1)
geo.height = 1;
/* base */
w -= c->basew;
h -= c->baseh;
geo.width -= c->basew;
geo.height -= c->baseh;
/* aspect */
if (c->minay > 0 && c->maxay > 0
&& c->minax > 0 && c->maxax > 0)
{
if (w * c->maxay > h * c->maxax)
w = h * c->maxax / c->maxay;
else if (w * c->minay < h * c->minax)
h = w * c->minay / c->minax;
if (geo.width * c->maxay > geo.height * c->maxax)
geo.width = geo.height * c->maxax / c->maxay;
else if (geo.width * c->minay < geo.height * c->minax)
geo.height = geo.width * c->minay / c->minax;
}
/* incremental */
if(c->incw)
w -= w % c->incw;
geo.width -= geo.width % c->incw;
if(c->inch)
h -= h % c->inch;
geo.height -= geo.height % c->inch;
/* base dimension */
w += c->basew;
h += c->baseh;
geo.width += c->basew;
geo.height += c->baseh;
if(c->minw > 0 && w < c->minw)
w = c->minw;
if(c->minh > 0 && h < c->minh)
h = c->minh;
if(c->maxw > 0 && w > c->maxw)
w = c->maxw;
if(c->maxh > 0 && h > c->maxh)
h = c->maxh;
if(w <= 0 || h <= 0)
if(c->minw > 0 && geo.width < c->minw)
geo.width = c->minw;
if(c->minh > 0 && geo.height < c->minh)
geo.height = c->minh;
if(c->maxw > 0 && geo.width > c->maxw)
geo.width = c->maxw;
if(c->maxh > 0 && geo.height > c->maxh)
geo.height = c->maxh;
if(geo.width <= 0 || geo.height <= 0)
return;
}
/* }}} */
c->max = False;
if(c->x != x || c->y != y
|| c->w != w || c->h != h)
if(c->geo.x != geo.x || c->geo.y != geo.y
|| c->geo.width != geo.width || c->geo.height != geo.height)
{
c->x = x; c->y = y;
c->w = w; c->h = h;
c->geo = geo;
XMoveResizeWindow(dpy, c->win, x, y + conf.ttbarheight, w, h - conf.ttbarheight - 1);
XMoveResizeWindow(dpy, c->win, geo.x, geo.y + conf.ttbarheight, geo.width, geo.height - conf.ttbarheight);
if(conf.ttbarheight)
bar_moveresize(c->tbar, x, y - 1, w, conf.ttbarheight);
bar_moveresize(c->tbar, geo.x, geo.y, geo.width, conf.ttbarheight);
updatetitlebar(c);
XSync(dpy, False);
@@ -407,8 +411,7 @@ client_size_hints(Client *c)
}
else if(size.flags & PBaseSize)
{
c->minw = size.base_width;
c->minh = size.base_height;
c->minw = size.base_width; c->minh = size.base_height;
}
else
c->minw = c->minh = 0;
@@ -449,9 +452,12 @@ client_unhide(Client *c)
{
if(!c)
return;
XMoveWindow(dpy, c->win, c->x, c->y + conf.ttbarheight);
XMoveWindow(dpy, c->win, c->geo.x, c->geo.y + conf.ttbarheight);
if(conf.ttbarheight)
bar_moveresize(c->tbar, c->x, c->y - 1, c->w, conf.ttbarheight);
bar_moveresize(c->tbar,
c->geo.x,
c->geo.y,
c->geo.width, conf.ttbarheight);
setwinstate(c->win, NormalState);
c->hide = False;

View File

@@ -226,13 +226,14 @@ configurerequest(XEvent ev)
{
Client *c;
XWindowChanges wc;
XRectangle geo;
if((c = getclient(ev.xconfigurerequest.window)))
if(c->tile || c->lmax)
return;
wc.x = ev.xconfigurerequest.x;
wc.y = ev.xconfigurerequest.y;
wc.width = ev.xconfigurerequest.width;
wc.height = ev.xconfigurerequest.height;
geo.x = wc.x = ev.xconfigurerequest.x;
geo.y = wc.y = ev.xconfigurerequest.y;
geo.width = wc.width = ev.xconfigurerequest.width;
geo.height = wc.height = ev.xconfigurerequest.height;
wc.border_width = ev.xconfigurerequest.border_width;
wc.sibling = ev.xconfigurerequest.above;
wc.stack_mode = ev.xconfigurerequest.detail;
@@ -240,7 +241,11 @@ configurerequest(XEvent ev)
ev.xconfigurerequest.value_mask, &wc);
if((c = getclient(ev.xconfigurerequest.window)))
if(wc.y < mw && wc.x < mh)
client_moveresize(c, wc.x, wc.y, wc.width, wc.height, True);
{
geo.y -= conf.ttbarheight;
geo.height += conf.ttbarheight;
client_moveresize(c, geo, True);
}
return;
}
@@ -398,18 +403,19 @@ void
mouseaction(Client *c, int x, int y, int type)
{
int ocx, ocy;
XRectangle geo;
XEvent ev;
if(c->max || c->tile || c->lmax)
return;
ocx = c->x;
ocy = c->y;
ocx = c->geo.x;
ocy = c->geo.y;
if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
None, cursor[((type) ?CurResize:CurMove)], CurrentTime) != GrabSuccess)
return;
if(type)
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->geo.width, c->geo.height);
for(;;)
{
@@ -417,7 +423,7 @@ mouseaction(Client *c, int x, int y, int type)
if(ev.type == ButtonRelease)
{
if(type)
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->geo.width, c->geo.height);
XUngrabPointer(dpy, CurrentTime);
updatebar();
return;
@@ -427,14 +433,21 @@ mouseaction(Client *c, int x, int y, int type)
XSync(dpy, False);
/* Resize */
if(type)
client_moveresize(c, c->x, c->y,
((ev.xmotion.x - ocx <= 0) ? 1 : ev.xmotion.x - ocx),
((ev.xmotion.y - ocy <= 0) ? 1 : ev.xmotion.y - ocy), True);
{
geo.x = c->geo.x; geo.y = c->geo.y;
geo.width = ((ev.xmotion.x - ocx <= 0) ? 1 : ev.xmotion.x - ocx);
geo.height = ((ev.xmotion.y - ocy <= 0) ? 1 : ev.xmotion.y - ocy);
client_moveresize(c, geo, True);
}
/* Move */
else
client_moveresize(c, (ocx + (ev.xmotion.x - x)),
(ocy + (ev.xmotion.y - y)),
c->w, c->h, True);
{
geo.x = (ocx + (ev.xmotion.x - x));
geo.y = (ocy + (ev.xmotion.y - y));
geo.width = c->geo.width;
geo.height = c->geo.height;
client_moveresize(c, geo, True);
}
}
else if(ev.type == Expose)
expose(ev);

View File

@@ -59,6 +59,7 @@ void
freelayout(void)
{
Client *c;
XRectangle geo;
for(c = clients; c; c = c->next)
{
@@ -66,9 +67,11 @@ freelayout(void)
{
if(c->tile || c->lmax)
{
client_moveresize(c, c->ox, c->oy, c->ow, c->oh, True);
c->tile = False;
c->lmax = False;
geo.x = c->ogeo.x; geo.y = c->ogeo.y;
geo.width = c->ogeo.width;
geo.height = c->ogeo.height;
client_moveresize(c, geo, True);
c->tile = c->lmax = False;
}
}
}
@@ -117,17 +120,20 @@ void
maxlayout(void)
{
Client *c;
XRectangle geo;
for(c = nexttiled(clients); c; c = nexttiled(c->next))
{
c->tile = False;
c->lmax = True;
c->ox = c->x; c->oy = c->y;
c->ow = c->w; c->oh = c->h;
c->ogeo.x = c->geo.x; c->ogeo.y = c->geo.y;
c->ogeo.width = c->geo.width; c->ogeo.height = c->geo.height;
client_moveresize(c, sgeo.x, sgeo.y,
(sgeo.width - (conf.borderheight * 2)),
(sgeo.height - (conf.borderheight * 2)), False);
geo.x = sgeo.x; geo.y = sgeo.y;
geo.width = sgeo.width - (conf.borderheight * 2);
geo.height = sgeo.height - (conf.borderheight * 2);
client_moveresize(c, geo, False);
}
return;
@@ -214,8 +220,8 @@ tile(void)
/* Set client property */
c->max = c->lmax = False;
c->tile = True;
c->ox = c->x; c->oy = c->y;
c->ow = c->w; c->oh = c->h;
c->ogeo.x = c->geo.x; c->ogeo.y = c->geo.y;
c->ogeo.width = c->geo.width; c->ogeo.height = c->geo.height;
/* Master Client */
if(i < nmaster)
@@ -249,10 +255,10 @@ tile(void)
cgeo.height = tileheight - border;
}
client_moveresize(c, cgeo.x, cgeo.y, cgeo.width, cgeo.height, tags[seltag].resizehint);
client_moveresize(c, cgeo, tags[seltag].resizehint);
if(n > nmaster && tileheight != sgeo.height)
cgeo.y = c->y + c->h + border;
cgeo.y = c->geo.y + c->geo.height + border;
}
return;
@@ -279,21 +285,29 @@ uicb_tile_switch(uicb_t cmd)
void
uicb_togglemax(uicb_t cmd)
{
XRectangle geo;
if(!sel || ishide(sel) || sel->hint)
return;
if(!sel->max)
{
sel->ox = sel->x; sel->oy = sel->y;
sel->ow = sel->w; sel->oh = sel->h;
client_moveresize(sel, 0, (conf.ttbarheight + ((conf.bartop) ? barheight: 0)),
(mw - (conf.borderheight * 2)),
(mh - (conf.borderheight * 2)- conf.ttbarheight - barheight), False);
sel->ogeo.x = sel->geo.x; sel->ogeo.y = sel->geo.y;
sel->ogeo.width = sel->geo.width; sel->ogeo.height = sel->geo.height;
geo.x = sgeo.x; geo.y = sgeo.y;
geo.width = sgeo.width - (conf.borderheight * 2);
geo.height = sgeo.height - (conf.borderheight * 2);
client_moveresize(sel, geo, False);
raiseclient(sel);
sel->max = True;
}
else if(sel->max)
{
client_moveresize(sel, sel->ox, sel->oy, sel->ow, sel->oh, False);
geo.x = sel->ogeo.x; geo.y = sel->ogeo.y;
geo.width = sel->ogeo.width; geo.height = sel->ogeo.height;
client_moveresize(sel, geo, False);
sel->max = False;
}
arrange();

View File

@@ -71,9 +71,9 @@ struct Client
/* Tag num */
int tag;
/* Window attribute */
int x, y, w, h;
XRectangle geo;
/* Old window attribute */
int ox, oy, ow, oh;
XRectangle ogeo;
/* For resizehint usage */
int basew, baseh, incw, inch;
int maxw, maxh, minw, minh;

View File

@@ -177,7 +177,7 @@ init(void)
/* INIT WORKABLE SPACE */
sgeo.x = 0;
sgeo.y = (conf.bartop) ? barheight+1 : 1;
sgeo.y = (conf.bartop) ? barheight : 0;
sgeo.width = DisplayWidth(dpy, screen);
sgeo.height = DisplayHeight(dpy, screen) - barheight;

View File

@@ -97,7 +97,7 @@ void client_hide(Client *c);
Bool ishide(Client *c);
void mapclient(Client *c);
void client_manage(Window w, XWindowAttributes *wa);
void client_moveresize(Client *c, int x, int y, int w, int h, bool r);
void client_moveresize(Client *c, XRectangle geo, bool r);
void client_size_hints(Client *c);
void raiseclient(Client *c);
void client_unhide(Client *c);