Split: Begin to set split mode

This commit is contained in:
Martin Duquesnoy 2011-06-02 23:54:03 +02:00
parent a0e4a1657d
commit b36af57fb0
9 changed files with 162 additions and 28 deletions

View File

@ -39,15 +39,15 @@
client_focus(c); \
} while(/* CONSTCOND */ 0) \
#define CLIENT_ACTION_LIST(A, L) \
void \
uicb_client_##A##_##L(uicb_t cmd) \
{ \
Client *c; \
(void)cmd; \
\
if((c = client_get_##L())) \
client_##A(c); \
#define CLIENT_ACTION_LIST(A, L) \
void \
uicb_client_##A##_##L(uicb_t cmd) \
{ \
Client *c; \
(void)cmd; \
\
if((c = client_get_##L())) \
client_##A(c); \
}
#define CLIENT_ACTION_DIR(A, D) \
@ -235,7 +235,7 @@ client_above(Client *c)
client_moveresize(c, geo, (tags[c->screen][c->tag].flags & ResizeHintFlag));
client_raise(c);
tags[c->screen][c->tag].layout.func(c->screen);
layout_func(c->screen, c->tag);
return;
}
@ -648,7 +648,7 @@ client_set_rules(Client *c)
}
if(!conf.rule[i].ignoretags)
tags[c->screen][c->tag].layout.func(c->screen);
layout_func(c->screen, c->tag);
if(conf.rule[i].follow_client)
seltag[c->screen] = c->tag;
@ -786,6 +786,8 @@ client_manage(Window w, XWindowAttributes *wa, Bool ar)
ewmh_get_client_list();
ewmh_manage_window_type(c);
split_set_current(c, NULL);
if(ar)
arrange(c->screen, True);
@ -1182,13 +1184,16 @@ client_unmanage(Client *c)
ewmh_get_client_list();
if(c->flags & TileFlag)
{
tags[c->screen][c->tag].flags |= CleanFactFlag;
split_set_current(NULL, c);
}
if(c->tag == MAXTAG + 1)
{
for(i = 0; i < conf.ntag[c->screen]; i++)
tags[c->screen][i].flags |= RequestUpdateFlag;
tags[c->screen][seltag[c->screen]].layout.func(c->screen);
layout_func(c->screen, seltag[c->screen]);
}
else
{
@ -1201,12 +1206,12 @@ client_unmanage(Client *c)
}
else if(tags[i][seltag[i]].tagad & TagFlag(c->tag))
{
tags[i][seltag[i]].layout.func(c->screen);
layout_func(i, seltag[i]);
break;
}
if(b)
tags[c->screen][c->tag].layout.func(c->screen);
layout_func(c->screen, c->tag);
else
{
tags[c->screen][c->tag].flags |= RequestUpdateFlag;

View File

@ -108,6 +108,7 @@ const func_name_list_t func_list[] =
{"check_clist", uicb_checkclist },
{"toggle_tagautohide", uicb_toggle_tagautohide },
{"toggle_tag_expose", uicb_tag_toggle_expose},
{"split_toggle", uicb_split_toggle },
/*{"split_client_vertical", uicb_split_client_vertical },
{"split_client_horizontal", uicb_split_client_horizontal }, */
{NULL, NULL}

View File

@ -423,7 +423,7 @@ ewmh_manage_window_type(Client *c)
c->flags &= ~(TileFlag | MaxFlag | LMaxFlag);
client_moveresize(c, c->ogeo, True);
client_focus(c);
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
layout_func(selscreen, seltag[selscreen]);
}
}
XFree(data);

View File

@ -54,7 +54,7 @@ arrange(int screen, Bool update_layout)
if(tags[screen][seltag[screen]].layout.func)
{
if(update_layout)
tags[screen][seltag[screen]].layout.func(screen);
layout_func(screen, seltag[screen]);
infobar_draw(screen);
}
@ -62,6 +62,19 @@ arrange(int screen, Bool update_layout)
return;
}
/** Apply layout function
*/
void
layout_func(int screen, int tag)
{
if(tags[screen][tag].flags & SplitFlag)
split_apply_current(screen, tag);
else
tags[screen][tag].layout.func(screen);
return;
}
/** The free layout function
*/
void
@ -117,7 +130,7 @@ layoutswitch(Bool b)
ewmh_update_current_tag_prop();
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
layout_func(selscreen, seltag[selscreen]);
infobar_draw(selscreen);
return;
@ -205,7 +218,7 @@ uicb_set_mwfact(uicb_t cmd)
return;
tags[selscreen][seltag[selscreen]].mwfact += c;
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
layout_func(selscreen, seltag[selscreen]);
ewmh_update_current_tag_prop();
@ -231,7 +244,7 @@ uicb_set_nmaster(uicb_t cmd)
tags[selscreen][seltag[selscreen]].nmaster += n;
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
layout_func(selscreen, seltag[selscreen]);
ewmh_update_current_tag_prop();
@ -720,8 +733,8 @@ uicb_togglefree(uicb_t cmd)
if(sel->flags & FreeFlag)
{
split_set_current(NULL, sel);
sel->flags &= ~(TileFlag | MaxFlag | LMaxFlag);
client_moveresize(sel, sel->free_geo, True);
client_raise(sel);
}
@ -729,12 +742,13 @@ uicb_togglefree(uicb_t cmd)
{
sel->free_geo = sel->geo;
sel->ogeo = sel->geo;
split_set_current(sel, NULL);
}
client_update_attributes(sel);
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
layout_func(selscreen, seltag[selscreen]);
return;
}
@ -759,6 +773,7 @@ uicb_togglemax(uicb_t cmd)
sel->free_geo = sel->geo;
sel->flags &= ~(TileFlag | FreeFlag);
split_set_current(NULL, sel);
client_maximize(sel);
XRaiseWindow(dpy, sel->frame);
}
@ -769,7 +784,9 @@ uicb_togglemax(uicb_t cmd)
client_moveresize(sel, sel->geo, True);
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
split_set_current(sel, NULL);
layout_func(selscreen, seltag[selscreen]);
}
return;
@ -819,7 +836,7 @@ uicb_toggle_abovefc(uicb_t cmd)
}
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
layout_func(selscreen, seltag[selscreen]);
}
client_focus(sel);
@ -871,7 +888,7 @@ layout_set_client_master(Client *c)
client_attach(c);
tags[selscreen][seltag[selscreen]].flags |= CleanFactFlag;
tags[selscreen][seltag[selscreen]].layout.func(selscreen);
layout_func(selscreen, seltag[selscreen]);
return;
}

