Add preview borders for client_resize_dir
This commit is contained in:
parent
e32012a0c3
commit
dfc277a7a3
112
src/client.c
112
src/client.c
@ -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
|
||||
|
||||
13
src/draw.h
13
src/draw.h
@ -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)
|
||||
{
|
||||
|
||||
87
src/layout.c
87
src/layout.c
@ -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)
|
||||
{
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
15
src/wmfs.h
15
src/wmfs.h
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user