9front - general discussion about 9front
 help / color / mirror / Atom feed
From: ori@eigenstate.org
To: 9front@9front.org
Subject: Re: [9front] Patch for libframe and acme to eliminate redrawing body of documents when typing in the tagline.
Date: Wed, 14 Jul 2021 18:49:01 -0400	[thread overview]
Message-ID: <8C7FAF35B198ED4A031CABAE694F097C@eigenstate.org> (raw)
In-Reply-To: <1B8E29F8DEDD6F983112C3915D7FDED9@eigenstate.org>

Quoth ori@eigenstate.org:
> Quoth David Leimbach <leimy2k@icloud.com>:
> > 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 */
> > };
> > 
> 
> Just as a note, your mail client appears to have also
> mangled the text of this patch. Got it to apply with
> a couple of edits:
> 
> 	,s/^[^	@+\-]/ &/g
> 
> but it seems to have stripped the leading space from
> a bunch of lines.
> 

This is working well for me. Kivk(?) has reported
some redraw artifacts which I can't reproduce.

If anyone else wants to test, let me know -- but
otherwise, I'll commit this weekend.

(Below, an updated patch that should apply just fine:)

--- //.git/fs/object/6560e7c6fd26dc99604beba0f45292f592155aeb/tree//sys/include/frame.h
+++ /sys/include/frame.h
@@ -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);
binary files /tmp/diff100003385159 /sys/src/cmd/acme/6.out differ
--- //.git/fs/object/6560e7c6fd26dc99604beba0f45292f592155aeb/tree//sys/src/cmd/acme/acme.c
+++ /sys/src/cmd/acme/acme.c
@@ -256,6 +256,7 @@
 	w->body.file->mod = FALSE;
 	w->dirty = 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;
--- //.git/fs/object/6560e7c6fd26dc99604beba0f45292f592155aeb/tree//sys/src/cmd/acme/cols.c
+++ /sys/src/cmd/acme/cols.c
@@ -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;
@@ -215,7 +215,7 @@
 		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 +271,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);
@@ -298,7 +298,7 @@
 			r.max.y = cr.max.y;
 		else
 			r.max.y = c->w[i+1]->r.min.y;
-		winresize(w, r, FALSE);
+		winresize(w, r, FALSE, TRUE);
 		return;
 	}
 	cr.min.y = c->w[0]->r.min.y;
@@ -309,7 +309,7 @@
 			c->w[i] = v;
 		}
 		draw(screen, cr, textcols[BACK], nil, ZP);
-		winresize(w, cr, FALSE);
+		winresize(w, cr, FALSE, TRUE);
 		for(i=1; i<c->nw; i++)
 			c->w[i]->body.maxlines = 0;
 		c->safe = FALSE;
@@ -367,7 +367,7 @@
 			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);
+			winresize(v, r, c->safe, FALSE);
 		}
 		r.min.y = v->r.max.y;
 		r.max.y += Border;
