[comp.windows.x] Hacks to twm

mende@athos.rutgers.edu (Bob Mende) (01/16/90)

The following patch set is to the twm window manager (from the R4
distribution.  The patches add a few new features and changes one default
to a more reasonable value.  These changes are detailed below.

Change the default value of MoveDelta.  The default vaule should not be 0.
	A value of 0 never lets the f.deltastop function be used.  I
	changed the default value to 1.
Modified f.warpto so ``f.warpto ""'' will warpto the current window, not
	the last one window created.  The syntax is similar to that of
	f.warptoiconmgr. 
Modified f.deiconify to work on unmapped windows as well as icons.   
Added the function f.relativeresize.  This function performs a resize with
	the AutoRelativeResize flag set on.
Added the function f.opaquemove.  This function performs a move with the
	OpaqueMove flag set on.
Added the function f.constrainedmove.  This function performs a constrained
	move without need of a second click within ConstrainedMoveTime.
Added the keyword SortTwmWindows.  If set, entries in the TWM Windows menu
	will be sorted in alphabetical order.  This function honors the
	NoCaseSensitive flag.
Added the function f.menufunction.  This function is similar to the f.menu
	function, but allows a function to be called if the pullright menu
	is not activated.   An example is:
		f.function "func.zoom" { f.fullzoom }
		f.menu "menu.zoom" 
		{
		        "Full Screen"           f.fullzoom
		        "Verticle"              f.zoom
		        "Horizontal"            f.horizoom
		}
		f.menufunc "menu.zoom" : "func.zoom"
	Thus if the menu "menu.zoom" is not selected, the function
	"func.zoom" is executed and a default zoom is performed. 
Added the keyword ListRings.   This variable indicates that duplicate list
	entries will be handled in a ring like manner.  In the example
	below: 
                 SqueezeTitle
                  {
                       "XTerm"        right          0    0
                       "XTerm"        center         0    0
                       "XTerm"        left      0    0
                  }
	the first xterm created will have its tab on the left side of the
	window.  The second xterm will have the tab in the center, and the
	third on the right.  The forth will receive it on the left.

A few things that I would like to see but dont have the time and/or
knowledge of what the folks at MIT want done are:
o	The icon for the pullright menu's to be user setable.
o	A second menu pixmap for menufunc's 
o	The ability to "slide" titletabs around.


				/Bob Mende...
{...}!rutgers!mende         mende@cs.rutgers.edu          mende@zodiac.bitnet


	
:	This is a shell archive.
:	Remove everything above this line and
:	run the following text with /bin/sh to create:
:	foo
: This archive created: Tue Jan 16 00:00:07 1990
cat << 'SHAR_EOF' > foo
*** ORIG/events.c	Thu Dec 14 14:52:19 1989
--- events.c	Wed Jan 10 11:12:48 1990
***************
*** 515,521 ****
  	    /* weed out the functions that don't make sense to execute
  	     * from a key press 
  	     */
! 	    if (key->func == F_MOVE || key->func == F_RESIZE)
  		return;
  
  	    if (key->cont != C_NAME)
--- 515,522 ----
  	    /* weed out the functions that don't make sense to execute
  	     * from a key press 
  	     */
! 	    if (key->func == F_MOVE || 
! 		key->func == F_RESIZE || key->func == F_RELATIVERESIZE)
  		return;
  
  	    if (key->cont != C_NAME)
***************
*** 1412,1417 ****
--- 1413,1420 ----
  	{
  	    Action = ActiveItem->action;
  	    if (ActiveItem->func == F_MOVE ||
+ 		ActiveItem->func == F_CONSTRAINEDMOVE ||
+ 		ActiveItem->func == F_OPAQUEMOVE ||
  		ActiveItem->func == F_FORCEMOVE)
  		    ButtonPressed = -1;
  	    ExecuteFunction(ActiveItem->func, ActiveItem->action,
***************
*** 1564,1570 ****
  
  	for (i = 0, tbw = Tmp_win->titlebuttons; i < nb; i++, tbw++) {
  	    if (Event.xany.window == tbw->window) {
! 		if (tbw->info->func == F_MENU) {
  		    ButtonEvent = Event;
  		    ButtonWindow = Tmp_win;
  		    do_menu (tbw->info->menuroot, tbw->window);
--- 1567,1574 ----
  
  	for (i = 0, tbw = Tmp_win->titlebuttons; i < nb; i++, tbw++) {
  	    if (Event.xany.window == tbw->window) {
! 		if (tbw->info->func == F_MENU || 
! 		    tbw->info->func == F_MENUFUNC) {
  		    ButtonEvent = Event;
  		    ButtonWindow = Tmp_win;
  		    do_menu (tbw->info->menuroot, tbw->window);
***************
*** 1675,1681 ****
  	return;
  
      RootFunction = NULL;
!     if (Scr->Mouse[Event.xbutton.button][Context][modifier].func == F_MENU)
      {
  	do_menu (Scr->Mouse[Event.xbutton.button][Context][modifier].menu,
  		 None);
--- 1679,1686 ----
  	return;
  
      RootFunction = NULL;
!     if (Scr->Mouse[Event.xbutton.button][Context][modifier].func == F_MENU ||
! 	Scr->Mouse[Event.xbutton.button][Context][modifier].func == F_MENUFUNC)
      {
  	do_menu (Scr->Mouse[Event.xbutton.button][Context][modifier].menu,
  		 None);
***************
*** 1689,1695 ****
      }
      else if (Scr->DefaultFunction.func != NULL)
      {
! 	if (Scr->DefaultFunction.func == F_MENU)
  	{
  	    do_menu (Scr->DefaultFunction.menu, None);
  	}
--- 1694,1702 ----
      }
      else if (Scr->DefaultFunction.func != NULL)
      {
! 	if (Scr->DefaultFunction.func == F_MENU ||
! 	    Scr->DefaultFunction.func == F_MENUFUNC )
! 
  	{
  	    do_menu (Scr->DefaultFunction.menu, None);
  	}
*** ORIG/gram.y	Fri Dec 15 14:01:02 1989
--- gram.y	Wed Jan 10 11:13:19 1990
***************
*** 567,573 ****
  				    }
  				    break;
  				} /* end switch */
! 				   }
  		;
  
  
--- 567,580 ----
  				    }
  				    break;
  				} /* end switch */
! 			    }
!                 | FSKEYWORD string COLON string {
! 		                $$ = $1;
! 				Action = $4;
! 				pull = GetRoot ($2, NULLSTR,NULLSTR);
! 				pull->prev = root;
! 				break;
! 			    }
  		;
  
  
***************
*** 718,724 ****
  	    continue;
  
  	Scr->Mouse[butt][i][mods].func = func;
! 	if (func == F_MENU)
  	{
  	    pull->prev = NULL;
  	    Scr->Mouse[butt][i][mods].menu = pull;
--- 725,731 ----
  	    continue;
  
  	Scr->Mouse[butt][i][mods].func = func;
! 	if (func == F_MENU || func == F_MENUFUNC)
  	{
  	    pull->prev = NULL;
  	    Scr->Mouse[butt][i][mods].menu = pull;
*** ORIG/list.c	Sun Dec 10 18:50:22 1989
--- list.c	Wed Jan 10 20:59:11 1990
***************
*** 117,147 ****
  XClassHint *class;
  {
      name_list *nptr;
  
      /* look for the name first */
      for (nptr = list_head; nptr != NULL; nptr = nptr->next)
      {
  	if (strncmp(name, nptr->name, nptr->namelen) == 0)
! 	    return (nptr->ptr);
      }
  
!     if (class)
      {
  	/* look for the res_name next */
  	for (nptr = list_head; nptr != NULL; nptr = nptr->next)
  	{
  	    if (strncmp(class->res_name, nptr->name, nptr->namelen) == 0)
! 		return (nptr->ptr);
  	}
  
  	/* finally look for the res_class */
! 	for (nptr = list_head; nptr != NULL; nptr = nptr->next)
  	{
! 	    if (strncmp(class->res_class, nptr->name, nptr->namelen) == 0)
! 		return (nptr->ptr);
  	}
      }
!     return (NULL);
  }
  
  char *
--- 117,207 ----
  XClassHint *class;
  {
      name_list *nptr;
+     char *return_name = NULL;
  
      /* look for the name first */
      for (nptr = list_head; nptr != NULL; nptr = nptr->next)
      {
  	if (strncmp(name, nptr->name, nptr->namelen) == 0)
! 	{
! 	    return_name = nptr->ptr;
! 	    break;
! 	}
      }
  
!     if ((return_name == NULL) && class)
      {
  	/* look for the res_name next */
  	for (nptr = list_head; nptr != NULL; nptr = nptr->next)
  	{
  	    if (strncmp(class->res_name, nptr->name, nptr->namelen) == 0)
! 	    {
! 		return_name = nptr->ptr;
! 		break;
! 	    }
  	}
  
  	/* finally look for the res_class */
! 	if (return_name == NULL)
  	{
! 	    for (nptr = list_head; nptr != NULL; nptr = nptr->next)
! 	    {
! 		if (strncmp(class->res_class, nptr->name, nptr->namelen) == 0)
! 		{
! 		    return_name = nptr->ptr;
! 		    break;
! 		}
! 	    }
  	}
      }
! 
!     if ((Scr->ListRings == TRUE) && (return_name != NULL)
! 	&& (list_head->next != NULL)) 
!     {
! 	/* To implement a ring on the linked list where we cant change the */
! 	/* list_head, use a simple unlink/link-at-end alg. unless you need */
! 	/* to move the first link.   In that case swap the contents of the */
! 	/* first link with the contents of the second then proceed as */
! 	/* normal.  */
! 	name_list *tmp_namelist;
! 	
! 	if (list_head->ptr == return_name)
! 	{
! 	    int tmp_namelen;
! 	    char *tmp_name;
! 	    char *tmp_ptr;
! 	    
! 	    tmp_namelen = list_head->namelen;
! 	    tmp_name = list_head->name;
! 	    tmp_ptr = list_head->ptr;
! 	    
! 	    list_head->namelen = list_head->next->namelen;
! 	    list_head->name = list_head->next->name;
! 	    list_head->ptr = list_head->next->ptr;
! 	    
! 	    list_head->next->namelen = tmp_namelen;
! 	    list_head->next->name = tmp_name;
! 	    list_head->next->ptr = tmp_ptr;
! 	}
! 	
! 	for (nptr = list_head; nptr->next != NULL; nptr = nptr->next)
! 	{
! 	    if (nptr->next->ptr == return_name)
! 	      break;
! 	}
! 	
! 	if (nptr->next->next != NULL)
! 	{
! 	    tmp_namelist = nptr->next;
! 	    nptr->next = nptr->next->next;
! 	    
! 	    for (nptr = nptr->next; nptr->next != NULL; nptr = nptr->next);
! 	    nptr->next = tmp_namelist;
! 	    nptr->next->next = NULL;
! 	}
!     }
!     
!     return (return_name);
  }
  
  char *
*** ORIG/menus.c	Thu Dec 14 17:15:04 1989
--- menus.c	Wed Jan 10 11:14:02 1990
***************
*** 53,59 ****
--- 53,61 ----
  #include "parse.h"
  #include "gram.h"
  #include "screen.h"
+ #include <X11/Xmu/CharSet.h>
  #include <X11/bitmaps/menu12>
+ #include <X11/Xmu/CharSet.h>
  #include "version.h"
  
  extern XEvent Event;
***************
*** 393,399 ****
  		text_y, mi->item, mi->strlen);
  	}
  
! 	if (mi->func == F_MENU)
  	{
  
  	    /* create the pull right pixmap if needed */
--- 395,401 ----
  		text_y, mi->item, mi->strlen);
  	}
  
! 	if (mi->func == F_MENU || mi->func == F_MENUFUNC)
  	{
  
  	    /* create the pull right pixmap if needed */
***************
*** 537,543 ****
  	}
  
  	/* now check to see if we were over the arrow of a pull right entry */
! 	if (ActiveItem->func == F_MENU && 
  	    ((ActiveMenu->width - x) < (ActiveMenu->width >> 1)))
  	{
  	    MenuRoot *save = ActiveMenu;
--- 539,545 ----
  	}
  
  	/* now check to see if we were over the arrow of a pull right entry */
! 	if ((ActiveItem->func == F_MENU || ActiveItem->func == F_MENUFUNC) && 
  	    ((ActiveMenu->width - x) < (ActiveMenu->width >> 1)))
  	{
  	    MenuRoot *save = ActiveMenu;
***************
*** 967,979 ****
  	menu->mapped = NEVER_MAPPED;
  
  	AddToMenu(menu, "TWM Windows", NULLSTR, NULL, F_TITLE,NULLSTR,NULLSTR);
! 	for (tmp_win = Scr->TwmRoot.next;
! 	     tmp_win != NULL;
! 	     tmp_win = tmp_win->next)
! 	{
! 	    AddToMenu (menu, tmp_win->name, (char *) tmp_win, NULL, F_POPUP, 
! 		       NULLSTR, NULLSTR);
  	}
  	MakeMenu(menu);
      }
  
--- 969,1025 ----
  	menu->mapped = NEVER_MAPPED;
  
  	AddToMenu(menu, "TWM Windows", NULLSTR, NULL, F_TITLE,NULLSTR,NULLSTR);
! 
!         if (Scr->SortTwmWindows)
!         {
! 	    int WindowNameOffset, WindowNameCount;
! 	    TwmWindow **WindowNames;
! 	    TwmWindow *tmp_win2,*tmp_win3;
! 	    int i;
! 	    int (*compar)() = 
! 	      (Scr->CaseSensitive ? strcmp : XmuCompareISOLatin1);
! 
!             WindowNameOffset=(char *)Scr->TwmRoot.next->name -
!                              (char *)Scr->TwmRoot.next;
!             for(tmp_win = Scr->TwmRoot.next , WindowNameCount=0;
!                 tmp_win != NULL;
!                 tmp_win = tmp_win->next)
!               WindowNameCount++;
!             WindowNames =
!               (TwmWindow **)malloc(sizeof(TwmWindow *)*WindowNameCount);
!             WindowNames[0] = Scr->TwmRoot.next;
!             for(tmp_win = Scr->TwmRoot.next->next , WindowNameCount=1;
!                 tmp_win != NULL;
!                 tmp_win = tmp_win->next,WindowNameCount++)
!             {
!                 tmp_win2 = tmp_win;
!                 for (i=0;i<WindowNameCount;i++)
!                 {
!                     if ((*compar)(tmp_win2->name,WindowNames[i]->name) < 0)
!                     {
!                         tmp_win3 = tmp_win2;
!                         tmp_win2 = WindowNames[i];
!                         WindowNames[i] = tmp_win3;
!                     }
!                 }
!                 WindowNames[WindowNameCount] = tmp_win2;
!             }
!             for (i=0; i<WindowNameCount; i++)
!             {
!                 AddToMenu(menu, WindowNames[i]->name, (char *)WindowNames[i],
!                           NULL, F_POPUP,NULL,NULL);
!             }
!             free(WindowNames);
!         } else {
! 	    for (tmp_win = Scr->TwmRoot.next;
! 		 tmp_win != NULL;
! 		 tmp_win = tmp_win->next)
! 	    {
! 		AddToMenu (menu, tmp_win->name, (char *) tmp_win, NULL, 
! 			   F_POPUP, NULLSTR, NULLSTR);
! 	    }
  	}
+ 
  	MakeMenu(menu);
      }
  
***************
*** 1133,1138 ****
--- 1179,1185 ----
  {
      static Time last_time = 0;
  
+     short Real_OpaqueMove;                  /* holder for F_OPAQUEMOVE */
      char tmp[200];
      char *ptr;
      char buff[MAX_FILE_SIZE];
***************
*** 1278,1283 ****
--- 1325,1331 ----
  	}
  	break;
  
+     case F_RELATIVERESIZE:
      case F_RESIZE:
  	EventHandler[EnterNotify] = HandleUnknown;
  	EventHandler[LeaveNotify] = HandleUnknown;
***************
*** 1285,1291 ****
  	    return TRUE;
  
  	PopDownMenu();
- 
  	if (pulldown)
  	    XWarpPointer(dpy, None, Scr->Root, 
  		0, 0, 0, 0, eventp->xbutton.x_root, eventp->xbutton.y_root);
--- 1333,1338 ----
***************
*** 1307,1313 ****
  		}
  	    }
  
! 	    StartResize (eventp, tmp_win, fromtitlebar);
  	    return TRUE;
  	}
  	break;
