shithub: lola

Download patch

ref: 502b51ff4082dcdf557bafafc2450637a5a6109b
parent: ed2124f31c1951c787469a9b140733c8cd024984
author: aap <aap@papnet.eu>
date: Wed Feb 28 05:54:55 EST 2024

redid some window messaging. various cleanups

--- a/inc.h
+++ b/inc.h
@@ -67,6 +67,7 @@
 void xsetrects(Text *x, Rectangle textr, Rectangle scrollr);
 void xclear(Text *x);
 void xredraw(Text *x);
+void xfullredraw(Text *x);
 uint xinsert(Text *x, Rune *r, int n, uint q0);
 void xfill(Text *x);
 void xdelete(Text *x, uint q0, uint q1);
@@ -86,7 +87,7 @@
 void xcut(Text *x);
 void xpaste(Text *x);
 void xsend(Text *x);
-int xplumb(Text *w, char *dir, int maxsize);
+int xplumb(Text *w, char *src, char *dir, int maxsize);
 void freescrtemps(void);
 
 enum
@@ -179,7 +180,6 @@
 
 enum
 {
-	Closed,
 	Resized,
 	Moved,
 	Deleted,
@@ -253,7 +253,7 @@
 void wdecor(Window *w);
 void wresize(Window *w, Rectangle r);
 Window *wcreate(Rectangle r, bool hidden, bool scrolling);
-int wrelease(Window *w);
+void wrelease(Window *w);
 void wsendmsg(Window *w, int type);
 Window *wfind(int id);
 Window *wpointto(Point pt);
--- a/main.c
+++ b/main.c
@@ -482,7 +482,7 @@
 		xscrdraw(x);			// TODO let snarf handle this?
 		break;
 	case Plumb:
-		if(xplumb(x, w->dir, fsys.msize-1024)){
+		if(xplumb(x, "lola", w->dir, fsys.msize-1024)){
 			c = cursor;
 			setcursoroverride(&query, TRUE);
 			sleep(300);
--- a/text.c
+++ b/text.c
@@ -45,6 +45,20 @@
 	xscrdraw(x);
 }
 
+void
+xfullredraw(Text *x)
+{
+	xfill(x);
+	x->ticked = 0;
+	if(x->p0 > 0)
+		frdrawsel(x, frptofchar(x, 0), 0, x->p0, 0);
+	if(x->p1 < x->nchars)
+		frdrawsel(x, frptofchar(x, x->p1), x->p1, x->nchars, 0);
+	frdrawsel(x, frptofchar(x, x->p0), x->p0, x->p1, 1);
+	x->lastsr = ZR;
+	xscrdraw(x);
+}
+
 uint
 xinsert(Text *w, Rune *r, int n, uint q0)
 {
@@ -95,12 +109,8 @@
 		w->qh += n;
 	if(q0 < w->org)
 		w->org += n;
-	else if(q0 <= w->org+w->nchars){
-for(int i = 0; i < n; i++)
-if(r[i] == 0)
-abort();
+	else if(q0 <= w->org+w->nchars)
 		frinsert(w, r, r+n, q0-w->org);
-}
 	return q0;
 }
 
@@ -910,7 +920,7 @@
 }
 
 int
-xplumb(Text *w, char *dir, int maxsize)
+xplumb(Text *w, char *src, char *dir, int maxsize)
 {
 	Plumbmsg *m;
 	static int fd = -2;
@@ -922,7 +932,7 @@
 	if(fd < 0)
 		return 0;
 	m = emalloc(sizeof(Plumbmsg));
-	m->src = estrdup("lola");		/* TODO: argument? */
+	m->src = estrdup(src);
 	m->dst = nil;
 	m->wdir = estrdup(dir);
 	m->type = estrdup("text");
--- a/wind.c
+++ b/wind.c
@@ -158,6 +158,9 @@
 	free(w);
 }
 
+/* logically and visually close the window.
+ * struct and thread will stick around until all references are gone.
+ * safe to call multiple times. */
 static void
 wclose(Window *w)
 {
@@ -184,25 +187,28 @@
 }
 
 int
-wrelease(Window *w)
+inwinthread(Window *w)
 {
-	int i;
+	return w->threadname == threadgetname();
+}
 
-	i = decref(w);
-	if(i > 0)
-		return 0;
-	if(i < 0)
-		panic("negative ref count");
-	wunfocus(w);
-	wclose(w);
-	wsendmsg(w, Closed);
-	return 1;
+/* decrement reference, close window once all references gone. */
+void
+wrelease(Window *w)
+{
+	if(decref(w) == 0){
+		wunfocus(w);
+		wclose(w);
+		if(!inwinthread(w))
+			wsendmsg(w, Wakeup);
+	}else
+		assert(w->ref > 0);
 }
 
 void
 wsendmsg(Window *w, int type)
 {
-	assert(w->threadname != threadgetname());
+	assert(!inwinthread(w));
 	sendul(w->ctl, type);
 }
 
@@ -361,6 +367,17 @@
 }
 
 void
