Almost finish tabbing, reload/tagtransfert/maybesomemore to do

This commit is contained in:
Martin Duquesnoy 2011-11-19 04:14:16 +01:00
parent 469ff393ee
commit 9aaaf7ef63
5 changed files with 169 additions and 55 deletions

View File

@ -61,7 +61,7 @@ CLIENT_ACTION_DIR(focus, Top)
CLIENT_ACTION_DIR(focus, Bottom)
/* uicb_client_tab_dir() */
#define client_tab(c) _client_tab(c, W->client)
#define client_tab(c) _client_tab(W->client, c)
CLIENT_ACTION_DIR(tab, Right)
CLIENT_ACTION_DIR(tab, Left)
CLIENT_ACTION_DIR(tab, Top)
@ -323,6 +323,9 @@ client_grabbuttons(struct client *c, bool focused)
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
}
#define _XTEXT() \
if((xt = ((f >> 1) - (w >> 1) - PAD)) < 0) \
xt = 0;
void
client_frame_update(struct client *c, struct colpair *cp)
{
@ -338,7 +341,7 @@ client_frame_update(struct client *c, struct colpair *cp)
c->titlebar->bg = cp->bg;
SLIST_FOREACH(cc, &c->tag->clients, tnext)
if(cc->tbgeo == &c->geo)
if(cc->tabmaster == c)
++n;
barwin_reparent(c->titlebar, c->frame);
@ -346,8 +349,7 @@ client_frame_update(struct client *c, struct colpair *cp)
barwin_resize(c->titlebar, (f = (c->geo.w / n)), c->tbarw);
barwin_refresh_color(c->titlebar);
if((xt = ((f >> 1) - (w >> 1) - PAD)) < 0)
xt = 0;
_XTEXT();
draw_text(c->titlebar->dr, c->theme, xt,
TEXTY(c->theme, c->tbarw), cp->fg, c->title);
@ -359,13 +361,12 @@ client_frame_update(struct client *c, struct colpair *cp)
int x = f;
SLIST_FOREACH(cc, &c->tag->clients, tnext)
if(cc->tbgeo == &c->geo && cc->titlebar)
if(cc->tabmaster == c && cc->titlebar)
{
cc->titlebar->bg = c->ncol.bg;
w = draw_textw(c->theme, cc->title);
if((xt = ((f >> 1) - (w >> 1) - PAD)) < 0)
xt = 0;
_XTEXT();
barwin_map(cc->titlebar);
barwin_reparent(cc->titlebar, c->frame);
@ -384,6 +385,110 @@ client_frame_update(struct client *c, struct colpair *cp)
}
}
void
_client_tab(struct client *c, struct client *cm)
{
/* Do not tab already tabed client */
if(c->flags & (CLIENT_TABBED | CLIENT_TABMASTER))
return;
layout_split_arrange_closed(c);
struct geo g = cm->geo;
/* Isolate tabbed client */
client_unmap(c);
g.x += W->xmaxw;
g.y += W->xmaxh;
c->geo = c->tgeo = g;
c->tabmaster = cm;
cm->tabmaster = NULL;
c->flags |= CLIENT_TABBED;
cm->flags |= CLIENT_TABMASTER;
client_focus(cm);
}
static void
client_tab_focus(struct client *c)
{
if(c->flags & CLIENT_TABBED && c->tabmaster)
{
struct client *cc;
struct geo g = c->tabmaster->geo;
c->flags |= CLIENT_TABMASTER;
c->flags &= ~CLIENT_TABBED;
client_moveresize(c, &c->tabmaster->geo);
client_map(c);
c->tabmaster->flags &= ~CLIENT_TABMASTER;
c->tabmaster->flags |= CLIENT_TABBED;
client_unmap(c->tabmaster);
if(!(c->flags & CLIENT_DYING))
{
g.x += W->xmaxw;
g.y += W->xmaxh;
c->tabmaster->geo = c->tabmaster->tgeo = g;
}
SLIST_FOREACH(cc, &c->tag->clients, tnext)
if(cc != c && cc->tabmaster == c->tabmaster)
cc->tabmaster = c;
c->tabmaster->tabmaster = c;
c->tabmaster = NULL;
}
}
static void
client_untab(struct client *c)
{
struct client *cc = c->tabmaster;
struct geo og = c->geo;
if(!(c->flags & (CLIENT_TABBED | CLIENT_TABMASTER)))
return;
c->flags &= ~CLIENT_TABMASTER;
if(!cc)
SLIST_FOREACH(cc, &c->tag->clients, tnext)
if(cc->tabmaster == c)
break;
if(cc)
{
client_tab_focus(cc);
c->flags &= ~CLIENT_TABBED;
c->tabmaster = NULL;
if(!(c->flags & CLIENT_DYING))
{
c->geo = c->tgeo = og;
layout_split_integrate(c, cc);
client_moveresize(c, &c->geo);
client_map(c);
}
client_frame_update(cc, CCOL(cc));
}
}
void
uicb_client_untab(Uicb cmd)
{
(void)cmd;
if(W->client)
client_untab(W->client);
}
void
client_focus(struct client *c)
{
@ -399,35 +504,7 @@ client_focus(struct client *c)
{
c->tag->sel = c;
client_grabbuttons(c, true);
if(c->flags & CLIENT_TABBED)
{
struct geo ocg = c->geo;
struct client *cc, *tc;
SLIST_FOREACH(cc, &c->tag->clients, tnext)
if(c->tbgeo == &cc->geo)
{
c->flags &= ~CLIENT_TABBED;
cc->flags |= CLIENT_TABBED;
client_map(c);
client_unmap(cc);
client_moveresize(c, c->tbgeo);
client_moveresize(cc, &ocg);
cc->tbgeo = &c->geo;
c->tbgeo = NULL;
SLIST_FOREACH(tc, &c->tag->clients, tnext)
if(tc->flags & CLIENT_TABBED && tc->tbgeo == &cc->geo)
tc->tbgeo = &c->geo;
break;
}
}
client_tab_focus(c);
client_frame_update(c, &c->scol);
XSetInputFocus(W->dpy, c->win, RevertToPointerRoot, CurrentTime);
}
@ -829,8 +906,6 @@ client_winsize(struct client *c, struct geo *g)
void
client_moveresize(struct client *c, struct geo *g)
{
struct geo og = c->geo;
if(c->flags & CLIENT_TABBED)
return;
@ -846,11 +921,8 @@ client_moveresize(struct client *c, struct geo *g)
}
/* Real geo regarding full root size */
if(!(c->flags & CLIENT_TABSLAVE))
{
c->rgeo.x += c->screen->ugeo.x;
c->rgeo.y += c->screen->ugeo.y;
}
c->rgeo.x += c->screen->ugeo.x;
c->rgeo.y += c->screen->ugeo.y;
XMoveResizeWindow(W->dpy, c->frame,
c->rgeo.x, c->rgeo.y,
@ -1094,10 +1166,12 @@ client_fac_hint(struct client *c)
void
client_remove(struct client *c)
{
c->flags |= CLIENT_DYING;
XGrabServer(W->dpy);
XSetErrorHandler(wmfs_error_handler_dummy);
XReparentWindow(W->dpy, c->win, W->root, c->rgeo.x, c->rgeo.y);
WIN_STATE(c->win, Map);
client_map(c);
client_untab(c);
XDestroyWindow(W->dpy, c->frame);
if(c->titlebar)

View File

@ -22,6 +22,8 @@ void client_swap2(struct client *c1, struct client *c2);
void client_swap(struct client *c, enum position p);
#define CCOL(c) (c == c->tag->sel ? &c->scol : &c->ncol)
void client_frame_update(struct client *c, struct colpair *cp);
void client_tab_pull(struct client *c);
void _client_tab(struct client *c, struct client *cm);
void client_focus(struct client *c);
void client_get_name(struct client *c);
void client_close(struct client *c);
@ -43,6 +45,7 @@ void client_apply_tgeo(struct tag *t);
void client_update_props(struct client *c, Flags f);
inline void client_fac_hint(struct client *c);
void uicb_client_untab(Uicb cmd);
/* Generated */
void uicb_client_resize_Right(Uicb);
@ -85,6 +88,23 @@ client_prev(struct client *c)
return cc;
}
static inline struct client*
clien_tab_next(struct client *c)
{
struct client *cc;
if(c->flags & (CLIENT_TABBED | CLIENT_TABMASTER))
SLIST_FOREACH(cc, &c->tag->clients, tnext)
{
if(c == cc)
continue;
if(c->tabmaster == c || c->tabmaster == c->tabmaster)
return cc;
}
return NULL;
}
static inline void
client_map(struct client *c)
{
@ -100,19 +120,37 @@ client_unmap(struct client *c)
}
static inline void
_client_tab(struct client *c, struct client *cc)
client_tab_slave(struct client *c)
{
layout_split_arrange_closed(cc);
/* Fake geo to don't act in layout functions */
struct geo g = { W->xmaxw + c->geo.x, W->xmaxh + c->geo.y, c->geo.w, c->geo.h };
cc->tbgeo = &c->geo;
c->flags &= ~CLIENT_TABMASTER;
c->flags |= CLIENT_TABBED;
cc->flags |= CLIENT_TABBED;
c->geo = c->tgeo = g;
client_unmap(cc);
client_focus(c);
client_unmap(c);
}
static inline void
client_tab_master(struct client *c)
{
struct client *cc;
c->flags |= CLIENT_TABMASTER;
c->flags &= ~CLIENT_TABBED;
client_moveresize(c, &c->tabmaster->geo);
client_map(c);
client_tab_slave(c->tabmaster);
/* Parent tabbed client take new master as tabmaster */
SLIST_FOREACH(cc, &c->tag->clients, tnext)
if(cc->tabmaster == c->tabmaster)
cc->tabmaster = c;
c->tabmaster->tabmaster = c;
c->tabmaster = NULL;
}
#endif /* CLIENT_H */

View File

@ -60,6 +60,7 @@ static const struct { char *name; void (*func)(Uicb cmd); } uicb_list[] =
{ "client_focus_prev", uicb_client_focus_prev },
{ "client_swap_next", uicb_client_swapsel_next },
{ "client_swap_prev", uicb_client_swapsel_prev },
{ "client_untab", uicb_client_untab },
{ NULL, NULL }
};

View File

@ -53,7 +53,8 @@ tag_screen(struct screen *s, struct tag *t)
*/
if(!SLIST_EMPTY(&t->clients))
{
client_map(c);
SLIST_FOREACH(c, &t->clients, tnext)
client_map(c);
client_focus(t->sel);
}
@ -77,6 +78,7 @@ tag_client(struct tag *t, struct client *c)
if(!(c->flags & CLIENT_IGNORE_LAYOUT))
layout_split_arrange_closed(c);
SLIST_REMOVE(&c->tag->clients, c, client, tnext);
if(c->tag->sel == c || W->client == c)

View File

@ -162,8 +162,7 @@ struct client
#define CLIENT_RULED 0x20
#define CLIENT_TABBED 0x40
#define CLIENT_TABMASTER 0x80
#define CLIENT_TABBING 0x100
#define CLIENT_TABSLAVE 0x200
#define CLIENT_DYING 0x100 /* Saddest flag ever */
Flags flags;
Window win, frame;
SLIST_ENTRY(client) next; /* Global list */