wmii/cmd/wm/layout_float.c

247 lines
4.9 KiB
C
Raw Normal View History

2005-12-05 04:09:27 +03:00
/*
* (C)opyright MMIV-MMV Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "wm.h"
#include "layoutdef.h"
2005-12-05 04:09:27 +03:00
2006-01-12 18:06:50 +03:00
static void init_float(Layout *l, Client * clients);
static Client *deinit_float(Layout *l);
static void arrange_float(Layout *l);
static Bool attach_float(Layout *l, Client * c);
static void detach_float(Layout *l, Client * c, Bool unmap);
2005-12-21 18:18:11 +03:00
static void resize_float(Frame * f, XRectangle * new, XPoint * pt);
static void focus_float(Layout * l, Client * c, Bool raise);
2006-01-12 18:06:50 +03:00
static Frame *frames_float(Layout *l);
static Client *sel_float(Layout *l);
2006-01-12 18:06:50 +03:00
static Action *actions_float(Layout *l);
2005-12-11 01:43:45 +03:00
static void select_frame(void *obj, char *arg);
Action lfloat_acttbl[] = {
2005-12-21 18:18:11 +03:00
{"select", select_frame},
{0, 0}
2005-12-11 01:43:45 +03:00
};
2005-12-05 04:09:27 +03:00
2005-12-16 19:18:00 +03:00
typedef struct {
2005-12-21 18:18:11 +03:00
Frame *frames;
Frame *sel;
size_t nframes;
2005-12-16 19:18:00 +03:00
} Float;
2005-12-05 04:09:27 +03:00
2005-12-21 18:18:11 +03:00
void
init_layout_float()
2005-12-05 04:09:27 +03:00
{
2006-01-12 18:06:50 +03:00
LayoutDef *lp, *l = cext_emallocz(sizeof(LayoutDef));
2005-12-21 18:18:11 +03:00
l->name = "float";
l->init = init_float;
l->deinit = deinit_float;
l->arrange = arrange_float;
l->attach = attach_float;
l->detach = detach_float;
l->resize = resize_float;
l->focus = focus_float;
l->frames = frames_float;
l->sel = sel_float;
l->actions = actions_float;
for(lp = layouts; lp && lp->next; lp = lp->next);
if(lp)
lp->next = l;
else
layouts = l;
2005-12-05 04:09:27 +03:00
}
2005-12-21 18:18:11 +03:00
static void
2006-01-12 18:06:50 +03:00
arrange_float(Layout *l)
2005-12-05 04:09:27 +03:00
{
}
2005-12-21 18:18:11 +03:00
static void
2006-01-12 18:06:50 +03:00
init_float(Layout *l, Client * clients)
{
2005-12-21 18:18:11 +03:00
Client *n, *c = clients;
Float *fl = cext_emallocz(sizeof(Float));
2006-01-12 18:06:50 +03:00
l->aux = fl;
2005-12-21 18:18:11 +03:00
while(c) {
n = c->next;
2006-01-12 18:06:50 +03:00
attach_float(l, c);
2005-12-21 18:18:11 +03:00
c = n;
}
}
2005-12-21 18:18:11 +03:00
static void
2006-01-12 18:06:50 +03:00
attach_frame(Layout *l, Frame * new)
2005-12-05 04:09:27 +03:00
{
2006-01-12 18:06:50 +03:00
Float *fl = l->aux;
2005-12-21 18:18:11 +03:00
Frame *f;
for(f = fl->frames; f && f->next; f = f->next);
if(!f)
fl->frames = new;
else {
f->next = new;
new->prev = f;
}
2006-01-12 18:06:50 +03:00
attach_frame_to_layout(l, new);
2005-12-21 18:18:11 +03:00
fl->nframes++;
}
2005-12-21 18:18:11 +03:00
static void
2006-01-12 18:06:50 +03:00
detach_frame(Layout *l, Frame * old)
{
2006-01-12 18:06:50 +03:00
Float *fl = l->aux;
2005-12-21 18:18:11 +03:00
if(old->prev)
old->prev->next = old->next;
else
fl->frames = old->next;
if(old->next)
old->next->prev = old->prev;
if(fl->sel == old)
2005-12-21 18:18:11 +03:00
fl->sel = fl->frames;
old->prev = old->next = nil;
2006-01-12 18:06:50 +03:00
detach_frame_from_layout(old);
2005-12-21 18:18:11 +03:00
fl->nframes--;
2005-12-05 04:09:27 +03:00
}
2005-12-21 18:18:11 +03:00
static Client *
2006-01-12 18:06:50 +03:00
deinit_float(Layout *l)
2005-12-05 04:09:27 +03:00
{
2006-01-12 18:06:50 +03:00
Float *fl = l->aux;
2005-12-21 18:18:11 +03:00
Client *res = nil, *c = nil, *cl;
Frame *f;
while((f = fl->frames)) {
while((cl = f->clients)) {
detach_client_from_frame(cl, False);
cl->prev = cl->next = 0;
if(!res)
res = c = cl;
else {
c->next = cl;
cl->prev = c;
c = cl;
}
}
2006-01-12 18:06:50 +03:00
detach_frame(l, f);
2005-12-21 18:18:11 +03:00
destroy_frame(f);
}
free(fl);
2006-01-12 18:06:50 +03:00
l->aux = nil;
2005-12-21 18:18:11 +03:00
return res;
2005-12-05 04:09:27 +03:00
}
2005-12-21 18:18:11 +03:00
static Bool
2006-01-12 18:06:50 +03:00
attach_float(Layout *l, Client * c)
2005-12-05 04:09:27 +03:00
{
Frame *f;
2005-12-21 18:18:11 +03:00
/* check for tabbing? */
2006-01-12 18:06:50 +03:00
if(c->rect.y < layout_rect.y)
c->rect.y = layout_rect.y;
if(c->rect.x < layout_rect.x)
c->rect.x = layout_rect.x;
f = alloc_frame(&c->rect);
2006-01-12 18:06:50 +03:00
attach_frame_to_layout(l, f);
attach_frame(l, f);
2005-12-21 18:18:11 +03:00
attach_client_to_frame(f, c);
2006-01-12 18:06:50 +03:00
if(l->page == selpage)
2005-12-21 18:18:11 +03:00
XMapWindow(dpy, f->win);
focus_float(l, c, True);
2005-12-21 18:18:11 +03:00
return True;
2005-12-05 04:09:27 +03:00
}
2005-12-21 18:18:11 +03:00
static void
2006-01-12 18:06:50 +03:00
detach_float(Layout *l, Client * c, Bool unmap)
2005-12-05 04:09:27 +03:00
{
2005-12-21 18:18:11 +03:00
Frame *f = c->frame;
detach_client_from_frame(c, unmap);
if(!f->clients) {
2006-01-12 18:06:50 +03:00
detach_frame(l, f);
2005-12-21 18:18:11 +03:00
destroy_frame(f);
}
2005-12-05 04:09:27 +03:00
}
2005-12-21 18:18:11 +03:00
static void
resize_float(Frame * f, XRectangle * new, XPoint * pt)
2005-12-05 04:09:27 +03:00
{
2005-12-21 18:18:11 +03:00
f->rect = *new;
2005-12-05 04:09:27 +03:00
}
2005-12-21 18:18:11 +03:00
static void
focus_float(Layout *l, Client *c, Bool raise)
2005-12-11 01:43:45 +03:00
{
2006-01-12 18:06:50 +03:00
Float *fl = l->aux;
2006-01-18 16:42:44 +03:00
Client *old = sel_client();
2005-12-21 18:18:11 +03:00
2006-01-18 16:42:44 +03:00
c->frame->sel = c;
fl->sel = c->frame;
l->file[L_SEL_FRAME]->content = c->frame->file[F_PREFIX]->content;
2006-01-18 16:42:44 +03:00
2005-12-21 18:18:11 +03:00
if(raise) {
XRaiseWindow(dpy, c->frame->win);
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0,
c->rect.width / 2, c->rect.height / 2);
2005-12-21 18:18:11 +03:00
}
2006-01-18 16:42:44 +03:00
focus_client(c, old);
2005-12-11 01:43:45 +03:00
}
2005-12-21 18:18:11 +03:00
static Frame *
2006-01-12 18:06:50 +03:00
frames_float(Layout *l)
2005-12-11 01:43:45 +03:00
{
2006-01-12 18:06:50 +03:00
Float *fl = l->aux;
2005-12-21 18:18:11 +03:00
return fl->frames;
2005-12-11 01:43:45 +03:00
}
2005-12-21 18:18:11 +03:00
static void
select_frame(void *obj, char *arg)
{
2006-01-12 18:06:50 +03:00
Layout *l = obj;
Float *fl = l->aux;
2005-12-21 18:18:11 +03:00
Frame *f = fl->sel;
if(!f || !arg)
return;
if(!strncmp(arg, "prev", 5)) {
if(f->prev)
f = f->prev;
else
for(f = fl->frames; f && f->next; f = f->next);
} else if(!strncmp(arg, "next", 5)) {
if(f->next)
f = f->next;
else
f = fl->frames;
} else {
unsigned int i = 0, idx = blitz_strtonum(arg, 0, fl->nframes - 1);
for(f = fl->frames; f && i != idx; f = f->next)
i++;
}
if(f)
focus_float(l, f->sel, True);
2005-12-16 19:18:00 +03:00
}
static Client *
2006-01-12 18:06:50 +03:00
sel_float(Layout *l)
2005-12-21 18:18:11 +03:00
{
2006-01-12 18:06:50 +03:00
Float *fl = l->aux;
return fl->sel ? fl->sel->sel : nil;
}
2005-12-21 18:18:11 +03:00
static Action *
2006-01-12 18:06:50 +03:00
actions_float(Layout *l)
{
2005-12-21 18:18:11 +03:00
return lfloat_acttbl;
}