Client/Layout: Improve client tile factor
This commit is contained in:
parent
82eb33df85
commit
11edb78e84
29
TODO
29
TODO
@ -1,5 +1,24 @@
|
||||
· Add Doxygen comment <-> OK
|
||||
· Mouse bindings in the config file
|
||||
· Can change client position in the tile grid
|
||||
· Fix all the bug \o/
|
||||
· XCB ?
|
||||
,
|
||||
dM
|
||||
MMr
|
||||
4MMML .
|
||||
MMMMM. xf
|
||||
. "M6MMM .MM-
|
||||
Mh.. +MM5MMM .MMMM
|
||||
.MMM. .MMMMML. MMMMMh
|
||||
)MMMh. MM5MMM MMMMMMM
|
||||
3MMMMx. 'MMM3MMf xnMMMMMM"
|
||||
'*MMMMM MMMMMM. nMMMMMMP"
|
||||
*MMMMMx "MMM5M\ .MMMMMMM=
|
||||
*MMMMMh "MMMMM" JMMMMMMP
|
||||
MMMMMM GMMMM. dMMMMMM .
|
||||
MMMMMM "MMMM .MMMMM( .nnMP"
|
||||
.. *MMMMx MMM" dMMMM" .nnMMMMM*
|
||||
"MMn... 'MMMMr 'MM MMM" .nMMMMMMM*"
|
||||
"4MMMMnn.. *MMM MM MMP" .dMMMMMMM""
|
||||
^MMMMMMMMx. *ML "M .M* .MMMMMM**"
|
||||
*PMMMMMMhn. *x > M .MMMM**""
|
||||
""**MMMMhx/.h/ .=*"
|
||||
.3P"%....
|
||||
nP" "*MMnx
|
||||
|
||||
|
||||
121
src/client.c
121
src/client.c
@ -523,9 +523,9 @@ client_urgent(Client *c, Bool u)
|
||||
* \param y y value
|
||||
* \return The client
|
||||
*/
|
||||
Client* get_client_with_pos(int x, int y)
|
||||
Client* client_gb_pos(Client *c, int x, int y)
|
||||
{
|
||||
Client *c, *psel = sel;
|
||||
Client *ret;
|
||||
Window w;
|
||||
int d, dx, dy, basex, basey;
|
||||
|
||||
@ -538,12 +538,12 @@ client_urgent(Client *c, Bool u)
|
||||
XQueryPointer(dpy, ROOT, &w, &w, &dx, &dy, &d, &d, (uint *)&d);
|
||||
XWarpPointer(dpy, None, ROOT, 0, 0, 0, 0, basex, basey);
|
||||
|
||||
if(psel)
|
||||
client_focus(psel);
|
||||
|
||||
if((c = client_gb_frame(w)) || (c = client_gb_win(w)))
|
||||
if(w == ROOT)
|
||||
return c;
|
||||
|
||||
if((ret = client_gb_frame(w)) || (ret = client_gb_win(w)))
|
||||
return ret;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -892,11 +892,12 @@ client_manage(Window w, XWindowAttributes *wa, Bool ar)
|
||||
c->ogeo.y = c->geo.y = my;
|
||||
c->ogeo.width = c->geo.width = wa->width;
|
||||
c->ogeo.height = c->geo.height = wa->height;
|
||||
c->free_geo = c->geo;
|
||||
c->free_geo = c->pgeo = c->geo;
|
||||
c->tag = seltag[c->screen];
|
||||
c->focusontag = -1;
|
||||
|
||||
c->layer = (sel && sel->layer > 0) ? sel->layer : 1;
|
||||
tags[c->screen][c->tag].cleanfact = True;
|
||||
client_clean_tile_fact(c);
|
||||
|
||||
at.event_mask = PropertyChangeMask;
|
||||
|
||||
@ -1052,6 +1053,9 @@ client_moveresize(Client *c, XRectangle geo, Bool r)
|
||||
&& c->tag != MAXTAG + 1)
|
||||
c->tag = seltag[c->screen];
|
||||
|
||||
if(c->flags & TileFlag)
|
||||
c->geo = client_get_geo_factor(c->pgeo, c->tilefact);
|
||||
|
||||
frame_moveresize(c, c->geo);
|
||||
|
||||
XMoveResizeWindow(dpy, c->win, BORDH, TBARH, c->geo.width, c->geo.height);
|
||||
@ -1322,6 +1326,7 @@ client_unmanage(Client *c)
|
||||
XUngrabServer(dpy);
|
||||
ewmh_get_client_list();
|
||||
|
||||
tags[c->screen][c->tag].cleanfact = True;
|
||||
|
||||
if(c->tag == MAXTAG + 1)
|
||||
{
|
||||
@ -1689,6 +1694,51 @@ uicb_client_set_master(uicb_t cmd)
|
||||
return;
|
||||
}
|
||||
|
||||
/** Clean client tile factors
|
||||
*\param c Client pointer
|
||||
*/
|
||||
void
|
||||
client_clean_tile_fact(Client *c)
|
||||
{
|
||||
CHECK(c);
|
||||
|
||||
if(!tags[c->screen][c->tag].cleanfact)
|
||||
return;
|
||||
|
||||
c->tilefact[Right] = c->tilefact[Left] = 0;
|
||||
c->tilefact[Top] = c->tilefact[Bottom] = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** Return new geo of client with factors applied
|
||||
*\param c Client pointer
|
||||
*\return geo
|
||||
*/
|
||||
XRectangle
|
||||
client_get_geo_factor(XRectangle geo, int fact[4])
|
||||
{
|
||||
XRectangle cgeo = { 0, 0, 0, 0 };
|
||||
|
||||
cgeo = geo;
|
||||
|
||||
/* Right factor */
|
||||
cgeo.width += fact[Right];
|
||||
|
||||
/* Left factor */
|
||||
cgeo.x -= fact[Left];
|
||||
cgeo.width += fact[Left];
|
||||
|
||||
/* Top factor */
|
||||
cgeo.y -= fact[Top];
|
||||
cgeo.height += fact[Top];
|
||||
|
||||
/* Bottom factor */
|
||||
cgeo.height += fact[Bottom];
|
||||
|
||||
return cgeo;
|
||||
}
|
||||
|
||||
/** Manual resizing of tiled clients
|
||||
* \param c Client pointer
|
||||
* \param p Direction of resizing
|
||||
@ -1700,52 +1750,32 @@ client_tile_factor_set(Client *c, Position p, int fac)
|
||||
Client *gc = NULL;
|
||||
int x, y;
|
||||
XRectangle cgeo, scgeo;
|
||||
Position reversepos[4] = { Left, Right, Bottom, Top };
|
||||
int cfact[4] = { 0 }, scfact[4] = { 0 };
|
||||
char scanfac[4][3] =
|
||||
{
|
||||
{ 1, 0 }, { -1, 0 }, /* Right, Left */
|
||||
{ 0, -1 }, { 0, 1 } /* Top, Bottom */
|
||||
{ 1, 0 }, { -1, 0 }, /* Right, Left */
|
||||
{ 0, -1 }, { 0, 1 } /* Top, Bottom */
|
||||
};
|
||||
|
||||
if(!c || !(c->flags & TileFlag) || p > Bottom)
|
||||
if(!c || p > Bottom)
|
||||
return;
|
||||
|
||||
cgeo = c->geo;
|
||||
|
||||
/* Scan in right direction to next(p) physical client */
|
||||
/* Start place of pointer for faster scanning */
|
||||
x = c->geo.x + ((p == Right) ? c->geo.width : 0);
|
||||
y = c->geo.y + ((p == Bottom) ? c->geo.height : 0);
|
||||
for(; (gc = get_client_with_pos(x, y)) == c; x += scanfac[p][0], y += scanfac[p][1]);
|
||||
|
||||
if(!gc)
|
||||
/* Scan in right direction to next(p) physical client */
|
||||
for(; (gc = client_gb_pos(c, x, y)) == c; x += scanfac[p][0], y += scanfac[p][1]);
|
||||
|
||||
if(!gc || c->screen != gc->screen)
|
||||
return;
|
||||
|
||||
scgeo = gc->geo;
|
||||
cfact[p] += fac;
|
||||
scfact[reversepos[p]] -= fac;
|
||||
|
||||
/* Modify client geometry */
|
||||
switch(p)
|
||||
{
|
||||
default:
|
||||
case Right:
|
||||
scgeo.x += fac;
|
||||
cgeo.width += fac;
|
||||
scgeo.width -= fac;
|
||||
break;
|
||||
case Left:
|
||||
cgeo.x -= fac;
|
||||
cgeo.width += fac;
|
||||
scgeo.width -= fac;
|
||||
break;
|
||||
case Top:
|
||||
cgeo.y -= fac;
|
||||
cgeo.height += fac;
|
||||
scgeo.height -= fac;
|
||||
break;
|
||||
case Bottom:
|
||||
scgeo.y += fac;
|
||||
cgeo.height += fac;
|
||||
scgeo.height -= fac;
|
||||
break;
|
||||
}
|
||||
cgeo = client_get_geo_factor(c->geo, cfact);
|
||||
scgeo = client_get_geo_factor(gc->geo, scfact);
|
||||
|
||||
/* Too big */
|
||||
if(scgeo.width > (1 << 15) || scgeo.height > (1 << 15)
|
||||
@ -1757,6 +1787,13 @@ client_tile_factor_set(Client *c, Position p, int fac)
|
||||
|| cgeo.width < 1 || cgeo.height < 1)
|
||||
return;
|
||||
|
||||
/* Check if move/resize is needed for same col/row clients */
|
||||
/*for(sc = tiled_client(c->screen, clients); sc; tiled_client(c->screen, c->next))
|
||||
if(sc->geo.*/
|
||||
|
||||
c->tilefact[p] += fac;
|
||||
gc->tilefact[reversepos[p]] -= fac;
|
||||
|
||||
/* Magic moment */
|
||||
client_moveresize(c, cgeo, tags[c->screen][c->tag].resizehint);
|
||||
client_moveresize(gc, scgeo, tags[gc->screen][gc->tag].resizehint);
|
||||
|
||||
@ -530,7 +530,7 @@ conf_tag_section(void)
|
||||
fetch_opt_first(def_tag, "0.6", "mwfact").fnum,
|
||||
fetch_opt_first(def_tag, "1", "nmaster").num,
|
||||
False, fetch_opt_first(def_tag, "False", "resizehint").bool,
|
||||
False, False, bar_pos, bar_pos,
|
||||
False, False, False, bar_pos, bar_pos,
|
||||
layout_name_to_struct(conf.layout, fetch_opt_first(def_tag, "title_right", "layout").str, conf.nlayout, layout_list),
|
||||
0, NULL, 0, False };
|
||||
|
||||
|
||||
39
src/layout.c
39
src/layout.c
@ -54,7 +54,10 @@ arrange(int screen, Bool update_layout)
|
||||
if(tags[screen][seltag[screen]].layout.func)
|
||||
{
|
||||
if(update_layout)
|
||||
{
|
||||
tags[screen][seltag[screen]].cleanfact = True;
|
||||
tags[screen][seltag[screen]].layout.func(screen);
|
||||
}
|
||||
|
||||
infobar_draw(screen);
|
||||
}
|
||||
@ -116,6 +119,7 @@ layoutswitch(Bool b)
|
||||
}
|
||||
|
||||
ewmh_update_current_tag_prop();
|
||||
tags[selscreen][seltag[selscreen]].cleanfact = True;
|
||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
||||
infobar_draw(selscreen);
|
||||
|
||||
@ -151,7 +155,7 @@ uicb_layout_prev(uicb_t cmd)
|
||||
* \param c Client pointer
|
||||
* \return a client pointer
|
||||
*/
|
||||
static Client*
|
||||
Client*
|
||||
tiled_client(int screen, Client *c)
|
||||
{
|
||||
for(;c && ((c->flags & MaxFlag)
|
||||
@ -229,6 +233,7 @@ uicb_set_nmaster(uicb_t cmd)
|
||||
return;
|
||||
|
||||
tags[selscreen][seltag[selscreen]].nmaster += n;
|
||||
tags[c->screen][c->tag].cleanfact = True;
|
||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
||||
|
||||
ewmh_update_current_tag_prop();
|
||||
@ -270,6 +275,9 @@ grid(int screen, Bool horizontal)
|
||||
c->flags &= ~(MaxFlag | LMaxFlag);
|
||||
c->flags |= TileFlag;
|
||||
++cpcols;
|
||||
|
||||
client_clean_tile_fact(c);
|
||||
|
||||
cgeo.width = (sg.width / cols) - (BORDH * 2);
|
||||
cgeo.height = (sg.height / rows) - BORDH;
|
||||
|
||||
@ -282,19 +290,20 @@ grid(int screen, Bool horizontal)
|
||||
cgeo.width = sg.width - (cgeo.x - (sg.x - (BORDH * 2)));
|
||||
|
||||
/* Resize */
|
||||
client_moveresize(c, cgeo, tags[screen][seltag[screen]].resizehint);
|
||||
client_moveresize(c, (c->pgeo = cgeo), tags[screen][seltag[screen]].resizehint);
|
||||
|
||||
/* Set all the other size with current client info */
|
||||
cgeo.y = c->geo.y + c->geo.height + BORDH + TBARH;
|
||||
cgeo.y = c->pgeo.y + c->pgeo.height + BORDH + TBARH;
|
||||
|
||||
if(cpcols + 1 > rows)
|
||||
{
|
||||
cpcols = 0;
|
||||
cgeo.x = c->geo.x + c->geo.width + (BORDH * 2);
|
||||
cgeo.x = c->pgeo.x + c->pgeo.width + (BORDH * 2);
|
||||
cgeo.y = sg.y;
|
||||
}
|
||||
}
|
||||
|
||||
tags[screen][seltag[screen]].cleanfact = False;
|
||||
ewmh_update_current_tag_prop();
|
||||
|
||||
return;
|
||||
@ -355,6 +364,8 @@ multi_tile(int screen, Position type)
|
||||
c->flags &= ~(MaxFlag | LMaxFlag);
|
||||
c->flags |= TileFlag;
|
||||
|
||||
client_clean_tile_fact(c);
|
||||
|
||||
/* MASTER */
|
||||
if(i < nmaster)
|
||||
{
|
||||
@ -415,15 +426,16 @@ multi_tile(int screen, Position type)
|
||||
}
|
||||
|
||||
/* Magic instant */
|
||||
client_moveresize(c, cgeo, tags[screen][seltag[screen]].resizehint);
|
||||
client_moveresize(c, (c->pgeo = cgeo), tags[screen][seltag[screen]].resizehint);
|
||||
|
||||
/* Set the position of the next client */
|
||||
if(type == Top || type == Bottom)
|
||||
cgeo.x = c->geo.x + c->geo.width + (BORDH * 2);
|
||||
cgeo.x = c->pgeo.x + c->pgeo.width + (BORDH * 2);
|
||||
else
|
||||
cgeo.y = c->geo.y + c->geo.height + BORDH + TBARH;
|
||||
cgeo.y = c->pgeo.y + c->pgeo.height + BORDH + TBARH;
|
||||
}
|
||||
|
||||
tags[screen][seltag[screen]].cleanfact = False;
|
||||
ewmh_update_current_tag_prop();
|
||||
|
||||
return;
|
||||
@ -444,7 +456,7 @@ mirror(int screen, Bool horizontal)
|
||||
uint i, n, tilesize = 0, mwfact;
|
||||
uint nmaster = tags[screen][seltag[screen]].nmaster;
|
||||
int pa, imp;
|
||||
Bool isp = 0;
|
||||
Bool isp = False;
|
||||
|
||||
memset(nextg, 0, sizeof(nextg));
|
||||
|
||||
@ -510,6 +522,8 @@ mirror(int screen, Bool horizontal)
|
||||
c->flags &= ~(MaxFlag | LMaxFlag);
|
||||
c->flags |= TileFlag;
|
||||
|
||||
client_clean_tile_fact(c);
|
||||
|
||||
if(i < nmaster)
|
||||
{
|
||||
cgeo = mastergeo;
|
||||
@ -571,10 +585,10 @@ mirror(int screen, Bool horizontal)
|
||||
}
|
||||
}
|
||||
|
||||
client_moveresize(c, cgeo, tags[screen][seltag[screen]].resizehint);
|
||||
client_moveresize(c, (c->pgeo = cgeo), tags[screen][seltag[screen]].resizehint);
|
||||
|
||||
if(i >= nmaster)
|
||||
nextg[!isp] = c->geo;
|
||||
nextg[!isp] = c->pgeo;
|
||||
|
||||
/* Next y/x position */
|
||||
if(i >= nmaster - 1)
|
||||
@ -604,6 +618,7 @@ mirror(int screen, Bool horizontal)
|
||||
|
||||
}
|
||||
|
||||
tags[screen][seltag[screen]].cleanfact = False;
|
||||
ewmh_update_current_tag_prop();
|
||||
|
||||
return;
|
||||
@ -720,6 +735,7 @@ uicb_togglefree(uicb_t cmd)
|
||||
|
||||
client_update_attributes(sel);
|
||||
|
||||
tags[selscreen][seltag[selscreen]].cleanfact = True;
|
||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
||||
|
||||
return;
|
||||
@ -752,6 +768,7 @@ uicb_togglemax(uicb_t cmd)
|
||||
sel->geo = sel->ogeo;
|
||||
client_moveresize(sel, sel->geo, True);
|
||||
sel->flags &= ~MaxFlag;
|
||||
tags[selscreen][seltag[selscreen]].cleanfact = True;
|
||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
||||
}
|
||||
|
||||
@ -796,6 +813,7 @@ uicb_toggle_abovefc(uicb_t cmd)
|
||||
break;
|
||||
}
|
||||
|
||||
tags[selscreen][seltag[selscreen]].cleanfact = True;
|
||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
||||
}
|
||||
|
||||
@ -846,6 +864,7 @@ layout_set_client_master(Client *c)
|
||||
client_detach(c);
|
||||
client_attach(c);
|
||||
|
||||
tags[selscreen][seltag[selscreen]].cleanfact = True;
|
||||
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
|
||||
|
||||
return;
|
||||
|
||||
@ -188,16 +188,16 @@ struct Client
|
||||
int focusontag;
|
||||
/* Screen */
|
||||
int screen;
|
||||
/* Layer */
|
||||
int layer;
|
||||
/* Window attribute */
|
||||
XRectangle geo;
|
||||
XRectangle geo, pgeo;
|
||||
XRectangle tmp_geo;
|
||||
XRectangle frame_geo;
|
||||
/* Old window attribute */
|
||||
XRectangle ogeo;
|
||||
/* Free window attribute */
|
||||
XRectangle free_geo;
|
||||
/* Tile size factors */
|
||||
int tilefact[4];
|
||||
/* For resizehint usage */
|
||||
int basew, baseh, incw, inch;
|
||||
int maxw, maxh, minw, minh;
|
||||
@ -286,6 +286,7 @@ typedef struct
|
||||
Bool resizehint;
|
||||
Bool request_update;
|
||||
Bool abovefc;
|
||||
Bool cleanfact;
|
||||
int barpos;
|
||||
int prev_barpos;
|
||||
Layout layout;
|
||||
|
||||
12
src/tag.c
12
src/tag.c
@ -372,7 +372,7 @@ uicb_tag_stay_last(uicb_t cmd)
|
||||
{
|
||||
int i;
|
||||
remove_old_last_tag(selscreen);
|
||||
|
||||
|
||||
for(i = seltag[selscreen]; i <= conf.ntag[selscreen]; i++)
|
||||
{
|
||||
tag_swap(selscreen, seltag[selscreen], seltag[selscreen] + 1);
|
||||
@ -603,9 +603,9 @@ tag_new(int s, char *name)
|
||||
|
||||
Tag t = { displayedName, NULL, 0, 0,
|
||||
conf.default_tag.mwfact, conf.default_tag.nmaster,
|
||||
False, conf.default_tag.resizehint, False, False,
|
||||
conf.default_tag.barpos, conf.default_tag.barpos, conf.default_tag.layout,
|
||||
0, NULL, 0, False };
|
||||
False, conf.default_tag.resizehint, False, False, False,
|
||||
conf.default_tag.barpos, conf.default_tag.barpos,
|
||||
conf.default_tag.layout, 0, NULL, 0, False };
|
||||
|
||||
tags[s][conf.ntag[s]] = t;
|
||||
|
||||
@ -760,7 +760,7 @@ uicb_tag_toggle_expose(uicb_t cmd)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tag_new(selscreen, conf.tag_expose_name);
|
||||
|
||||
for(i = 0; i < conf.nlayout; ++i)
|
||||
@ -775,7 +775,7 @@ uicb_tag_toggle_expose(uicb_t cmd)
|
||||
{
|
||||
tags[selscreen][conf.ntag[selscreen]].tagad ^= TagFlag(i);
|
||||
}
|
||||
|
||||
|
||||
tags[selscreen][conf.ntag[selscreen]].request_update = True;
|
||||
arrange(selscreen, True);
|
||||
|
||||
|
||||
@ -163,7 +163,7 @@ Client* client_gb_frame(Window w);
|
||||
Client* client_gb_titlebar(Window w);
|
||||
Client* client_gb_resize(Window w);
|
||||
Client* client_gb_button(Window w, int *n);
|
||||
Client* get_client_with_pos(int x, int y);
|
||||
Client* client_gb_pos(Client *c, int x, int y);
|
||||
/* }}} */
|
||||
void client_get_name(Client *c);
|
||||
void client_hide(Client *c);
|
||||
@ -183,6 +183,8 @@ void client_unmanage(Client *c);
|
||||
void client_unmap(Client *c);
|
||||
void client_update_attributes(Client *c);
|
||||
void client_urgent(Client *c, Bool u);
|
||||
void client_clean_tile_fact(Client *c);
|
||||
XRectangle client_get_geo_factor(XRectangle geo, int fact[4]);
|
||||
void uicb_client_raise(uicb_t);
|
||||
void uicb_client_next(uicb_t);
|
||||
void uicb_client_prev(uicb_t);
|
||||
@ -335,6 +337,7 @@ void systray_update(void);
|
||||
|
||||
/* layout.c */
|
||||
void arrange(int screen, Bool update_layout);
|
||||
Client *tiled_client(int screen, Client *c);
|
||||
void freelayout(int screen);
|
||||
void layoutswitch(Bool b);
|
||||
void maxlayout(int screen);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user