ref: 502b51ff4082dcdf557bafafc2450637a5a6109b
parent: ed2124f31c1951c787469a9b140733c8cd024984
author: aap <[email protected]>
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