diff --git a/wmfs2/src/client.c b/wmfs2/src/client.c index ef35441..7dd293a 100644 --- a/wmfs2/src/client.c +++ b/wmfs2/src/client.c @@ -102,15 +102,19 @@ client_gb_win(Window w) return c; } -struct client* +inline struct client* client_gb_pos(struct tag *t, int x, int y) { - struct client *c; + struct client *c = SLIST_FIRST(&t->clients); - SLIST_FOREACH(c, &t->clients, tnext) + while(c) + { if(INAREA(x, y, c->geo)) return c; + c = SLIST_NEXT(c, tnext); + } + return NULL; } @@ -125,6 +129,7 @@ client_next_with_pos(struct client *bc, Position p) struct client *c; int x, y; const static char scanfac[PositionLast] = { +10, -10, 0, 0 }; + Position ip = Bottom - p; /* * Set start place of pointer (edge with position @@ -139,7 +144,7 @@ client_next_with_pos(struct client *bc, Position p) while((c = client_gb_pos(bc->tag, x, y)) == bc) { x += scanfac[p]; - y += scanfac[Bottom - p]; + y += scanfac[ip]; } return c; diff --git a/wmfs2/src/client.h b/wmfs2/src/client.h index fce8ed2..fc43eee 100644 --- a/wmfs2/src/client.h +++ b/wmfs2/src/client.h @@ -11,7 +11,7 @@ void client_configure(struct client *c); struct client *client_gb_win(Window w); -struct client *client_gb_pos(struct tag *t, int x, int y); +inline struct client *client_gb_pos(struct tag *t, int x, int y); struct client *client_next_with_pos(struct client *bc, Position p); void client_swap(struct client *c1, struct client *c2); void client_focus(struct client *c); diff --git a/wmfs2/src/config.h b/wmfs2/src/config.h index 4538af9..998bd2a 100644 --- a/wmfs2/src/config.h +++ b/wmfs2/src/config.h @@ -31,9 +31,10 @@ static const struct { char *name; void (*func)(Uicb cmd); } uicb_list[] = { "tag_prev", uicb_tag_prev }, /* Layout */ - { "layout_vmirror", uicb_layout_vmirror }, - { "layout_hmirror", uicb_layout_hmirror }, - { "layout_rotate", uicb_layout_rotate }, + { "layout_vmirror", uicb_layout_vmirror }, + { "layout_hmirror", uicb_layout_hmirror }, + { "layout_rotate_left", uicb_layout_rotate_left }, + { "layout_rotate_right", uicb_layout_rotate_right }, /* Client */ { "client_close", uicb_client_close }, diff --git a/wmfs2/src/layout.c b/wmfs2/src/layout.c index 3d64d2d..207a0db 100644 --- a/wmfs2/src/layout.c +++ b/wmfs2/src/layout.c @@ -169,27 +169,104 @@ layout_split_integrate(struct client *c, struct client *sc) client_moveresize(c, g); } -void +/* Arrange inter-clients holes: + * ___________ ___________ + * | || | -> | | | + * | A || B | -> | A >| B | + * | || | -> | >| | + * |_____||____| -> |______|____| + * ^ void + * + * and client-screen edge holes + * ___________ ___________ + * | | || -> | | | + * | A | B || -> | A | B >| + * | | || -> | | >| + * |_____|----'| -> |_____|__v__| + * ^^^ void + */ +static inline void +layout_fix_hole(struct client *c) +{ + struct client *cr = client_next_with_pos(c, Right); + struct client *cb = client_next_with_pos(c, Bottom); + + c->geo.w += (cr ? cr->geo.x : c->screen->ugeo.w) - (c->geo.x + c->geo.w); + c->geo.h += (cb ? cb->geo.y : c->screen->ugeo.h) - (c->geo.y + c->geo.h); + + client_moveresize(c, c->geo); +} + +/* Layout rotation: Rotate 90° all client to right or left. + * Avoid if(left) condition in layout_rotate loop; use func ptr + * + * Left rotation + * _____________ _____________ + * | | B | -> | A | + * | A |________| -> |-------------| + * | | | | -> | C | B | + * | | C | D | -> |_____| | + * |____|____|___| -> |_____|_______| + * ^ D + * Right rotation + * _____________ _____________ + * | | B | -> | |_________|< D + * | A |________| -> | B | C | + * | | | | -> |___|_________| + * | | C | D | -> | A | + * |____|____|___| -> |_____________| + * + */ + +static inline void +_pos_rotate_left(struct geo *g, struct geo ug, struct geo og) +{ + g->x = (ug.h - (og.y + og.h)); + g->y = og.x; +} + +static inline void +_pos_rotate_right(struct geo *g, struct geo ug, struct geo og) +{ + g->x = og.y; + g->y = (ug.w - (og.x + og.w)); +} + +static void layout_rotate(struct tag *t, bool left) { struct client *c; - struct geo g, ug = t->screen->ugeo; + struct geo g; + float f1 = (float)t->screen->ugeo.w / (float)t->screen->ugeo.h; + float f2 = 1 / f1; + void (*pos)(struct geo*, struct geo, struct geo) = + (left ? _pos_rotate_left : _pos_rotate_right); SLIST_FOREACH(c, &t->clients, tnext) { - g = c->geo; - c->geo.x = (g.y * ug.h) / ug.w; - c->geo.y = (g.x * ug.w) / ug.h; + pos(&g, t->screen->ugeo, c->geo); - c->geo.w = (g.h * ug.w) / ug.h; - c->geo.h = (g.w * ug.h) / ug.w; + g.x *= f1; + g.y *= f2; + g.w = c->geo.h * f1; + g.h = c->geo.w * f2; - client_moveresize(c, c->geo); + client_moveresize(c, g); } + + /* Rotate sometimes do not set back perfect size.. */ + SLIST_FOREACH(c, &t->clients, tnext) + layout_fix_hole(c); } void -uicb_layout_rotate(Uicb cmd) +uicb_layout_rotate_left(Uicb cmd) +{ + layout_rotate(W->screen->seltag, true); +} + +void +uicb_layout_rotate_right(Uicb cmd) { layout_rotate(W->screen->seltag, false); } @@ -204,6 +281,13 @@ uicb_layout_rotate(Uicb cmd) * | A |_______| -> |_______| A | * | | C | D | -> | D | C | | * |____|___|___| -> |___|___|____| + * + * Horizontal mirror + * ____________ ____________ + * | | B | -> | | C | D | + * | A |_______| -> | A |___|___| + * | | C | D | -> | | B | + * |____|___|___| -> |____|_______| */ void uicb_layout_vmirror(Uicb cmd) @@ -217,14 +301,6 @@ uicb_layout_vmirror(Uicb cmd) } } -/* - * Horinzontal mirror - * ____________ ____________ - * | | B | -> | | C | D | - * | A |_______| -> | A |___|___| - * | | C | D | -> | | B | - * |____|___|___| -> |____|_______| - */ void uicb_layout_hmirror(Uicb cmd) { diff --git a/wmfs2/src/layout.h b/wmfs2/src/layout.h index 6e16285..0cdc7a7 100644 --- a/wmfs2/src/layout.h +++ b/wmfs2/src/layout.h @@ -33,7 +33,8 @@ void layout_split_integrate(struct client *c, struct client *sc); void layout_split_arrange_closed(struct client *ghost); void uicb_layout_vmirror(Uicb cmd); void uicb_layout_hmirror(Uicb cmd); -void uicb_layout_rotate(Uicb cmd); +void uicb_layout_rotate_left(Uicb cmd); +void uicb_layout_rotate_right(Uicb cmd); #endif /* LAYOUT_H */ diff --git a/wmfs2/src/parse.c b/wmfs2/src/parse.c index d4e97a5..8247441 100644 --- a/wmfs2/src/parse.c +++ b/wmfs2/src/parse.c @@ -655,8 +655,9 @@ int get_conf(const char *filename) { struct conf_sec *s; - struct keyword *head = parse_keywords(filename); - struct keyword *kw = parse_keywords(filename); + struct keyword *head, *kw; + + head = kw = parse_keywords(filename); if(!head) return -1; /* TODO ERREUR */ diff --git a/wmfs2/wmfsrc2 b/wmfs2/wmfsrc2 index 24f035d..7ee90d2 100644 --- a/wmfs2/wmfsrc2 +++ b/wmfs2/wmfsrc2 @@ -116,8 +116,7 @@ [key] mod = {"Super"} key = "q" func = "client_close" [/key] # Focus next / prev client - [key] mod = { "Alt" } key = "Tab" func = "client_focus_next" [/key] - [key] mod = { "Alt", "Shift" } key = "Tab" func = "client_focus_prev" [/key] + [key] mod = { "Alt" } key = "Tab" func = "client_focus_next" [/key][key] mod = { "Alt", "Shift" } key = "Tab" func = "client_focus_prev" [/key] # Focus next client with direction [key] mod = {"Alt"} key = "h" func = "client_focus_left" [/key] @@ -125,7 +124,7 @@ [key] mod = {"Alt"} key = "k" func = "client_focus_top" [/key] [key] mod = {"Alt"} key = "j" func = "client_focus_bottom" [/key] - # swap next client with direction: + # swap next client with direction: [key] mod = {"Control", "Shift"} key = "h" func = "client_swap_left" [/key] [key] mod = {"Control", "Shift"} key = "l" func = "client_swap_right" [/key] [key] mod = {"Control", "Shift"} key = "k" func = "client_swap_top" [/key] @@ -141,5 +140,10 @@ [key] mod = {"Super", "Control"} key = "k" func = "client_resize_bottom" cmd = "-20" [/key] [key] mod = {"Super", "Control"} key = "j" func = "client_resize_bottom" cmd = "20" [/key] + # Layout manipulation + [key] mod = {"Super"} key = "m" func = "layout_vmirror" [/key] + [key] mod = {"Super", "Shift"} key = "m" func = "layout_hmirror" [/key] + [key] mod = {"Super"} key = "r" func = "layout_rotate_right" [/key] + [key] mod = {"Super", "Shift"} key = "r" func = "layout_rotate_left" [/key] [/keys]