@@ -389,17 +389,12 @@
 	/* 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);
-	}
+	r.max.y = winresize(w, r, c->safe, TRUE);
 	if(i < c->nw-1){
 		r.min.y = r.max.y;
 		r.max.y += Border;
@@ -413,24 +408,18 @@
 		v = c->w[j];
 		r = v->r;
 		r.min.y = y1;
-		r.max.y = y1+Dy(v->tag.all);
+		//r.max.y = y1+Dy(v->tag.all);
+		r.max.y = y1+Dy(v->tagtop);
 		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);
-		}
+		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;
 			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 +454,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);
@@ -494,10 +485,10 @@
 	if(i == 0)
 		return;
 	v = c->w[i-1];
-	if(p.y < v->tag.all.max.y)
-		p.y = v->tag.all.max.y;
-	if(p.y > w->r.max.y-Dy(w->tag.all)-Border)
-		p.y = w->r.max.y-Dy(w->tag.all)-Border;
+	if(p.y < v->tagtop.max.y)
+		p.y = v->tagtop.max.y;
+	if(p.y > w->r.max.y-Dy(w->tagtop)-Border)
+		p.y = w->r.max.y-Dy(w->tagtop)-Border;
 	r = v->r;
 	r.max.y = p.y;
 	if(r.max.y > v->body.r.min.y){
@@ -505,11 +496,7 @@
 		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;
+	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;
@@ -517,10 +504,7 @@
 		r.max.y = c->r.max.y;
 	else
 		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);
 }
--- //.git/fs/object/6560e7c6fd26dc99604beba0f45292f592155aeb/tree//sys/src/cmd/acme/dat.h
+++ /sys/src/cmd/acme/dat.h
@@ -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);
--- //.git/fs/object/6560e7c6fd26dc99604beba0f45292f592155aeb/tree//sys/src/cmd/acme/exec.c
+++ /sys/src/cmd/acme/exec.c
@@ -908,6 +908,8 @@
 		textinsert(t, t->file->nc, L"\n", 1, TRUE);
 		textsetselect(t, t->file->nc, t->file->nc);
 	}
+	t->iq1 = t->q1;
+	textshow(t, t->q1, t->q1, 1);
 }
 
 void
@@ -1219,7 +1221,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);
--- //.git/fs/object/6560e7c6fd26dc99604beba0f45292f592155aeb/tree//sys/src/cmd/acme/rows.c
+++ /sys/src/cmd/acme/rows.c
@@ -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);
@@ -258,6 +258,9 @@
 	Window *w;
 	Text *t;
 
+	if (r == 0)
+		r = 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 == Tag) {
+				//t->w->tagsafe = FALSE;
+				if(r == '\n')
+					t->w->tagexpand = TRUE;
+				winresize(w, w->r, TRUE, TRUE);
+			}
 			winunlock(w);
 		}
 	}
--- //.git/fs/object/6560e7c6fd26dc99604beba0f45292f592155aeb/tree//sys/src/cmd/acme/text.c
+++ /sys/src/cmd/acme/text.c
@@ -45,7 +45,8 @@
 	frinit(t, r, f, b, t->Frame.cols);
 	rr = t->r;
 	rr.min.x -= 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 = maxtab;
 	if(t->what == Body){
@@ -68,14 +69,14 @@
 }
 
 int
-textresize(Text *t, Rectangle r)
+textresize(Text *t, Rectangle r, int keepextra)
 {
 	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(!keepextra)
+		r.max.y -= Dy(r)%t->font->height;
 	odx = Dx(t->all);
 	t->all = r;
 	t->scrollr = r;
@@ -84,9 +85,17 @@
 	r.min.x += 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 -= 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
 textclose(Text *t)
 {
@@ -276,7 +285,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);
@@ -364,6 +373,8 @@
 			}
 					
 	}
+	if(q0 < t->iq1)
+		t->iq1 += n;
 	if(q0 < t->q1)
 		t->q1 += n;
 	if(q0 < t->q0)
@@ -457,6 +468,8 @@
 				}
 			}
 	}
+	if(q0 < t->iq1)
+		t->iq1 -= min(n, t->iq1-q0);
 	if(q0 < t->q0)
 		t->q0 -= min(n, t->q0-q0);
 	if(q0 < t->q1)
@@ -668,6 +681,11 @@
 	Rune *rp;
 	Text *u;
 
+	if(t->what!=Body && t->what!=Tag && r=='\n')
+		return;
+	if(t->what == Tag)
+		t->w->tagsafe = FALSE;
+
 	nr = 1;
 	rp = &r;
 	switch(r){
@@ -682,9 +700,13 @@
 			textshow(t, t->q1+1, t->q1+1, TRUE);
 		return;
 	case Kdown:
+		if(t->what == Tag)
+			goto Tagdown;
 		n = t->maxlines/3;
 		goto case_Down;
 	case Kscrollonedown:
+		if(t->what == Tag)
+			goto Tagdown;
 		n = mousescrollsize(t->maxlines);
 		if(n <= 0)
 			n = 1;
@@ -693,13 +715,16 @@
 		n = 2*t->maxlines/3;
 	case_Down:
 		q0 = t->org+frcharofpt(t, Pt(t->r.min.x, t->r.min.y+n*t->font->height));
-		if(t->what == Body)
-			textsetorigin(t, q0, TRUE);
+		textsetorigin(t, q0, TRUE);
 		return;
 	case Kup:
+		if(t->what == Tag)
+			goto Tagup;
 		n = t->maxlines/3;
 		goto case_Up;
 	case Kscrolloneup:
+		if(t->what == Tag)
+			goto Tagup;
 		n = mousescrollsize(t->maxlines);
 		goto case_Up;
 	case Kpgup:
@@ -706,16 +731,27 @@
 		n = 2*t->maxlines/3;
 	case_Up:
 		q0 = textbacknl(t, t->org, n);
-		if(t->what == 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 = 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 = t->file->nc;
+			}
+			q0 = 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 = TRUE;
+			winresize(t->w, t->w->r, FALSE, TRUE);
+		}
+		return;
+
+	Tagup:
+		/* shrink tag to single line */
+		if(t->w->tagexpand){
+			t->w->tagexpand = FALSE;
+			winresize(t->w, t->w->r, FALSE, TRUE);
+		}
+		return;
 	}
