2006-10-12 18:10:57 +04:00
|
|
|
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
|
2006-03-08 15:00:10 +03:00
|
|
|
* See LICENSE file for license details.
|
|
|
|
*/
|
2006-10-20 12:07:55 +04:00
|
|
|
#include "wmii.h"
|
2006-04-12 12:44:07 +04:00
|
|
|
#include <stdlib.h>
|
2006-06-19 20:26:06 +04:00
|
|
|
#include <string.h>
|
2006-04-12 12:44:07 +04:00
|
|
|
|
|
|
|
Frame *
|
2006-10-12 18:10:57 +04:00
|
|
|
create_frame(Client *c, View *v) {
|
2006-04-12 12:44:07 +04:00
|
|
|
static unsigned short id = 1;
|
2006-10-12 18:10:57 +04:00
|
|
|
Frame *f = ixp_emallocz(sizeof(Frame));
|
2006-04-12 12:44:07 +04:00
|
|
|
|
|
|
|
f->id = id++;
|
|
|
|
f->client = c;
|
2006-06-25 17:16:03 +04:00
|
|
|
f->view = v;
|
2007-01-15 13:47:15 +03:00
|
|
|
if(c->sel) {
|
2006-06-26 06:18:00 +04:00
|
|
|
f->revert = c->sel->revert;
|
|
|
|
f->rect = c->sel->rect;
|
2006-07-03 20:41:14 +04:00
|
|
|
}
|
|
|
|
else{
|
2006-06-26 06:18:00 +04:00
|
|
|
f->revert = f->rect = c->rect;
|
|
|
|
f->revert.width = f->rect.width += 2 * def.border;
|
2006-10-12 18:12:22 +04:00
|
|
|
f->revert.height = f->rect.height += def.border + labelh(&def.font);
|
2006-06-26 06:18:00 +04:00
|
|
|
}
|
2006-06-12 14:11:22 +04:00
|
|
|
f->collapsed = False;
|
2006-06-22 13:03:42 +04:00
|
|
|
f->tile.blitz = &blz;
|
2006-06-22 17:25:59 +04:00
|
|
|
f->tile.drawable = pmap;
|
2006-06-22 13:03:42 +04:00
|
|
|
f->tile.gc = c->gc;
|
|
|
|
f->tile.font = &def.font;
|
|
|
|
f->tile.color = def.normcolor;
|
2006-12-21 16:37:41 +03:00
|
|
|
f->tile.border = False;
|
2006-07-10 11:13:09 +04:00
|
|
|
f->grabbox = f->titlebar = f->tile;
|
2006-06-22 13:03:42 +04:00
|
|
|
f->titlebar.align = WEST;
|
2006-06-22 14:42:27 +04:00
|
|
|
|
2006-04-12 12:44:07 +04:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
2006-06-08 12:54:19 +04:00
|
|
|
void
|
2006-10-12 18:10:57 +04:00
|
|
|
remove_frame(Frame *f) {
|
2007-02-05 04:57:28 +03:00
|
|
|
Area *a;
|
|
|
|
Frame **ft;
|
2006-06-10 03:57:00 +04:00
|
|
|
|
2007-02-05 04:57:28 +03:00
|
|
|
a = f->area;
|
|
|
|
for(ft = &a->frame; *ft; ft=&(*ft)->anext)
|
|
|
|
if(*ft == f) break;
|
2006-06-08 12:54:19 +04:00
|
|
|
*ft = f->anext;
|
2007-02-09 04:31:12 +03:00
|
|
|
|
|
|
|
if(a->floating) {
|
|
|
|
for(ft = &a->stack; *ft; ft=&(*ft)->snext)
|
|
|
|
if(*ft == f) break;
|
|
|
|
*ft = f->snext;
|
|
|
|
}
|
2006-06-08 12:54:19 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2006-10-12 18:10:57 +04:00
|
|
|
insert_frame(Frame *pos, Frame *f, Bool before) {
|
2007-02-09 04:31:12 +03:00
|
|
|
Frame *ft, **p;
|
2006-06-08 12:54:19 +04:00
|
|
|
Area *a = f->area;
|
2006-10-12 18:10:57 +04:00
|
|
|
|
2006-06-08 12:54:19 +04:00
|
|
|
if(before) {
|
2007-02-06 05:56:03 +03:00
|
|
|
for(ft=a->frame; ft; ft=ft->anext)
|
|
|
|
if(ft->anext == pos) break;
|
2006-06-08 12:54:19 +04:00
|
|
|
pos=ft;
|
|
|
|
}
|
2007-02-09 04:31:12 +03:00
|
|
|
p = &a->frame;
|
|
|
|
if(pos)
|
|
|
|
p = &pos->anext;
|
2006-06-08 12:54:19 +04:00
|
|
|
f->anext = *p;
|
|
|
|
*p = f;
|
2007-02-09 04:31:12 +03:00
|
|
|
|
|
|
|
if(a->floating) {
|
|
|
|
f->snext = a->stack;
|
|
|
|
a->stack = f;
|
|
|
|
}
|
2006-06-08 12:54:19 +04:00
|
|
|
}
|
|
|
|
|
2007-02-07 05:48:28 +03:00
|
|
|
void
|
|
|
|
resize_frame(Frame *f, XRectangle *r) {
|
|
|
|
BlitzAlign stickycorner = 0;
|
|
|
|
Client *c;
|
|
|
|
|
|
|
|
c = f->client;
|
|
|
|
|
|
|
|
if(f->rect.x != r->x && (f->rect.x + f->rect.width) == (r->x + r->width))
|
|
|
|
stickycorner |= EAST;
|
|
|
|
else
|
|
|
|
stickycorner |= WEST;
|
|
|
|
if(f->rect.y != r->y && (f->rect.y + f->rect.height) == (r->y + r->height))
|
|
|
|
stickycorner |= SOUTH;
|
|
|
|
else
|
|
|
|
stickycorner |= NORTH;
|
|
|
|
|
|
|
|
f->rect = *r;
|
|
|
|
if((f->area->mode != Colstack) || (f->area->sel == f))
|
|
|
|
match_sizehints(c, &f->rect, f->area->floating, stickycorner);
|
|
|
|
}
|
|
|
|
|
2007-02-09 08:07:22 +03:00
|
|
|
Bool
|
2007-02-08 07:23:18 +03:00
|
|
|
frame_to_top(Frame *f) {
|
|
|
|
Frame **tf;
|
|
|
|
Area *a;
|
|
|
|
|
|
|
|
a = f->area;
|
2007-02-09 08:07:22 +03:00
|
|
|
if(!a->floating || f == a->stack)
|
|
|
|
return False;
|
2007-02-09 04:31:12 +03:00
|
|
|
for(tf=&a->stack; *tf; tf=&(*tf)->snext)
|
2007-02-08 07:23:18 +03:00
|
|
|
if(*tf == f) break;
|
2007-02-09 04:31:12 +03:00
|
|
|
*tf = f->snext;
|
|
|
|
f->snext = a->stack;
|
|
|
|
a->stack = f;
|
2007-02-10 05:29:21 +03:00
|
|
|
update_client_grab(f->client);
|
2007-02-09 08:07:22 +03:00
|
|
|
return True;
|
2007-02-08 07:23:18 +03:00
|
|
|
}
|
|
|
|
|
2007-02-05 08:26:02 +03:00
|
|
|
void
|
|
|
|
swap_frames(Frame *fa, Frame *fb) {
|
|
|
|
XRectangle trect;
|
|
|
|
Area *a;
|
|
|
|
Frame **fp_a, **fp_b, *ft;
|
|
|
|
|
|
|
|
if(fa == fb) return;
|
2007-02-05 09:54:39 +03:00
|
|
|
|
2007-02-05 08:26:02 +03:00
|
|
|
a = fa->area;
|
2007-02-05 12:38:32 +03:00
|
|
|
for(fp_a = &a->frame; *fp_a; fp_a = &(*fp_a)->anext)
|
2007-02-05 08:26:02 +03:00
|
|
|
if(*fp_a == fa) break;
|
|
|
|
a = fb->area;
|
2007-02-05 12:38:32 +03:00
|
|
|
for(fp_b = &a->frame; *fp_b; fp_b = &(*fp_b)->anext)
|
2007-02-05 08:26:02 +03:00
|
|
|
if(*fp_b == fb) break;
|
|
|
|
|
2007-02-05 10:36:18 +03:00
|
|
|
if(fa->anext == fb) {
|
|
|
|
*fp_a = fb;
|
|
|
|
fa->anext = fb->anext;
|
|
|
|
fb->anext = fa;
|
|
|
|
} else if(fb->anext == fa) {
|
|
|
|
*fp_b = fa;
|
|
|
|
fb->anext = fa->anext;
|
|
|
|
fa->anext = fb;
|
|
|
|
} else {
|
|
|
|
*fp_a = fb;
|
|
|
|
*fp_b = fa;
|
|
|
|
ft = fb->anext;
|
|
|
|
fb->anext = fa->anext;
|
|
|
|
fa->anext = ft;
|
|
|
|
}
|
2007-02-05 08:26:02 +03:00
|
|
|
|
2007-02-05 13:07:26 +03:00
|
|
|
if(fb->area->sel == fb)
|
|
|
|
fb->area->sel = fa;
|
|
|
|
if(fa->area->sel == fa)
|
|
|
|
fa->area->sel = fb;
|
|
|
|
|
2007-02-05 08:26:02 +03:00
|
|
|
fb->area = fa->area;
|
|
|
|
fa->area = a;
|
|
|
|
|
|
|
|
trect = fa->rect;
|
|
|
|
fa->rect = fb->rect;
|
|
|
|
fb->rect = trect;
|
|
|
|
}
|
|
|
|
|
2006-06-19 20:26:06 +04:00
|
|
|
void
|
2006-10-12 18:10:57 +04:00
|
|
|
update_frame_widget_colors(Frame *f) {
|
2006-12-24 17:52:00 +03:00
|
|
|
if(f->area->sel == f) {
|
|
|
|
if(sel_screen && (f->client == sel_client()))
|
|
|
|
f->grabbox.color = f->tile.color = f->titlebar.color = def.focuscolor;
|
|
|
|
else
|
|
|
|
f->grabbox.color = f->tile.color = f->titlebar.color = def.selcolor;
|
|
|
|
}
|
2006-06-19 20:26:06 +04:00
|
|
|
else
|
2006-12-24 17:52:00 +03:00
|
|
|
f->grabbox.color = f->tile.color = f->titlebar.color = def.normcolor;
|
2006-06-19 20:26:06 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2006-10-12 18:10:57 +04:00
|
|
|
draw_frame(Frame *f) {
|
2006-06-19 20:26:06 +04:00
|
|
|
if(def.border) {
|
2007-02-09 09:01:54 +03:00
|
|
|
f->tile.border = def.border;
|
2006-06-22 13:03:42 +04:00
|
|
|
f->tile.rect = f->rect;
|
|
|
|
f->tile.rect.x = f->tile.rect.y = 0;
|
2007-02-09 21:21:07 +03:00
|
|
|
draw_border(&f->tile);
|
2006-06-19 20:26:06 +04:00
|
|
|
}
|
2006-07-10 11:13:09 +04:00
|
|
|
f->grabbox.rect = f->tile.rect;
|
2006-10-12 18:12:22 +04:00
|
|
|
f->grabbox.rect.height = labelh(&def.font);
|
2006-07-11 10:42:15 +04:00
|
|
|
f->grabbox.rect.width = def.font.height;
|
2006-07-10 11:13:09 +04:00
|
|
|
f->titlebar.rect = f->grabbox.rect;
|
|
|
|
f->titlebar.rect.x = f->grabbox.rect.x + f->grabbox.rect.width;
|
2006-09-27 09:56:40 +04:00
|
|
|
f->titlebar.rect.width = f->rect.width - f->titlebar.rect.x;
|
2007-02-09 21:21:07 +03:00
|
|
|
f->titlebar.border = 0;
|
2006-10-12 18:12:22 +04:00
|
|
|
draw_tile(&f->tile);
|
2007-02-10 19:53:27 +03:00
|
|
|
f->grabbox.border = 3;
|
2006-10-12 18:12:22 +04:00
|
|
|
draw_tile(&f->grabbox);
|
|
|
|
draw_label(&f->titlebar, f->client->name);
|
2007-02-09 09:13:02 +03:00
|
|
|
/* XXX: Hack */
|
2007-02-09 21:21:07 +03:00
|
|
|
f->titlebar.rect.x = 0;
|
|
|
|
f->titlebar.rect.width += f->grabbox.rect.width;
|
|
|
|
f->titlebar.border = 1;
|
|
|
|
draw_border(&f->titlebar);
|
2006-07-03 20:41:14 +04:00
|
|
|
XCopyArea(blz.dpy, pmap, f->client->framewin, f->client->gc,
|
2006-06-29 13:53:45 +04:00
|
|
|
0, 0, f->rect.width, f->rect.height, 0, 0);
|
2006-07-03 20:41:14 +04:00
|
|
|
XSync(blz.dpy, False);
|
2006-06-19 20:26:06 +04:00
|
|
|
}
|
2006-06-20 16:32:19 +04:00
|
|
|
|
|
|
|
void
|
2006-10-12 18:10:57 +04:00
|
|
|
draw_frames() {
|
2006-06-20 16:32:19 +04:00
|
|
|
Client *c;
|
2006-10-12 18:10:57 +04:00
|
|
|
|
2006-06-20 16:32:19 +04:00
|
|
|
for(c=client; c; c=c->next)
|
2006-06-30 10:02:44 +04:00
|
|
|
if(c->sel && c->sel->view == screen->sel) {
|
2006-06-20 16:32:19 +04:00
|
|
|
update_frame_widget_colors(c->sel);
|
|
|
|
draw_frame(c->sel);
|
|
|
|
}
|
|
|
|
}
|
2007-02-03 22:27:32 +03:00
|
|
|
|
|
|
|
void
|
|
|
|
check_frame_constraints(XRectangle *rect) {
|
|
|
|
int max_height;
|
2007-02-05 12:38:32 +03:00
|
|
|
int barheight;
|
|
|
|
|
|
|
|
barheight = screen->brect.height;
|
|
|
|
max_height = screen->rect.height - barheight;
|
2007-02-03 22:27:32 +03:00
|
|
|
|
|
|
|
if(rect->height > max_height)
|
|
|
|
rect->height = max_height;
|
|
|
|
if(rect->width > screen->rect.width)
|
|
|
|
rect->width = screen->rect.width;
|
2007-02-05 12:38:32 +03:00
|
|
|
if(rect->x + barheight > screen->rect.width)
|
|
|
|
rect->x = screen->rect.width - barheight;
|
|
|
|
if(rect->y + barheight > max_height)
|
|
|
|
rect->y = max_height - barheight;
|
|
|
|
if(rect->x + rect->width < barheight)
|
|
|
|
rect->x = barheight - rect->width;
|
|
|
|
if(rect->y + rect->height < barheight)
|
|
|
|
rect->y = barheight - rect->height;
|
2007-02-03 22:27:32 +03:00
|
|
|
}
|