--- 1354,1367 ----
  		}
  	    }
  
! 	    if (func = F_RELATIVERESIZE) {
! 		short Real_AutoRelativeResize = Scr->AutoRelativeResize;
! 		Scr->AutoRelativeResize = TRUE;
! 		StartResize (eventp, tmp_win, fromtitlebar);
! 		Scr->AutoRelativeResize = Real_AutoRelativeResize;
! 	    } else {
! 		StartResize (eventp, tmp_win, fromtitlebar);
! 	    }
  	    return TRUE;
  	}
  	break;
***************
*** 1327,1332 ****
--- 1381,1388 ----
  
      case F_MOVE:
      case F_FORCEMOVE:
+     case F_CONSTRAINEDMOVE:
+     case F_OPAQUEMOVE:
  	if (DeferExecution(context, func, Scr->MoveCursor))
  	    return TRUE;
  
***************
*** 1333,1339 ****
  	PopDownMenu();
  	rootw = eventp->xbutton.root;
  	MoveFunction = func;
! 
  	if (pulldown)
  	    XWarpPointer(dpy, None, Scr->Root, 
  		0, 0, 0, 0, eventp->xbutton.x_root, eventp->xbutton.y_root);
--- 1389,1399 ----
  	PopDownMenu();
  	rootw = eventp->xbutton.root;
  	MoveFunction = func;
