From 41882b4a7e06128c8999363a22f40bf5970f768e Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Fri, 7 Oct 2011 02:25:33 +0200 Subject: [PATCH] Fix client_fac with size-hinted client --- src/client.c | 65 +++++++++++++++++++++++++++++++++++++++++----------- src/client.h | 8 ++++--- src/event.c | 18 ++++++++------- src/layout.c | 4 ++-- src/wmfs.h | 3 ++- 5 files changed, 70 insertions(+), 28 deletions(-) diff --git a/src/client.c b/src/client.c index cc2cc24..77c4bbd 100644 --- a/src/client.c +++ b/src/client.c @@ -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 diff --git a/src/client.h b/src/client.h index 25857eb..188b025 100644 --- a/src/client.h +++ b/src/client.h @@ -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; } } diff --git a/src/event.c b/src/event.c index d919aba..4fdd950 100644 --- a/src/event.c +++ b/src/event.c @@ -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; diff --git a/src/layout.c b/src/layout.c index 14b7980..165320a 100644 --- a/src/layout.c +++ b/src/layout.c @@ -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: diff --git a/src/wmfs.h b/src/wmfs.h index 84fb80f..f39680e 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -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 */