More Xinerama work

This commit is contained in:
Kris Maglione 2008-10-15 21:16:14 -04:00
parent 878d02cf53
commit 38efe73427
14 changed files with 174 additions and 113 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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*

View File

@ -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);
}

View File

@ -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. */

View File

@ -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)

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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;
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;
/* 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);
}
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;