Add preview borders for client_resize_dir

This commit is contained in:
Martin Duquesnoy 2011-10-10 22:05:29 +02:00
parent e32012a0c3
commit dfc277a7a3
6 changed files with 224 additions and 7 deletions

View File

@ -7,6 +7,7 @@
#include "client.h"
#include "config.h"
#include "event.h"
#include "util.h"
#include "barwin.h"
#include "ewmh.h"
@ -537,7 +538,7 @@ _fac_apply(struct client *c, enum position p, int fac)
static inline void
_fac_arrange_row(struct client *c, enum position p, int fac)
{
struct geo g = c->geo;
struct geo g = c->tgeo;
struct client *cc;
/* Travel clients to search row parents and apply fac */
@ -546,8 +547,8 @@ _fac_arrange_row(struct client *c, enum position p, int fac)
_fac_apply(cc, p, fac);
}
void
client_fac_resize(struct client *c, enum position p, int fac)
static void
_fac_resize(struct client *c, enum position p, int fac)
{
struct client *cc, *gc = client_next_with_pos(c, p);
enum position rp = RPOS(p);
@ -587,10 +588,109 @@ client_fac_resize(struct client *c, enum position p, int fac)
return;
}
}
/* It's ok, resize */
SLIST_FOREACH(gc, &c->tag->clients, tnext)
client_moveresize(gc, &gc->tgeo);
#define _REV_BORDER() \
SLIST_FOREACH(gc, &c->tag->clients, tnext) \
draw_reversed_rect(c->tag->frame, rgc, gc->tgeo);
void
client_fac_resize(struct client *c, enum position p, int fac)
{
struct keybind *k;
struct client *gc;
bool b = true;
XEvent ev;
KeySym keysym;
GC rgc;
XGCValues xgc =
{
.function = GXinvert,
.subwindow_mode = IncludeInferiors,
.line_width = THEME_DEFAULT->client_border_width
};
/* Do it once before */
_fac_resize(c, p, fac);
/* TODO
if(option_simple_manual_resize)
returnl
*/
XGrabKeyboard(W->dpy, W->root, True, GrabModeAsync, GrabModeAsync, CurrentTime);
rgc = XCreateGC(W->dpy, c->tag->frame, GCFunction | GCSubwindowMode | GCLineWidth, &xgc);
_REV_BORDER();
do
{
XMaskEvent(W->dpy, KeyPressMask, &ev);
if(ev.type == KeyPress)
{
XKeyPressedEvent *ke = &ev.xkey;
keysym = XKeycodeToKeysym(W->dpy, (KeyCode)ke->keycode, 0);
_REV_BORDER();
SLIST_FOREACH(k, &W->h.keybind, next)
if(k->keysym == keysym && KEYPRESS_MASK(k->mod) == KEYPRESS_MASK(ke->state)
&& k->func)
{
if(k->func == uicb_client_resize_Right)
_fac_resize(c, Right, ATOI(k->cmd));
else if(k->func == uicb_client_resize_Left)
_fac_resize(c, Left, ATOI(k->cmd));
else if(k->func == uicb_client_resize_Top)
_fac_resize(c, Top, ATOI(k->cmd));
else if(k->func == uicb_client_resize_Bottom)
_fac_resize(c, Bottom, ATOI(k->cmd));
else
{
k->func(k->cmd);
keysym = XK_Escape;
}
}
_REV_BORDER();
/* Gtfo of this loop */
if(keysym == XK_Return)
break;
else if(keysym == XK_Escape)
{
b = false;
break;
}
XSync(W->dpy, False);
}
XNextEvent(W->dpy, &ev);
} while(ev.type != KeyPress);
_REV_BORDER();
/* Success, resize clients */
if(b)
{
SLIST_FOREACH(gc, &c->tag->clients, tnext)
client_moveresize(gc, &gc->tgeo);
}
/* Aborted with escape, Set back original geos */
else
{
SLIST_FOREACH(gc, &c->tag->clients, tnext)
{
gc->tgeo = gc->geo;
gc->flags &= ~CLIENT_DID_WINSIZE;
}
}
XFreeGC(W->dpy, rgc);
XUngrabKeyboard(W->dpy, CurrentTime);
}
void

View File

