Tk Source Code

Artifact [9f040490]
Login

Artifact 9f0404904ae610f8a70b96ada197f9c322e58709:

Attachment "raise-delay-8-3-4.patch" to ticket [601518ff] added by jenglish 2002-09-04 03:01:49.
Index: tkUnixWm.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/unix/tkUnixWm.c,v
retrieving revision 1.8.2.1
diff -c -r1.8.2.1 tkUnixWm.c
*** tkUnixWm.c	28 Aug 2001 19:28:43 -0000	1.8.2.1
--- tkUnixWm.c	3 Sep 2002 19:56:58 -0000
***************
*** 4082,4089 ****
   *
   * Side effects:
   *	WinPtr gets restacked  as specified by aboveBelow and otherPtr.
-  *	This procedure doesn't return until the restack has taken
-  *	effect and the ConfigureNotify event for it has been received.
   *
   *----------------------------------------------------------------------
   */
--- 4082,4087 ----
***************
*** 4098,4288 ****
  				 * above or below *all* siblings. */
  {
      XWindowChanges changes;
-     XWindowAttributes atts;
      unsigned int mask;
-     Window window, dummy1, dummy2, vRoot;
-     Window *children;
-     unsigned int numChildren;
-     int i;
-     int desiredIndex = 0;	/* Initialized to stop gcc warnings. */
-     int ourIndex = 0;		/* Initialized to stop gcc warnings. */
-     unsigned long serial;
-     Tk_ErrorHandler handler;
      TkWindow *wrapperPtr;
  
      changes.stack_mode = aboveBelow;
-     changes.sibling = None;
      mask = CWStackMode;
-     if (winPtr->window == None) {
- 	Tk_MakeWindowExist((Tk_Window) winPtr);
-     }
-     if (winPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) {
- 	/*
- 	 * Can't set stacking order properly until the window is on the
- 	 * screen (mapping it may give it a reparent window), so make sure
- 	 * it's on the screen.
- 	 */
- 
- 	TkWmMapWindow(winPtr);
-     }
-     wrapperPtr = winPtr->wmInfoPtr->wrapperPtr;
-     window = (winPtr->wmInfoPtr->reparent != None)
- 	    ? winPtr->wmInfoPtr->reparent : wrapperPtr->window;
-     if (otherPtr != NULL) {
- 	if (otherPtr->window == None) {
- 	    Tk_MakeWindowExist((Tk_Window) otherPtr);
- 	}
- 	if (otherPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) {
- 	    TkWmMapWindow(otherPtr);
- 	}
- 	changes.sibling = (otherPtr->wmInfoPtr->reparent != None)
- 		? otherPtr->wmInfoPtr->reparent
- 		: otherPtr->wmInfoPtr->wrapperPtr->window;
- 	mask = CWStackMode|CWSibling;
-     }
  
      /*
!      * Before actually reconfiguring the window, see if it's already
!      * in the right place.  If so then don't reconfigure it.  The
!      * reason for this extra work is that some window managers will
!      * ignore the reconfigure request if the window is already in
!      * the right place, causing a long delay in WaitForConfigureNotify
!      * while it times out.  Special note: if the window is almost in
!      * the right place, and the only windows between it and the right
!      * place aren't mapped, then we don't reconfigure it either, for
!      * the same reason.
       */
! 
!     vRoot = winPtr->wmInfoPtr->vRoot;
!     if (vRoot == None) {
! 	vRoot = RootWindowOfScreen(Tk_Screen((Tk_Window) winPtr));
      }
!     if (XQueryTree(winPtr->display, vRoot, &dummy1, &dummy2,
! 	    &children, &numChildren) != 0) {
! 	/*
! 	 * Find where our window is in the stacking order, and
! 	 * compute the desired location in the stacking order.
! 	 */
! 
! 	for (i = 0; i < numChildren; i++) {
! 	    if (children[i] == window) {
! 		ourIndex = i;
! 	    }
! 	    if (children[i] == changes.sibling) {
! 		desiredIndex = i;
! 	    }
! 	}
! 	if (mask & CWSibling) {
! 	    if (aboveBelow == Above) {
! 		if (desiredIndex < ourIndex) {
! 		    desiredIndex += 1;
! 		}
! 	    } else {
! 		if (desiredIndex > ourIndex) {
! 		    desiredIndex -= 1;
! 		}
! 	    }
! 	} else {
! 	    if (aboveBelow == Above) {
! 		desiredIndex = numChildren-1;
! 	    } else {
! 		desiredIndex = 0;
! 	    }
! 	}
  
  	/*
! 	 * See if there are any mapped windows between where we are
! 	 * and where we want to be.
  	 */
! 
! 	handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1,
! 		(Tk_ErrorProc *) NULL, (ClientData) NULL);
! 	while (desiredIndex != ourIndex) {
! 	    if ((XGetWindowAttributes(winPtr->display, children[desiredIndex],
! 		    &atts) != 0) && (atts.map_state != IsUnmapped)) {
! 		break;
! 	    }
! 	    if (desiredIndex < ourIndex) {
! 		desiredIndex++;
! 	    } else {
! 		desiredIndex--;
! 	    }
! 	}
! 	Tk_DeleteErrorHandler(handler);
! 	XFree((char *) children);
! 	if (ourIndex == desiredIndex) {
! 	    return;
  	}
      }
  
      /*
!      * Reconfigure the window.  This tricky because of two things:
!      * (a) Some window managers, like olvwm, insist that we raise
!      *     or lower the toplevel window itself, as opposed to its
!      *     decorative frame.  Attempts to raise or lower the frame
!      *     are ignored.
!      * (b) If the raise or lower is relative to a sibling, X will
!      *     generate an error unless we work with the frames (the
!      *     toplevels themselves aren't siblings).
!      * Fortunately, the procedure XReconfigureWMWindow is supposed
!      * to handle all of this stuff, so be careful to use it instead
!      * of XConfigureWindow.
       */
  
