9front - general discussion about 9front
 help / color / mirror / Atom feed
* [9front] Patch for libframe and acme to eliminate redrawing body of documents when typing in the tagline.
@ 2021-05-20 18:14 David Leimbach
  2021-05-20 18:53 ` unobe
  2021-06-26 22:57 ` ori
  0 siblings, 2 replies; 6+ messages in thread
From: David Leimbach @ 2021-05-20 18:14 UTC (permalink / raw)
  To: 9front

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 = 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;
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 = 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);
}
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 = 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);
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 = 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);
		}
	}
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 = 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)
+	if(Dy(r) <= 0)
+		r.max.y = r.min.y;
+	else if(!keepextra)
		r.max.y -= Dy(r)%t->font->height;
-	else
-		r.max.y = r.min.y;
	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,29 +715,43 @@
		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:
		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
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 = 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)
{
@@ -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;

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


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-07-26  1:33 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-20 18:14 [9front] Patch for libframe and acme to eliminate redrawing body of documents when typing in the tagline 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
2021-07-26  0:44     ` ori

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