! 	if (MoveFunction == F_OPAQUEMOVE) {
! 	    Real_OpaqueMove = Scr->OpaqueMove;
! 	    Scr->OpaqueMove = TRUE;
! 	}
! 	
  	if (pulldown)
  	    XWarpPointer(dpy, None, Scr->Root, 
  		0, 0, 0, 0, eventp->xbutton.x_root, eventp->xbutton.y_root);
***************
*** 1379,1386 ****
  	 * only do the constrained move if timer is set; need to check it
  	 * in case of stupid or wicked fast servers
  	 */
! 	if (ConstrainedMoveTime && 
! 	    (eventp->xbutton.time - last_time) < ConstrainedMoveTime)
  	{
  	    int width, height;
  
--- 1439,1448 ----
  	 * only do the constrained move if timer is set; need to check it
  	 * in case of stupid or wicked fast servers
  	 */
! 	if ((ConstrainedMoveTime && 
! 	     (eventp->xbutton.time - last_time) < ConstrainedMoveTime) ||
! 	    (MoveFunction == F_CONSTRAINEDMOVE))
! 
  	{
  	    int width, height;
  
***************
*** 1550,1559 ****
  	if (!Scr->OpaqueMove && DragWindow == None)
  	    UninstallRootColormap();
  
          break;
  
      case F_FUNCTION:
! 	{
  	    MenuRoot *mroot;
  	    MenuItem *mitem;
  
--- 1612,1625 ----
  	if (!Scr->OpaqueMove && DragWindow == None)
  	    UninstallRootColormap();
  
+ 	if (MoveFunction == F_OPAQUEMOVE) 
+ 	  Scr->OpaqueMove = Real_OpaqueMove ;
+ 
          break;
  
      case F_FUNCTION:
!     case F_MENUFUNC:	
!         {
  	    MenuRoot *mroot;
  	    MenuItem *mitem;
  
***************
*** 1583,1589 ****
  	if (DeferExecution(context, func, Scr->SelectCursor))
  	    return TRUE;
  
! 	if (tmp_win->icon)
  	{
  	    DeIconify(tmp_win);
  	}
--- 1649,1655 ----
  	if (DeferExecution(context, func, Scr->SelectCursor))
  	    return TRUE;
  
! 	if (tmp_win->icon || !tmp_win->mapped )
  	{
  	    DeIconify(tmp_win);
  	}
***************
*** 1772,1789 ****
  
  	    len = strlen(action);
  
! 	    for (t = Scr->TwmRoot.next; t != NULL; t = t->next) {
! 		/* match only the first portion of WINDOW the name */
! 		if (!strncmp(action, t->name, len)) {
! 		    if (Scr->WarpUnmapped || t->mapped) {
! 			if (!t->mapped) DeIconify (t);
! 			XRaiseWindow (dpy, t->frame);
! 			WarpToWindow (t);
! 			break;
  		    }
  		}
  	    }
- 	    if (!t) XBell (dpy, 0);
  	}
  	break;
  
--- 1838,1867 ----
  
  	    len = strlen(action);
  
! 	    if (len == 0) {
! 		if (!tmp_win) {
! 		    XBell (dpy,0);
! 		} else {
! 		    if (Scr->WarpUnmapped || tmp_win->mapped) {
! 			if (!tmp_win->mapped) DeIconify (tmp_win);
! 			XRaiseWindow (dpy, tmp_win->frame);
! 			WarpToWindow (tmp_win);
  		    }
  		}
+ 	    } else {
+ 		for (t = Scr->TwmRoot.next; t != NULL; t = t->next) {
+ 		    /* match only the first portion of WINDOW the name */
+ 		    if (!strncmp(action, t->name, len)) {
+ 			if (Scr->WarpUnmapped || t->mapped) {
+ 			    if (!t->mapped) DeIconify (t);
+ 			    XRaiseWindow (dpy, t->frame);
+ 			    WarpToWindow (t);
+ 			    break;
+ 			}
+ 		    }
+ 		}
+ 		if (!t) XBell (dpy, 0);
  	    }
  	}
  	break;
  
*** ORIG/parse.c	Fri Jan  5 21:37:32 1990
--- parse.c	Wed Jan 10 15:11:41 1990
***************
*** 312,317 ****
--- 312,319 ----
  #define kw0_NoCaseSensitive		23
  #define kw0_NoRaiseOnWarp		24
  #define kw0_WarpUnmapped		25
+ #define kw0_SortTwmWindows		26
+ #define kw0_ListRings		        27
  
  #define kws_UsePPosition		1
  #define kws_IconFont			2
***************
*** 393,398 ****
--- 395,401 ----
      { "f.circledown",		FKEYWORD, F_CIRCLEDOWN },
      { "f.circleup",		FKEYWORD, F_CIRCLEUP },
      { "f.colormap",		FSKEYWORD, F_COLORMAP },
+     { "f.constrainedmove",	FKEYWORD, F_CONSTRAINEDMOVE },
      { "f.cut",			FSKEYWORD, F_CUT },
      { "f.cutfile",		FKEYWORD, F_CUTFILE },
      { "f.deiconify",		FKEYWORD, F_DEICONIFY },
***************
*** 418,431 ****
--- 421,437 ----
      { "f.leftzoom",		FKEYWORD, F_LEFTZOOM },
      { "f.lower",		FKEYWORD, F_LOWER },
      { "f.menu",			FSKEYWORD, F_MENU },
+     { "f.menufunc",		FSKEYWORD, F_MENUFUNC },
      { "f.move",			FKEYWORD, F_MOVE },
      { "f.nexticonmgr",		FKEYWORD, F_NEXTICONMGR },
      { "f.nop",			FKEYWORD, F_NOP },
+     { "f.opaquemove",		FKEYWORD, F_OPAQUEMOVE },
      { "f.previconmgr",		FKEYWORD, F_PREVICONMGR },
      { "f.quit",			FKEYWORD, F_QUIT },
      { "f.raise",		FKEYWORD, F_RAISE },
      { "f.raiselower",		FKEYWORD, F_RAISELOWER },
      { "f.refresh",		FKEYWORD, F_REFRESH },
+     { "f.relativeresize",       FKEYWORD, F_RELATIVERESIZE },
      { "f.resize",		FKEYWORD, F_RESIZE },
      { "f.restart",		FKEYWORD, F_RESTART },
      { "f.righticonmgr",		FKEYWORD, F_RIGHTICONMGR },
***************
*** 475,480 ****
--- 481,487 ----
      { "interpolatemenucolors",	KEYWORD, kw0_InterpolateMenuColors },
      { "left",			JKEYWORD, J_LEFT },
      { "lefttitlebutton",	LEFT_TITLEBUTTON, 0 },
+     { "listrings",	        KEYWORD, kw0_ListRings },
      { "m",			META, 0 },
      { "maketitle",		MAKE_TITLE, 0 },
      { "maxwindowsize",		SKEYWORD, kws_MaxWindowSize },
***************
*** 520,525 ****
--- 527,533 ----
      { "shift",			SHIFT, 0 },
      { "showiconmanager",	KEYWORD, kw0_ShowIconManager },
      { "sorticonmanager",	KEYWORD, kw0_SortIconManager },
+     { "sorttwmwindows",	        KEYWORD, kw0_SortTwmWindows },
      { "south",			DKEYWORD, D_SOUTH },
      { "squeezetitle",		SQUEEZE_TITLE, 0 },
      { "starticonified",		START_ICONIFIED, 0 },
***************
*** 679,684 ****
--- 687,700 ----
  
        case kw0_WarpUnmapped:
  	Scr->WarpUnmapped = TRUE;
+ 	return 1;
+ 
+       case kw0_SortTwmWindows:
+ 	if (Scr->FirstTime) Scr->SortTwmWindows = TRUE;
+ 	return 1;
+ 
+       case kw0_ListRings:
+ 	if (Scr->FirstTime) Scr->ListRings = TRUE;
  	return 1;
      }
  
*** ORIG/parse.h	Thu Dec 14 14:51:26 1989
--- parse.h	Wed Jan 10 11:14:29 1990
***************
*** 90,95 ****
--- 90,98 ----
  #define F_CUTFILE		43
  #define F_SHOWLIST		44
  #define F_HIDELIST		45
+ #define F_RELATIVERESIZE        46
+ #define F_CONSTRAINEDMOVE       47
+ #define F_OPAQUEMOVE            48
  
  #define F_MENU			101	/* string */
  #define F_WARPTO		102	/* string */
***************
*** 101,106 ****
--- 104,110 ----
  #define F_FUNCTION		108	/* string */
  #define F_WARPTOSCREEN		109	/* string */
  #define F_COLORMAP		110	/* string */
+ #define F_MENUFUNC		111	/* string */
  
  #define D_NORTH			1
  #define D_SOUTH			2
*** ORIG/screen.h	Thu Dec 14 14:52:27 1989
--- screen.h	Wed Jan 10 15:12:29 1990
***************
*** 229,234 ****
--- 229,235 ----
      short MoveDelta;		/* number of pixels before f.move starts */
      short ZoomCount;		/* zoom outline count */
      short SortIconMgr;		/* sort entries in the icon manager */
+     short SortTwmWindows;	/* sort entries in the Twm Windows menu */
      short Shadow;		/* show the menu shadow */
      short InterpolateMenuColors;/* make pretty menus */
      short NoIconManagers;	/* Don't create any icon managers */
***************
*** 238,243 ****
--- 239,245 ----
      short FirstTime;		/* first time we've read .twmrc */
      short CaseSensitive;	/* be case-sensitive when sorting names */
      short WarpUnmapped;		/* allow warping to unmapped windows */
+     short ListRings;		/* allow lists to contain rings */
  
      FuncKey FuncKeyRoot;
  } ScreenInfo;