-     serial = NextRequest(winPtr->display);
-     if (window != wrapperPtr->window) {
- 	/*
- 	 * We're going to have to wait for events on a window that
- 	 * Tk doesn't own, so we have to tell X specially that we
- 	 * want to get events on that window.  To make matters worse,
- 	 * it's possible that the window doesn't exist anymore (e.g.
- 	 * the toplevel could have been withdrawn) so ignore events
- 	 * occurring during the request.
- 	 */
- 
- 	handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1,
- 		(Tk_ErrorProc *) NULL, (ClientData) NULL);
- 	XSelectInput(winPtr->display, window, StructureNotifyMask);
- 	Tk_DeleteErrorHandler(handler);
-     }
      XReconfigureWMWindow(winPtr->display, wrapperPtr->window,
  	    Tk_ScreenNumber((Tk_Window) winPtr), mask,  &changes);
- 
-     /*
-      * Wait for the reconfiguration to complete.  If we don't wait, then
-      * the window may not restack for a while and the application might
-      * observe it before it has restacked.  Waiting for the reconfiguration
-      * is tricky if winPtr has been reparented, since the window getting
-      * the event isn't one that Tk owns.
-      */
- 
-     if (window == wrapperPtr->window) {
- 	WaitForConfigureNotify(winPtr, serial);
-     } else {
- 	XEvent event;
- 	int diff;
- 
- 	while (1) {
- 	    if (WaitForEvent(winPtr->display, winPtr->wmInfoPtr,
- 		    ConfigureNotify, &event) != TCL_OK) {
- 		break;
- 	    }
- 	    diff = event.xconfigure.serial - serial;
- 	    if (diff >= 0) {
- 		break;
- 	    }
- 	}
- 	/*
- 	 * Ignore errors that occur when we are de-selecting events on
- 	 * window, since it's possible that the window doesn't exist
- 	 * anymore (see comment above previous call to XSelectInput).
- 	 */
- 
- 	handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1,
- 		(Tk_ErrorProc *) NULL, (ClientData) NULL);
- 	XSelectInput(winPtr->display, window, (long) 0);
- 	Tk_DeleteErrorHandler(handler);
-     }
  }
  
  /*
--- 4096,4138 ----
  				 * above or below *all* siblings. */
  {
      XWindowChanges changes;
      unsigned int mask;
      TkWindow *wrapperPtr;
  
+     memset(&changes, 0, sizeof(XWindowChanges));
      changes.stack_mode = aboveBelow;
      mask = CWStackMode;
  
      /*
!      * Make sure that winPtr and its wrapper window have been created.
       */
!     if (winPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) {
! 	TkWmMapWindow(winPtr);
      }
!     wrapperPtr = winPtr->wmInfoPtr->wrapperPtr;
  
+     if (otherPtr != NULL) {
  	/*
! 	 * The window is to be restacked with respect to another toplevel.
! 	 * Make sure it has been created as well.
  	 */
! 	if (otherPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) {
! 	    TkWmMapWindow(otherPtr);
  	}
+ 	changes.sibling = otherPtr->wmInfoPtr->wrapperPtr->window;
+ 	mask |= CWSibling;
      }
  
      /*
!      * Reconfigure the window.  Note that we use XReconfigureWMWindow
!      * instead of XConfigureWindow, in order to handle the case
!      * where the window is to be restacked with respect to another toplevel.  
!      * See [ICCCM] 4.1.5 "Configuring the Window" and XReconfigureWMWindow(3)
!      * for details.
       */
  
      XReconfigureWMWindow(winPtr->display, wrapperPtr->window,
  	    Tk_ScreenNumber((Tk_Window) winPtr), mask,  &changes);
  }
  
  /*