one frame per tag
This commit is contained in:
parent
3f7978b9e2
commit
3870db7dfc
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user