fix: calm down winwatch and assure its full repaint
This commit is contained in:
@@ -35,7 +35,9 @@ int sortlabels;
|
|||||||
int showwmnames;
|
int showwmnames;
|
||||||
extern Font *font;
|
extern Font *font;
|
||||||
Image *lightblue;
|
Image *lightblue;
|
||||||
|
Image *backbuffer = nil;
|
||||||
|
vlong last = 0;
|
||||||
|
vlong now;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PAD = 3,
|
PAD = 3,
|
||||||
@@ -276,7 +278,7 @@ refreshwin(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
drawnowin(int i)
|
drawnowin(Image *dst, int i)
|
||||||
{
|
{
|
||||||
Rectangle r;
|
Rectangle r;
|
||||||
|
|
||||||
@@ -286,17 +288,17 @@ drawnowin(int i)
|
|||||||
Pt(MARGIN + (PAD + Dx(r)) * (i / rows),
|
Pt(MARGIN + (PAD + Dx(r)) * (i / rows),
|
||||||
MARGIN + (PAD + Dy(r)) * (i % rows))),
|
MARGIN + (PAD + Dy(r)) * (i % rows))),
|
||||||
screen->r.min);
|
screen->r.min);
|
||||||
draw(screen, insetrect(r, -1), lightblue, nil, ZP);
|
draw(dst, insetrect(r, -1), lightblue, nil, ZP);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
drawwin(int i)
|
drawwin(Image *dst, int i)
|
||||||
{
|
{
|
||||||
draw(screen, win[i].r, lightblue, nil, ZP);
|
draw(dst, win[i].r, lightblue, nil, ZP);
|
||||||
_string(screen, addpt(win[i].r.min, Pt(2, 0)), display->black, ZP,
|
_string(dst, addpt(win[i].r.min, Pt(2, 0)), display->black, ZP,
|
||||||
font, win[i].label, nil, strlen(win[i].label),
|
font, win[i].label, nil, strlen(win[i].label),
|
||||||
win[i].r, nil, ZP, SoverD);
|
win[i].r, nil, ZP, SoverD);
|
||||||
border(screen, win[i].r, 1, display->black, ZP);
|
border(dst, win[i].r, 1, display->black, ZP);
|
||||||
win[i].dirty = 0;
|
win[i].dirty = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,17 +338,39 @@ redraw(Image *screen, int all)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
all |= geometry();
|
all |= geometry();
|
||||||
if(all)
|
|
||||||
draw(screen, screen->r, lightblue, nil, ZP);
|
/* 1. Allocate/Resize buffer only if screen size changes */
|
||||||
|
if(backbuffer == nil || Dx(backbuffer->r) != Dx(screen->r) || Dy(backbuffer->r) != Dy(screen->r)){
|
||||||
|
if(backbuffer)
|
||||||
|
freeimage(backbuffer);
|
||||||
|
|
||||||
|
/* Create buffer with the same coordinates as the screen */
|
||||||
|
backbuffer = allocimage(display, screen->r, screen->chan, 0, DWhite);
|
||||||
|
if(backbuffer == nil)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2. Paint background on the off-screen buffer */
|
||||||
|
draw(backbuffer, backbuffer->r, lightblue, nil, ZP);
|
||||||
|
|
||||||
|
/* 3. Draw all items onto the buffer */
|
||||||
for(i=0; i<nwin; i++)
|
for(i=0; i<nwin; i++)
|
||||||
if(all || win[i].dirty)
|
drawwin(backbuffer, i);
|
||||||
drawwin(i);
|
|
||||||
if(!all)
|
|
||||||
for (; i<onwin; i++)
|
for (; i<onwin; i++)
|
||||||
drawnowin(i);
|
drawnowin(backbuffer, i);
|
||||||
|
|
||||||
|
/* 4. Atomic Copy to Screen (The Fix) */
|
||||||
|
/* We use backbuffer->r.min as the source point, ensuring alignment */
|
||||||
|
draw(screen, screen->r, backbuffer, nil, backbuffer->r.min);
|
||||||
|
|
||||||
|
/* 5. Force the update to the X server immediately */
|
||||||
|
flushimage(display, 1);
|
||||||
|
|
||||||
onwin = nwin;
|
onwin = nwin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
eresized(int new)
|
eresized(int new)
|
||||||
{
|
{
|
||||||
@@ -483,9 +507,18 @@ main(int argc, char **argv)
|
|||||||
case Emouse:
|
case Emouse:
|
||||||
if(e.mouse.buttons)
|
if(e.mouse.buttons)
|
||||||
click(e.mouse);
|
click(e.mouse);
|
||||||
/* fall through */
|
|
||||||
|
/* Rate-limited fallthrough */
|
||||||
|
now = nsec();
|
||||||
|
/* If less than 200ms (200,000,000ns) has passed, skip refresh */
|
||||||
|
if(now - last < 200*1000000LL)
|
||||||
|
break;
|
||||||
|
/* Otherwise, fall through to refresh */
|
||||||
|
|
||||||
default: /* Etimer */
|
default: /* Etimer */
|
||||||
|
last = nsec();
|
||||||
refreshwin();
|
refreshwin();
|
||||||
|
/* Always redraw. It is cheap now, with the buffered drawing and the limited rate. */
|
||||||
redraw(screen, 0);
|
redraw(screen, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user