one frame per tag

This commit is contained in:
Martin Duquesnoy 2011-09-09 07:54:14 +02:00
parent 3f7978b9e2
commit 3870db7dfc
7 changed files with 83 additions and 235 deletions

View File

@ -117,9 +117,6 @@ client_focus(struct client *c)
XSetInputFocus(W->dpy, c->win, RevertToPointerRoot, CurrentTime);
}
else
XSetInputFocus(W->dpy, W->root, RevertToPointerRoot, CurrentTime);
}
/** Get a client name
@ -212,12 +209,9 @@ client_new(Window w, XWindowAttributes *wa)
/* Attach */
SLIST_INSERT_HEAD(&W->h.client, c, next);
/* Insert in frame */
frame_client(c->tag->frame, c);
/* Map */
WIN_STATE(c->win, Map);
XRaiseWindow(W->dpy, w);
ewmh_set_wm_state(c->win, NormalState);
client_configure(c);
@ -231,22 +225,24 @@ client_remove(struct client *c)
XGrabServer(W->dpy);
XSetErrorHandler(wmfs_error_handler_dummy);
XReparentWindow(W->dpy, c->win, W->root, c->geo.x, c->geo.y);
if(W->client == c)
client_focus(NULL);
if(c->tag->sel == c)
c->tag->sel = SLIST_FIRST(&c->tag->clients);
{
W->client = NULL;
XSetInputFocus(W->dpy, W->root, RevertToPointerRoot, CurrentTime);
}
/* Remove from global client list */
SLIST_REMOVE(&W->h.client, c, client, next);
tag_client(NULL, c);
frame_client(NULL, c);
ewmh_set_wm_state(c->win, WithdrawnState);
XSync(W->dpy, False);
XUngrabButton(W->dpy, AnyButton, AnyModifier, c->win);
XUngrabServer(W->dpy);
XSync(W->dpy, False);
XSetErrorHandler(wmfs_error_handler);
free(c);

View File

@ -1,150 +0,0 @@
/*
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
* For license, see COPYING.
*/
#include <X11/Xutil.h>
#include "wmfs.h"
#include "frame.h"
#include "barwin.h"
#include "tag.h"
#include "util.h"
#include "config.h"
struct frame*
frame_new(struct tag *t)
{
struct frame *f = xcalloc(1, sizeof(struct frame));
XSetWindowAttributes at =
{
.background_pixel = THEME_DEFAULT->frame_bg,
.override_redirect = true,
.background_pixmap = ParentRelative,
.event_mask = BARWIN_MASK
};
f->tag = t;
f->geo = t->screen->ugeo;
t->frame = f;
f->win = XCreateWindow(W->dpy, W->root,
f->geo.x, f->geo.y,
f->geo.w, f->geo.h,
0, CopyFromParent,
InputOutput,
CopyFromParent,
(CWOverrideRedirect | CWBackPixmap | CWBackPixel | CWEventMask),
&at);
SLIST_INIT(&f->clients);
SLIST_INSERT_HEAD(&t->frames, f, next);
}
static void
frame_remove(struct frame *f)
{
SLIST_REMOVE(&f->tag->frames, f, frame, next);
XDestroyWindow(W->dpy, f->win);
/* frame_arrange(f->tag); */
free(f);
}
void
frame_free(struct tag *t)
{
struct frame *f;
SLIST_FOREACH(f, &t->frames, next)
frame_remove(f);
}
void
frame_client(struct frame *f, struct client *c)
{
/* Remove client from its previous frame */
if(c->frame)
{
if(c->frame == f)
return;
SLIST_REMOVE(&c->frame->clients, c, client, fnext);
}
/* Case of client remove, f = NULL */
if(!f)
{
if(c->frame && FRAME_EMPTY(c->frame))
frame_unmap(c->frame);
XReparentWindow(W->dpy, c->win, W->root, c->geo.x, c->geo.y);
return;
}
XReparentWindow(W->dpy, c->win, f->win,
THEME_DEFAULT->client_border_width,
THEME_DEFAULT->client_titlebar_width);
XResizeWindow(W->dpy, c->win,
f->geo.w - (THEME_DEFAULT->client_border_width << 1) - 1,
f->geo.h - (THEME_DEFAULT->client_titlebar_width
+ THEME_DEFAULT->client_border_width >> 1));
/* XReparentWindow(W->dpy, c->win, c->titlebar->win, 1, 1); */
/*split_integrate(f, c) */
SLIST_INSERT_HEAD(&f->clients, c, fnext);
frame_update(f);
}
void
frame_map(struct frame *f)
{
struct client *c;
WIN_STATE(f->win, Map);
SLIST_FOREACH(c, &f->clients, fnext)
ewmh_set_wm_state(c->win, NormalState);
}
void
frame_unmap(struct frame *f)
{
struct client *c;
WIN_STATE(f->win, Unmap);
SLIST_FOREACH(c, &f->clients, fnext)
ewmh_set_wm_state(c->win, IconicState);
}
void
frame_update(struct frame *f)
{
if(FRAME_EMPTY(f))
return;
/* Resize frame */
/* TODO: frame_arrange or something */
XMoveResizeWindow(W->dpy,
f->win,
f->geo.x,
f->geo.y,
f->geo.w,
f->geo.h);
frame_map(f);
}

