[comp.windows.x] Window border bug

karenb@westford.ccur.com (Karen Bircsak) (04/12/90)

			  X Window System Bug Report
			    xbugs@expo.lcs.mit.edu


VERSION:
    R4 (Patchlevel 9, not using SHAPE extension)

CLIENT MACHINE and OPERATING SYSTEM:
    Concurrent 5400 (68020-based) running RTU (real-time unix)

DISPLAY TYPE:
    Concurrent 12-plane GA1000

WINDOW MANAGER:
    uwm (R3)
    (I'm still trying to port the server to R4 & haven't started porting the
    clients yet!:-)

AREA:
    server

SYNOPSIS:
    Window border portions are not being repainted when the window is resized.

DESCRIPTION:
    If the window is changing size, SlideAndSizeWindow() 
    {mit/server/dix/window.c} saves the currently-visible border region in 
    the window's valdata.before.borderVisible structure.  However, in certain 
    cases (as when the window is being resized) some portions of the existing 
    border may be overdrawn in the ddx CopyWindow routine, but are not removed 
    from borderVisible.  miComputeClips() {mit/server/ddx/mi/mivaltree.c} uses 
    the borderVisible region to decide which portions of the border to repaint 
    in HandleExposures() {mit/server/dix/window.c}.  The portions that were 
    overdrawn are not repainted because it is assumed they are still visible.

REPEAT BY:
    I started up an xclock (with -bw 4 to make it easier to see.)  Then I 
    resized the window using uwm.  (I know it's unsupported but it doesn't slap 
    on its own borders like mwm.  This problem doesn't show up with mwm.)  

SAMPLE FIX:
    This is a first cut and may not be the most efficient solution.  It seems
    to work OK for the few cases I tested.  File is mit/server/dix/window.c.

***************
*** 2188,2193
      SetWinSize (pWin);
      SetBorderSize (pWin);
  
      dw = (int)w - (int)width;
      dh = (int)h - (int)height;
      ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);

--- 2188,2209 -----
      SetWinSize (pWin);
      SetBorderSize (pWin);
  
+     /*
+     ** We need to redraw portions of the border that will be overwritten
+     ** when the window is moved to the new position.  So remove them
+     ** from borderVisible.
+     */
+     if (borderVisible && (shrunk || newx != oldx || newy != oldy))
+     {
+         RegionRec overlap;
+ 
+         (*pScreen->RegionInit) (&overlap, NullBox, 0);
+         (*pScreen->Intersect) (&overlap, borderVisible,
+                                 &pWin->borderSize);
+         (*pScreen->Subtract) (borderVisible, borderVisible, &overlap);
+         (*pScreen->RegionUninit) (&overlap);
+     }
+ 
      dw = (int)w - (int)width;
      dh = (int)h - (int)height;
      ResizeChildrenWinSize(pWin, x - oldx, y - oldy, dw, dh);

--------------------------------------------------------------------------------
...!{decvax,uunet}!masscomp!karenb
karenb@westford.ccur.com
--------------------------------------------------------------------------------