Add layout_rotate_right/left

This commit is contained in:
Martin Duquesnoy 2011-09-23 09:33:38 +02:00
parent eb5d932f66
commit d66ada9acb
7 changed files with 119 additions and 31 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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 },

View File

@ -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)
{

View File

@ -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 */

View File

@ -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 */

View File

@ -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]