View File

@ -1,37 +0,0 @@
/*
* wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
* For license, see COPYING.
*/
#ifndef FRAME_H
#define FRAME_H
#include "wmfs.h"
#define FRAME_EMPTY(f) SLIST_EMPTY(&f->clients)
/*
* Update each frame's geo of a screen after
* usable geo update (infobar_placement())
*/
static inline void
frame_update_geo(struct screen *s)
{
struct tag *t;
struct frame *f;
TAILQ_FOREACH(t, &s->tags, next)
{
SLIST_FOREACH(f, &t->frames, next)
f->geo = s->ugeo;
}
}
struct frame *frame_new(struct tag *t);
void frame_free(struct tag *t);
void frame_update(struct frame *f);
void frame_map(struct frame *f);
void frame_unmap(struct frame *f);
#endif /* FRAME_H */

View File

@ -9,7 +9,7 @@
#include "wmfs.h"
#include "util.h"
#include "draw.h"
#include "frame.h"
#include "tag.h"
enum { ElemTag = 0, ElemLayout, ElemSelbar, ElemStatus, ElemCustom, ElemLast };
@ -53,7 +53,7 @@ infobar_placement(struct infobar *i, Barpos p)
return false;
}
frame_update_geo(i->screen);
tag_update_frame_geo(i->screen);
return true;
}

View File