*** ORIG/twm.c	Mon Dec 18 13:48:36 1989
--- twm.c	Wed Jan 10 15:12:49 1990
***************
*** 605,613 ****
      Scr->OpaqueMove = FALSE;
      Scr->Highlight = TRUE;
      Scr->TitleHighlight = TRUE;
!     Scr->MoveDelta = 0;
      Scr->ZoomCount = 8;
      Scr->SortIconMgr = FALSE;
      Scr->Shadow = TRUE;
      Scr->InterpolateMenuColors = FALSE;
      Scr->NoIconManagers = FALSE;
--- 605,614 ----
      Scr->OpaqueMove = FALSE;
      Scr->Highlight = TRUE;
      Scr->TitleHighlight = TRUE;
!     Scr->MoveDelta = 1;
      Scr->ZoomCount = 8;
      Scr->SortIconMgr = FALSE;
+     Scr->SortTwmWindows = FALSE;
      Scr->Shadow = TRUE;
      Scr->InterpolateMenuColors = FALSE;
      Scr->NoIconManagers = FALSE;
***************
*** 619,624 ****
--- 620,626 ----
      Scr->HaveFonts = FALSE;		/* i.e. not loaded yet */
      Scr->CaseSensitive = TRUE;
      Scr->WarpUnmapped = FALSE;
