void float_detach(Frame *f) { Frame *pr; Area *a, *sel, *oldsel; View *v; v = f->view; a = f->area; sel = view_findarea(v, v->selscreen, v->selcol, false); oldsel = v->oldsel; pr = f->aprev; frame_remove(f); if(a->sel == f) { while(pr && pr->client->nofocus) pr = pr->aprev; if(!pr) for(pr=a->frame; pr && pr->anext; pr=pr->anext) if(!pr->client->nofocus) break; a->sel = nil; area_setsel(a, pr); } f->area = nil; if(oldsel) area_focus(oldsel); else if(!a->frame || pr && pr->client->nofocus) if(sel && sel->frame) area_focus(sel); }
void area_destroy(Area *a) { Area *newfocus; View *v; int idx; v = a->view; if(a->frame) die("destroying non-empty area"); if(v->revert == a) v->revert = nil; if(v->oldsel == a) v->oldsel = nil; idx = area_idx(a); if(a->prev && !a->prev->floating) newfocus = a->prev; else newfocus = a->next; /* Can only destroy the floating area when destroying a * view---after destroying all columns. */ assert(!a->floating || !v->areas[0]); if(a->prev) a->prev->next = a->next; else if(!a->floating) v->areas[a->screen] = a->next; else v->floating = nil; if(a->next) a->next->prev = a->prev; if(newfocus && v->sel == a) area_focus(newfocus); view_arrange(v); event("DestroyArea %d\n", idx); free(a); }
Area* area_create(View *v, Area *pos, int scrn, uint width) { static ushort id = 1; int i, j; uint minwidth, index; int numcols; Area *a; assert(!pos || pos->screen == scrn); SET(index); if(v->areas) { /* Creating a column. */ minwidth = column_minwidth(); index = pos ? area_idx(pos) : 1; numcols = 0; for(a=v->areas[scrn]; a; a=a->next) numcols++; /* TODO: Need a better sizing/placing algorithm. */ if(width == 0) { if(numcols >= 0) { width = view_newcolwidth(v, index); if (width == 0) width = Dx(v->r[scrn]) / (numcols + 1); } else width = Dx(v->r[scrn]); } if(width < minwidth) width = minwidth; minwidth = numcols * minwidth + minwidth; if(minwidth > Dx(v->r[scrn])) return nil; i = minwidth - Dx(v->pad[scrn]) - Dx(v->r[scrn]); if(i > 0 && Dx(v->pad[scrn])) { j = min(i/2, v->pad[scrn].min.x); v->pad[scrn].min.x -= j; v->pad[scrn].max.x += i - j; } view_scale(v, scrn, Dx(v->r[scrn]) - width); } a = emallocz(sizeof *a); a->view = v; a->screen = scrn; a->id = id++; a->floating = !v->floating; if(a->floating) a->mode = Coldefault; else a->mode = def.colmode; a->frame = nil; a->sel = nil; a->r = v->r[scrn]; a->r.min.x = 0; a->r.max.x = width; if(a->floating) { v->floating = a; a->screen = -1; } else if(pos) { a->next = pos->next; a->prev = pos; } else { a->next = v->areas[scrn]; v->areas[scrn] = a; } if(a->prev) a->prev->next = a; if(a->next) a->next->prev = a; if(v->sel == nil && !a->floating) area_focus(a); if(!a->floating) event("CreateColumn %ud\n", index); return a; }