@ -11,6 +11,7 @@
#include <X11/Xlib.h>
#include "wmfs.h"
#include "config.h"
#define TEXTY(t, w) ((t->font.height - t->font.de) + ((w - t->font.height) >> 1))
#define PAD (8)
@ -29,6 +30,18 @@ draw_rect(Drawable d, struct geo g, Color bg)
XFillRectangle(W->dpy, d, W->gc, g.x, g.y, g.w, g.h);
}
/*
* For client use
*/
static inline void
draw_reversed_rect(Drawable dr, GC gc, struct geo g)
{
int i = THEME_DEFAULT->client_border_width;
XDrawRectangle(W->dpy, dr, gc, g.x + i, g.y + i,
g.w - (i << 1), g.h - (i << 1));
}
static inline unsigned short
draw_textw(struct theme *t, const char *str)
{

View File

@ -8,6 +8,93 @@
#include "client.h"
#include "util.h"
static void
layout_save_set(struct tag *t)
{
struct client *c;
struct layout_set *l;
struct geo_list *g;
int n = 0;
l = xcalloc(1, sizeof(struct layout_set));
SLIST_INIT(&l->geos);
SLIST_FOREACH(c, &t->clients, tnext)
{
g = xcalloc(1, sizeof(struct geo_list));
g->geo = c->geo;
SLIST_INSERT_HEAD(&l->geos, g, next);
++n;
}
l->n = n;
SLIST_INSERT_HEAD(&t->sets, l, next);
}
static void
layout_apply_set(struct tag *t, struct layout_set *l)
{
struct geo_list *g;
struct client *c, cc;
for(g = SLIST_FIRST(&l->geos), c = SLIST_FIRST(&t->clients);
c;
c = SLIST_NEXT(c, tnext), g = SLIST_NEXT(g, next))
{
if(g)
{
if(!client_winsize(c, &g->geo, &c->wgeo))
client_moveresize(c, &g->geo);
}
/*
* Not enough geos in the set;
* then integrate remains of client
*/
else
layout_split_integrate(c, SLIST_FIRST(&t->clients));
}
/*
* Not enough clients for geos in set;
* arrange clients with not set geo.
*/
if(g)
{
cc.tag = t;
while(g)
{
cc.geo = g->geo;
layout_split_arrange_closed(&cc);
g = SLIST_NEXT(g, next);
}
}
/* Re-insert set in historic */
SLIST_INSERT_HEAD(&t->sets, l, next);
}
void
layout_free_set(struct tag *t)
{
struct layout_set *l;
while(!SLIST_EMPTY(&t->sets))
{
l = SLIST_FIRST(&t->sets);
SLIST_REMOVE_HEAD(&t->sets, next);
/* Set can be several times in list */
if(l)
{
FREE_LIST(geo_list, l->geos);
free(l);
}
}
}
static struct geo
layout_split(struct client *c, bool vertical)
{

View File

@ -29,6 +29,7 @@
/* Debug */
#define DGEO(G) printf(": %d %d %d %d\n", G.x, G.y, G.w, G.h)
void layout_free_set(struct tag *t);
void layout_split_integrate(struct client *c, struct client *sc);
void layout_split_arrange_closed(struct client *ghost);
void uicb_layout_vmirror(Uicb cmd);

View File

@ -45,6 +45,7 @@ tag_new(struct screen *s, char *name)
&at);
SLIST_INIT(&t->clients);
SLIST_INIT(&t->sets);
TAILQ_INSERT_TAIL(&s->tags, t, next);
@ -182,6 +183,8 @@ tag_remove(struct tag *t)
XDestroyWindow(W->dpy, t->frame);
layout_free_set(t);
free(t);
}

View File

@ -69,6 +69,12 @@ struct geo
int x, y, w, h;
};
struct geo_list
{
struct geo geo;
SLIST_ENTRY(geo_list) next;
};
struct barwin
{
struct geo geo;
@ -124,6 +130,7 @@ struct tag
Flags flags;
Window frame;
SLIST_HEAD(, client) clients;
SLIST_HEAD(, layout_set) sets;
TAILQ_ENTRY(tag) next;
};
@ -142,7 +149,13 @@ struct client
Window win;
SLIST_ENTRY(client) next; /* Global list */
SLIST_ENTRY(client) tnext; /* struct tag list */
SLIST_ENTRY(client) vnext; /* various list */
};
struct layout_set
{
int n;
SLIST_HEAD(, geo_list) geos;
SLIST_ENTRY(layout_set) next;
};
struct keybind