+     Scr->ListRings = FALSE;
  
      /* setup default fonts; overridden by defaults from system.twmrc */
  #define DEFAULT_NICE_FONT "variable"
*** ORIG/twm.man	Fri Dec 22 14:40:46 1989
--- twm.man	Wed Jan 10 20:50:46 1990
***************
*** 511,516 ****
--- 511,530 ----
  between black and white, and the background colors between red and green.
  Similarly, the foreground for ``entry4'' will be half-way between white and
  red, and the background will be half-way between green and white.
+ .IP "\fBListRings\fP" 8
+ This variable indicates that duplicate list entries will be handled in a
+ ring like manner.  In the example below:
+ .EX 0
+ \fBSqueezeTitle\fP
+ {
+ 	"XTerm"		right		0	0
+ 	"XTerm"		center		0	0
+ 	"XTerm"		left		0	0
+ }
+ .EE
+ the first xterm created will have its tab on the left side of the window.
+ The second xterm will have the tab in the center, and the third on the
+ right.  The forth will receive it on the left.
  .IP "\fBMakeTitle\fP { \fIwin-list\fP }" 8
  This variable specifies a list of windows on which a titlebar should be placed
  and is used to request titles on specific windows when \fBNoTitle\fP has been
***************
*** 550,556 ****
  .IP "\fBMoveDelta\fP \fIpixels\fP" 8
  This variable specifies the number of pixels the pointer
  must move before the \fBf.move\fP function starts working.  Also