+wfocuschanged(Window *w)
+{
+	if(w == nil)
+		return;
+	w->wctlready = TRUE;
+	wrepaint(w);
+	if(!inwinthread(w))
+		wsendmsg(w, Wakeup);
+}
+
+void
 wfocus(Window *w)
 {
 	Window *prev;
@@ -369,18 +386,8 @@
 		return;
 	prev = focused;
 	focused = w;
-	/* TODO a bit ugly the repetition,
-	 * but this might not stay anyways */
-	if(prev){
-		prev->wctlready = TRUE;
-		wrepaint(prev);
-		wsendmsg(prev, Wakeup);
-	}
-	if(focused){
-		focused->wctlready = TRUE;
-		wrepaint(focused);
-		wsendmsg(focused, Wakeup);
-	}
+	wfocuschanged(prev);
+	wfocuschanged(focused);
 }
 
 void
@@ -423,13 +430,13 @@
 void
 wsethold(Window *w, int hold)
 {
-	int prev;
+	int switched;
 
 	if(hold)
-		prev = w->holdmode++;
+		switched = w->holdmode++ == 0;
 	else
-		prev = --w->holdmode;
-	if(prev == 0){
+		switched = --w->holdmode == 0;
+	if(switched){
 		wsetcursor(w);
 		wrepaint(w);
 	}
@@ -663,7 +670,7 @@
 			return;
 		case Kdel:
 			if(w->holdmode)
-				wsethold(w, 0);
+				wsethold(w, FALSE);
 			break;
 		}
 	}
@@ -705,7 +712,7 @@
 	wrelease(w);
 }
 
-int
+void
 winctl(Window *w, int type)
 {
 	Text *x;
@@ -713,10 +720,6 @@
 
 	x = &w->text;
 	switch(type){
-	case Closed:
-		wfree(w);
-		return 1;
-
 	case Deleted:
 		if(w->notefd >= 0)
 			write(w->notefd, "hangup", 6);
@@ -734,20 +737,12 @@
 		break;
 
 	case Refresh:
-/* TODO: clean this up? */
+		/* take over window again */
 		if(w->deleted)
 			break;
 		draw(w->img, w->img->r, x->cols[BACK], nil, ZP);
 		wdecor(w);
-		xfill(x);
-		x->ticked = 0;
-		if(x->p0 > 0)
-			frdrawsel(x, frptofchar(x, 0), 0, x->p0, 0);
-		if(x->p1 < x->nchars)
-			frdrawsel(x, frptofchar(x, x->p1), x->p1, x->nchars, 0);
-		frdrawsel(x, frptofchar(x, x->p0), x->p0, x->p1, 1);
-		x->lastsr = ZR;
-		xscrdraw(x);
+		xfullredraw(&w->text);
 		break;
 
 	case Holdon:
@@ -766,7 +761,6 @@
 		x->nraw = 0;
 		break;
 	}
-	return 0;
 }
 
 static void
@@ -948,10 +942,7 @@
 			break;
 
 		case ACtl:
-			if(winctl(w, cm)){
-				free(cnv.buf);
-				return;
-			}
+			winctl(w, cm);
 			break;
 
 		case AComplete:
@@ -973,6 +964,14 @@
 			break;
 		}
 		flushimage(display, 1);
+
+		/* window is gone, clean up and exit thread */
+		if(w->ref == 0){
+			wfree(w);
+			chanfree(fsc);
+			free(cnv.buf);
+			return;
+		}
 	}
 }
 
@@ -1009,14 +1008,17 @@
 		sendul(pidc, 0);
 		threadexits("open");	/* BUG? was terminate() */
 	}
-	if(wrelease(w) == 0){	/* remove extra ref hanging from creation */
-		notify(nil);
-		dup(1, 2);
-		if(dir)
-			chdir(dir);
-		procexec(pidc, cmd, argv);
-		_exits("exec failed");
-	}
+	/* remove extra ref hanging from creation.
+	 * not in main proc here, so be careful with wrelease! */
+	assert(w->ref > 1);
+	wrelease(w);
+
+	notify(nil);
+	dup(1, 2);
+	if(dir)
+		chdir(dir);
+	procexec(pidc, cmd, argv);
+	_exits("exec failed");
 }
 
 int