+
 	if(t->what == Body){
 		seq++;
 		filemark(t->file);
@@ -812,7 +865,7 @@
 		}
 		break;
 	case '\n':
-		if(t->what == Body && t->w->indent[AUTOINDENT]){
+		if(t->w->indent[AUTOINDENT]){
 			/* find beginning of previous line using backspace code */
 			nnb = textbswidth(t, 0x15); /* ^U case */
 			rp = runemalloc(nnb + 1);
@@ -825,6 +878,7 @@
 				rp[nr++] = rr;
 			}
 		}
+
 		break; /* fall through to normal code */
 	}
 	/* otherwise ordinary character; just insert, typically in caches of all texts */
@@ -836,6 +890,16 @@
 			u->cq0 = t->q0;
 		else if(t->q0 != 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==Body && u->ncache==0) {
+			u->needundo = TRUE;
+			winsettag(t->w);
+			u->needundo = FALSE;
+		}
 		textinsert(u, t->q0, rp, nr, FALSE);
 		if(u != t)
 			textsetselect(u, u->q0, u->q1);
@@ -851,6 +915,7 @@
 	textsetselect(t, t->q0+nr, t->q0+nr);
 	if(r=='\n' && t->w!=nil)
 		wincommit(t->w, t);
+	t->iq1 = t->q0;
 }
 
 void
--- //.git/fs/object/6560e7c6fd26dc99604beba0f45292f592155aeb/tree//sys/src/cmd/acme/wind.c
+++ /sys/src/cmd/acme/wind.c
@@ -13,7 +13,25 @@
 
 int	winid;
 
+/*
+ * Draw the appropriate button.
+ */
 void