View File

@ -52,7 +52,7 @@ mouse_dragborder(XRectangle geo, GC g)
static void
mouse_cfactor_border(Client *c, int f[4], GC g)
{
int e;
int e;
mouse_dragborder(cfactor_geo(c->wrgeo, f, &e), g);

View File

@ -62,6 +62,67 @@ _split_check_row(XRectangle g1, XRectangle g2, Position p)
return (g1.x >= g2.x && (g1.x + g1.width) <= (g2.x + g2.width));
}
/** Set layout current clients to split/unsplit
*/
void
split_set_current(Client *nc, Client *ghost)
{
if(nc && (tags[nc->screen][nc->tag].flags & SplitFlag))
{
tags[nc->screen][nc->tag].layout.nc = nc;
tags[nc->screen][nc->tag].layout.flags |= IntegrationFlag;
}
if(ghost && (tags[ghost->screen][ghost->tag].flags & SplitFlag))
{
tags[ghost->screen][ghost->tag].layout.ghost = *ghost;
tags[ghost->screen][ghost->tag].layout.flags |= ArrangeFlag;
}
return;
}
/** Apply current operation about split
*/
void
split_apply_current(int screen, int tag)
{
Client *c;
/* Need to use split geo */
if(tags[screen][tag].layout.flags & UseGeoFlag)
{
for(c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next))
{
cfactor_clean(c);
client_moveresize(c, (c->pgeo = c->split_geo), (tags[screen][tag].flags & ResizeHintFlag));
}
tags[screen][tag].layout.flags &= ~UseGeoFlag;
tags[screen][tag].flags &= ~CleanFactFlag;
}
/* Integrate in split mode */
if(tags[screen][tag].layout.flags & IntegrationFlag)
{
if(tags[screen][tag].layout.nc == (c = sel)
|| c->screen != screen || c->tag != tag)
c = client_get_next();
split_client_integrate(tags[screen][tag].layout.nc, c, screen, tag);
tags[screen][tag].layout.flags &= ~IntegrationFlag;
}
/* Remove from split mode */
if(tags[screen][tag].layout.flags & ArrangeFlag)
{
split_arrange_closed(&tags[screen][tag].layout.ghost);
tags[screen][tag].layout.flags &= ~ArrangeFlag;
}
return;
}
/** Store split geos of clients
*/
void
@ -255,7 +316,8 @@ split_client_integrate(Client *c, Client *sc, int screen, int tag)
Bool b = True;
XRectangle g;
if(!c || c->flags & FreeFlag)
if(!c || c->flags & FreeFlag
|| !(tags[screen][tag].flags & SplitFlag))
return;
if(!sc || sc->screen != screen || sc->tag != tag)
@ -293,4 +355,21 @@ split_client_integrate(Client *c, Client *sc, int screen, int tag)
return;
}
/** Toggle split mode
*/
void
uicb_split_toggle(uicb_t cmd)
{
(void)cmd;
if((tags[selscreen][seltag[selscreen]].flags ^= SplitFlag) & SplitFlag)
split_store_geo(selscreen, seltag[selscreen]);
layout_func(selscreen, seltag[selscreen]);
return;
}

