Commit Diff


commit - a2db69c8bda889f30ea38dae5473689cde108458
commit + 41636940514d72e2a941f55f28dc07685e74b3b4
blob - be5a2aa8a1ce65166506c78fab36ddf3188e4a46
blob + 424358e79e8b6f22501fee6230971307745ebc60
--- src/cmd/acme/cols.c
+++ src/cmd/acme/cols.c
@@ -53,7 +53,7 @@ coladd(Column *c, Window *w, Window *clone, int y)
 {
 	Rectangle r, r1;
 	Window *v;
-	int i, j, minht, ymax;
+	int i, j, minht, ymax, buggered;
 
 	v = nil;
 	r = c->r;
@@ -68,6 +68,7 @@ coladd(Column *c, Window *w, Window *clone, int y)
 		if(y < v->r.max.y)
 			break;
 	}
+	buggered = 0;
 	if(c->nw > 0){
 		if(i < c->nw)
 			i++;	/* new window will go after v */
@@ -78,7 +79,7 @@ coladd(Column *c, Window *w, Window *clone, int y)
 		j = 0;
 		while(!c->safe || v->body.fr.maxlines<=3 || Dy(v->body.all) <= minht){
 			if(++j > 10){
-				fprint(2, "coladd: bug dy=%d\n", Dy(v->body.all));
+				buggered = 1;	/* too many windows in column */
 				break;
 			}
 			colgrow(c, v, 1);
@@ -87,20 +88,28 @@ coladd(Column *c, Window *w, Window *clone, int y)
 		/*
 		 * figure out where to split v to make room for w
 		 */
-		if(i == c->nw)
-			ymax = c->r.max.y;
-		else
+		
+		/* new window stops where next window begins */
+		if(i < c->nw)
 			ymax = c->w[i]->r.min.y-Border;
-		y = min(y, v->body.all.min.y+Dy(v->body.all)/2);
+		else
+			ymax = c->r.max.y;
+		
+		/* new window must start after v's tag ends */
+		y = max(y, v->tagtop.max.y+Border);
+		
+		/* new window must start early enough to end before ymax */
 		y = min(y, ymax - minht);
-		y = max(y, v->body.all.min.y);
-		ymax = max(ymax, y+minht);
-		r = v->r;
-		r.max.y = ymax;
+		
+		/* if y is too small, too many windows in column */
+		if(y < v->tagtop.max.y+Border)
+			buggered = 1;
 
 		/*
-		 * redraw w
+		 * resize & redraw v
 		 */
+		r = v->r;
+		r.max.y = ymax;
 		draw(screen, r, textcols[BACK], nil, ZP);
 		r1 = r;
 		y = min(y, ymax-(v->tag.fr.font->height*v->taglines+v->body.fr.font->height+Border+1));
@@ -108,6 +117,10 @@ coladd(Column *c, Window *w, Window *clone, int y)
 		r1.min.y = winresize(v, r1, FALSE, FALSE);
 		r1.max.y = r1.min.y+Border;
 		draw(screen, r1, display->black, nil, ZP);
+		
+		/*
+		 * leave r with w's coordinates
+		 */
 		r.min.y = r1.max.y;
 	}
 	if(w == nil){
@@ -127,11 +140,16 @@ coladd(Column *c, Window *w, Window *clone, int y)
 	memmove(c->w+i+1, c->w+i, (c->nw-i)*sizeof(Window*));
 	c->nw++;
 	c->w[i] = w;
+	c->safe = TRUE;
+	
+	/* if there were too many windows, redraw the whole column */
+	if(buggered)
+		colresize(c, c->r);
+
 	savemouse(w);
-	/* near but not on the button */
+	/* near the button, but in the body */
 	moveto(mousectl, addpt(w->tag.scrollr.max, Pt(3, 3)));
 	barttext = &w->body;
-	c->safe = TRUE;
 	return w;
 }
 
@@ -406,7 +424,7 @@ colgrow(Column *c, Window *w, int but)
 	if(Dy(r) < Dy(w->tagtop)+1+h+Border)
 		r.max.y = r.min.y + Dy(w->tagtop)+1+h+Border;
 	/* draw window */
-	r.max.y = winresize(w, r, c->safe, i==c->nw-1);
+	r.max.y = winresize(w, r, c->safe, TRUE);
 	if(i < c->nw-1){
 		r.min.y = r.max.y;
 		r.max.y += Border;
blob - afd21afc78962ad7cf215cf50dccd3a0dbfb5994
blob + 70a4edecff46f4c37bfa12b6e0fc869dca870f3a
--- src/cmd/acme/wind.c
+++ src/cmd/acme/wind.c
@@ -142,9 +142,12 @@ wintaglines(Window *w, Rectangle r)
 int
 winresize(Window *w, Rectangle r, int safe, int keepextra)
 {
-	int oy, y, mouseintag, tagresized;
+	int oy, y, mouseintag, mouseinbody, tagresized;
 	Point p;
 	Rectangle r1;
+
+	mouseintag = ptinrect(mouse->xy, w->tag.all);
+	mouseinbody = ptinrect(mouse->xy, w->body.all);
 
 	/* tagtop is first line of tag */
 	w->tagtop = r;
@@ -152,7 +155,6 @@ winresize(Window *w, Rectangle r, int safe, int keepex
 
 	r1 = r;
 	r1.max.y = min(r.max.y, r1.min.y + w->taglines*font->height);
-	mouseintag = ptinrect(mouse->xy, w->tag.all);
 
 	/* If needed, recompute number of lines in tag. */
 	if(!safe || !w->tagsafe || !eqrect(w->tag.all, r1)){
@@ -178,7 +180,7 @@ winresize(Window *w, Rectangle r, int safe, int keepex
 		}
 
 		/* If mouse is in body, push down as tag expands. */
-		if(!mouseintag && ptinrect(mouse->xy, w->tag.all)){
+		if(mouseinbody && ptinrect(mouse->xy, w->tag.all)){
 			p = mouse->xy;
 			p.y = w->tag.all.max.y+3;
 			moveto(mousectl, p);