From 1b02cfed3e1577e4c596f64344c7ba35f3275545 Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Wed, 11 May 2011 21:43:14 +0200 Subject: [PATCH] Layout: Add layout_split_client functio with 2 uicb; split_client_{vertical/horizontal} --- src/client.c | 8 +++-- src/config.c | 7 +++-- src/layout.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/structs.h | 4 ++- src/tag.c | 4 +-- src/wmfs.h | 3 ++ 6 files changed, 102 insertions(+), 8 deletions(-) diff --git a/src/client.c b/src/client.c index 2ffbea0..4d191cf 100644 --- a/src/client.c +++ b/src/client.c @@ -938,12 +938,14 @@ client_manage(Window w, XWindowAttributes *wa, Bool ar) ewmh_manage_window_type(c); - if(ar) + if(ar && !tags[c->screen][c->tag].split) arrange(c->screen, True); - if(!conf.client.set_new_win_master) + if(!conf.client.set_new_win_master && !tags[c->screen][c->tag].split) layout_set_client_master(c); + layout_split_apply(c); + if(c->tag == (uint)seltag[selscreen]) client_focus(c); @@ -1028,6 +1030,8 @@ client_moveresize(Client *c, XRectangle geo, Bool r) if(c->flags & TileFlag) geo = cfactor_geo(c->pgeo, c->tilefact, &e); + if(e) + printf("EE: &e\n"); if(r) client_geo_hints(&geo, c); diff --git a/src/config.c b/src/config.c index ac78c9f..2a81182 100644 --- a/src/config.c +++ b/src/config.c @@ -104,6 +104,8 @@ const func_name_list_t func_list[] = {"check_clist", uicb_checkclist }, {"toggle_tagautohide", uicb_toggle_tagautohide }, {"toggle_tag_expose", uicb_tag_toggle_expose}, + {"split_client_vertical", uicb_split_client_vertical }, + {"split_client_horizontal", uicb_split_client_horizontal }, {NULL, NULL} }; @@ -526,11 +528,11 @@ conf_tag_section(void) /* If there is no tag in the conf or more than * MAXTAG (36) print an error and create only one. */ - Tag default_tag = { fetch_opt_first(def_tag, "new tag", "name").str, NULL, 0, 1, + Tag default_tag = { fetch_opt_first(def_tag, "new tag", "name").str, NULL, 1, 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, False, bar_pos, bar_pos, + False, False, False, False, bar_pos, bar_pos, layout_name_to_struct(conf.layout, fetch_opt_first(def_tag, "tile_right", "layout").str, conf.nlayout, layout_list), 0, NULL, 0, False }; @@ -583,7 +585,6 @@ conf_tag_section(void) tags[k][conf.ntag[k]].nmaster = fetch_opt_first(tag[i], fetch_opt_first(def_tag, "1", "nmaster").str, "nmaster").num; tags[k][conf.ntag[k]].resizehint = fetch_opt_first(tag[i], fetch_opt_first(def_tag, "false", "resizehint").str, "resizehint").bool; tags[k][conf.ntag[k]].abovefc = fetch_opt_first(tag[i], "false", "abovefc").bool; - tags[k][conf.ntag[k]].layers = 1; tmp = fetch_opt_first(tag[i], fetch_opt_first(def_tag, "top", "infobar_position").str, "infobar_position").str; diff --git a/src/layout.c b/src/layout.c index 256a124..001a6ec 100644 --- a/src/layout.c +++ b/src/layout.c @@ -868,6 +868,90 @@ layout_set_client_master(Client *c) return; } +/** Split client hor or vert to insert another client in the new area + *\param c Client pointer + *\param p True = Vertical, False = Horizontal +*/ +static void +layout_split_client(Client *c, Bool p) +{ + XRectangle geo, sgeo; + + if(!c || !(c->flags & TileFlag) + || tags[c->screen][c->tag].split) + return; + + tags[c->screen][c->tag].split = True; + + cfactor_clean(c); + + geo = sgeo = c->geo; + + if(p) + { + geo.x += (geo.width / 2); + geo.width /= 2; + sgeo.width = (sgeo.width / 2) - (BORDH * 2); + } + else + { + geo.y += (geo.height / 2); + geo.height /= 2; + sgeo.height = (sgeo.height / 2) - (BORDH + TBARH); + } + + tags[c->screen][c->tag].layout.sgeo = sgeo; + + client_moveresize(c, (c->pgeo = geo), tags[c->screen][c->tag].resizehint); + + return; +} + +/** Apply new attributes to splitted client + *\param c Client pointer +*/ +void +layout_split_apply(Client *c) +{ + if(!c || !tags[c->screen][c->tag].split) + return; + + c->flags &= ~(MaxFlag | LMaxFlag); + c->flags |= TileFlag; + + cfactor_clean(c); + client_moveresize(c, (c->pgeo = tags[c->screen][c->tag].layout.sgeo), + tags[c->screen][c->tag].resizehint); + + tags[c->screen][c->tag].split = False; + + return; +} + +void +uicb_split_client_vertical(uicb_t cmd) +{ + (void)cmd; + + CHECK(sel); + + layout_split_client(sel, True); + + return; +} + +void +uicb_split_client_horizontal(uicb_t cmd) +{ + (void)cmd; + + CHECK(sel); + + layout_split_client(sel, False); + + return; +} + /** Check the selected client is max * \param cmd uicb_t type unused */ diff --git a/src/structs.h b/src/structs.h index 0fdd349..242faf0 100644 --- a/src/structs.h +++ b/src/structs.h @@ -259,6 +259,8 @@ typedef struct /* Layout Structure */ typedef struct { + XRectangle sgeo; + int sfact[4]; char *symbol; char *type; void (*func)(int screen); @@ -279,9 +281,9 @@ typedef struct char *name; char **clients; int nclients; - int layers; float mwfact; int nmaster; + Bool split; Bool urgent; Bool resizehint; Bool request_update; diff --git a/src/tag.c b/src/tag.c index edab536..511d23d 100644 --- a/src/tag.c +++ b/src/tag.c @@ -601,9 +601,9 @@ tag_new(int s, char *name) displayedName = xstrdup(name); - Tag t = { displayedName, NULL, 0, 0, + Tag t = { displayedName, NULL, 0, conf.default_tag.mwfact, conf.default_tag.nmaster, - False, conf.default_tag.resizehint, False, False, False, + False, conf.default_tag.resizehint, False, False, False, False, conf.default_tag.barpos, conf.default_tag.barpos, conf.default_tag.layout, 0, NULL, 0, False }; diff --git a/src/wmfs.h b/src/wmfs.h index 734e03b..7b80cd9 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -365,6 +365,9 @@ void uicb_set_layout(uicb_t); void uicb_toggle_resizehint(uicb_t); void uicb_toggle_abovefc(uicb_t cmd); void layout_set_client_master(Client *c); +void layout_split_apply(Client *c); +void uicb_split_client_vertical(uicb_t); +void uicb_split_client_horizontal(uicb_t); Bool uicb_checkmax(uicb_t); Bool uicb_checkfree(uicb_t); Bool uicb_checklayout(uicb_t);