! see the \fBf.deltastop\fP function.  The default is zero pixels.
  .IP "\fBNoBackingStore\fP" 8
  This variable indicates that \fItwm\fP's menus should not request backing
  store to minimize repainting of menus.  This is typically
--- 564,570 ----
  .IP "\fBMoveDelta\fP \fIpixels\fP" 8
  This variable specifies the number of pixels the pointer
  must move before the \fBf.move\fP function starts working.  Also
! see the \fBf.deltastop\fP function.  The default is one pixel.
  .IP "\fBNoBackingStore\fP" 8
  This variable indicates that \fItwm\fP's menus should not request backing
  store to minimize repainting of menus.  This is typically
***************
*** 557,564 ****
  used with servers that can repaint faster than they can handle backing store.
  .IP "\fBNoCaseSensitive\fP" 8
  This variable indicates that case should be ignored when sorting icon names
! in an icon manager.  This option is typically used with applications that 
! capitalize the first letter of their icon name.
  .IP "\fBNoDefaults\fP" 8
  This variable indicates that \fItwm\fP should not supply the default 
  titlebuttons and bindings.  This option should only be used if the startup
--- 571,579 ----
  used with servers that can repaint faster than they can handle backing store.
  .IP "\fBNoCaseSensitive\fP" 8
  This variable indicates that case should be ignored when sorting icon names
