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) CLIENT_ACTION_DIR(focus, Bottom)
/* uicb_client_tab_dir() */ /* 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, Right)
CLIENT_ACTION_DIR(tab, Left) CLIENT_ACTION_DIR(tab, Left)
CLIENT_ACTION_DIR(tab, Top) CLIENT_ACTION_DIR(tab, Top)
@@ -323,6 +323,9 @@ client_grabbuttons(struct client *c, bool focused)
ButtonMask, GrabModeAsync, GrabModeSync, None, None); ButtonMask, GrabModeAsync, GrabModeSync, None, None);
} }
#define _XTEXT() \
if((xt = ((f >> 1) - (w >> 1) - PAD)) < 0) \
xt = 0;
void void
client_frame_update(struct client *c, struct colpair *cp) 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; c->titlebar->bg = cp->bg;
SLIST_FOREACH(cc, &c->tag->clients, tnext) SLIST_FOREACH(cc, &c->tag->clients, tnext)
if(cc->tbgeo == &c->geo) if(cc->tabmaster == c)
++n; ++n;
barwin_reparent(c->titlebar, c->frame); 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_resize(c->titlebar, (f = (c->geo.w / n)), c->tbarw);
barwin_refresh_color(c->titlebar); barwin_refresh_color(c->titlebar);
if((xt = ((f >> 1) - (w >> 1) - PAD)) < 0) _XTEXT();
xt = 0;
draw_text(c->titlebar->dr, c->theme, xt, draw_text(c->titlebar->dr, c->theme, xt,
TEXTY(c->theme, c->tbarw), cp->fg, c->title); 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; int x = f;
SLIST_FOREACH(cc, &c->tag->clients, tnext) 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; cc->titlebar->bg = c->ncol.bg;
w = draw_textw(c->theme, cc->title); w = draw_textw(c->theme, cc->title);
if((xt = ((f >> 1) - (w >> 1) - PAD)) < 0) _XTEXT();
xt = 0;
barwin_map(cc->titlebar); barwin_map(cc->titlebar);
barwin_reparent(cc->titlebar, c->frame); 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 void
client_focus(struct client *c) client_focus(struct client *c)
{ {
@@ -399,35 +504,7 @@ client_focus(struct client *c)
{ {
c->tag->sel = c; c->tag->sel = c;
client_grabbuttons(c, true); client_grabbuttons(c, true);
client_tab_focus(c);
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_frame_update(c, &c->scol); client_frame_update(c, &c->scol);
XSetInputFocus(W->dpy, c->win, RevertToPointerRoot, CurrentTime); XSetInputFocus(W->dpy, c->win, RevertToPointerRoot, CurrentTime);
} }
@@ -829,8 +906,6 @@ client_winsize(struct client *c, struct geo *g)
void void
client_moveresize(struct client *c, struct geo *g) client_moveresize(struct client *c, struct geo *g)
{ {
struct geo og = c->geo;
if(c->flags & CLIENT_TABBED) if(c->flags & CLIENT_TABBED)
return; return;
@@ -846,11 +921,8 @@ client_moveresize(struct client *c, struct geo *g)
} }
/* Real geo regarding full root size */ /* 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, XMoveResizeWindow(W->dpy, c->frame,
c->rgeo.x, c->rgeo.y, c->rgeo.x, c->rgeo.y,
@@ -1094,10 +1166,12 @@ client_fac_hint(struct client *c)
void void
client_remove(struct client *c) client_remove(struct client *c)
{ {
c->flags |= CLIENT_DYING;
XGrabServer(W->dpy); XGrabServer(W->dpy);
XSetErrorHandler(wmfs_error_handler_dummy); XSetErrorHandler(wmfs_error_handler_dummy);
XReparentWindow(W->dpy, c->win, W->root, c->rgeo.x, c->rgeo.y); 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); XDestroyWindow(W->dpy, c->frame);
if(c->titlebar) 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); void client_swap(struct client *c, enum position p);
#define CCOL(c) (c == c->tag->sel ? &c->scol : &c->ncol) #define CCOL(c) (c == c->tag->sel ? &c->scol : &c->ncol)
void client_frame_update(struct client *c, struct colpair *cp); 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_focus(struct client *c);
void client_get_name(struct client *c); void client_get_name(struct client *c);
void client_close(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); void client_update_props(struct client *c, Flags f);
inline void client_fac_hint(struct client *c); inline void client_fac_hint(struct client *c);
void uicb_client_untab(Uicb cmd);
/* Generated */ /* Generated */
void uicb_client_resize_Right(Uicb); void uicb_client_resize_Right(Uicb);
@@ -85,6 +88,23 @@ client_prev(struct client *c)
return cc; 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 static inline void
client_map(struct client *c) client_map(struct client *c)
{ {
@@ -100,19 +120,37 @@ client_unmap(struct client *c)
} }
static inline void 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 }; 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_unmap(c);
client_focus(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 */ #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_focus_prev", uicb_client_focus_prev },
{ "client_swap_next", uicb_client_swapsel_next }, { "client_swap_next", uicb_client_swapsel_next },
{ "client_swap_prev", uicb_client_swapsel_prev }, { "client_swap_prev", uicb_client_swapsel_prev },
{ "client_untab", uicb_client_untab },
{ NULL, NULL } { NULL, NULL }
}; };

View File

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

View File

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