Fix client_fac with size-hinted client

This commit is contained in:
Martin Duquesnoy 2011-10-07 02:25:33 +02:00
parent f224f7056f
commit 41882b4a7e
5 changed files with 70 additions and 28 deletions

View File

@ -149,11 +149,17 @@ void
client_swap(struct client *c1, struct client *c2)
{
struct tag *t;
struct geo g;
struct geo g, foo;
/* Conflict / errors */
if(c1 == c2 || !c1 || !c2)
return;
/* are swapped geos compatible? */
if(client_winsize(c1, &c2->geo, &foo)
|| client_winsize(c2, &c1->geo, &foo))
return;
t = c1->tag;
g = c1->geo;
@ -164,6 +170,9 @@ client_swap(struct client *c1, struct client *c2)
client_moveresize(c1, &c2->geo);
client_moveresize(c2, &g);
c1->flags |= CLIENT_IGNORE_ENTER;
c2->flags |= CLIENT_IGNORE_ENTER;
}
static void
@ -435,20 +444,34 @@ client_geo_hints(struct geo *g, int *s)
g->h = s[MAXH];
}
bool
client_winsize(struct client *c, struct geo *g, struct geo *ret)
{
int ow, bord = THEME_DEFAULT->client_border_width;
/* Window geo */
ret->x = g->x + bord;
ret->y = g->y + bord;
ret->h = g->h - (bord << 1);
ret->w = ow = g->w - (bord << 1);
client_geo_hints(ret, (int*)c->sizeh);
if(ret->h > g->h || ret->w > g->w)
return true;
/* Balance position with new size */
ret->x += (ow - c->wgeo.w) >> 1;
return false;
}
void
client_moveresize(struct client *c, struct geo *g)
{
int bord = THEME_DEFAULT->client_border_width;
c->tgeo = c->geo = *g;
c->geo = *g;
/* Window geo */
c->wgeo.x = g->x + bord;
c->wgeo.y = g->y + bord ;
c->wgeo.w = g->w - (bord << 1);
c->wgeo.h = g->h - (bord << 1);
client_geo_hints(&c->wgeo, (int*)c->sizeh);
client_winsize(c, g, &c->wgeo);
XMoveResizeWindow(W->dpy, c->win,
c->wgeo.x, c->wgeo.y,
@ -474,6 +497,7 @@ void
client_fac_resize(struct client *c, enum position p, int fac)
{
struct client *gc = client_next_with_pos(c, p);
struct geo foo;
enum position rp = RPOS(p);
if(!gc || gc->screen != c->screen)
@ -486,12 +510,11 @@ client_fac_resize(struct client *c, enum position p, int fac)
|| !client_fac_check_row(gc, rp, -fac))
return;
/* Simple resize with only c & gc */
if(GEO_CHECK2(c->geo, gc->geo, p))
{
client_moveresize(c, &c->tgeo);
client_moveresize(gc, &gc->tgeo);
c->flags |= CLIENT_IGNORE_ENTER;
gc->flags |= CLIENT_IGNORE_ENTER;
}
/* Resize with row parents */
else
@ -499,6 +522,20 @@ client_fac_resize(struct client *c, enum position p, int fac)
client_fac_arrange_row(c, p, fac);
client_fac_arrange_row(gc, rp, -fac);
}
/*
* Check if every tag client are compatible with
* future globals geo. Problem here is that we must *not*
* resize client because of possible error with next
* clients in linked list.
*/
SLIST_FOREACH(gc, &c->tag->clients, tnext)
if(client_winsize(gc, &gc->tgeo, &foo))
return;
/* It's ok, resize */
SLIST_FOREACH(gc, &c->tag->clients, tnext)
client_moveresize(gc, &gc->tgeo);
}
void

View File