+windrawbutton(Window *w)
+{
+	Image *b;
+	Rectangle br;
+
+	b = button;
+	if(!w->isdir && !w->isscratch && (w->body.file->mod || w->body.ncache))
+		b = modbutton;
+	br.min = w->tag.scrollr.min;
+	br.max.x = br.min.x + Dx(b->r);
+	br.max.y = br.min.y + Dy(b->r);
+	draw(screen, br, b, nil, b->r.min);
+}
+
+void
 wininit(Window *w, Window *clone, Rectangle r)
 {
 	Rectangle r1, br;
@@ -33,9 +51,11 @@
 	w->ctlfid = ~0;
 	w->utflastqid = -1;
 	r1 = r;
-	r1.max.y = r1.min.y + font->height;
+
 	w->tagtop = r;
 	w->tagtop.max.y = r.min.y + font->height;
+	r1.max.y = r1.min.y + w->taglines * font->height;
+
 	incref(&reffont);
 	f = 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 = r;
-	w->r.max.y = w->body.r.max.y;
 	br.min = w->tag.scrollr.min;
 	br.max.x = br.min.x + Dx(button->r);
 	br.max.y = br.min.y + Dy(button->r);
@@ -136,9 +155,9 @@
 	if(!w->tagexpand && !w->showdel)
 		return 1;
 	w->showdel = FALSE;
-	w->noredraw = 1;
-	textresize(&w->tag, r);
-	w->noredraw = 0;
+	w->tag.noredraw = 1;
+	textresize(&w->tag, r, TRUE);
+	w->tag.noredraw = 0;
 	w->tagsafe = FALSE;
 	
 	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 = ptinrect(mouse->xy, w->tag.all);
 	mouseinbody = ptinrect(mouse->xy, w->body.all);
 
+	/* tagtop is the first line of the 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 needed, recompute the number of lies in the tag. */
 	if(!safe || !w->tagsafe || !eqrect(w->tag.all, 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)
-			b = modbutton;
-		br.min = w->tag.scrollr.min;
-		br.max.x = br.min.x + Dx(b->r);
-		br.max.y = br.min.y + Dy(b->r);
-		draw(screen, br, b, nil, b->r.min);
-
+		windrawbutton(w);
 		w->tagsafe = 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 = r;
+	r1.min.y = y;
+	if(!safe || !eqrect(w->body.all, r1)){
 		oy = y;
 		if(y+1+w->body.font->height <= r.max.y){	/* room for one line */
   			r1.min.y = y;
@@ -234,7 +248,7 @@
 			r1.min.y = y;
 			r1.max.y = y;
 		}
-		y = textresize(&w->body, r1);
+		y = textresize(&w->body, r1, keepextra);
 		w->r = r;
 		w->r.max.y = y;
 		textscrdraw(&w->body);
@@ -395,8 +409,6 @@
 	int i;
 
 	texttype(t, r);
-	if(t->what == Tag)
-		w->tagsafe = FALSE;
 	if(t->what == Body)
 		for(i=0; i<t->file->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!=0 || w->tag.file->mod)
@@ -457,16 +467,17 @@
 		old = runemalloc(w->tag.file->nc+1);
 		bufread(w->tag.file, 0, old, w->tag.file->nc);
 		old[w->tag.file->nc] = '\0';
-		w->tagsafe = FALSE;
 	}
+	/* compute the text for the whole tag, replacing current only if it differs */
 	new = runemalloc(w->body.file->nname+100);
 	i = 0;
-	runemove(new+i, w->body.file->name, w->body.file->nname);
+	if(w->body.file->nname != 0)
+		runemove(new, w->body.file->name, w->body.file->nname);
 	i += w->body.file->nname;
 	runemove(new+i, L" Del Snarf", 10);
 	i += 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 += 5;
 		}
@@ -496,10 +507,12 @@
 			i += 6;
 		}
 	}
-
 	new[i] = 0;
+
 	/* replace tag if the new one is different */
+	resize = 0;
 	if(runeeq(new, i, old, k) == FALSE){
+		resize = 1;
 		n = k;
 		if(n > i)
 			n = i;
@@ -520,7 +533,6 @@
 				w->tag.q1 = q1+bar;
 			}
 		}
-		w->tagsafe = FALSE;
 	}
 	free(old);
 	free(new);
@@ -531,15 +543,11 @@
 	if(w->tag.q1 > n)
 		w->tag.q1 = n;
 	textsetselect(&w->tag, w->tag.q0, w->tag.q1);
-	b = button;
-	if(!w->isdir && !w->isscratch && (w->body.file->mod || w->body.ncache))
-		b = modbutton;
-	br.min = w->tag.scrollr.min;
-	br.max.x = br.min.x + Dx(b->r);
-	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);
+	windrawbutton(w);
+	if(resize){
+		w->tagsafe = 0;
+		winresize(w, w->r, TRUE, TRUE);
+	}
 }
 
 void
--- //.git/fs/object/6560e7c6fd26dc99604beba0f45292f592155aeb/tree//sys/src/libframe/frdraw.c
+++ /sys/src/libframe/frdraw.c
@@ -13,7 +13,7 @@
 
 	for(nb=0,b=f->box; nb<f->nbox; nb++, b++){
 		_frcklinewrap(f, &pt, b);
-		if(b->nrune >= 0){
+		if(!f->noredraw && b->nrune >= 0){
 			stringbg(f->b, pt, text, ZP, f->font, (char*)b->ptr, back, ZP);
 		}
 		pt.x += b->wid;


  reply	other threads:[~2021-07-14 22:56 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-20 18:14 David Leimbach
2021-05-20 18:53 ` unobe
2021-06-26 22:54   ` ori
2021-06-26 22:57 ` ori
2021-07-14 22:49   ` ori [this message]
2021-07-26  0:44     ` ori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8C7FAF35B198ED4A031CABAE694F097C@eigenstate.org \
    --to=ori@eigenstate.org \
    --cc=9front@9front.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).