Finalize client free mode with multi-screen, mouse and swap
This commit is contained in:
parent
2ac4d8ffd0
commit
32f8c69a81
63
src/client.c
63
src/client.c
@ -186,38 +186,68 @@ client_next_with_pos(struct client *bc, enum position p)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define FLAG_SWAP2(f1, f2, m1) \
|
||||||
|
if((f1 & m1) != (f2 & m1)) \
|
||||||
|
{ \
|
||||||
|
f1 ^= m1; \
|
||||||
|
f2 ^= m1; \
|
||||||
|
}
|
||||||
|
#define SWAP_ARRANGE_TAB(C) \
|
||||||
|
SLIST_FOREACH(c, &C->tag->clients, tnext) \
|
||||||
|
{ \
|
||||||
|
if(c->tabmaster == C) \
|
||||||
|
{ \
|
||||||
|
c->screen = C->screen; \
|
||||||
|
if((C->flags & CLIENT_FREE) != (c->flags & CLIENT_FREE)) \
|
||||||
|
{ \
|
||||||
|
c->flags ^= CLIENT_FREE; \
|
||||||
|
c->flags ^= CLIENT_TILED; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
void
|
void
|
||||||
client_swap2(struct client *c1, struct client *c2)
|
client_swap2(struct client *c1, struct client *c2)
|
||||||
{
|
{
|
||||||
|
struct client *c;
|
||||||
struct tag *t;
|
struct tag *t;
|
||||||
|
struct geo g;
|
||||||
|
|
||||||
/* Conflict / errors */
|
/* Conflict / errors */
|
||||||
if(c1 == c2 || !c1 || !c2)
|
if(c1 == c2 || !c1 || !c2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* are swapped geos compatible? */
|
/* Reverse FREE/TILED flags if there are different */
|
||||||
if(client_winsize(c1, &c2->geo)
|
FLAG_SWAP2(c1->flags, c2->flags, CLIENT_FREE);
|
||||||
|| client_winsize(c2, &c1->geo))
|
FLAG_SWAP2(c1->flags, c2->flags, CLIENT_TILED);
|
||||||
return;
|
|
||||||
|
|
||||||
if(c1->screen != c2->screen)
|
if(c1->screen != c2->screen)
|
||||||
swap_ptr((void**)&c1->screen, (void**)&c2->screen);
|
swap_ptr((void**)&c1->screen, (void**)&c2->screen);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Arrange flags for all tabbed client of
|
||||||
|
* possible c1/c2 tabmaster
|
||||||
|
*/
|
||||||
|
if(c1->flags & CLIENT_TABMASTER)
|
||||||
|
SWAP_ARRANGE_TAB(c1);
|
||||||
|
if(c2->flags & CLIENT_TABMASTER)
|
||||||
|
SWAP_ARRANGE_TAB(c2);
|
||||||
|
|
||||||
if(c1->tag != c2->tag)
|
if(c1->tag != c2->tag)
|
||||||
{
|
{
|
||||||
|
c1->flags |= CLIENT_IGNORE_LAYOUT;
|
||||||
|
c2->flags |= CLIENT_IGNORE_LAYOUT;
|
||||||
|
|
||||||
t = c1->tag;
|
t = c1->tag;
|
||||||
tag_client(c2->tag, c1);
|
tag_client(c2->tag, c1);
|
||||||
tag_client(t, c2);
|
tag_client(t, c2);
|
||||||
}
|
}
|
||||||
|
|
||||||
c1->tgeo = c2->geo;
|
g = c1->geo;
|
||||||
c2->tgeo = c1->geo;
|
client_moveresize(c1, &c2->geo);
|
||||||
|
client_moveresize(c2, &g);
|
||||||
|
|
||||||
c1->flags |= CLIENT_IGNORE_ENTER;
|
c1->flags |= CLIENT_IGNORE_ENTER;
|
||||||
c2->flags |= CLIENT_IGNORE_ENTER;
|
c2->flags |= CLIENT_IGNORE_ENTER;
|
||||||
|
|
||||||
client_moveresize(c1, &c1->tgeo);
|
|
||||||
client_moveresize(c2, &c2->tgeo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct client*
|
static inline struct client*
|
||||||
@ -491,7 +521,7 @@ client_tab_focus(struct client *c)
|
|||||||
void
|
void
|
||||||
_client_tab(struct client *c, struct client *cm)
|
_client_tab(struct client *c, struct client *cm)
|
||||||
{
|
{
|
||||||
long m[2] = { CLIENT_TILED, CLIENT_FREE };
|
Flags m[2] = { CLIENT_TILED, CLIENT_FREE };
|
||||||
|
|
||||||
/* Do not tab already tabbed client */
|
/* Do not tab already tabbed client */
|
||||||
if(c->flags & (CLIENT_TABBED | CLIENT_TABMASTER)
|
if(c->flags & (CLIENT_TABBED | CLIENT_TABMASTER)
|
||||||
@ -505,12 +535,7 @@ _client_tab(struct client *c, struct client *cm)
|
|||||||
cm->tabmaster = c;
|
cm->tabmaster = c;
|
||||||
|
|
||||||
if(cm->flags & CLIENT_FREE)
|
if(cm->flags & CLIENT_FREE)
|
||||||
{
|
swap_int((int*)&m[0], (int*)&m[1]);
|
||||||
/* Swap masks to add/del from cm->flags */
|
|
||||||
m[1] = m[0] ^ m[1];
|
|
||||||
m[0] = m[1] ^ m[0];
|
|
||||||
m[1] = m[0] ^ m[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
c->flags |= m[0];
|
c->flags |= m[0];
|
||||||
c->flags &= ~m[1];
|
c->flags &= ~m[1];
|
||||||
@ -597,7 +622,7 @@ client_focus(struct client *c)
|
|||||||
client_frame_update(c, CCOL(c));
|
client_frame_update(c, CCOL(c));
|
||||||
|
|
||||||
if(c->flags & CLIENT_FREE
|
if(c->flags & CLIENT_FREE
|
||||||
&& !(c->flags & (CLIENT_FULLSCREEN | CLIENT_TABMASTER)))
|
&& !(c->flags & (CLIENT_FULLSCREEN | CLIENT_TABBED)))
|
||||||
XRaiseWindow(W->dpy, c->frame);
|
XRaiseWindow(W->dpy, c->frame);
|
||||||
|
|
||||||
XSetInputFocus(W->dpy, c->win, RevertToPointerRoot, CurrentTime);
|
XSetInputFocus(W->dpy, c->win, RevertToPointerRoot, CurrentTime);
|
||||||
@ -891,7 +916,7 @@ client_new(Window w, XWindowAttributes *wa, bool scan)
|
|||||||
c->geo.y = wa->y;
|
c->geo.y = wa->y;
|
||||||
c->geo.w = wa->width;
|
c->geo.w = wa->width;
|
||||||
c->geo.h = wa->height;
|
c->geo.h = wa->height;
|
||||||
c->tgeo = c->wgeo = c->rgeo = c->fgeo = c->geo;
|
c->tgeo = c->wgeo = c->rgeo = c->geo;
|
||||||
c->tbgeo = NULL;
|
c->tbgeo = NULL;
|
||||||
|
|
||||||
if(!scan)
|
if(!scan)
|
||||||
@ -1072,8 +1097,6 @@ client_moveresize(struct client *c, struct geo *g)
|
|||||||
client_winsize(c, g);
|
client_winsize(c, g);
|
||||||
}
|
}
|
||||||
|
|
||||||
c->fgeo = c->geo;
|
|
||||||
|
|
||||||
/* Real geo regarding full root size */
|
/* Real geo regarding full root size */
|
||||||
c->rgeo.x += c->screen->ugeo.x;
|
c->rgeo.x += c->screen->ugeo.x;
|
||||||
c->rgeo.y += c->screen->ugeo.y;
|
c->rgeo.y += c->screen->ugeo.y;
|
||||||
|
|||||||
@ -556,9 +556,6 @@ uicb_layout_hmirror(Uicb cmd)
|
|||||||
void
|
void
|
||||||
layout_client(struct client *c)
|
layout_client(struct client *c)
|
||||||
{
|
{
|
||||||
if(c->flags & CLIENT_TABBED)
|
|
||||||
c = c->tabmaster;
|
|
||||||
|
|
||||||
if(c->flags & CLIENT_IGNORE_LAYOUT)
|
if(c->flags & CLIENT_IGNORE_LAYOUT)
|
||||||
{
|
{
|
||||||
c->flags ^= CLIENT_IGNORE_LAYOUT;
|
c->flags ^= CLIENT_IGNORE_LAYOUT;
|
||||||
@ -569,7 +566,7 @@ layout_client(struct client *c)
|
|||||||
{
|
{
|
||||||
layout_split_arrange_closed(c);
|
layout_split_arrange_closed(c);
|
||||||
c->flags ^= CLIENT_TILED;
|
c->flags ^= CLIENT_TILED;
|
||||||
client_moveresize(c, &c->fgeo);
|
client_moveresize(c, &c->geo);
|
||||||
XRaiseWindow(W->dpy, c->frame);
|
XRaiseWindow(W->dpy, c->frame);
|
||||||
}
|
}
|
||||||
else if(!(c->flags & CLIENT_TABBED))
|
else if(!(c->flags & CLIENT_TABBED))
|
||||||
|
|||||||
31
src/mouse.c
31
src/mouse.c
@ -24,6 +24,7 @@ mouse_resize(struct client *c)
|
|||||||
XEvent ev;
|
XEvent ev;
|
||||||
Window w;
|
Window w;
|
||||||
int d, u, ox, oy, ix, iy;
|
int d, u, ox, oy, ix, iy;
|
||||||
|
int mx, my;
|
||||||
|
|
||||||
XQueryPointer(W->dpy, W->root, &w, &w, &ox, &oy, &d, &d, (uint *)&u);
|
XQueryPointer(W->dpy, W->root, &w, &w, &ox, &oy, &d, &d, (uint *)&u);
|
||||||
XGrabServer(W->dpy);
|
XGrabServer(W->dpy);
|
||||||
@ -48,16 +49,22 @@ mouse_resize(struct client *c)
|
|||||||
if(ev.type != MotionNotify)
|
if(ev.type != MotionNotify)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
mx = ev.xmotion.x_root;
|
||||||
|
my = ev.xmotion.y_root;
|
||||||
|
|
||||||
if(c->flags & CLIENT_FREE)
|
if(c->flags & CLIENT_FREE)
|
||||||
{
|
{
|
||||||
_REV_SBORDER(c);
|
_REV_SBORDER(c);
|
||||||
|
|
||||||
c->geo.w = ((ev.xmotion.x_root - c->geo.x <= c->sizeh[MINW] + c->border + c->border)
|
mx -= c->screen->ugeo.x;
|
||||||
|
my -= c->screen->ugeo.y;
|
||||||
|
|
||||||
|
c->geo.w = ((mx - c->geo.x <= c->sizeh[MINW] + c->border + c->border)
|
||||||
? c->sizeh[MINW] + c->border + c->border
|
? c->sizeh[MINW] + c->border + c->border
|
||||||
: ev.xmotion.x_root - c->geo.x);
|
: mx - c->geo.x);
|
||||||
c->geo.h = ((ev.xmotion.y_root - c->geo.y <= (c->sizeh[MINH] + c->tbarw + c->border))
|
c->geo.h = ((my - c->geo.y <= (c->sizeh[MINH] + c->tbarw + c->border))
|
||||||
? c->sizeh[MINH] + c->tbarw + c->border
|
? c->sizeh[MINH] + c->tbarw + c->border
|
||||||
: ev.xmotion.y_root - c->geo.y);
|
: my - c->geo.y);
|
||||||
|
|
||||||
client_geo_hints(&c->geo, (int*)c->sizeh);
|
client_geo_hints(&c->geo, (int*)c->sizeh);
|
||||||
|
|
||||||
@ -71,18 +78,18 @@ mouse_resize(struct client *c)
|
|||||||
{
|
{
|
||||||
_REV_BORDER();
|
_REV_BORDER();
|
||||||
|
|
||||||
if(ix >= c->geo.x + (c->geo.w >> 1))
|
if(ix >= c->rgeo.x + (c->geo.w >> 1))
|
||||||
_fac_resize(c, Right, ev.xmotion.x_root - ox);
|
_fac_resize(c, Right, mx - ox);
|
||||||
else
|
else
|
||||||
_fac_resize(c, Left, ox - ev.xmotion.x_root);
|
_fac_resize(c, Left, ox - mx);
|
||||||
|
|
||||||
if(iy >= c->geo.y + (c->geo.h >> 1))
|
if(iy >= c->rgeo.y + (c->geo.h >> 1))
|
||||||
_fac_resize(c, Bottom, ev.xmotion.y_root - oy);
|
_fac_resize(c, Bottom, my - oy);
|
||||||
else
|
else
|
||||||
_fac_resize(c, Top, oy - ev.xmotion.y_root);
|
_fac_resize(c, Top, oy - my);
|
||||||
|
|
||||||
ox = ev.xmotion.x_root;
|
ox = mx;
|
||||||
oy = ev.xmotion.y_root;
|
oy = my;
|
||||||
|
|
||||||
_REV_BORDER();
|
_REV_BORDER();
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/screen.h
22
src/screen.h
@ -22,22 +22,26 @@ screen_gb_id(int id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline struct screen*
|
static inline struct screen*
|
||||||
screen_gb_mouse(void)
|
screen_gb_geo(int x, int y)
|
||||||
{
|
{
|
||||||
struct screen *s;
|
struct screen *s;
|
||||||
|
|
||||||
|
SLIST_FOREACH(s, &W->h.screen, next)
|
||||||
|
if(INAREA(x, y, s->geo))
|
||||||
|
return s;
|
||||||
|
|
||||||
|
return SLIST_FIRST(&W->h.screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct screen*
|
||||||
|
screen_gb_mouse(void)
|
||||||
|
{
|
||||||
Window w;
|
Window w;
|
||||||
int d, x, y;
|
int d, x, y;
|
||||||
|
|
||||||
XQueryPointer(W->dpy, W->root, &w, &w, &x, &y, &d, &d, (unsigned int *)&d);
|
XQueryPointer(W->dpy, W->root, &w, &w, &x, &y, &d, &d, (unsigned int *)&d);
|
||||||
|
|
||||||
SLIST_FOREACH(s, &W->h.screen, next)
|
return screen_gb_geo(x, y);
|
||||||
if(INAREA(x, y, s->geo))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(!s)
|
|
||||||
s = SLIST_FIRST(&W->h.screen);
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void screen_init(void);
|
void screen_init(void);
|
||||||
|
|||||||
@ -110,8 +110,11 @@ tag_client(struct tag *t, struct client *c)
|
|||||||
|
|
||||||
SLIST_FOREACH(cc, &c->prevtag->clients, tnext)
|
SLIST_FOREACH(cc, &c->prevtag->clients, tnext)
|
||||||
if(cc->tabmaster == c)
|
if(cc->tabmaster == c)
|
||||||
|
{
|
||||||
|
cc->flags |= CLIENT_IGNORE_LAYOUT;
|
||||||
tag_client(t, cc);
|
tag_client(t, cc);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(t != c->screen->seltag || c->flags & CLIENT_TABBED)
|
if(t != c->screen->seltag || c->flags & CLIENT_TABBED)
|
||||||
client_unmap(c);
|
client_unmap(c);
|
||||||
|
|||||||
@ -63,6 +63,14 @@ swap_ptr(void **x, void **y)
|
|||||||
*y = t;
|
*y = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
swap_int(int *x, int *y)
|
||||||
|
{
|
||||||
|
*y = *x ^ *y;
|
||||||
|
*x = *y ^ *x;
|
||||||
|
*y = *x ^ *y;
|
||||||
|
}
|
||||||
|
|
||||||
static inline enum position
|
static inline enum position
|
||||||
str_to_position(char *str)
|
str_to_position(char *str)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -177,7 +177,7 @@ struct client
|
|||||||
struct tag *tag, *prevtag;
|
struct tag *tag, *prevtag;
|
||||||
struct screen *screen;
|
struct screen *screen;
|
||||||
struct barwin *titlebar;
|
struct barwin *titlebar;
|
||||||
struct geo geo, wgeo, tgeo, ttgeo, rgeo, *tbgeo, fgeo;
|
struct geo geo, wgeo, tgeo, ttgeo, rgeo, *tbgeo;
|
||||||
struct colpair ncol, scol;
|
struct colpair ncol, scol;
|
||||||
struct theme *theme;
|
struct theme *theme;
|
||||||
struct client *tabmaster;
|
struct client *tabmaster;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user