View File

@ -54,6 +54,11 @@
#define FLayFlag (1 << 11)
#define DockFlag (1 << 12)
/* Layout flags definition */
#define IntegrationFlag (1 << 1)
#define ArrangeFlag (1 << 2)
#define UseGeoFlag (1 << 3)
/* Tag flags definition */
#define TagUrgentFlag (1 << 1)
#define ResizeHintFlag (1 << 2)
@ -267,6 +272,9 @@ typedef struct
typedef struct
{
Bool splitusegeo;
uint flags; /* Flags blibli */
Client *nc; /* New client needing integration */
Client ghost; /* Ghost client to arrange split */
char *symbol;
char *type;
void (*func)(int screen);

View File

@ -106,7 +106,7 @@ tag_set(int tag)
if(tags[selscreen][tag].flags & RequestUpdateFlag)
{
tags[selscreen][tag].layout.func(selscreen);
layout_func(selscreen, tag);
tags[selscreen][tag].flags &= ~RequestUpdateFlag;
}
@ -148,12 +148,22 @@ tag_transfert(Client *c, int tag)
s = c->screen;
tags[c->screen][c->tag].flags |= CleanFactFlag;
cfactor_clean(c);
/* Case of tag in split mode */
if(tags[c->screen][c->tag].flags & SplitFlag)
split_arrange_closed(c);
if(tags[selscreen][tag].flags & SplitFlag)
split_client_integrate(c, NULL, selscreen, tag);
/* Set new location */
c->tag = tag;
c->screen = selscreen;
if(s != c->screen)
arrange(s, True);
arrange(c->screen, True);
client_focus_next(c);
@ -500,11 +510,21 @@ tag_additional(int sc, int tag, int adtag)
|| adtag < 1 || adtag > conf.ntag[sc] || adtag == seltag[sc])
return;
if(tags[sc][tag].flags & SplitFlag)
return;
tags[sc][tag].tagad ^= TagFlag(adtag);
tags[sc][adtag].flags |= RequestUpdateFlag;
tags[sc][tag].flags |= CleanFactFlag;
tags[sc][adtag].flags |= CleanFactFlag;
if(tags[sc][adtag].flags & SplitFlag)
{
tags[sc][adtag].layout.flags |= UseGeoFlag;
tags[sc][adtag].flags |= CleanFactFlag;
split_apply_current(sc, adtag);
}
arrange(sc, True);
return;

View File

@ -357,6 +357,7 @@ void systray_update(void);
/* layout.c */
void arrange(int screen, Bool update_layout);
void layout_func(int screen, int tag);
Client *tiled_client(int screen, Client *c);
void freelayout(int screen);
void layoutswitch(Bool b);
@ -398,10 +399,13 @@ void getinfo(char *info);
/* split.c */
void split_store_geo(int screen, int tag);
void split_set_current(Client *nc, Client *ghost);
void split_apply_current(int screen, int tag);
void split_arrange_closed(Client *ghost);
XRectangle split_client(Client *c, Bool p);
void split_client_fill(Client *c, XRectangle geo);
void split_client_integrate(Client *c, Client *sc, int screen, int tag);
void uicb_split_toggle(uicb_t cmd);
/* viwmfs.c */
void viwmfs(int argc, char **argv);