@ -19,9 +19,11 @@ void client_get_name(struct client *c);
void client_close(struct client *c);
void uicb_client_close(Uicb cmd);
struct client *client_new(Window w, XWindowAttributes *wa);
bool client_winsize(struct client *c, struct geo *geo, struct geo *ret);
void client_moveresize(struct client *c, struct geo *g);
void client_maximize(struct client *c);
void client_fac_resize(struct client *c, enum position p, int fac);
void client_fac_adjust(struct client *c);
void client_remove(struct client *c);
void client_free(void);
@ -91,7 +93,7 @@ client_fac_geo(struct client *c, enum position p, int fac)
|| cg.w < 5 || cg.h < 5)
return false;
/* Set transformed geo in tmp geo */
/* Set transformed geo in tile geo */
c->tgeo = cg;
return true;
@ -119,10 +121,10 @@ client_fac_arrange_row(struct client *c, enum position p, int fac)
/* Travel clients to search row parents and apply fac */
SLIST_FOREACH(cc, &c->tag->clients, tnext)
if(GEO_PARENTROW(g, cc->geo, p))
if(GEO_PARENTROW(g, cc->tgeo, p))
{
client_fac_geo(cc, p, fac);
client_moveresize(cc, &cc->tgeo);
c->flags |= CLIENT_IGNORE_ENTER;
}
}

View File

@ -35,7 +35,6 @@ event_buttonpress(XEvent *e)
}
}
/*
static void
event_enternotify(XEvent *e)
{
@ -43,15 +42,18 @@ event_enternotify(XEvent *e)
struct client *c;
if((ev->mode != NotifyNormal
|| ev->detail == NotifyInferior
|| ev->detail == NotifyAncestor)
|| ev->detail == NotifyInferior)
&& ev->window != W->root)
return;
if((c = client_gb_win(ev->window)))
client_focus(c);
{
if(c->flags & CLIENT_IGNORE_ENTER)
c->flags ^= CLIENT_IGNORE_ENTER;
else
client_focus(c);
}
}
*/
static void
event_clientmessageevent(XEvent *e)
@ -191,14 +193,14 @@ event_motionnotify(XEvent *e)
{
XMotionEvent *ev = &e->xmotion;
struct client *c;
struct tag *t = W->screen->seltag;
/*
* Check client window and tag frame to get focused
* window with mouse motion
*/
if(((c = client_gb_win(ev->subwindow)) && c != c->tag->sel)
|| (ev->window == W->screen->seltag->frame
&& ((c = client_gb_pos(W->screen->seltag, ev->x, ev->y)))))
|| (ev->window == t->frame && ((c = client_gb_pos(t, ev->x, ev->y)))))
client_focus(c);
}
@ -250,7 +252,7 @@ event_init(void)
event_handle[ClientMessage] = event_clientmessageevent;
event_handle[ConfigureRequest] = event_configureevent;
event_handle[DestroyNotify] = event_destroynotify;
/*event_handle[EnterNotify] = event_enternotify;*/
event_handle[EnterNotify] = event_enternotify;
event_handle[Expose] = event_expose;
event_handle[FocusIn] = event_focusin;
event_handle[KeyPress] = event_keypress;

View File

@ -34,8 +34,6 @@ layout_split(struct client *c, bool vertical)
geo.h += (og.y + og.h) - (geo.y + geo.h);
}
client_moveresize(c, &c->geo);
return geo;
}
@ -171,7 +169,9 @@ layout_split_integrate(struct client *c, struct client *sc)
}
g = layout_split(sc, (sc->geo.h < sc->geo.w));
client_moveresize(c, &g);
client_moveresize(sc, &sc->geo);
}
/* Arrange inter-clients holes:

View File

@ -135,7 +135,8 @@ struct client
struct geo geo, tgeo, wgeo;
int sizeh[SHLAST];
char *title;
#define CLIENT_HINT_FLAG 0x01
#define CLIENT_HINT_FLAG 0x01
#define CLIENT_IGNORE_ENTER 0x02
Flags flags;
Window win;
SLIST_ENTRY(client) next; /* Global list */