! in an icon manager or window names in the TWM Windows menu.  This option is
! typically used with applications that capitalize the first letter of their
! icon name.
  .IP "\fBNoDefaults\fP" 8
  This variable indicates that \fItwm\fP should not supply the default 
  titlebuttons and bindings.  This option should only be used if the startup
***************
*** 658,663 ****
--- 673,681 ----
  This variable indicates that entries in the icon manager should be 
  sorted alphabetically rather than by simply appending new windows to 
  the end.
+ .IP "\fBSortTwmWindows\fP" 8
+ This variable indicates that entries in the TWM Windows menu should be 
+ sorted alphabetically rather than most recently created at top manner
  .IP "\fBSqueezeTitle\fP [{ \fIsqueeze-list\fP }] " 8
  This variable indicates that \fItwm\fP should attempt to use the SHAPE
  extension to make titlebars occupy only as much screen space as they need,
***************
*** 899,904 ****
--- 917,925 ----
  property on the window) that \fItwm\fP will display when the pointer
  is in this window.  The argument \fIstring\fP may have one of the following 
  values: \fB"next"\fP, \fB"prev"\fP, and \fB"default"\fP.
+ .IP "\fBf.constrainedmove\fP" 8
+ This funciton performs a constrained move (see f.move) without need of a
+ second click within \fBConstrainedMoveTime\fP.
  .\"OBSOLETE - should go away and use a clipboard.
  .\".IP "\fBf.cut\fP \fIstring\fP" 8
  .\"This function places the specified \fIstring\fP (followed by a newline
