Add preview borders for client_resize_dir
This commit is contained in:
112
src/client.c
112
src/client.c
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "event.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "barwin.h"
|
#include "barwin.h"
|
||||||
#include "ewmh.h"
|
#include "ewmh.h"
|
||||||
@@ -537,7 +538,7 @@ _fac_apply(struct client *c, enum position p, int fac)
|
|||||||
static inline void
|
static inline void
|
||||||
_fac_arrange_row(struct client *c, enum position p, int fac)
|
_fac_arrange_row(struct client *c, enum position p, int fac)
|
||||||
{
|
{
|
||||||
struct geo g = c->geo;
|
struct geo g = c->tgeo;
|
||||||
struct client *cc;
|
struct client *cc;
|
||||||
|
|
||||||
/* Travel clients to search row parents and apply fac */
|
/* 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);
|
_fac_apply(cc, p, fac);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
client_fac_resize(struct client *c, enum position p, int fac)
|
_fac_resize(struct client *c, enum position p, int fac)
|
||||||
{
|
{
|
||||||
struct client *cc, *gc = client_next_with_pos(c, p);
|
struct client *cc, *gc = client_next_with_pos(c, p);
|
||||||
enum position rp = RPOS(p);
|
enum position rp = RPOS(p);
|
||||||
@@ -587,10 +588,109 @@ client_fac_resize(struct client *c, enum position p, int fac)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* It's ok, resize */
|
#define _REV_BORDER() \
|
||||||
SLIST_FOREACH(gc, &c->tag->clients, tnext)
|
SLIST_FOREACH(gc, &c->tag->clients, tnext) \
|
||||||
client_moveresize(gc, &gc->tgeo);
|
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
|
void
|
||||||
|
|||||||
13
src/draw.h
13
src/draw.h
@@ -11,6 +11,7 @@
|
|||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
#include "wmfs.h"
|
#include "wmfs.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#define TEXTY(t, w) ((t->font.height - t->font.de) + ((w - t->font.height) >> 1))
|
#define TEXTY(t, w) ((t->font.height - t->font.de) + ((w - t->font.height) >> 1))
|
||||||
#define PAD (8)
|
#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);
|
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
|
static inline unsigned short
|
||||||
draw_textw(struct theme *t, const char *str)
|
draw_textw(struct theme *t, const char *str)
|
||||||
{
|
{
|
||||||
|
|||||||
87
src/layout.c
87
src/layout.c
@@ -8,6 +8,93 @@
|
|||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "util.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
|
static struct geo
|
||||||
layout_split(struct client *c, bool vertical)
|
layout_split(struct client *c, bool vertical)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
/* Debug */
|
/* Debug */
|
||||||
#define DGEO(G) printf(": %d %d %d %d\n", G.x, G.y, G.w, G.h)
|
#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_integrate(struct client *c, struct client *sc);
|
||||||
void layout_split_arrange_closed(struct client *ghost);
|
void layout_split_arrange_closed(struct client *ghost);
|
||||||
void uicb_layout_vmirror(Uicb cmd);
|
void uicb_layout_vmirror(Uicb cmd);
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ tag_new(struct screen *s, char *name)
|
|||||||
&at);
|
&at);
|
||||||
|
|
||||||
SLIST_INIT(&t->clients);
|
SLIST_INIT(&t->clients);
|
||||||
|
SLIST_INIT(&t->sets);
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&s->tags, t, next);
|
TAILQ_INSERT_TAIL(&s->tags, t, next);
|
||||||
|
|
||||||
@@ -182,6 +183,8 @@ tag_remove(struct tag *t)
|
|||||||
|
|
||||||
XDestroyWindow(W->dpy, t->frame);
|
XDestroyWindow(W->dpy, t->frame);
|
||||||
|
|
||||||
|
layout_free_set(t);
|
||||||
|
|
||||||
free(t);
|
free(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
15
src/wmfs.h
15
src/wmfs.h
@@ -69,6 +69,12 @@ struct geo
|
|||||||
int x, y, w, h;
|
int x, y, w, h;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct geo_list
|
||||||
|
{
|
||||||
|
struct geo geo;
|
||||||
|
SLIST_ENTRY(geo_list) next;
|
||||||
|
};
|
||||||
|
|
||||||
struct barwin
|
struct barwin
|
||||||
{
|
{
|
||||||
struct geo geo;
|
struct geo geo;
|
||||||
@@ -124,6 +130,7 @@ struct tag
|
|||||||
Flags flags;
|
Flags flags;
|
||||||
Window frame;
|
Window frame;
|
||||||
SLIST_HEAD(, client) clients;
|
SLIST_HEAD(, client) clients;
|
||||||
|
SLIST_HEAD(, layout_set) sets;
|
||||||
TAILQ_ENTRY(tag) next;
|
TAILQ_ENTRY(tag) next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -142,7 +149,13 @@ struct client
|
|||||||
Window win;
|
Window win;
|
||||||
SLIST_ENTRY(client) next; /* Global list */
|
SLIST_ENTRY(client) next; /* Global list */
|
||||||
SLIST_ENTRY(client) tnext; /* struct tag 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
|
struct keybind
|
||||||
|
|||||||
Reference in New Issue
Block a user