[comp.windows.x] Your double repaint problem

MAP@LCS.MIT.EDU (Michael A. Patton) (08/31/89)

I used a different approach to solving this general problem (alluded
to briefly in my previous message).  Be aware that the simple solution
as you describe will still get double repaints.  If the window is
popped up through several different overlapping windows it will get a
bunch of Expose events.

I used a solution with a flag which for reference I will call
"need_repaint".  The code below is from a program that uses Xlib, not
a toolkit, but it may be quite possible to adapt this approach.  There
must be some place where you handle your incoming events, you can use
the following code (or something like it):
	if (need_repaint && !XPending(dpy)) Repaint();
	XNextEvent(dpy, &event);
where Repaint sets need_repaint back to FALSE before doing the
repaint.  Then in your event processing for Expose you have simply:
	case Expose:
	    need_repaint = TRUE;
	    break;
This will neatly arrange to get all the pending Expose events before
doing any repainting.  I can think of several approaches to adopting
this for Toolkit use, but since your problem is that you're
constrained by the structure of your existing program, I'll let you
figure out what works best for you.  If you want to discuss any
particulars, feel free to contact me directly.

	    __
  /|  /|  /|  \		Michael A. Patton, Network Manager
 / | / | /_|__/		Laboratory for Computer Science
/  |/  |/  |atton	Massachusetts Institute of Technology

Disclaimer: The opinions expressed above are a figment of the phosphor
on your screen and do not represent the views of MIT, LCS, or MAP. :-)

jonnyg@AARDVARK.UMD.EDU (Jon Greenblatt) (08/31/89)

	The way I handle multiple repaints in one of my projects is the
following.

	1: If this is my first repaint event since the screen was last updated
		I create a region using the x,y,width, and height of
		the area that needs updating.
	   If this is not my first repaint event I add the new area to
		be painted to the original region using XUnionRectWithRegion.
	2: If the eposure count is 0 at this point I then take the regions
		I have collected and make them the clipping region of my
		current graphics context.

Here is a short clip of how the regions are collected. This is somewhat
dependent on my environment as you can see:

LOCAL addclip(Wnd,expose)
XlWindow Wnd;
XExposeEvent *expose;
        {XRectangle rect;
        if (Wnd->clip_count++ == 0)
                Wnd->clip_region = XCreateRegion();
        MAKE_XRECT(rect,expose->x,expose->y,
                        expose->width,expose->height);
        XUnionRectWithRegion(&rect,Wnd->clip_region,
                                   Wnd->clip_region);
        XClearArea(Dpy,Wnd->id,rect.x,rect.y,rect.width,rect.height,0);
        }

Here is where I set up for clipping:

        XSetRegion(Dpy,Wnd->expose_gc->id,
                        Wnd->clip_region);
        XDestroyRegion(Wnd->clip_region);
        Wnd->clip_count = 0;

I use this in my xlisp toolkit. If you would like to see the entire source
it in available VIA anonymous FTP from rover.umd.edu(128.8.2.73) in the
directory pub/xlisp2.0w.tar.Z. The file of interest is osstuff.x11 as it
contains the X11 dependent stuff. Toolkit designers may be interested in
some of my encapsulation methods I used here.

						JonnyG.