***************
*** 907,914 ****
  .\"This function reads the file indicated by the contents of the CUT_BUFFER0
  .\"window property and replaces the cut buffer.
  .IP "\fBf.deiconify\fP" 8
! This function deiconifies the selected window.  If the window is not an icon, 
! this function does nothing.
  .IP "\fBf.delete\fP" 8
  This function sends the WM_DELETE_WINDOW message to the selected window if
  the client application has requested it through the WM_PROTOCOLS window
--- 928,935 ----
  .\"This function reads the file indicated by the contents of the CUT_BUFFER0
  .\"window property and replaces the cut buffer.
  .IP "\fBf.deiconify\fP" 8
! This function deiconifies the selected window.  If the window is not an
! icon or an unmapped window, this function does nothing.
  .IP "\fBf.delete\fP" 8
  This function sends the WM_DELETE_WINDOW message to the selected window if
  the client application has requested it through the WM_PROTOCOLS window
***************
*** 981,986 ****
--- 1002,1011 ----
  .IP "\fBf.menu\fP \fIstring\fP" 8
  This function invokes the menu specified by the argument \fIstring\fP.
  Cascaded menus may be built by nesting calls to \fBf.menu\fP.
+ .IP "\fBf.menufunc\fP \fIstring1\fP \fI:\fP \fIstring2\fP" 8
+ This functions invokes a menu like f.menu, but if the user does not select
+ an entry from the menu "\fIstring1\fP" the function  \fIstring2\fP will be
+ called. 
  .IP "\fBf.move\fP" 8
  This function drags an outline of the selected window (or the window itself
  if the \fBOpaqueMove\fP variable is set) until the invoking pointer button
***************
*** 997,1002 ****
--- 1022,1029 ----
  .IP "\fBf.nop\fP" 8
  This function does nothing and is typically used with the \fBDefaultFunction\fP
  or \fBWindowFunction\fP variables or to introduce blank lines in menus.
+ .IP "\fBf.opaquemove\fI" 8
+ This function performs a move with the \fBOpaqueMove\fP flag set.
  .IP "\fBf.previconmgr\fI" 8
  This function warps the pointer to the previous icon manager containing any
  windows on the current or preceding screens.
***************
*** 1011,1016 ****
--- 1038,1045 ----
  it is occluded by any windows, otherwise the window will be lowered.
  .IP "\fBf.refresh\fP" 8
  This function causes all windows to be refreshed.
+ .IP "\fBf.relativeresize\fP" 8
+ This function performs a resize with the \fBAutoRelativeResize\fP flag set. 
  .IP "\fBf.resize\fP" 8
  This function displays an outline of the selected window.  Crossing a border
  (or setting \fBAutoRelativeResize\fP) will cause the outline to begin to 
***************
*** 1073,1079 ****
  .IP "\fBf.warpto\fP \fIstring\fP" 8
  This function warps the pointer to the window which has a name or class 
  that matches \fIstring\fP.  If the window is iconified, it will be deiconified
! if the variable \fBWarpUnmapped\fP is set or else ignored.
  .IP "\fBf.warptoiconmgr\fP \fIstring\fP" 8
  This function warps the pointer to the icon manager entry 
  associated with the window containing the pointer in the icon manager
--- 1102,1110 ----
  .IP "\fBf.warpto\fP \fIstring\fP" 8
  This function warps the pointer to the window which has a name or class 
  that matches \fIstring\fP.  If the window is iconified, it will be deiconified
! if the variable \fBWarpUnmapped\fP is set or else ignored.  If \fIstring\fP
! is empty (i.e. ""), the current window is selected.  This allows you to
! warpto the currently selected window from the IconManger.
  .IP "\fBf.warptoiconmgr\fP \fIstring\fP" 8
  This function warps the pointer to the icon manager entry 
  associated with the window containing the pointer in the icon manager
SHAR_EOF
:	End of shell archive
exit 0
-- 
{...}!rutgers!mende         mende@cs.rutgers.edu          mende@zodiac.bitnet