@ -3,16 +3,26 @@
* For license, see COPYING.
*/
#include <X11/Xutil.h> /* IconicState / NormalState */
#include "tag.h"
#include "util.h"
#include "infobar.h"
#include "client.h"
#include "frame.h"
#include "config.h"
#include "barwin.h"
struct tag*
tag_new(struct screen *s, char *name)
{
struct tag *t;
XSetWindowAttributes at =
{
.background_pixel = THEME_DEFAULT->frame_bg,
.override_redirect = true,
.background_pixmap = ParentRelative,
.event_mask = BARWIN_MASK
};
t = xcalloc(1, sizeof(struct tag));
@ -21,11 +31,18 @@ tag_new(struct screen *s, char *name)
t->flags = 0;
t->sel = NULL;
SLIST_INIT(&t->clients);
SLIST_INIT(&t->frames);
/* Frame window */
t->frame = XCreateWindow(W->dpy, W->root,
s->ugeo.x, s->ugeo.y,
s->ugeo.w, s->ugeo.h,
0, CopyFromParent,
InputOutput,
CopyFromParent,
(CWOverrideRedirect | CWBackPixmap
| CWBackPixel | CWEventMask),
&at);
/* only one frame for now, *tmp* */
frame_new(t); /* t->frame */
SLIST_INIT(&t->clients);
TAILQ_INSERT_TAIL(&s->tags, t, next);
@ -35,16 +52,23 @@ tag_new(struct screen *s, char *name)
void
tag_screen(struct screen *s, struct tag *t)
{
struct frame *f;
struct client *c;
/* Hide previous tag's frame */
SLIST_FOREACH(f, &s->seltag->frames, next)
frame_unmap(f);
/* Unmap previous tag's frame */
WIN_STATE(s->seltag->frame, Unmap);
SLIST_FOREACH(c, &s->seltag->clients, tnext)
ewmh_set_wm_state(c->win, IconicState);
/* Unhide selected tag's clients */
SLIST_FOREACH(f, &t->frames, next)
frame_update(f);
/*
* Map selected tag's frame, only if there is
* clients in t
*/
if(!SLIST_EMPTY(&t->clients))
{
WIN_STATE(t->frame, Map);
SLIST_FOREACH(c, &t->clients, tnext)
ewmh_set_wm_state(c->win, NormalState);
}
s->seltag = t;
@ -53,6 +77,7 @@ tag_screen(struct screen *s, struct tag *t)
infobar_elem_screen_update(s, ElemTag);
}
/* Set t to NULL to untag c from c->tag */
void
tag_client(struct tag *t, struct client *c)
{
@ -64,16 +89,30 @@ tag_client(struct tag *t, struct client *c)
SLIST_REMOVE(&c->tag->clients, c, client, tnext);
/* TODO: Focus next client */
if(c->tag->sel == c)
c->tag->sel = NULL;
}
/* Case of client remove */
if(!t)
{
/* Unmap frame if tag is now empty */
if(SLIST_EMPTY(&c->tag->clients))
WIN_STATE(c->tag->frame, Unmap);
return;
}
/* Map frame if tag was empty */
if(SLIST_EMPTY(&t->clients))
WIN_STATE(t->frame, Map);
c->tag = t;
/* Reparent client win in frame win */
XReparentWindow(W->dpy, c->win, t->frame, 0, 0);
/* Insert in new tag list */
SLIST_INSERT_HEAD(&t->clients, c, tnext);
}
@ -132,12 +171,8 @@ uicb_tag_prev(Uicb cmd)
static void
tag_remove(struct tag *t)
{
struct frame *f;
free(t->name);
frame_free(t);
XDestroyWindow(W->dpy, t->frame);
free(t);
}

View File

@ -17,4 +17,22 @@ void uicb_tag_set_with_name(Uicb cmd);
void uicb_tag_next(Uicb cmd);
void uicb_tag_prev(Uicb cmd);
/*
* Update frames size with screen usable geo
*/
static inline void
tag_update_frame_geo(struct screen *s)
{
struct tag *t;
TAILQ_FOREACH(t, &s->tags, next)
XMoveResizeWindow(W->dpy,
t->frame,
s->ugeo.x,
s->ugeo.y,
s->ugeo.w,
s->ugeo.h);
}
#endif /* TAG_H */

View File

@ -48,7 +48,6 @@ struct barwin
Window win;
Drawable dr;
Color fg, bg;
Flags flags;
void *ptr; /* Special cases */
SLIST_HEAD(, mousebind) mousebinds;
SLIST_ENTRY(barwin) next; /* global barwin */
@ -93,10 +92,9 @@ struct tag
{
struct screen *screen;
struct client *sel;
struct frame *frame;
char *name;
Flags flags;
SLIST_HEAD(, frame) frames;
Window frame;
SLIST_HEAD(, client) clients;
TAILQ_ENTRY(tag) next;
};
@ -105,7 +103,6 @@ struct client
{
struct tag *tag;
struct screen *screen;
struct frame *frame;
struct barwin *titlebar;
struct geo geo;
char *title;
@ -113,17 +110,6 @@ struct client
Window win;
SLIST_ENTRY(client) next; /* Global list */
SLIST_ENTRY(client) tnext; /* struct tag list */
SLIST_ENTRY(client) fnext; /* struct struct frame list */
};
struct frame
{
struct tag *tag;
struct geo geo;
Window win;
Color fg, bg;
SLIST_HEAD(, client) clients;
SLIST_ENTRY(frame) next;
};
struct keybind