diff --git a/Makefile b/Makefile index e031113..dad15eb 100644 --- a/Makefile +++ b/Makefile @@ -73,5 +73,6 @@ LIBS+= ${XRANDR_LIBS} LIBS+= ${IMLIB2_LIBS} # Install man and wmfsrc -install: ${INSTALL_DATA} wmfs.1 ${MANDIR}/man1 \ - ${INSTALL_DATA} wmfsrc ${XDG_CONFIG_DIR}/wmfs/ +install: + ${INSTALL_DATA} wmfs.1 ${MANDIR}/man1 + ${INSTALL_DATA} wmfsrc ${XDG_CONFIG_DIR}/wmfs/ diff --git a/src/client.c b/src/client.c index f00160b..e5b532a 100644 --- a/src/client.c +++ b/src/client.c @@ -88,7 +88,7 @@ client_detach(Client *c) /** Get the next client *\return The next client or NULL */ -static Client* +Client* client_get_next(void) { Client *c = NULL; @@ -331,6 +331,7 @@ client_above(Client *c) client_moveresize(c, geo, tags[c->screen][c->tag].resizehint); client_raise(c); + split_arrange_closed(c); tags[c->screen][c->tag].layout.func(c->screen); return; @@ -349,7 +350,10 @@ client_focus(Client *c) if(sel && sel != c) { if(sel->flags & AboveFlag) + { sel->flags &= ~AboveFlag; + split_client_integrate(sel, client_get_next(), sel->screen, sel->tag); + } XChangeProperty(dpy, sel->frame, net_atom[net_wm_window_opacity], XA_CARDINAL, 32, PropModeReplace, (uchar *)&conf.opacity, 1); @@ -739,6 +743,8 @@ client_set_rules(Client *c) else tags[c->screen][c->tag].layout.func(c->screen); + split_client_integrate(c, NULL, i, j); + /* Deprecated but still in use */ applied_tag_rule = True; applied_screen_rule = True; @@ -908,9 +914,10 @@ client_manage(Window w, XWindowAttributes *wa, Bool ar) client_get_name(c); tags[c->screen][c->tag].cleanfact = True; + client_update_attributes(c); /* Case of split layout */ - split_client_integrate(c, sel); + split_client_integrate(c, sel, c->screen, c->tag); /* If client will be visible soon so.. */ if(c->tag == (uint)seltag[selscreen]) @@ -1026,8 +1033,6 @@ client_moveresize(Client *c, XRectangle geo, Bool r) } } - c->flags &= ~MaxFlag; - /* Set geo without resizehint applied */ c->wrgeo = geo; @@ -1322,7 +1327,7 @@ client_unmanage(Client *c) if(c->flags & TileFlag) { tags[c->screen][c->tag].cleanfact = True; - split_arrange_closed(*c); + split_arrange_closed(c); } if(c->tag == MAXTAG + 1) @@ -1421,6 +1426,7 @@ client_set_screen(Client *c, int s) arrange(s, True); arrange(os, True); + split_client_integrate(c, NULL, c->screen, c->tag); if(!(c->flags & TileFlag)) { diff --git a/src/layout.c b/src/layout.c index 565b182..8fd2a5b 100644 --- a/src/layout.c +++ b/src/layout.c @@ -239,11 +239,12 @@ uicb_set_nmaster(uicb_t cmd) } /** Split layout function + * This function is a trick compared to dynamic layout function, see split.c */ void split(int screen) { - Client *c, *last; + Client *c; unsigned int n, on; on = tags[screen][seltag[screen]].nclients; @@ -251,15 +252,13 @@ split(int screen) for(n = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++n); CHECK((tags[screen][seltag[screen]].nclients = n)); - if(!(last = tiled_client(screen, clients)) || on == n) - return; + if((c = tiled_client(screen, clients)) && n == 1) + client_maximize(c); - if(n == 1) + for(c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next)) { - client_maximize(last); - - last->flags &= ~(MaxFlag | LMaxFlag); - last->flags |= TileFlag; + c->flags &= ~(MaxFlag | LMaxFlag); + c->flags |= (TileFlag | SplitFlag); } ewmh_update_current_tag_prop(); @@ -747,9 +746,10 @@ uicb_togglefree(uicb_t cmd) sel->flags ^= FreeFlag; - if((sel->flags & FreeFlag)) + if(sel->flags & FreeFlag) { - sel->flags &= ~(TileFlag | MaxFlag | LMaxFlag); + split_arrange_closed(sel); + sel->flags &= ~(TileFlag | MaxFlag | LMaxFlag | SplitFlag); client_moveresize(sel, sel->free_geo, True); client_raise(sel); } @@ -757,6 +757,7 @@ uicb_togglefree(uicb_t cmd) { sel->free_geo = sel->geo; sel->ogeo = sel->geo; + split_client_integrate(sel, client_get_next(), sel->screen, sel->tag); } client_update_attributes(sel); @@ -779,21 +780,22 @@ uicb_togglemax(uicb_t cmd) || (sel->flags & HintFlag)|| (sel->flags & FSSFlag)) return; - if(!(sel->flags & MaxFlag)) + sel->flags ^= MaxFlag; + + if(sel->flags & MaxFlag) { sel->ogeo = sel->geo; sel->free_geo = sel->geo; sel->flags &= ~(TileFlag | FreeFlag); + split_arrange_closed(sel); client_maximize(sel); XRaiseWindow(dpy, sel->frame); - sel->flags |= MaxFlag; - } else { sel->geo = sel->ogeo; client_moveresize(sel, sel->geo, True); - sel->flags &= ~MaxFlag; + split_client_integrate(sel, client_get_next(), sel->screen, sel->tag); tags[selscreen][seltag[selscreen]].cleanfact = True; tags[selscreen][seltag[selscreen]].layout.func(selscreen); } @@ -839,6 +841,7 @@ uicb_toggle_abovefc(uicb_t cmd) && c->tag == (uint)seltag[selscreen]) { c->flags &= ~AboveFlag; + split_client_integrate(c, NULL, sel->screen, sel->tag); break; } diff --git a/src/mouse.c b/src/mouse.c index 8b30334..b22c2af 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -52,7 +52,7 @@ mouse_cfactor_border(Client *c, int f[4], GC g) { int e; - mouse_dragborder(cfactor_geo(c->geo, f, &e), g); + mouse_dragborder(cfactor_geo(c->wrgeo, f, &e), g); return; } diff --git a/src/split.c b/src/split.c index a5b98e3..08f4bd9 100644 --- a/src/split.c +++ b/src/split.c @@ -66,13 +66,13 @@ _split_check_row(XRectangle g1, XRectangle g2, Position p) *\param ghost Ghost client */ void -split_arrange_closed(Client ghost) +split_arrange_closed(Client *ghost) { Position p; Bool b = False; XRectangle cgeo; Client *c, *cc; - int screen = ghost.screen; + int screen = ghost->screen; if(tags[screen][seltag[screen]].layout.func != split) return; @@ -97,10 +97,10 @@ split_arrange_closed(Client ghost) * |_____|_____| -> -> |_____|_____| */ for(p = Right; p < Bottom + 1; ++p) - if((c = client_get_next_with_direction(&ghost, p))) - if(cfactor_check_2pc(ghost.frame_geo, c->frame_geo, p)) + if((c = client_get_next_with_direction(ghost, p))) + if(cfactor_check_2pc(ghost->frame_geo, c->frame_geo, p)) { - _split_arrange_size(ghost.wrgeo, &c->wrgeo, p); + _split_arrange_size(ghost->wrgeo, &c->wrgeo, p); cfactor_clean(c); client_moveresize(c, (c->pgeo = c->wrgeo), tags[screen][c->tag].resizehint); @@ -116,14 +116,14 @@ split_arrange_closed(Client ghost) * |_____|_____| -> -> |___________| */ for(p = Right; p < Bottom + 1 && !b; ++p) - if((c = client_get_next_with_direction(&ghost, p))) + if((c = client_get_next_with_direction(ghost, p))) for(cgeo = c->frame_geo, cc = tiled_client(c->screen, clients); cc; cc = tiled_client(c->screen, cc->next)) { if(cfactor_parentrow(cgeo, cc->frame_geo, RPOS(p)) - && _split_check_row(cc->frame_geo, ghost.frame_geo, p)) + && _split_check_row(cc->frame_geo, ghost->frame_geo, p)) { - _split_arrange_size(ghost.wrgeo, &cc->wrgeo, p); + _split_arrange_size(ghost->wrgeo, &cc->wrgeo, p); cfactor_clean(cc); client_moveresize(cc, (cc->pgeo = cc->wrgeo), tags[screen][cc->tag].resizehint); b = True; @@ -149,6 +149,9 @@ split_client(Client *c, Bool p) cfactor_clean(c); + c->flags &= ~(MaxFlag | LMaxFlag); + c->flags |= (TileFlag | SplitFlag); + /* Use geometry without resizehint applied on it */ geo = sgeo = c->wrgeo; @@ -189,7 +192,7 @@ split_client_fill(Client *c, XRectangle geo) return; c->flags &= ~(MaxFlag | LMaxFlag); - c->flags |= TileFlag; + c->flags |= (TileFlag | SplitFlag); cfactor_clean(c); client_moveresize(c, (c->pgeo = geo), tags[c->screen][c->tag].resizehint); @@ -202,14 +205,19 @@ split_client_fill(Client *c, XRectangle geo) *\param sc Splitted client pointer */ void -split_client_integrate(Client *c, Client *sc) +split_client_integrate(Client *c, Client *sc, int screen, int tag) { XRectangle g; - if(tags[c->screen][c->tag].layout.func != split - || !sc || !c) + if(tags[screen][tag].layout.func != split + || c->flags & FreeFlag + || !tags[screen][tag].nclients || !c) return; + if(!sc || sc->screen != screen || sc->tag != tag) + if(!(sc = tiled_client(screen, clients))) + return; + g = split_client(sc, (sc->frame_geo.height < sc->frame_geo.width)); split_client_fill(c, g); diff --git a/src/structs.h b/src/structs.h index 6bdc820..db651b0 100644 --- a/src/structs.h +++ b/src/structs.h @@ -53,6 +53,7 @@ #define UrgentFlag (1 << 10) #define FLayFlag (1 << 11) #define DockFlag (1 << 12) +#define SplitFlag (1 << 13) #define TagFlag(t) (1 << (t)) diff --git a/src/tag.c b/src/tag.c index 28bf1ea..df365be 100644 --- a/src/tag.c +++ b/src/tag.c @@ -143,10 +143,14 @@ tag_transfert(Client *c, int tag) if(tag > conf.ntag[selscreen]) return; + if(c->flags & SplitFlag) + split_arrange_closed(c); + c->tag = tag; c->screen = selscreen; arrange(c->screen, True); + split_client_integrate(c, NULL, c->screen, c->tag); client_focus_next(c); @@ -494,6 +498,8 @@ uicb_tag_urgent(uicb_t cmd) void tag_additional(int sc, int tag, int adtag) { + Client *c; + if(tag < 0 || tag > conf.ntag[sc] || adtag < 1 || adtag > conf.ntag[sc] || adtag == seltag[sc]) return; @@ -502,6 +508,12 @@ tag_additional(int sc, int tag, int adtag) tags[sc][adtag].request_update = True; tags[sc][tag].cleanfact = True; tags[sc][adtag].cleanfact = True; + + if(tags[sc][tag].tagad & TagFlag(adtag)) + for(c = clients; c; c = c->next) + if(c->screen == sc && c->tag == adtag) + split_client_integrate(c, client_get_next(), sc, tag); + arrange(sc, True); return; diff --git a/src/wmfs.h b/src/wmfs.h index dee4022..58b576f 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -170,6 +170,7 @@ void client_attach(Client *c); void client_configure(Client *c); void client_detach(Client *c); void client_focus(Client *c); +Client *client_get_next(void); /* client_gb_*() {{{ */ Client* client_gb_win(Window w); Client* client_gb_frame(Window w); @@ -386,10 +387,10 @@ void init(void); void getinfo(char *info); /* split.c */ -void split_arrange_closed(Client ghost); +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); +void split_client_integrate(Client *c, Client *sc, int screen, int tag); /* viwmfs.c */ void viwmfs(int argc, char **argv);