wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

commit 38efe73427143571c65f6a6081cac0830498af10
parent 878d02cf53b66f981eb6e46129bce847c096f604
Author: Kris Maglione <jg@suckless.org>
Date:   Wed, 15 Oct 2008 21:16:14 -0400

More Xinerama work

Diffstat:
cmd/menu/menu.c | 5+++--
cmd/wmii/area.c | 14++++++--------
cmd/wmii/bar.c | 12++++++------
cmd/wmii/column.c | 10+++++-----
cmd/wmii/dat.h | 3++-
cmd/wmii/div.c | 8+++++---
cmd/wmii/ewmh.c | 13++++++-------
cmd/wmii/float.c | 1-
cmd/wmii/fns.h | 4++--
cmd/wmii/layout.c | 50+++++++++++++++++++++++++++++++-------------------
cmd/wmii/main.c | 5++++-
cmd/wmii/message.c | 5+++--
cmd/wmii/mouse.c | 8++++----
cmd/wmii/view.c | 149+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
14 files changed, 174 insertions(+), 113 deletions(-)

diff --git a/cmd/menu/menu.c b/cmd/menu/menu.c @@ -224,6 +224,7 @@ menu_show(void) { raisewin(barwin); menu_draw(); if(!grabkeyboard(barwin)) { + exit(1); srv.running = false; result = 1; } @@ -246,8 +247,8 @@ kdown_event(Window *w, XKeyEvent *e) { if(IsFunctionKey(ksym) || IsMiscFunctionKey(ksym) || IsKeypadKey(ksym) - || IsPrivateKeypadKey(ksym)) - || IsPFKey(ksym) + || IsPrivateKeypadKey(ksym) + || IsPFKey(ksym)) return; if(e->state & ControlMask) { diff --git a/cmd/wmii/area.c b/cmd/wmii/area.c @@ -60,7 +60,7 @@ area_create(View *v, Area *pos, int scrn, uint width) { SET(i); if(v->areas) { /* Creating a column. */ - minwidth = Dx(v->r)/NCOL; + minwidth = Dx(v->r[scrn])/NCOL; i = pos ? area_idx(pos) : 1; numcols = 0; for(a=v->areas[scrn]; a; a=a->next) @@ -72,18 +72,18 @@ area_create(View *v, Area *pos, int scrn, uint width) { if(numcols >= 0) { width = view_newcolwidth(v, i); if (width == 0) - width = Dx(v->r) / (numcols + 1); + width = Dx(v->r[scrn]) / (numcols + 1); } else - width = Dx(v->r); + width = Dx(v->r[scrn]); } if(width < minwidth) width = minwidth; - if(numcols && (numcols * minwidth + width) > Dx(v->r)) + if(numcols && (numcols * minwidth + width) > Dx(v->r[scrn])) return nil; - view_scale(v, Dx(v->r) - width); + view_scale(v, Dx(v->r[scrn]) - width); } a = emallocz(sizeof *a); @@ -97,7 +97,7 @@ area_create(View *v, Area *pos, int scrn, uint width) { a->frame = nil; a->sel = nil; - a->r = v->r; + a->r = v->r[scrn]; a->r.min.x = 0; a->r.max.x = width; @@ -122,8 +122,6 @@ area_create(View *v, Area *pos, int scrn, uint width) { if(v->sel == nil && !a->floating) area_focus(a); - print("%s: screen: %d a: %p mode: %x floating: %d v->floating: %p v->areas: %p\n", v->name, a->screen, a, a->mode, a->floating, v->floating, v->areas); - if(!a->floating) event("CreateColumn %ud\n", i); return a; diff --git a/cmd/wmii/bar.c b/cmd/wmii/bar.c @@ -52,26 +52,26 @@ bar_resize(WMScreen *s) { } void -bar_setbounds(int left, int right) { +bar_setbounds(WMScreen *s, int left, int right) { Rectangle *r; - r = &screen->brect; + r = &s->brect; r->min.x = left; r->max.x = right; - reshapewin(screen->barwin, *r); + reshapewin(s->barwin, *r); } void -bar_sety(int y) { +bar_sety(WMScreen *s, int y) { Rectangle *r; int dy; - r = &screen->brect; + r = &s->brect; dy = Dy(*r); r->min.y = y; r->max.y = y + dy; - reshapewin(screen->barwin, *r); + reshapewin(s->barwin, *r); } Bar* diff --git a/cmd/wmii/column.c b/cmd/wmii/column.c @@ -312,7 +312,7 @@ column_fit(Area *a, uint *ncolp, uint *nuncolp) { } /* FIXME: Kludge. */ - dy = Dy(a->view->r) - Dy(a->r); + dy = Dy(a->view->r[a->screen]) - Dy(a->r); minh = colh * (ncol + nuncol - 1) + uncolh; if(dy && Dy(a->r) < minh) a->r.max.y += min(dy, minh - Dy(a->r)); @@ -554,7 +554,7 @@ column_arrange(Area *a, bool dirty) { f->collapsed = (f != a->sel); break; default: - print("Dieing: %s: screen: %d a: %p mode: %x floating: %d\n", v->name, a->screen, a, a->mode, a->floating); + fprint(2, "Dieing: %s: screen: %d a: %p mode: %x floating: %d\n", v->name, a->screen, a, a->mode, a->floating); die("not reached"); break; } @@ -630,7 +630,7 @@ column_resizeframe(Frame *f, Rectangle r) { a = f->area; v = a->view; - minw = Dx(v->r) / NCOL; + minw = Dx(v->r[a->screen]) / NCOL; ar = a->next; al = a->prev; @@ -640,14 +640,14 @@ column_resizeframe(Frame *f, Rectangle r) { if(al) r.min.x = max(r.min.x, al->r.min.x + minw); else { /* Hm... */ - r.min.x = max(r.min.x, v->r.min.x); + r.min.x = max(r.min.x, v->r[a->screen].min.x); r.max.x = max(r.max.x, r.min.x + minw); } if(ar) r.max.x = min(r.max.x, ar->r.max.x - minw); else { - r.max.x = min(r.max.x, v->r.max.x); + r.max.x = min(r.max.x, v->r[a->screen].max.x); r.min.x = min(r.min.x, r.max.x - minw); } diff --git a/cmd/wmii/dat.h b/cmd/wmii/dat.h @@ -261,6 +261,7 @@ struct Strut { }; #define firstarea areas[screen->idx] +#define screenr r[screen->idx] struct View { View* next; char name[256]; @@ -272,7 +273,7 @@ struct View { Area* revert; int selcol; bool dead; - Rectangle r; + Rectangle *r; }; /* Yuck. */ diff --git a/cmd/wmii/div.c b/cmd/wmii/div.c @@ -53,8 +53,9 @@ div_set(Divide *d, int x) { d->x = x; r = rectaddpt(divimg->r, Pt(x - Dx(divimg->r)/2, 0)); - r.min.y = screen->sel->r.min.y; - r.max.y = screen->sel->r.max.y; + /* XXX: Multihead. */ + r.min.y = screen->sel->screenr.min.y; + r.max.y = screen->sel->screenr.max.y; reshapewin(d->w, r); mapdiv(d); @@ -90,7 +91,8 @@ update_imgs(void) { w = 2 * (labelh(def.font) / 3); w = max(w, 10); - h = Dy(screen->sel->r); + /* XXX: Multihead. */ + h = Dy(screen->sel->screenr); if(divimg) { if(w == Dx(divimg->r) && h == Dy(divimg->r) diff --git a/cmd/wmii/ewmh.c b/cmd/wmii/ewmh.c @@ -460,20 +460,19 @@ ewmh_updatestate(Client *c) { void ewmh_updateviews(void) { View *v; - char **tags; + Vector_ptr tags; long i; if(starting) return; + vector_pinit(&tags); for(v=view, i=0; v; v=v->next) - i++; - tags = emalloc((i + 1) * sizeof *tags); - for(v=view, i=0; v; v=v->next) - tags[i++] = v->name; - tags[i] = nil; - changeprop_textlist(&scr.root, Net("DESKTOP_NAMES"), "UTF8_STRING", tags); + vector_ppush(&tags, v->name); + vector_ppush(&tags, nil); + changeprop_textlist(&scr.root, Net("DESKTOP_NAMES"), "UTF8_STRING", (char**)tags.ary); changeprop_long(&scr.root, Net("NUMBER_OF_DESKTOPS"), "CARDINAL", &i, 1); + vector_pfree(&tags); ewmh_updateview(); ewmh_updateclients(); } diff --git a/cmd/wmii/float.c b/cmd/wmii/float.c @@ -75,7 +75,6 @@ float_arrange(Area *a) { f->collapsed = (f != a->sel); break; default: - print("colmode: %x\n", a->mode); die("not reached"); break; } diff --git a/cmd/wmii/fns.h b/cmd/wmii/fns.h @@ -51,8 +51,8 @@ void bar_draw(WMScreen*); Bar* bar_find(Bar*, const char*); void bar_init(WMScreen*); void bar_resize(WMScreen*); -void bar_sety(int); -void bar_setbounds(int, int); +void bar_sety(WMScreen*, int); +void bar_setbounds(WMScreen*, int, int); /* client.c */ int Cfmt(Fmt *f); diff --git a/cmd/wmii/layout.c b/cmd/wmii/layout.c @@ -117,6 +117,24 @@ static Handlers handlers = { .expose = expose_event, }; +static Area* +find_area(Point pt) { + View *v; + Area *a; + int s; + + v = screen->sel; + /* XXX: Multihead. Check this over. */ + for(s=0; s < nscreens; s++) { + if(!rect_haspoint_p(pt, screen[s].r)) + continue; + for(a=v->areas[s]; a; a=a->next) + if(pt.x < a->r.max.x) + return a; + } + return nil; /* XXX: Multihead. */ +} + static void vplace(Framewin *fw, Point pt) { Vector_long vec = {0}; @@ -125,20 +143,14 @@ vplace(Framewin *fw, Point pt) { Area *a; View *v; long l; - int hr, s; + int hr; v = screen->sel; - /* XXX: Multihead. Check this over. */ - for(s=0; s < nscreens; s++) { - if(!rect_haspoint_p(pt, screen[s].r)) - continue; - for(a=v->areas[s]; a; a=a->next) - if(pt.x < a->r.max.x) - goto found; - } - return; /* XXX: Multihead. */ -found: + a = find_area(pt); + if(a == nil) + return; /* XXX: Multihead. */ + fw->ra = a; pt.x = a->r.min.x; @@ -182,17 +194,16 @@ static void hplace(Framewin *fw, Point pt) { Area *a; View *v; - int minw, s; + int minw; v = screen->sel; - minw = Dx(v->r)/NCOL; - /* XXX: Multihead. Check this over. */ - foreach_column(v, s, a) - if(pt.x < a->r.max.x) - break; + a = find_area(pt); + if(a == nil) + return; /* XXX: Multihead. */ fw->ra = nil; + minw = Dx(v->r[a->screen])/NCOL; if(abs(pt.x - a->r.min.x) < minw/2) { pt.x = a->r.min.x; fw->ra = a->prev; @@ -473,9 +484,10 @@ tvcol(Frame *f) { pt = querypointer(&scr.root); pt2.x = pt.x; pt2.y = f->area->r.min.y; - fw = framewin(f, pt2, OVert, Dy(f->view->r)); - r = f->view->r; + r = f->view->r[f->area->screen]; + fw = framewin(f, pt2, OVert, Dy(r)); + r.min.y += fw->grabbox.min.y + Dy(fw->grabbox)/2; r.max.y = r.min.y + 1; cwin = createwindow(&scr.root, r, 0, InputOnly, &wa, 0); diff --git a/cmd/wmii/main.c b/cmd/wmii/main.c @@ -171,8 +171,11 @@ init_screens(void) { rects = xinerama_screens(&n); m = max(n, nscreens); screens = erealloc(screens, m * sizeof *screens); - for(v=view; v; v=v->next) + for(v=view; v; v=v->next) { v->areas = erealloc(v->areas, m * sizeof *v->areas); + v->r = erealloc(v->r, m * sizeof *v->r); + } + for(i=nscreens; i < m; i++) { screens[i] = (WMScreen){0}; for(v=view; v; v=v->next) diff --git a/cmd/wmii/message.c b/cmd/wmii/message.c @@ -363,7 +363,7 @@ getframe(View *v, IxpMsg *m) { a = strarea(v, s); if(a == nil) { - print("a == nil\n"); + fprint(2, "a == nil\n"); return nil; } @@ -469,7 +469,8 @@ message_root(void *p, IxpMsg *m) { if(fn) { freefont(def.font); def.font = fn; - bar_resize(screen); + for(n=0; n < nscreens; n++) + bar_resize(&screens[n]); }else ret = "can't load font"; view_update(screen->sel); diff --git a/cmd/wmii/mouse.c b/cmd/wmii/mouse.c @@ -224,7 +224,7 @@ mouse_resizecolframe(Frame *f, Align align) { if(align&East) d = d->next; - min.x = Dx(v->r)/NCOL; + min.x = Dx(v->r[a->screen])/NCOL; min.y = /*frame_delta_h() +*/ labelh(def.font); /* This would be so simple in lisp... */ /* This must be evil. But, I hate to repeat myself. */ @@ -329,7 +329,7 @@ mouse_resizecol(Divide *d) { pt = querypointer(&scr.root); - minw = Dx(v->r)/NCOL; + minw = Dx(v->r[a->screen])/NCOL; r.min.x = a->r.min.x + minw; r.max.x = a->next->r.max.x - minw; r.min.y = pt.y; @@ -445,8 +445,8 @@ mouse_resize(Client *c, Align align, bool grabmod) { pt = addpt(c->framewin->r.min, Pt(Dx(frect) * rx, Dy(frect) * ry)); - if(pt.y > f->view->r.max.y) - pt.y = f->view->r.max.y - 1; + if(pt.y > f->view->r[f->area->screen].max.y) + pt.y = f->view->r[f->area->screen].max.y - 1; warppointer(pt); free(rects); diff --git a/cmd/wmii/view.c b/cmd/wmii/view.c @@ -73,14 +73,14 @@ view_create(const char *name) { v = emallocz(sizeof *v); v->id = id++; - v->r = screen->r; + v->r = emallocz(nscreens * sizeof *v->r); + v->areas = emallocz(nscreens * sizeof *v->areas); utflcpy(v->name, name, sizeof v->name); event("CreateTag %s\n", v->name); area_create(v, nil, screen->idx, 0); - v->areas = emallocz(nscreens * sizeof *v->areas); for(i=0; i < nscreens; i++) view_init(v, i); @@ -147,6 +147,8 @@ view_destroy(View *v) { if(tv) view_focus(screen, tv); } + free(v->areas); + free(v->r); free(v); ewmh_updateviews(); } @@ -171,12 +173,45 @@ frames_update_sel(View *v) { f->client->sel = f; } +/* Don't let increment hints take up more than half + * of the screen, in either direction. + */ +static Rectangle +fix_rect(Rectangle old, Rectangle new) { + double r; + + new = rect_intersection(new, old); + + r = (Dy(old) - Dy(new)) / Dy(old); + if(r > .5) { + r -= .5; + new.min.y -= r * (new.min.y - old.min.y); + new.max.y += r * (old.max.y - new.max.y); + } + r = (Dx(old) - Dx(new)) / Dx(old); + if(r > .5) { + r -= .5; + new.min.x -= r * (new.min.x - old.min.x); + new.max.x += r * (old.max.x - new.max.x); + } + return new; +} + void view_update_rect(View *v) { - Rectangle r, sr, brect; + Rectangle r, sr, brect, scrnr; + WMScreen *scrn; Strut *strut; Frame *f; int left, right, top, bottom; + int s; + + /* XXX: + * Incidentally, really need to move screen->sel elsewhere. + if(v != screen->sel) + return false; + */ + top = 0; left = 0; @@ -192,37 +227,47 @@ view_update_rect(View *v) { right = min(right, strut->right.min.x); bottom = min(bottom, strut->bottom.min.y); } - r = screen->r; - r.min.y += min(top, .3 * Dy(screen->r)); - r.min.x += min(left, .3 * Dx(screen->r)); - r.max.x += max(right, -.3 * Dx(screen->r)); - r.max.y += max(bottom, -.3 * Dy(screen->r)); - if(screen->barpos == BTop) { - bar_sety(r.min.y); - r.min.y += Dy(screen->brect); - }else { - r.max.y -= Dy(screen->brect); - bar_sety(r.max.y); - } - v->floating->r = r; - v->r = r; + scrnr = scr.rect; + scrnr.min.y += top; + scrnr.min.x += left; + scrnr.max.x += right; + scrnr.max.y += bottom; + + /* FIXME: Multihead. */ + v->floating->r = scr.rect; + + for(s=0; s < nscreens; s++) { + scrn = &screens[s]; + r = fix_rect(scrn->r, scrnr); + + if(scrn->barpos == BTop) { + bar_sety(scrn, r.min.y); + r.min.y += Dy(scrn->brect); + }else { + r.max.y -= Dy(scrn->brect); + bar_sety(scrn, r.max.y); + } - brect = screen->brect; - brect.min.x = screen->r.min.x; - brect.max.x = screen->r.max.x; - for(f=v->floating->frame; f; f=f->anext) { - /* This is not pretty. :( */ - strut = f->client->strut; - if(!strut) - continue; - sr = strut->left; - if(rect_intersect_p(brect, sr)) - brect.min.x = sr.max.x; - sr = rectaddpt(strut->right, Pt(screen->r.max.x, 0)); - if(rect_intersect_p(brect, sr)) - brect.max.x = sr.min.x; + v->r[s] = r; + + brect = scrn->brect; + brect.min.x = r.min.x; + brect.max.x = r.max.x; + for(f=v->floating->frame; f; f=f->anext) { + /* This is not pretty. :( */ + strut = f->client->strut; + if(!strut) + continue; + sr = strut->left; + if(rect_intersect_p(brect, sr)) + brect.min.x = sr.max.x; + sr = rectaddpt(strut->right, Pt(scr.rect.max.x, 0)); + if(rect_intersect_p(brect, sr)) + brect.max.x = sr.min.x; + } + + bar_setbounds(scrn, brect.min.x, brect.max.x); } - bar_setbounds(brect.min.x, brect.max.x); } void @@ -428,6 +473,7 @@ view_restack(View *v) { XRestackWindows(display, (ulong*)wins.ary, wins.n); } +/* XXX: Multihead. */ void view_scale(View *v, int w) { uint xoff, numcol; @@ -436,7 +482,7 @@ view_scale(View *v, int w) { float scale; int dx; - minwidth = Dx(v->r)/NCOL; + minwidth = Dx(v->screenr)/NCOL; /* XXX: Multihead. */ if(!v->firstarea) return; @@ -449,30 +495,31 @@ view_scale(View *v, int w) { } scale = (float)w / dx; - xoff = v->r.min.x; + xoff = v->screenr.min.x; /* XXX: Multihead. */ for(a=v->firstarea; a; a=a->next) { a->r.max.x = xoff + Dx(a->r) * scale; a->r.min.x = xoff; if(!a->next) - a->r.max.x = v->r.min.x + w; + a->r.max.x = v->screenr.min.x + w; /* XXX: Multihead. */ xoff = a->r.max.x; } if(numcol * minwidth > w) return; - xoff = v->r.min.x; + xoff = v->screenr.min.x; /* XXX: Multihead. */ for(a=v->firstarea; a; a=a->next) { a->r.min.x = xoff; if(Dx(a->r) < minwidth) a->r.max.x = xoff + minwidth; if(!a->next) - a->r.max.x = v->r.min.x + w; + a->r.max.x = v->screenr.min.x + w; /* XXX: Multihead. */ xoff = a->r.max.x; } } +/* XXX: Multihead. */ void view_arrange(View *v) { Area *a; @@ -481,11 +528,11 @@ view_arrange(View *v) { return; view_update_rect(v); - view_scale(v, Dx(v->r)); + view_scale(v, Dx(v->screenr)); for(a=v->firstarea; a; a=a->next) { /* This is wrong... */ - a->r.min.y = v->r.min.y; - a->r.max.y = v->r.max.y; + a->r.min.y = v->screenr.min.y; + a->r.max.y = v->screenr.max.y; /* print("a->r: %R %R %R\n", a->r, v->r, screen->r); */ column_arrange(a, false); } @@ -495,24 +542,22 @@ view_arrange(View *v) { Rectangle* view_rects(View *v, uint *num, Frame *ignore) { - Rectangle *result; + Vector_rect result; Frame *f; int i; - i = 2; - for(f=v->floating->frame; f; f=f->anext) - i++; - result = emallocz(i * sizeof *result); + vector_rinit(&result); - i = 0; for(f=v->floating->frame; f; f=f->anext) if(f != ignore) - result[i++] = f->r; - result[i++] = screen->r; - result[i++] = screen->brect; + vector_rpush(&result, f->r); + for(i=0; i < nscreens; i++) { + vector_rpush(&result, v->r[i]); + vector_rpush(&result, screens[i].r); + } - *num = i; - return result; + *num = result.n; + return result.ary; } void @@ -545,7 +590,7 @@ view_newcolwidth(View *v, int num) { n = tokenize(toks, 16, buf, '+'); if(num < n) if(getulong(toks[num], &n)) - return Dx(v->r) * (n / 100.0); + return Dx(v->screenr) * (n / 100.0); /* XXX: Multihead. */ break; } return 0;