From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=0.2 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED autolearn=no autolearn_force=no version=3.4.4 Received: (qmail 23528 invoked from network); 4 Jan 2022 23:31:40 -0000 Received: from 4ess.inri.net (216.126.196.42) by inbox.vuxu.org with ESMTPUTF8; 4 Jan 2022 23:31:40 -0000 Received: from mail.9lab.org ([168.119.8.41]) by 4ess; Tue Jan 4 18:27:00 -0500 2022 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=9lab.org; s=20210803; t=1641336426; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type; bh=/ll63X6h3pknQ+SB26ayGHNV6H+RDomoGenRUbOcgeU=; b=rTQ8StcJPtQKkd05HOM2Z9X5AReyF4oKqsOCSSzXXLwM4XVHQYafASDKJiac5nsNAd45PH TcbciRODT+0jzOm+GIvGFkzqk8r+LrlvKmUsAJuOLveF4fPiDIzj7t4ExtJobYuIVCjNBL cOz7qh9xQsqXkuqFO1oYXr9NYwh9KXM= Received: from ken.9lab.home (host-185-64-155-70.ecsnet.at [185.64.155.70]) by mail.9lab.org (OpenSMTPD) with ESMTPSA id bd8a03c1 (TLSv1.2:ECDHE-RSA-CHACHA20-POLY1305:256:NO); Tue, 4 Jan 2022 23:47:06 +0100 (CET) Message-ID: <6749DB7684492D8171889089C5EBE3D0@9lab.org> To: 9front@9front.org CC: igor@9lab.org Date: Tue, 04 Jan 2022 23:47:05 +0100 From: igor@9lab.org MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="upas-zhzqfivvyjhunvbvosyrvdskch" List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: managed flexible ActivityPub table content-driven manager Subject: [9front] [PATCH] acme: fix window and scrollbar display glitches at bottom fringe of column Reply-To: 9front@9front.org Precedence: bulk This is a multi-part message in MIME format. --upas-zhzqfivvyjhunvbvosyrvdskch Content-Disposition: inline Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit The following patch fixes acme display glitches at the bottom fringe of columns when adding/moving/resizing windows. Here an example of an easy to reproduce case: • https://invidio.xamh.de/watch?v=iLekQrxycaM …opening acme and resizing a column is all that is needed. Here is another example of the issue, note the white line at the bottom of the acme columns: • https://9lab.org/img/plan9/acid.png The functions winresize(…) and textresize(…) are extended with an additional parameter `fillfringe` to indicate if a window/tag shall fill a potential fringe area that would otherwise remain white. The changes have been inspired by the approach taken in plan9port acme. If you are an acme user please give this a try and/or provide feedback if you run into any issues or disagree with the solution. If there is agreement and no one runs into problems over the next week or two I will merge this patch. The patch is also attached for git/import. Thanks. Cheers, Igor --- diff 2c9a6e5c49ec76c65275c3b1e308626b87cc71f4 7fbd06cc25562c141b0f0f3bf7b61a7175118028 --- a/sys/src/cmd/acme/acme.c Sun Dec 12 17:20:17 2021 +++ b/sys/src/cmd/acme/acme.c Tue Jan 4 20:11:07 2022 @@ -295,9 +295,6 @@ Command *c; fsysclose(); -// if(display) -// flushimage(display, 1); - for(c=command; c; c=c->next) postnote(PNGROUP, c->pid, "hangup"); remove(acmeerrorfile); --- a/sys/src/cmd/acme/cols.c Sun Dec 12 17:20:17 2021 +++ b/sys/src/cmd/acme/cols.c Tue Jan 4 20:11:07 2022 @@ -77,7 +77,7 @@ r1 = r; y = min(y, t-(v->tag.font->height+v->body.font->height+Border+1)); r1.max.y = min(y, v->body.r.min.y+v->body.nlines*v->body.font->height); - r1.min.y = winresize(v, r1, FALSE); + r1.min.y = winresize(v, r1, FALSE, FALSE); r1.max.y = r1.min.y+Border; draw(screen, r1, display->black, nil, ZP); r.min.y = r1.max.y; @@ -90,7 +90,7 @@ wininit(w, clone, r); }else{ w->col = c; - winresize(w, r, FALSE); + winresize(w, r, FALSE, TRUE); } w->tag.col = c; w->tag.row = c->row; @@ -152,7 +152,7 @@ if(c->safe) { if(!didmouse && up) w->showdel = TRUE; - winresize(w, r, FALSE); + winresize(w, r, FALSE, TRUE); if(!didmouse && up) movetodel(w); } @@ -193,7 +193,7 @@ clearmouse(); r1 = r; r1.max.y = r1.min.y + c->tag.font->height; - textresize(&c->tag, r1); + textresize(&c->tag, r1, TRUE); draw(screen, c->tag.scrollr, colbutton, nil, colbutton->r.min); r1.min.y = r1.max.y; r1.max.y += Border; @@ -208,14 +208,15 @@ r1.max.y = r.max.y; else { r1.max.y = r1.min.y; - if(new > 0 && old > 0 && Dy(w->r) > font->height) - r1.max.y += (Dy(w->r)-font->height)*new/old + Border + font->height; + if(new > 0 && old > 0 && Dy(w->r) > Border+font->height) + r1.max.y += (Dy(w->r)-Border-font->height)*new/old + Border + font->height; } + r1.max.y = max(r1.max.y, r1.min.y + Border+font->height); r2 = r1; r2.max.y = r2.min.y+Border; draw(screen, r2, display->black, nil, ZP); r1.min.y = r2.max.y; - r1.min.y = winresize(w, r1, FALSE); + r1.min.y = winresize(w, r1, FALSE, i==c->nw-1); } c->r = r; } @@ -271,7 +272,7 @@ r1.max.y = r1.min.y+Border; draw(screen, r1, display->black, nil, ZP); r.min.y = r1.max.y; - y = winresize(w, r, FALSE); + y = winresize(w, r, FALSE, i==c->nw-1); } free(rp); free(c->w); @@ -297,8 +298,8 @@ if(i==c->nw-1 || c->safe==FALSE) r.max.y = cr.max.y; else - r.max.y = c->w[i+1]->r.min.y; - winresize(w, r, FALSE); + r.max.y = c->w[i+1]->r.min.y - Border; + winresize(w, r, FALSE, TRUE); return; } cr.min.y = c->w[0]->r.min.y; @@ -309,7 +310,7 @@ c->w[i] = v; } draw(screen, cr, textcols[BACK], nil, ZP); - winresize(w, cr, FALSE); + winresize(w, cr, FALSE, TRUE); for(i=1; inw; i++) c->w[i]->body.maxlines = 0; c->safe = FALSE; @@ -367,9 +368,9 @@ r.max.y += 1 + nl[j]*v->body.font->height; if(!c->safe || !eqrect(v->r, r)){ draw(screen, r, textcols[BACK], nil, ZP); - winresize(v, r, c->safe); - } - r.min.y = v->r.max.y; + r.min.y = winresize(v, r, c->safe, FALSE); + }else + r.min.y = v->r.max.y; r.max.y += Border; draw(screen, r, display->black, nil, ZP); y1 = r.max.y; @@ -389,17 +390,13 @@ /* compute new size of window */ r = w->r; r.min.y = y1; - r.max.y = r.min.y+Dy(w->tag.all); + r.max.y = y2; h = w->body.font->height; - if(y2-r.max.y >= 1+h+Border){ - r.max.y += 1; - r.max.y += h*((y2-r.max.y)/h); - } + if(Dy(r) < Dy(w->tagtop)+1+h+Border) + r.max.y = r.min.y + Dy(w->tagtop)+1+h+Border; /* draw window */ - if(!c->safe || !eqrect(w->r, r)){ - draw(screen, r, textcols[BACK], nil, ZP); - winresize(w, r, c->safe); - } + draw(screen, r, textcols[BACK], nil, ZP); + r.max.y = winresize(w, r, c->safe, TRUE); if(i < c->nw-1){ r.min.y = r.max.y; r.max.y += Border; @@ -416,21 +413,15 @@ r.max.y = y1+Dy(v->tag.all); if(nl[j]) r.max.y += 1 + nl[j]*v->body.font->height; - if(!c->safe || !eqrect(v->r, r)){ - draw(screen, r, textcols[BACK], nil, ZP); - winresize(v, r, c->safe); - } + draw(screen, r, textcols[BACK], nil, ZP); + y1 = winresize(v, r, c->safe, j==c->nw-1); if(j < c->nw-1){ /* no border on last window */ - r.min.y = v->r.max.y; - r.max.y = r.min.y + Border; + r.min.y = y1; + r.max.y += Border; draw(screen, r, display->black, nil, ZP); + y1 = r.max.y; } - y1 = r.max.y; } - r = w->r; - r.min.y = y1; - r.max.y = c->r.max.y; - draw(screen, r, textcols[BACK], nil, ZP); free(nl); free(ny); c->safe = TRUE; @@ -465,6 +456,8 @@ error("can't find window"); Found: + if(w->tagexpand) /* force recomputation of window tag size */ + w->taglines = 1; p = mouse->xy; if(abs(p.x-op.x)<5 && abs(p.y-op.y)<5){ colgrow(c, w, but); @@ -505,11 +498,8 @@ if(v->body.r.min.y == v->body.r.max.y) r.max.y++; } - if(!eqrect(v->r, r)){ - draw(screen, r, textcols[BACK], nil, ZP); - winresize(v, r, c->safe); - } - r.min.y = v->r.max.y; + draw(screen, r, textcols[BACK], nil, ZP); + r.min.y = winresize(v, r, c->safe, FALSE); r.max.y = r.min.y+Border; draw(screen, r, display->black, nil, ZP); r.min.y = r.max.y; @@ -519,10 +509,10 @@ r.max.y = c->w[i+1]->r.min.y-Border; if(!eqrect(w->r, r)){ draw(screen, r, textcols[BACK], nil, ZP); - winresize(w, r, c->safe); + winresize(w, r, c->safe, TRUE); } c->safe = TRUE; - winmousebut(w); + winmousebut(w); } Text* --- a/sys/src/cmd/acme/dat.h Sun Dec 12 17:20:17 2021 +++ b/sys/src/cmd/acme/dat.h Tue Jan 4 20:11:07 2022 @@ -213,7 +213,7 @@ Rune textreadc(Text*, uint); void textredraw(Text*, Rectangle, Font*, Image*, int); void textreset(Text*); -int textresize(Text*, Rectangle); +int textresize(Text*, Rectangle, int); void textscrdraw(Text*); void textscroll(Text*, int); void textselect(Text*); @@ -245,7 +245,6 @@ uchar dirty; uchar indent[NINDENT]; uchar showdel; - uint noredraw; int id; Range addr; Range limit; @@ -290,7 +289,7 @@ void winsettag(Window*); void winsettag1(Window*); void wincommit(Window*, Text*); -int winresize(Window*, Rectangle, int); +int winresize(Window*, Rectangle, int, int); void winclose(Window*); void windelete(Window*); int winclean(Window*, int); --- a/sys/src/cmd/acme/exec.c Sun Dec 12 17:20:17 2021 +++ b/sys/src/cmd/acme/exec.c Tue Jan 4 20:11:07 2022 @@ -1217,7 +1217,7 @@ if(tab > 0){ if(w->body.tabstop != tab){ w->body.tabstop = tab; - winresize(w, w->r, 1); + winresize(w, w->r, FALSE, TRUE); } }else warning(nil, "%.*S: Tab %d\n", w->body.file->nname, w->body.file->name, w->body.tabstop); --- a/sys/src/cmd/acme/rows.c Sun Dec 12 17:20:17 2021 +++ b/sys/src/cmd/acme/rows.c Tue Jan 4 20:11:07 2022 @@ -102,7 +102,7 @@ row->r = r; r1 = r; r1.max.y = r1.min.y + font->height; - textresize(&row->tag, r1); + textresize(&row->tag, r1, TRUE); r1.min.y = r1.max.y; r1.max.y += Border; draw(screen, r1, display->black, nil, ZP); --- a/sys/src/cmd/acme/text.c Sun Dec 12 17:20:17 2021 +++ b/sys/src/cmd/acme/text.c Tue Jan 4 20:11:07 2022 @@ -68,14 +68,14 @@ } int -textresize(Text *t, Rectangle r) +textresize(Text *t, Rectangle r, int fillfringe) { int odx; - if(Dy(r) > 0) - r.max.y -= Dy(r)%t->font->height; - else + if(Dy(r) <= 0) r.max.y = r.min.y; + else if(!fillfringe) + r.max.y -= Dy(r)%t->font->height; odx = Dx(t->all); t->all = r; t->scrollr = r; @@ -84,7 +84,14 @@ r.min.x += Scrollwid+Scrollgap; frclear(t, 0); textredraw(t, r, t->font, t->b, odx); - return r.max.y; + if(fillfringe && t->r.max.y < t->all.max.y){ + /* draw background in bottom fringe of text window */ + r.min.x -= Scrollgap; + r.min.y = t->r.max.y; + r.max.y = t->all.max.y; + draw(screen, r, t->cols[BACK], nil, ZP); + } + return t->all.max.y; } void @@ -276,7 +283,7 @@ if(u != t){ if(u->org > u->file->nc) /* will be 0 because of reset(), but safety first */ u->org = 0; - textresize(u, u->all); + textresize(u, u->all, TRUE); textbacknl(u, u->org, 0); /* go to beginning of line */ } textsetselect(u, q0, q0); --- a/sys/src/cmd/acme/wind.c Sun Dec 12 17:20:17 2021 +++ b/sys/src/cmd/acme/wind.c Tue Jan 4 20:11:07 2022 @@ -136,9 +136,7 @@ if(!w->tagexpand && !w->showdel) return 1; w->showdel = FALSE; - w->noredraw = 1; - textresize(&w->tag, r); - w->noredraw = 0; + textresize(&w->tag, r, TRUE); w->tagsafe = FALSE; if(!w->tagexpand) { @@ -167,34 +165,33 @@ } int -winresize(Window *w, Rectangle r, int safe) +winresize(Window *w, Rectangle r, int safe, int fillfringe) { - int oy, mouseintag, mouseinbody; + int oy, y, mouseintag, mouseinbody; Point p; Rectangle r1; - int y; Image *b; Rectangle br; mouseintag = ptinrect(mouse->xy, w->tag.all); mouseinbody = ptinrect(mouse->xy, w->body.all); + /* Tagtop is first line of tag. */ w->tagtop = r; w->tagtop.max.y = r.min.y+font->height; r1 = r; - r1.max.y = r1.min.y + font->height; r1.max.y = min(r.max.y, r1.min.y + w->taglines*font->height); - if(!safe || !w->tagsafe || !eqrect(w->tag.all, r1)){ + /* If needed, recompute number of lines in tag. */ + if(!safe || !w->tagsafe || !eqrect(w->tag.r, r1)){ w->taglines = wintaglines(w, r); r1.max.y = min(r.max.y, r1.min.y + w->taglines*font->height); } - if(Dy(r1) < font->height) - r1.max.y = r1.min.y+font->height; + /* If needed, resize & redraw tag. */ y = r1.max.y; - if(!safe || !eqrect(w->tag.r, r1)){ - textresize(&w->tag, r1); + if(!safe || !w->tagsafe || !eqrect(w->tag.r, r1)){ + textresize(&w->tag, r1, TRUE); y = w->tag.r.max.y; b = button; if(w->body.file->mod && !w->isdir && !w->isscratch) @@ -219,8 +216,10 @@ p.y = w->tag.all.max.y+3; moveto(mousectl, p); } - } + /* If needed, resize & redraw body. */ + r1 = r; + r1.min.y = y; if(!safe || !eqrect(w->body.r, r1)){ oy = y; if(y+1+w->body.font->height <= r.max.y){ /* room for one line */ @@ -234,7 +233,7 @@ r1.min.y = y; r1.max.y = y; } - y = textresize(&w->body, r1); + y = textresize(&w->body, r1, fillfringe); w->r = r; w->r.max.y = y; textscrdraw(&w->body); @@ -539,7 +538,7 @@ br.max.y = br.min.y + Dy(b->r); draw(screen, br, b, nil, b->r.min); if(w->tagsafe == FALSE) - winresize(w, w->r, TRUE); + winresize(w, w->r, TRUE, TRUE); } void --upas-zhzqfivvyjhunvbvosyrvdskch Content-Disposition: attachment; filename=acme-fix-display-glitch.patch Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit From: Igor Böhm Date: Tue, 04 Jan 2022 19:11:07 +0000 Subject: [PATCH] acme: fix window and scrollbar display glitches at bottom fringe of column The following patch fixes acme display glitches at the bottom fringe of columns when adding/moving/resizing windows. Here an example of an easy to reproduce case: • https://invidio.xamh.de/watch?v=iLekQrxycaM …opening acme and resizing a column to the right is all that is needed. The functions winresize(…) and textresize(…) are extended with an additional parameter `fillfringe` to indicate if a window/tag shall fill a potential fringe area that would otherwise remain white. The changes have been inspired by the approach taken in plan9port acme. --- diff 2c9a6e5c49ec76c65275c3b1e308626b87cc71f4 7fbd06cc25562c141b0f0f3bf7b61a7175118028 --- a/sys/src/cmd/acme/acme.c Sun Dec 12 17:20:17 2021 +++ b/sys/src/cmd/acme/acme.c Tue Jan 4 20:11:07 2022 @@ -295,9 +295,6 @@ Command *c; fsysclose(); -// if(display) -// flushimage(display, 1); - for(c=command; c; c=c->next) postnote(PNGROUP, c->pid, "hangup"); remove(acmeerrorfile); --- a/sys/src/cmd/acme/cols.c Sun Dec 12 17:20:17 2021 +++ b/sys/src/cmd/acme/cols.c Tue Jan 4 20:11:07 2022 @@ -77,7 +77,7 @@ r1 = r; y = min(y, t-(v->tag.font->height+v->body.font->height+Border+1)); r1.max.y = min(y, v->body.r.min.y+v->body.nlines*v->body.font->height); - r1.min.y = winresize(v, r1, FALSE); + r1.min.y = winresize(v, r1, FALSE, FALSE); r1.max.y = r1.min.y+Border; draw(screen, r1, display->black, nil, ZP); r.min.y = r1.max.y; @@ -90,7 +90,7 @@ wininit(w, clone, r); }else{ w->col = c; - winresize(w, r, FALSE); + winresize(w, r, FALSE, TRUE); } w->tag.col = c; w->tag.row = c->row; @@ -152,7 +152,7 @@ if(c->safe) { if(!didmouse && up) w->showdel = TRUE; - winresize(w, r, FALSE); + winresize(w, r, FALSE, TRUE); if(!didmouse && up) movetodel(w); } @@ -193,7 +193,7 @@ clearmouse(); r1 = r; r1.max.y = r1.min.y + c->tag.font->height; - textresize(&c->tag, r1); + textresize(&c->tag, r1, TRUE); draw(screen, c->tag.scrollr, colbutton, nil, colbutton->r.min); r1.min.y = r1.max.y; r1.max.y += Border; @@ -208,14 +208,15 @@ r1.max.y = r.max.y; else { r1.max.y = r1.min.y; - if(new > 0 && old > 0 && Dy(w->r) > font->height) - r1.max.y += (Dy(w->r)-font->height)*new/old + Border + font->height; + if(new > 0 && old > 0 && Dy(w->r) > Border+font->height) + r1.max.y += (Dy(w->r)-Border-font->height)*new/old + Border + font->height; } + r1.max.y = max(r1.max.y, r1.min.y + Border+font->height); r2 = r1; r2.max.y = r2.min.y+Border; draw(screen, r2, display->black, nil, ZP); r1.min.y = r2.max.y; - r1.min.y = winresize(w, r1, FALSE); + r1.min.y = winresize(w, r1, FALSE, i==c->nw-1); } c->r = r; } @@ -271,7 +272,7 @@ r1.max.y = r1.min.y+Border; draw(screen, r1, display->black, nil, ZP); r.min.y = r1.max.y; - y = winresize(w, r, FALSE); + y = winresize(w, r, FALSE, i==c->nw-1); } free(rp); free(c->w); @@ -297,8 +298,8 @@ if(i==c->nw-1 || c->safe==FALSE) r.max.y = cr.max.y; else - r.max.y = c->w[i+1]->r.min.y; - winresize(w, r, FALSE); + r.max.y = c->w[i+1]->r.min.y - Border; + winresize(w, r, FALSE, TRUE); return; } cr.min.y = c->w[0]->r.min.y; @@ -309,7 +310,7 @@ c->w[i] = v; } draw(screen, cr, textcols[BACK], nil, ZP); - winresize(w, cr, FALSE); + winresize(w, cr, FALSE, TRUE); for(i=1; inw; i++) c->w[i]->body.maxlines = 0; c->safe = FALSE; @@ -367,9 +368,9 @@ r.max.y += 1 + nl[j]*v->body.font->height; if(!c->safe || !eqrect(v->r, r)){ draw(screen, r, textcols[BACK], nil, ZP); - winresize(v, r, c->safe); - } - r.min.y = v->r.max.y; + r.min.y = winresize(v, r, c->safe, FALSE); + }else + r.min.y = v->r.max.y; r.max.y += Border; draw(screen, r, display->black, nil, ZP); y1 = r.max.y; @@ -389,17 +390,13 @@ /* compute new size of window */ r = w->r; r.min.y = y1; - r.max.y = r.min.y+Dy(w->tag.all); + r.max.y = y2; h = w->body.font->height; - if(y2-r.max.y >= 1+h+Border){ - r.max.y += 1; - r.max.y += h*((y2-r.max.y)/h); - } + if(Dy(r) < Dy(w->tagtop)+1+h+Border) + r.max.y = r.min.y + Dy(w->tagtop)+1+h+Border; /* draw window */ - if(!c->safe || !eqrect(w->r, r)){ - draw(screen, r, textcols[BACK], nil, ZP); - winresize(w, r, c->safe); - } + draw(screen, r, textcols[BACK], nil, ZP); + r.max.y = winresize(w, r, c->safe, TRUE); if(i < c->nw-1){ r.min.y = r.max.y; r.max.y += Border; @@ -416,21 +413,15 @@ r.max.y = y1+Dy(v->tag.all); if(nl[j]) r.max.y += 1 + nl[j]*v->body.font->height; - if(!c->safe || !eqrect(v->r, r)){ - draw(screen, r, textcols[BACK], nil, ZP); - winresize(v, r, c->safe); - } + draw(screen, r, textcols[BACK], nil, ZP); + y1 = winresize(v, r, c->safe, j==c->nw-1); if(j < c->nw-1){ /* no border on last window */ - r.min.y = v->r.max.y; - r.max.y = r.min.y + Border; + r.min.y = y1; + r.max.y += Border; draw(screen, r, display->black, nil, ZP); + y1 = r.max.y; } - y1 = r.max.y; } - r = w->r; - r.min.y = y1; - r.max.y = c->r.max.y; - draw(screen, r, textcols[BACK], nil, ZP); free(nl); free(ny); c->safe = TRUE; @@ -465,6 +456,8 @@ error("can't find window"); Found: + if(w->tagexpand) /* force recomputation of window tag size */ + w->taglines = 1; p = mouse->xy; if(abs(p.x-op.x)<5 && abs(p.y-op.y)<5){ colgrow(c, w, but); @@ -505,11 +498,8 @@ if(v->body.r.min.y == v->body.r.max.y) r.max.y++; } - if(!eqrect(v->r, r)){ - draw(screen, r, textcols[BACK], nil, ZP); - winresize(v, r, c->safe); - } - r.min.y = v->r.max.y; + draw(screen, r, textcols[BACK], nil, ZP); + r.min.y = winresize(v, r, c->safe, FALSE); r.max.y = r.min.y+Border; draw(screen, r, display->black, nil, ZP); r.min.y = r.max.y; @@ -519,10 +509,10 @@ r.max.y = c->w[i+1]->r.min.y-Border; if(!eqrect(w->r, r)){ draw(screen, r, textcols[BACK], nil, ZP); - winresize(w, r, c->safe); + winresize(w, r, c->safe, TRUE); } c->safe = TRUE; - winmousebut(w); + winmousebut(w); } Text* --- a/sys/src/cmd/acme/dat.h Sun Dec 12 17:20:17 2021 +++ b/sys/src/cmd/acme/dat.h Tue Jan 4 20:11:07 2022 @@ -213,7 +213,7 @@ Rune textreadc(Text*, uint); void textredraw(Text*, Rectangle, Font*, Image*, int); void textreset(Text*); -int textresize(Text*, Rectangle); +int textresize(Text*, Rectangle, int); void textscrdraw(Text*); void textscroll(Text*, int); void textselect(Text*); @@ -245,7 +245,6 @@ uchar dirty; uchar indent[NINDENT]; uchar showdel; - uint noredraw; int id; Range addr; Range limit; @@ -290,7 +289,7 @@ void winsettag(Window*); void winsettag1(Window*); void wincommit(Window*, Text*); -int winresize(Window*, Rectangle, int); +int winresize(Window*, Rectangle, int, int); void winclose(Window*); void windelete(Window*); int winclean(Window*, int); --- a/sys/src/cmd/acme/exec.c Sun Dec 12 17:20:17 2021 +++ b/sys/src/cmd/acme/exec.c Tue Jan 4 20:11:07 2022 @@ -1217,7 +1217,7 @@ if(tab > 0){ if(w->body.tabstop != tab){ w->body.tabstop = tab; - winresize(w, w->r, 1); + winresize(w, w->r, FALSE, TRUE); } }else warning(nil, "%.*S: Tab %d\n", w->body.file->nname, w->body.file->name, w->body.tabstop); --- a/sys/src/cmd/acme/rows.c Sun Dec 12 17:20:17 2021 +++ b/sys/src/cmd/acme/rows.c Tue Jan 4 20:11:07 2022 @@ -102,7 +102,7 @@ row->r = r; r1 = r; r1.max.y = r1.min.y + font->height; - textresize(&row->tag, r1); + textresize(&row->tag, r1, TRUE); r1.min.y = r1.max.y; r1.max.y += Border; draw(screen, r1, display->black, nil, ZP); --- a/sys/src/cmd/acme/text.c Sun Dec 12 17:20:17 2021 +++ b/sys/src/cmd/acme/text.c Tue Jan 4 20:11:07 2022 @@ -68,14 +68,14 @@ } int -textresize(Text *t, Rectangle r) +textresize(Text *t, Rectangle r, int fillfringe) { int odx; - if(Dy(r) > 0) - r.max.y -= Dy(r)%t->font->height; - else + if(Dy(r) <= 0) r.max.y = r.min.y; + else if(!fillfringe) + r.max.y -= Dy(r)%t->font->height; odx = Dx(t->all); t->all = r; t->scrollr = r; @@ -84,7 +84,14 @@ r.min.x += Scrollwid+Scrollgap; frclear(t, 0); textredraw(t, r, t->font, t->b, odx); - return r.max.y; + if(fillfringe && t->r.max.y < t->all.max.y){ + /* draw background in bottom fringe of text window */ + r.min.x -= Scrollgap; + r.min.y = t->r.max.y; + r.max.y = t->all.max.y; + draw(screen, r, t->cols[BACK], nil, ZP); + } + return t->all.max.y; } void @@ -276,7 +283,7 @@ if(u != t){ if(u->org > u->file->nc) /* will be 0 because of reset(), but safety first */ u->org = 0; - textresize(u, u->all); + textresize(u, u->all, TRUE); textbacknl(u, u->org, 0); /* go to beginning of line */ } textsetselect(u, q0, q0); --- a/sys/src/cmd/acme/wind.c Sun Dec 12 17:20:17 2021 +++ b/sys/src/cmd/acme/wind.c Tue Jan 4 20:11:07 2022 @@ -136,9 +136,7 @@ if(!w->tagexpand && !w->showdel) return 1; w->showdel = FALSE; - w->noredraw = 1; - textresize(&w->tag, r); - w->noredraw = 0; + textresize(&w->tag, r, TRUE); w->tagsafe = FALSE; if(!w->tagexpand) { @@ -167,34 +165,33 @@ } int -winresize(Window *w, Rectangle r, int safe) +winresize(Window *w, Rectangle r, int safe, int fillfringe) { - int oy, mouseintag, mouseinbody; + int oy, y, mouseintag, mouseinbody; Point p; Rectangle r1; - int y; Image *b; Rectangle br; mouseintag = ptinrect(mouse->xy, w->tag.all); mouseinbody = ptinrect(mouse->xy, w->body.all); + /* Tagtop is first line of tag. */ w->tagtop = r; w->tagtop.max.y = r.min.y+font->height; r1 = r; - r1.max.y = r1.min.y + font->height; r1.max.y = min(r.max.y, r1.min.y + w->taglines*font->height); - if(!safe || !w->tagsafe || !eqrect(w->tag.all, r1)){ + /* If needed, recompute number of lines in tag. */ + if(!safe || !w->tagsafe || !eqrect(w->tag.r, r1)){ w->taglines = wintaglines(w, r); r1.max.y = min(r.max.y, r1.min.y + w->taglines*font->height); } - if(Dy(r1) < font->height) - r1.max.y = r1.min.y+font->height; + /* If needed, resize & redraw tag. */ y = r1.max.y; - if(!safe || !eqrect(w->tag.r, r1)){ - textresize(&w->tag, r1); + if(!safe || !w->tagsafe || !eqrect(w->tag.r, r1)){ + textresize(&w->tag, r1, TRUE); y = w->tag.r.max.y; b = button; if(w->body.file->mod && !w->isdir && !w->isscratch) @@ -219,8 +216,10 @@ p.y = w->tag.all.max.y+3; moveto(mousectl, p); } - } + /* If needed, resize & redraw body. */ + r1 = r; + r1.min.y = y; if(!safe || !eqrect(w->body.r, r1)){ oy = y; if(y+1+w->body.font->height <= r.max.y){ /* room for one line */ @@ -234,7 +233,7 @@ r1.min.y = y; r1.max.y = y; } - y = textresize(&w->body, r1); + y = textresize(&w->body, r1, fillfringe); w->r = r; w->r.max.y = y; textscrdraw(&w->body); @@ -539,7 +538,7 @@ br.max.y = br.min.y + Dy(b->r); draw(screen, br, b, nil, b->r.min); if(w->tagsafe == FALSE) - winresize(w, w->r, TRUE); + winresize(w, w->r, TRUE, TRUE); } void --upas-zhzqfivvyjhunvbvosyrvdskch--