one frame per tag
This commit is contained in:
@@ -117,9 +117,6 @@ client_focus(struct client *c)
|
|||||||
|
|
||||||
XSetInputFocus(W->dpy, c->win, RevertToPointerRoot, CurrentTime);
|
XSetInputFocus(W->dpy, c->win, RevertToPointerRoot, CurrentTime);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
XSetInputFocus(W->dpy, W->root, RevertToPointerRoot, CurrentTime);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get a client name
|
/** Get a client name
|
||||||
@@ -212,12 +209,9 @@ client_new(Window w, XWindowAttributes *wa)
|
|||||||
/* Attach */
|
/* Attach */
|
||||||
SLIST_INSERT_HEAD(&W->h.client, c, next);
|
SLIST_INSERT_HEAD(&W->h.client, c, next);
|
||||||
|
|
||||||
/* Insert in frame */
|
/* Map */
|
||||||
frame_client(c->tag->frame, c);
|
|
||||||
|
|
||||||
WIN_STATE(c->win, Map);
|
WIN_STATE(c->win, Map);
|
||||||
|
ewmh_set_wm_state(c->win, NormalState);
|
||||||
XRaiseWindow(W->dpy, w);
|
|
||||||
|
|
||||||
client_configure(c);
|
client_configure(c);
|
||||||
|
|
||||||
@@ -231,22 +225,24 @@ client_remove(struct client *c)
|
|||||||
|
|
||||||
XGrabServer(W->dpy);
|
XGrabServer(W->dpy);
|
||||||
XSetErrorHandler(wmfs_error_handler_dummy);
|
XSetErrorHandler(wmfs_error_handler_dummy);
|
||||||
|
XReparentWindow(W->dpy, c->win, W->root, c->geo.x, c->geo.y);
|
||||||
|
|
||||||
if(W->client == c)
|
if(W->client == c)
|
||||||
client_focus(NULL);
|
{
|
||||||
|
W->client = NULL;
|
||||||
if(c->tag->sel == c)
|
XSetInputFocus(W->dpy, W->root, RevertToPointerRoot, CurrentTime);
|
||||||
c->tag->sel = SLIST_FIRST(&c->tag->clients);
|
}
|
||||||
|
|
||||||
|
/* Remove from global client list */
|
||||||
SLIST_REMOVE(&W->h.client, c, client, next);
|
SLIST_REMOVE(&W->h.client, c, client, next);
|
||||||
|
|
||||||
tag_client(NULL, c);
|
tag_client(NULL, c);
|
||||||
frame_client(NULL, c);
|
|
||||||
|
|
||||||
ewmh_set_wm_state(c->win, WithdrawnState);
|
ewmh_set_wm_state(c->win, WithdrawnState);
|
||||||
|
|
||||||
XSync(W->dpy, False);
|
XUngrabButton(W->dpy, AnyButton, AnyModifier, c->win);
|
||||||
XUngrabServer(W->dpy);
|
XUngrabServer(W->dpy);
|
||||||
|
XSync(W->dpy, False);
|
||||||
XSetErrorHandler(wmfs_error_handler);
|
XSetErrorHandler(wmfs_error_handler);
|
||||||
|
|
||||||
free(c);
|
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 "wmfs.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
#include "frame.h"
|
#include "tag.h"
|
||||||
|
|
||||||
enum { ElemTag = 0, ElemLayout, ElemSelbar, ElemStatus, ElemCustom, ElemLast };
|
enum { ElemTag = 0, ElemLayout, ElemSelbar, ElemStatus, ElemCustom, ElemLast };
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ infobar_placement(struct infobar *i, Barpos p)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame_update_geo(i->screen);
|
tag_update_frame_geo(i->screen);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,16 +3,26 @@
|
|||||||
* For license, see COPYING.
|
* For license, see COPYING.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <X11/Xutil.h> /* IconicState / NormalState */
|
||||||
|
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "infobar.h"
|
#include "infobar.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "frame.h"
|
#include "config.h"
|
||||||
|
#include "barwin.h"
|
||||||
|
|
||||||
struct tag*
|
struct tag*
|
||||||
tag_new(struct screen *s, char *name)
|
tag_new(struct screen *s, char *name)
|
||||||
{
|
{
|
||||||
struct tag *t;
|
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));
|
t = xcalloc(1, sizeof(struct tag));
|
||||||
|
|
||||||
@@ -21,11 +31,18 @@ tag_new(struct screen *s, char *name)
|
|||||||
t->flags = 0;
|
t->flags = 0;
|
||||||
t->sel = NULL;
|
t->sel = NULL;
|
||||||
|
|
||||||
SLIST_INIT(&t->clients);
|
/* Frame window */
|
||||||
SLIST_INIT(&t->frames);
|
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* */
|
SLIST_INIT(&t->clients);
|
||||||
frame_new(t); /* t->frame */
|
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&s->tags, t, next);
|
TAILQ_INSERT_TAIL(&s->tags, t, next);
|
||||||
|
|
||||||
@@ -35,16 +52,23 @@ tag_new(struct screen *s, char *name)
|
|||||||
void
|
void
|
||||||
tag_screen(struct screen *s, struct tag *t)
|
tag_screen(struct screen *s, struct tag *t)
|
||||||
{
|
{
|
||||||
struct frame *f;
|
|
||||||
struct client *c;
|
struct client *c;
|
||||||
|
|
||||||
/* Hide previous tag's frame */
|
/* Unmap previous tag's frame */
|
||||||
SLIST_FOREACH(f, &s->seltag->frames, next)
|
WIN_STATE(s->seltag->frame, Unmap);
|
||||||
frame_unmap(f);
|
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)
|
* Map selected tag's frame, only if there is
|
||||||
frame_update(f);
|
* 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;
|
s->seltag = t;
|
||||||
|
|
||||||
@@ -53,6 +77,7 @@ tag_screen(struct screen *s, struct tag *t)
|
|||||||
infobar_elem_screen_update(s, ElemTag);
|
infobar_elem_screen_update(s, ElemTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set t to NULL to untag c from c->tag */
|
||||||
void
|
void
|
||||||
tag_client(struct tag *t, struct client *c)
|
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);
|
SLIST_REMOVE(&c->tag->clients, c, client, tnext);
|
||||||
|
|
||||||
|
/* TODO: Focus next client */
|
||||||
if(c->tag->sel == c)
|
if(c->tag->sel == c)
|
||||||
c->tag->sel = NULL;
|
c->tag->sel = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Case of client remove */
|
/* Case of client remove */
|
||||||
if(!t)
|
if(!t)
|
||||||
|
{
|
||||||
|
/* Unmap frame if tag is now empty */
|
||||||
|
if(SLIST_EMPTY(&c->tag->clients))
|
||||||
|
WIN_STATE(c->tag->frame, Unmap);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Map frame if tag was empty */
|
||||||
|
if(SLIST_EMPTY(&t->clients))
|
||||||
|
WIN_STATE(t->frame, Map);
|
||||||
|
|
||||||
c->tag = t;
|
c->tag = t;
|
||||||
|
|
||||||
|
/* Reparent client win in frame win */
|
||||||
|
XReparentWindow(W->dpy, c->win, t->frame, 0, 0);
|
||||||
|
|
||||||
/* Insert in new tag list */
|
/* Insert in new tag list */
|
||||||
SLIST_INSERT_HEAD(&t->clients, c, tnext);
|
SLIST_INSERT_HEAD(&t->clients, c, tnext);
|
||||||
}
|
}
|
||||||
@@ -132,12 +171,8 @@ uicb_tag_prev(Uicb cmd)
|
|||||||
static void
|
static void
|
||||||
tag_remove(struct tag *t)
|
tag_remove(struct tag *t)
|
||||||
{
|
{
|
||||||
struct frame *f;
|
|
||||||
|
|
||||||
free(t->name);
|
free(t->name);
|
||||||
|
XDestroyWindow(W->dpy, t->frame);
|
||||||
frame_free(t);
|
|
||||||
|
|
||||||
free(t);
|
free(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,4 +17,22 @@ void uicb_tag_set_with_name(Uicb cmd);
|
|||||||
void uicb_tag_next(Uicb cmd);
|
void uicb_tag_next(Uicb cmd);
|
||||||
void uicb_tag_prev(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 */
|
#endif /* TAG_H */
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ struct barwin
|
|||||||
Window win;
|
Window win;
|
||||||
Drawable dr;
|
Drawable dr;
|
||||||
Color fg, bg;
|
Color fg, bg;
|
||||||
Flags flags;
|
|
||||||
void *ptr; /* Special cases */
|
void *ptr; /* Special cases */
|
||||||
SLIST_HEAD(, mousebind) mousebinds;
|
SLIST_HEAD(, mousebind) mousebinds;
|
||||||
SLIST_ENTRY(barwin) next; /* global barwin */
|
SLIST_ENTRY(barwin) next; /* global barwin */
|
||||||
@@ -93,10 +92,9 @@ struct tag
|
|||||||
{
|
{
|
||||||
struct screen *screen;
|
struct screen *screen;
|
||||||
struct client *sel;
|
struct client *sel;
|
||||||
struct frame *frame;
|
|
||||||
char *name;
|
char *name;
|
||||||
Flags flags;
|
Flags flags;
|
||||||
SLIST_HEAD(, frame) frames;
|
Window frame;
|
||||||
SLIST_HEAD(, client) clients;
|
SLIST_HEAD(, client) clients;
|
||||||
TAILQ_ENTRY(tag) next;
|
TAILQ_ENTRY(tag) next;
|
||||||
};
|
};
|
||||||
@@ -105,7 +103,6 @@ struct client
|
|||||||
{
|
{
|
||||||
struct tag *tag;
|
struct tag *tag;
|
||||||
struct screen *screen;
|
struct screen *screen;
|
||||||
struct frame *frame;
|
|
||||||
struct barwin *titlebar;
|
struct barwin *titlebar;
|
||||||
struct geo geo;
|
struct geo geo;
|
||||||
char *title;
|
char *title;
|
||||||
@@ -113,17 +110,6 @@ struct client
|
|||||||
Window win;
|
Window win;
|
||||||
SLIST_ENTRY(client) next; /* Global list */
|
SLIST_ENTRY(client) next; /* Global list */
|
||||||
SLIST_ENTRY(client) tnext; /* struct tag 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
|
struct keybind
|
||||||
|
|||||||
Reference in New Issue
Block a user