From: ouster@sprite.Berkeley.EDU (John Ousterhout)
Newsgroups: comp.lang.tcl
Subject: Re: Tk3.0 bug?
Date: 22 Dec 92 16:59:18 GMT
Organization: U.C. Berkeley Sprite Project
NNTP-Posting-Host: tyranny.berkeley.edu

Mea culpa.  When I posted a patch yesterday for the bug whereby
"wm withdraw" didn't work correctly, I forgot that I've made
several changes to tkWm.c since the release, and I didn't get them
all in the patch.  Here's a better tkWm.c patch:

*** /tmp/,RCSt1084828	Tue Dec 22 08:57:35 1992
--- tkWm.c	Mon Dec 21 11:43:16 1992
***************
*** 206,211 ****
--- 206,214 ----
   * WM_VROOT_OFFSET_STALE -	non-zero means that (x,y) offset information
   *				about the virtual root window is stale and
   *				needs to be fetched fresh from the X server.
+  * WM_ABOUT_TO_MAP -		non-zero means that the window is about to
+  *				be mapped by TkWmMapWindow.  This is used
+  *				by UpdateGeometryInfo to modify its behavior.
   */
  
  #define WM_NEVER_MAPPED		1
***************
*** 215,220 ****
--- 218,224 ----
  #define WM_UPDATE_SIZE_HINTS	0x10
  #define WM_SYNC_PENDING		0x20
  #define WM_VROOT_OFFSET_STALE	0x40
+ #define WM_ABOUT_TO_MAP		0x100
  
  /*
   * This module keeps a list of all top-level windows, primarily to
***************
*** 382,391 ****
      XTextProperty textProp;
      int savedX, savedY, savedFlags;
  
-     if (wmPtr->hints.initial_state == WithdrawnState) {
- 	return;
-     }
      if (wmPtr->flags & WM_NEVER_MAPPED) {
  	/*
  	 * This is the first time this window has ever been mapped.
  	 * Store all the window-manager-related information for the
--- 386,394 ----
      XTextProperty textProp;
      int savedX, savedY, savedFlags;
  
      if (wmPtr->flags & WM_NEVER_MAPPED) {
+ 	wmPtr->flags &= ~WM_NEVER_MAPPED;
+ 
  	/*
  	 * This is the first time this window has ever been mapped.
  	 * Store all the window-manager-related information for the
***************
*** 427,433 ****
--- 430,441 ----
  	    }
  	}
      }
+     if (wmPtr->hints.initial_state == WithdrawnState) {
+ 	return;
+     }
+     wmPtr->flags |= WM_ABOUT_TO_MAP;
      UpdateGeometryInfo((ClientData) winPtr);
+     wmPtr->flags &= ~WM_ABOUT_TO_MAP;
  
      /*
       * Map the window, wait to be sure that the window manager has
***************
*** 435,441 ****
       * if there were explicit positions asked for.
       */
  
-     wmPtr->flags &= ~WM_NEVER_MAPPED;
      XMapWindow(winPtr->display, winPtr->window);
      savedX = wmPtr->x;
      savedY = wmPtr->y;
--- 443,448 ----
***************
*** 585,590 ****
--- 592,603 ----
      char c;
      int length;
  
+     if (argc < 2) {
+ 	wrongNumArgs:
+ 	Tcl_AppendResult(interp, "wrong # args: should be \"",
+ 		argv[0], " option window ?arg ...?\"", (char *) NULL);
+ 	return TCL_ERROR;
+     }
      c = argv[1][0];
      length = strlen(argv[1]);
      if ((c == 't') && (strncmp(argv[1], "tracing", length) == 0)
***************
*** 602,610 ****
      }
  
      if (argc < 3) {
! 	Tcl_AppendResult(interp, "wrong # args: should be \"",
! 		argv[0], " option window ?arg ...?\"", (char *) NULL);
! 	return TCL_ERROR;
      }
      winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[2], tkwin);
      if (winPtr == NULL) {
--- 615,621 ----
      }
  
      if (argc < 3) {
! 	goto wrongNumArgs;
      }
      winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[2], tkwin);
      if (winPtr == NULL) {
***************
*** 1235,1243 ****
  	    wmPtr->protPtr = protPtr;
  	    protPtr->interp = interp;
  	    strcpy(protPtr->command, argv[4]);
- 	    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
- 		UpdateWmProtocols(wmPtr);
- 	    }
  	}
  	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
  	    UpdateWmProtocols(wmPtr);
--- 1246,1251 ----
***************
*** 1970,1976 ****
  	return;
      }
  
!     if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
  	int savedX, savedY, savedFlags;
  
  	savedX = wmPtr->x;
--- 1978,1991 ----
  	return;
      }
  
!     /*
!      * Wait for the configure operation to complete, then verify that the
!      * window was positioned where it was supposed to be and adjust it if
!      * it wasn't.  Don't need to do this, however, if the window is about
!      * to be mapped:  it will be taken care of elsewhere.
!      */
! 
!     if (!(wmPtr->flags & WM_ABOUT_TO_MAP)) {
  	int savedX, savedY, savedFlags;
  
  	savedX = wmPtr->x;