From: ouster@sprite.Berkeley.EDU (John Ousterhout)
Newsgroups: comp.lang.tcl
Subject: Re: New releases:  Tk 3.0 and Tcl 6.5
Date: 18 Dec 1992 17:27:52 GMT
Organization: U.C. Berkeley Sprite Project
Distribution: world
NNTP-Posting-Host: tyranny.berkeley.edu

In article <eillihca.92121806254921182@drizzle.Stanford.EDU>, eillihca@drizzle.StanFord.EDU ( Achille Hui, the Day Dreamer ) writes:
|> ouster@sprite.Berkeley.EDU (John Ousterhout) writes: 
|> 
|> >
|> >I have just released new versions of Tk and Tcl.  Tk 3.0 is a major
|> >new release with several incompatibilities (hence the change in
|> >major version number).  It doesn't have a lot of fancy new features
|> >but includes many bug fixes and major structural improvements, such as
|> 
|> The following patch fixes two more bugs (a. never setting up the WM_CLASS
|> property on a toplevel window. b. wish cores dump when you call wm without
|> any argument) of Tk3.0 in tkWm.c. Also, the new restriction that a
|> menubutton cannot "post" arbitary menus is a little bit annoying
|> 
|> 				-achille (eillihca@drizzle.stanford.edu)
|> %%%%%%%%%%%%%% cut here %%%%%%%%%%%%%%%%%% cut here %%%%%%%%%%%%%%%%%%%%
|> *** tkWm.c,dist Wed Dec 16 11:59:15 1992
|> --- tkWm.c      Fri Dec 18 06:17:33 1992
|> ***************
|> *** 386,391 ****
|> --- 386,392 ----
|>         return;
|>       }
|>       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
|> ***************
|> *** 585,609 ****
|>       char c;
|>       int length;
|>   
|> !     c = argv[1][0];
|> !     length = strlen(argv[1]);
|> !     if ((c == 't') && (strncmp(argv[1], "tracing", length) == 0)
|> !           && (length >= 3)) {
|> !       if ((argc != 2) && (argc != 3)) {
|> !           Tcl_AppendResult(interp, "wrong # arguments: must be \"",
|> !                   argv[0], " tracing ?boolean?\"", (char *) NULL);
|> !           return TCL_ERROR;
|> !       }
|>         if (argc == 2) {
|>             interp->result = (wmTracing) ? "on" : "off";
|>             return TCL_OK;
|>         }
|> !       return Tcl_GetBoolean(interp, argv[2], &wmTracing);
|> !     }
|> ! 
|> !     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);
|> --- 586,611 ----
|>       char c;
|>       int length;
|>   
|> !     if(argc < 2){
|> !       Tcl_AppendResult(interp, "wrong # args: should be \"",
|> !               argv[0], " option window ?arg ...?\"", (char *) NULL);
|> !       return TCL_ERROR;
|> !     } else if(((c = argv[1][0]) == 't') &&
|> !             (strncmp(argv[1],"tracing",length = strlen(argv[1])) == 0) &&
|> !             (length >= 3)){
|>         if (argc == 2) {
|>             interp->result = (wmTracing) ? "on" : "off";
|>             return TCL_OK;
|> +       } else if(argc == 3){
|> +           return Tcl_GetBoolean(interp, argv[2], &wmTracing);
|> +       } else {
|> +           Tcl_AppendResult(interp, "wrong # arguments: must be \"",
|> +                   argv[0], " tracing ?boolean?\"", (char *) NULL);
|> +           return TCL_ERROR;
|>         }
|> !     } else 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);
|> 

This message is correct about the problems, but doesn't quite solve the
WM_CLASS problem correctly (it introduces problems with other things).
Here's my patch, which I believe fixes both problems correctly.

*** /tmp/,RCSt1281395	Fri Dec 18 09:27:05 1992
--- tkWm.c	Fri Dec 18 09:22:56 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
***************
*** 386,391 ****
--- 390,397 ----
  	return;
      }
      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 ****
--- 433,441 ----
  	    }
  	}
      }
+     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) {
***************
*** 1970,1976 ****
  	return;
      }
  
!     if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
  	int savedX, savedY, savedFlags;
  
  	savedX = wmPtr->x;
--- 1981,1994 ----
  	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;
Newsgroups: comp.lang.tcl