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, FREEMAIL_FROM autolearn=no autolearn_force=no version=3.4.4 Received: (qmail 16337 invoked from network); 20 May 2021 18:18:59 -0000 Received: from 1ess.inri.net (216.126.196.35) by inbox.vuxu.org with ESMTPUTF8; 20 May 2021 18:18:59 -0000 Received: from st43p00im-ztfb10073301.me.com ([17.58.63.186]) by 1ess; Thu May 20 14:14:06 -0400 2021 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=icloud.com; s=1a1hai; t=1621534443; bh=SYdBxFo1uLVCTkGAlR72SzvpZmOCdm/F5jJZblD2ta4=; h=From:Content-Type:Mime-Version:Subject:Message-Id:Date:To; b=Ts88dqU58YzKjBdyfLo0bcy3X0rMnFr/P2nO9ZWNByGjDX/Q6t/RYFJ9Vy7b8N37C P5gsI5/igS33rt+hPf7UHof4Lq1M+4qL2DCaUwpNljsXFjjoS9rlyTky68kC1TgDJ8 Zr72x6ZCivXDjTX8MHSvnbZKRCcwEkiK0menlj1A3l3mwBFOB4AVUudenAODfYL9ZI 1DGlXmAg34kd0Gu0QWtX9Bai2W05fL/y44xC27g1jdTMv2PqgJ871ruQEd+r6ZB2aP n/vJ051CKIjWuqmIRWZFlI2WwxSqFBRLTfw7xuYroP0YjGhx9wLF0MGvzZARRRKoXH PjuigVPb/s8Tw== Received: from smtpclient.apple (pool-74-99-165-73.hrbgpa.fios.verizon.net [74.99.165.73]) by st43p00im-ztfb10073301.me.com (Postfix) with ESMTPSA id 20AB72A0371 for <9front@9front.org>; Thu, 20 May 2021 18:14:03 +0000 (UTC) From: David Leimbach Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 (Mac OS X Mail 14.0 \(3654.80.0.2.43\)) Message-Id: Date: Thu, 20 May 2021 14:14:02 -0400 To: 9front@9front.org X-Mailer: Apple Mail (2.3654.80.0.2.43) X-Proofpoint-Virus-Version: =?UTF-8?Q?vendor=3Dfsecure_engine=3D1.1.170-22c6f66c430a71ce266a39bfe25bc?= =?UTF-8?Q?2903e8d5c8f:6.0.391,18.0.761,17.0.607.475.0000000_definitions?= =?UTF-8?Q?=3D2021-05-20=5F04:2021-05-20=5F03,2021-05-20=5F04,2020-04-07?= =?UTF-8?Q?=5F01_signatures=3D0?= X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 mlxscore=0 bulkscore=0 mlxlogscore=999 adultscore=0 clxscore=1015 suspectscore=0 malwarescore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2009150000 definitions=main-2105200112 List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: responsive decentralized framework general-purpose cloud-based control Subject: [9front] Patch for libframe and acme to eliminate redrawing body of documents when typing in the tagline. Reply-To: 9front@9front.org Precedence: bulk diff -r aa49706ca881 sys/include/frame.h --- a/sys/include/frame.h Wed May 12 22:40:51 2021 +0200 +++ b/sys/include/frame.h Thu May 20 11:58:46 2021 -0400 @@ -49,6 +49,7 @@ Image *tick; /* typing tick */ Image *tickback; /* saved image under tick */ int ticked; /* flag: is tick onscreen? */ + int noredraw; /* don't draw on the = screen */ }; ulong frcharofpt(Frame*, Point); diff -r aa49706ca881 sys/src/cmd/acme/acme.c --- a/sys/src/cmd/acme/acme.c Wed May 12 22:40:51 2021 +0200 +++ b/sys/src/cmd/acme/acme.c Thu May 20 11:58:46 2021 -0400 @@ -256,6 +256,7 @@ w->body.file->mod =3D FALSE; w->dirty =3D FALSE; winsettag(w); + winresize(w, w->r, FALSE, TRUE); textscrdraw(&w->body); textsetselect(&w->tag, w->tag.file->nc, w->tag.file->nc); xfidlog(w, "new"); @@ -464,6 +465,7 @@ case MResize: if(getwindow(display, Refnone) < 0) error("attach to window"); + draw(screen, screen->r, display->white, nil, = ZP); scrlresize(); rowresize(&row, screen->clipr); break; diff -r aa49706ca881 sys/src/cmd/acme/cols.c --- a/sys/src/cmd/acme/cols.c Wed May 12 22:40:51 2021 +0200 +++ b/sys/src/cmd/acme/cols.c Thu May 20 11:58:46 2021 -0400 @@ -77,7 +77,7 @@ r1 =3D r; y =3D min(y, = t-(v->tag.font->height+v->body.font->height+Border+1)); r1.max.y =3D min(y, = v->body.r.min.y+v->body.nlines*v->body.font->height); - r1.min.y =3D winresize(v, r1, FALSE); + r1.min.y =3D winresize(v, r1, FALSE, FALSE); r1.max.y =3D r1.min.y+Border; draw(screen, r1, display->black, nil, ZP); r.min.y =3D r1.max.y; @@ -90,7 +90,7 @@ wininit(w, clone, r); }else{ w->col =3D c; - winresize(w, r, FALSE); + winresize(w, r, FALSE, TRUE); } w->tag.col =3D c; w->tag.row =3D c->row; @@ -152,7 +152,7 @@ if(c->safe) { if(!didmouse && up) w->showdel =3D TRUE; - winresize(w, r, FALSE); + winresize(w, r, FALSE, TRUE); if(!didmouse && up) movetodel(w); } @@ -193,7 +193,7 @@ clearmouse(); r1 =3D r; r1.max.y =3D 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 =3D r1.max.y; r1.max.y +=3D Border; @@ -215,7 +215,7 @@ r2.max.y =3D r2.min.y+Border; draw(screen, r2, display->black, nil, ZP); r1.min.y =3D r2.max.y; - r1.min.y =3D winresize(w, r1, FALSE); + r1.min.y =3D winresize(w, r1, FALSE, i=3D=3Dc->nw-1); } c->r =3D r; } @@ -271,7 +271,7 @@ r1.max.y =3D r1.min.y+Border; draw(screen, r1, display->black, nil, ZP); r.min.y =3D r1.max.y; - y =3D winresize(w, r, FALSE); + y =3D winresize(w, r, FALSE, i=3D=3Dc->nw-1); } free(rp); free(c->w); @@ -298,7 +298,7 @@ r.max.y =3D cr.max.y; else r.max.y =3D c->w[i+1]->r.min.y; - winresize(w, r, FALSE); + winresize(w, r, FALSE, TRUE); return; } cr.min.y =3D c->w[0]->r.min.y; @@ -309,7 +309,7 @@ c->w[i] =3D v; } draw(screen, cr, textcols[BACK], nil, ZP); - winresize(w, cr, FALSE); + winresize(w, cr, FALSE, TRUE); for(i=3D1; inw; i++) c->w[i]->body.maxlines =3D 0; c->safe =3D FALSE; @@ -367,7 +367,7 @@ r.max.y +=3D 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); + winresize(v, r, c->safe, FALSE); } r.min.y =3D v->r.max.y; r.max.y +=3D Border; @@ -389,17 +389,12 @@ /* compute new size of window */ r =3D w->r; r.min.y =3D y1; - r.max.y =3D r.min.y+Dy(w->tag.all); + r.max.y =3D y2; h =3D w->body.font->height; - if(y2-r.max.y >=3D 1+h+Border){ - r.max.y +=3D 1; - r.max.y +=3D h*((y2-r.max.y)/h); - } + if(Dy(r) < Dy(w->tagtop)+1+h+Border) + r.max.y =3D 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); - } + r.max.y =3D winresize(w, r, c->safe, TRUE); if(i < c->nw-1){ r.min.y =3D r.max.y; r.max.y +=3D Border; @@ -413,24 +408,18 @@ v =3D c->w[j]; r =3D v->r; r.min.y =3D y1; - r.max.y =3D y1+Dy(v->tag.all); + //r.max.y =3D y1+Dy(v->tag.all); + r.max.y =3D y1+Dy(v->tagtop); if(nl[j]) r.max.y +=3D 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); - } + y1 =3D winresize(v, r, c->safe, j=3D=3Dc->nw-1); if(j < c->nw-1){ /* no border on last window */ r.min.y =3D v->r.max.y; r.max.y =3D r.min.y + Border; draw(screen, r, display->black, nil, ZP); + y1 =3D r.max.y; } - y1 =3D r.max.y; } - r =3D w->r; - r.min.y =3D y1; - r.max.y =3D c->r.max.y; - draw(screen, r, textcols[BACK], nil, ZP); free(nl); free(ny); c->safe =3D TRUE; @@ -465,6 +454,8 @@ error("can't find window"); Found: + if(w->tagexpand) /* force recomputation of window tag = size */ + w->taglines =3D 1; p =3D mouse->xy; if(abs(p.x-op.x)<5 && abs(p.y-op.y)<5){ colgrow(c, w, but); @@ -494,10 +485,10 @@ if(i =3D=3D 0) return; v =3D c->w[i-1]; - if(p.y < v->tag.all.max.y) - p.y =3D v->tag.all.max.y; - if(p.y > w->r.max.y-Dy(w->tag.all)-Border) - p.y =3D w->r.max.y-Dy(w->tag.all)-Border; + if(p.y < v->tagtop.max.y) + p.y =3D v->tagtop.max.y; + if(p.y > w->r.max.y-Dy(w->tagtop)-Border) + p.y =3D w->r.max.y-Dy(w->tagtop)-Border; r =3D v->r; r.max.y =3D p.y; if(r.max.y > v->body.r.min.y){ @@ -505,11 +496,7 @@ if(v->body.r.min.y =3D=3D 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 =3D v->r.max.y; + r.min.y =3D winresize(v, r, c->safe, FALSE); r.max.y =3D r.min.y+Border; draw(screen, r, display->black, nil, ZP); r.min.y =3D r.max.y; @@ -517,10 +504,7 @@ r.max.y =3D c->r.max.y; else r.max.y =3D 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 =3D TRUE; winmousebut(w); } diff -r aa49706ca881 sys/src/cmd/acme/dat.h --- a/sys/src/cmd/acme/dat.h Wed May 12 22:40:51 2021 +0200 +++ b/sys/src/cmd/acme/dat.h Thu May 20 11:58:46 2021 -0400 @@ -185,7 +185,7 @@ Rectangle all; Row *row; Column *col; - + uint iq1; /* last input position */ uint eq0; /* start of typing for ESC */ uint cq0; /* cache position */ int ncache; /* storage for insert */ @@ -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*); @@ -290,7 +290,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); diff -r aa49706ca881 sys/src/cmd/acme/exec.c --- a/sys/src/cmd/acme/exec.c Wed May 12 22:40:51 2021 +0200 +++ b/sys/src/cmd/acme/exec.c Thu May 20 11:58:46 2021 -0400 @@ -908,6 +908,8 @@ textinsert(t, t->file->nc, L"\n", 1, TRUE); textsetselect(t, t->file->nc, t->file->nc); } + t->iq1 =3D t->q1; + textshow(t, t->q1, t->q1, 1); } void @@ -1219,7 +1221,7 @@ if(tab > 0){ if(w->body.tabstop !=3D tab){ w->body.tabstop =3D 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); diff -r aa49706ca881 sys/src/cmd/acme/rows.c --- a/sys/src/cmd/acme/rows.c Wed May 12 22:40:51 2021 +0200 +++ b/sys/src/cmd/acme/rows.c Thu May 20 11:58:46 2021 -0400 @@ -102,7 +102,7 @@ row->r =3D r; r1 =3D r; r1.max.y =3D r1.min.y + font->height; - textresize(&row->tag, r1); + textresize(&row->tag, r1, TRUE); r1.min.y =3D r1.max.y; r1.max.y +=3D Border; draw(screen, r1, display->black, nil, ZP); @@ -258,6 +258,9 @@ Window *w; Text *t; + if (r =3D=3D 0) + r =3D Runeerror; + clearmouse(); qlock(row); if(bartflag) @@ -271,6 +274,13 @@ else{ winlock(w, 'K'); wintype(w, t, r); + /* Expand tag if necessary */ + if(t->what =3D=3D Tag) { + //t->w->tagsafe =3D FALSE; + if(r =3D=3D '\n') + t->w->tagexpand =3D TRUE; + winresize(w, w->r, TRUE, TRUE); + } winunlock(w); } } diff -r aa49706ca881 sys/src/cmd/acme/text.c --- a/sys/src/cmd/acme/text.c Wed May 12 22:40:51 2021 +0200 +++ b/sys/src/cmd/acme/text.c Thu May 20 11:58:46 2021 -0400 @@ -45,7 +45,8 @@ frinit(t, r, f, b, t->Frame.cols); rr =3D t->r; rr.min.x -=3D Scrollwid+Scrollgap; /* back fill to scroll = bar */ - draw(t->b, rr, t->cols[BACK], nil, ZP); + if(!t->noredraw) + draw(t->b, rr, t->cols[BACK], nil, ZP); /* use no wider than 3-space tabs in a directory */ maxt =3D maxtab; if(t->what =3D=3D Body){ @@ -68,14 +69,14 @@ } int -textresize(Text *t, Rectangle r) +textresize(Text *t, Rectangle r, int keepextra) { int odx; - if(Dy(r) > 0) + if(Dy(r) <=3D 0) + r.max.y =3D r.min.y; + else if(!keepextra) r.max.y -=3D Dy(r)%t->font->height; - else - r.max.y =3D r.min.y; odx =3D Dx(t->all); t->all =3D r; t->scrollr =3D r; @@ -84,9 +85,17 @@ r.min.x +=3D Scrollwid+Scrollgap; frclear(t, 0); textredraw(t, r, t->font, t->b, odx); - return r.max.y; + if(keepextra && t->r.max.y < t->all.max.y && !t->noredraw){ + /* draw background in bottom fringe of window */ + r.min.x -=3D Scrollgap; + r.min.y =3D t->r.max.y; + r.max.y =3D t->all.max.y; + draw(screen, r, t->cols[BACK], nil, ZP); + } + return t->all.max.y; } + void textclose(Text *t) { @@ -276,7 +285,7 @@ if(u !=3D t){ if(u->org > u->file->nc) /* will be 0 = because of reset(), but safety first */ u->org =3D 0; - textresize(u, u->all); + textresize(u, u->all, TRUE); textbacknl(u, u->org, 0); /* go to = beginning of line */ } textsetselect(u, q0, q0); @@ -364,6 +373,8 @@ } =09 } + if(q0 < t->iq1) + t->iq1 +=3D n; if(q0 < t->q1) t->q1 +=3D n; if(q0 < t->q0) @@ -457,6 +468,8 @@ } } } + if(q0 < t->iq1) + t->iq1 -=3D min(n, t->iq1-q0); if(q0 < t->q0) t->q0 -=3D min(n, t->q0-q0); if(q0 < t->q1) @@ -668,6 +681,11 @@ Rune *rp; Text *u; + if(t->what!=3DBody && t->what!=3DTag && r=3D=3D'\n') + return; + if(t->what =3D=3D Tag) + t->w->tagsafe =3D FALSE; + nr =3D 1; rp =3D &r; switch(r){ @@ -682,9 +700,13 @@ textshow(t, t->q1+1, t->q1+1, TRUE); return; case Kdown: + if(t->what =3D=3D Tag) + goto Tagdown; n =3D t->maxlines/3; goto case_Down; case Kscrollonedown: + if(t->what =3D=3D Tag) + goto Tagdown; n =3D mousescrollsize(t->maxlines); if(n <=3D 0) n =3D 1; @@ -693,29 +715,43 @@ n =3D 2*t->maxlines/3; case_Down: q0 =3D t->org+frcharofpt(t, Pt(t->r.min.x, = t->r.min.y+n*t->font->height)); - if(t->what =3D=3D Body) - textsetorigin(t, q0, TRUE); + textsetorigin(t, q0, TRUE); return; case Kup: + if(t->what =3D=3D Tag) + goto Tagup; n =3D t->maxlines/3; goto case_Up; case Kscrolloneup: + if(t->what =3D=3D Tag) + goto Tagup; n =3D mousescrollsize(t->maxlines); goto case_Up; case Kpgup: n =3D 2*t->maxlines/3; case_Up: q0 =3D textbacknl(t, t->org, n); - if(t->what =3D=3D Body) - textsetorigin(t, q0, TRUE); + textsetorigin(t, q0, TRUE); return; case Khome: typecommit(t); - textshow(t, 0, 0, FALSE); + if(t->org > t->iq1) { + q0 =3D textbacknl(t, t->iq1, 1); + textsetorigin(t, q0, TRUE); + } else + textshow(t, 0, 0, FALSE); return; case Kend: typecommit(t); - textshow(t, t->file->nc, t->file->nc, FALSE); + if(t->iq1 > t->org+t->nchars) { + if(t->iq1 > t->file->nc) { + // should not happen, but does. and it = will crash textbacknl. + t->iq1 =3D t->file->nc; + } + q0 =3D textbacknl(t, t->iq1, 1); + textsetorigin(t, q0, TRUE); + } else + textshow(t, t->file->nc, t->file->nc, FALSE); return; case 0x01: /* ^A: beginning of line */ typecommit(t); @@ -732,7 +768,24 @@ q0++; textshow(t, q0, q0, TRUE); return; + + Tagdown: + /* expand tag to show all text */ + if(!t->w->tagexpand){ + t->w->tagexpand =3D TRUE; + winresize(t->w, t->w->r, FALSE, TRUE); + } + return; + + Tagup: + /* shrink tag to single line */ + if(t->w->tagexpand){ + t->w->tagexpand =3D FALSE; + winresize(t->w, t->w->r, FALSE, TRUE); + } + return; } + if(t->what =3D=3D Body){ seq++; filemark(t->file); @@ -812,7 +865,7 @@ } break; case '\n': - if(t->what =3D=3D Body && t->w->indent[AUTOINDENT]){ + if(t->w->indent[AUTOINDENT]){ /* find beginning of previous line using = backspace code */ nnb =3D textbswidth(t, 0x15); /* ^U case */ rp =3D runemalloc(nnb + 1); @@ -825,6 +878,7 @@ rp[nr++] =3D rr; } } + break; /* fall through to normal code */ } /* otherwise ordinary character; just insert, typically in = caches of all texts */ @@ -836,6 +890,16 @@ u->cq0 =3D t->q0; else if(t->q0 !=3D u->cq0+u->ncache) error("text.type cq1"); + /* + * Change the tag before we add to ncache, + * so that if the window body is resized the + * commit will not find anything in ncache + */ + if(u->what=3D=3DBody && u->ncache=3D=3D0) { + u->needundo =3D TRUE; + winsettag(t->w); + u->needundo =3D FALSE; + } textinsert(u, t->q0, rp, nr, FALSE); if(u !=3D t) textsetselect(u, u->q0, u->q1); @@ -851,6 +915,7 @@ textsetselect(t, t->q0+nr, t->q0+nr); if(r=3D=3D'\n' && t->w!=3Dnil) wincommit(t->w, t); + t->iq1 =3D t->q0; } void diff -r aa49706ca881 sys/src/cmd/acme/wind.c --- a/sys/src/cmd/acme/wind.c Wed May 12 22:40:51 2021 +0200 +++ b/sys/src/cmd/acme/wind.c Thu May 20 11:58:46 2021 -0400 @@ -13,6 +13,24 @@ int winid; +/* + * Draw the appropriate button. + */ +void +windrawbutton(Window *w) +{ + Image *b; + Rectangle br; + + b =3D button; + if(!w->isdir && !w->isscratch && (w->body.file->mod || = w->body.ncache)) + b =3D modbutton; + br.min =3D w->tag.scrollr.min; + br.max.x =3D br.min.x + Dx(b->r); + br.max.y =3D br.min.y + Dy(b->r); + draw(screen, br, b, nil, b->r.min); +} + void wininit(Window *w, Window *clone, Rectangle r) { @@ -33,9 +51,11 @@ w->ctlfid =3D ~0; w->utflastqid =3D -1; r1 =3D r; - r1.max.y =3D r1.min.y + font->height; + w->tagtop =3D r; w->tagtop.max.y =3D r.min.y + font->height; + r1.max.y =3D r1.min.y + w->taglines * font->height; + incref(&reffont); f =3D fileaddtext(nil, &w->tag); textinit(&w->tag, f, r1, &reffont, tagcols); @@ -71,7 +91,6 @@ draw(screen, r1, tagcols[BORD], nil, ZP); textscrdraw(&w->body); w->r =3D r; - w->r.max.y =3D w->body.r.max.y; br.min =3D w->tag.scrollr.min; br.max.x =3D br.min.x + Dx(button->r); br.max.y =3D br.min.y + Dy(button->r); @@ -136,9 +155,9 @@ if(!w->tagexpand && !w->showdel) return 1; w->showdel =3D FALSE; - w->noredraw =3D 1; - textresize(&w->tag, r); - w->noredraw =3D 0; + w->tag.noredraw =3D 1; + textresize(&w->tag, r, TRUE); + w->tag.noredraw =3D 0; w->tagsafe =3D FALSE; =09 if(!w->tagexpand) { @@ -167,43 +186,34 @@ } int -winresize(Window *w, Rectangle r, int safe) +winresize(Window *w, Rectangle r, int safe, int keepextra) { - int oy, mouseintag, mouseinbody; + int oy, y, mouseintag, mouseinbody; Point p; Rectangle r1; - int y; - Image *b; - Rectangle br; mouseintag =3D ptinrect(mouse->xy, w->tag.all); mouseinbody =3D ptinrect(mouse->xy, w->body.all); + /* tagtop is the first line of the tag */ w->tagtop =3D r; w->tagtop.max.y =3D r.min.y+font->height; r1 =3D r; - r1.max.y =3D r1.min.y + font->height; r1.max.y =3D min(r.max.y, r1.min.y + w->taglines*font->height); + /* If needed, recompute the number of lies in the tag. */ if(!safe || !w->tagsafe || !eqrect(w->tag.all, r1)){ w->taglines =3D wintaglines(w, r); r1.max.y =3D min(r.max.y, r1.min.y + = w->taglines*font->height); } - if(Dy(r1) < font->height) - r1.max.y =3D r1.min.y+font->height; + + /* If needed, resize & redraw tag. */ y =3D 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 =3D w->tag.r.max.y; - b =3D button; - if(w->body.file->mod && !w->isdir && !w->isscratch) - b =3D modbutton; - br.min =3D w->tag.scrollr.min; - br.max.x =3D br.min.x + Dx(b->r); - br.max.y =3D br.min.y + Dy(b->r); - draw(screen, br, b, nil, b->r.min); - + windrawbutton(w); w->tagsafe =3D TRUE; /* If mouse is in tag, pull up as tag closes. */ @@ -221,7 +231,11 @@ } } - if(!safe || !eqrect(w->body.r, r1)){ + + /* If needed, resize & redraw body. */ + r1 =3D r; + r1.min.y =3D y; + if(!safe || !eqrect(w->body.all, r1)){ oy =3D y; if(y+1+w->body.font->height <=3D r.max.y){ /* room = for one line */ r1.min.y =3D y; @@ -234,7 +248,7 @@ r1.min.y =3D y; r1.max.y =3D y; } - y =3D textresize(&w->body, r1); + y =3D textresize(&w->body, r1, keepextra); w->r =3D r; w->r.max.y =3D y; textscrdraw(&w->body); @@ -395,8 +409,6 @@ int i; texttype(t, r); - if(t->what =3D=3D Tag) - w->tagsafe =3D FALSE; if(t->what =3D=3D Body) for(i=3D0; ifile->ntext; i++) textscrdraw(t->file->text[i]); @@ -435,11 +447,9 @@ void winsettag1(Window *w) { - int i, j, k, n, bar, dirty; + int i, j, k, n, bar, dirty, resize; Rune *new, *old, *r; - Image *b; uint q0, q1; - Rectangle br; /* there are races that get us here with stuff in the tag cache, = so we take extra care to sync it */ if(w->tag.ncache!=3D0 || w->tag.file->mod) @@ -457,16 +467,17 @@ old =3D runemalloc(w->tag.file->nc+1); bufread(w->tag.file, 0, old, w->tag.file->nc); old[w->tag.file->nc] =3D '\0'; - w->tagsafe =3D FALSE; } + /* compute the text for the whole tag, replacing current only if = it differs */ new =3D runemalloc(w->body.file->nname+100); i =3D 0; - runemove(new+i, w->body.file->name, w->body.file->nname); + if(w->body.file->nname !=3D 0) + runemove(new, w->body.file->name, w->body.file->nname); i +=3D w->body.file->nname; runemove(new+i, L" Del Snarf", 10); i +=3D 10; if(w->filemenu){ - if(w->body.file->delta.nc>0 || w->body.ncache){ + if(w->body.needundo || w->body.file->delta.nc>0 || = w->body.ncache){ runemove(new+i, L" Undo", 5); i +=3D 5; } @@ -496,10 +507,12 @@ i +=3D 6; } } + new[i] =3D 0; - new[i] =3D 0; /* replace tag if the new one is different */ + resize =3D 0; if(runeeq(new, i, old, k) =3D=3D FALSE){ + resize =3D 1; n =3D k; if(n > i) n =3D i; @@ -520,7 +533,6 @@ w->tag.q1 =3D q1+bar; } } - w->tagsafe =3D FALSE; } free(old); free(new); @@ -531,15 +543,11 @@ if(w->tag.q1 > n) w->tag.q1 =3D n; textsetselect(&w->tag, w->tag.q0, w->tag.q1); - b =3D button; - if(!w->isdir && !w->isscratch && (w->body.file->mod || = w->body.ncache)) - b =3D modbutton; - br.min =3D w->tag.scrollr.min; - br.max.x =3D br.min.x + Dx(b->r); - br.max.y =3D br.min.y + Dy(b->r); - draw(screen, br, b, nil, b->r.min); - if(w->tagsafe =3D=3D FALSE) - winresize(w, w->r, TRUE); + windrawbutton(w); + if(resize){ + w->tagsafe =3D 0; + winresize(w, w->r, TRUE, TRUE); + } } void diff -r aa49706ca881 sys/src/libframe/frdraw.c --- a/sys/src/libframe/frdraw.c Wed May 12 22:40:51 2021 +0200 +++ b/sys/src/libframe/frdraw.c Thu May 20 11:58:46 2021 -0400 @@ -13,7 +13,7 @@ for(nb=3D0,b=3Df->box; nbnbox; nb++, b++){ _frcklinewrap(f, &pt, b); - if(b->nrune >=3D 0){ + if(!f->noredraw && b->nrune >=3D 0){ stringbg(f->b, pt, text, ZP, f->font, = (char*)b->ptr, back, ZP); } pt.x +=3D b->wid;