patches

Michal Vitecek (M.Vitecek@sh.cvut.cz)
Mon, 24 Aug 1998 17:27:46 +0200



--ibTvN161/egqYuK8
Content-Type: text/plain; charset=us-ascii

 hello all,

 i'm attaching two patches: 
 -  the 1st one replaces the menu order patch which didn't work correctly
    under certain conditions.
 -  the 2nd implements new Feel file option 'AutoTabThroughDesks' and
    allows for winblows-like warping (alt-tabbing) when AutoReverse is set
    to 2. big thanks go to ethan for helping me with this one. (it
    wouldn't come to my mind that i have to use XUngrabKeyboard() - thanks
    again, ethan :)).
-- 
			fuf


------------------------------ na IRC -------------------------------------
 BillGates [bgates@www.microsoft.com] has joined #LINUX
 ...
 mode/#linux [+b BillGates!*@*] by DoDad
 BillGates was kicked off #linux by DoDad (banned: We see enough of Bill
          Gates already.)
 


--ibTvN161/egqYuK8
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="1.5pre9-01-fuf-menu-order-sort-fix.patch"

diff -u -N -r AfterStep-KERNEL-1.5pre9/lib/homeanddirs.c AfterStep-KERNEL-1.5pre9-fuf/lib/homeanddirs.c
--- AfterStep-KERNEL-1.5pre9/lib/homeanddirs.c	Fri Aug  7 12:48:57 1998
+++ AfterStep-KERNEL-1.5pre9-fuf/lib/homeanddirs.c	Fri Aug 21 15:37:05 1998
@@ -319,55 +319,70 @@
     return (*d1)->d_mode - (*d2)->d_mode;
 }
 
-/* Sort entries based on their names. A comes before Z. */
 
 #define BUF_SIZE 10
+/* compares two names, names with <number>_<item name> format come 
+   before <item name> only format */
+int my_numbersort(char *name1, char *name2)
+{
+  char		*underscore1, *underscore2;
+  char		buf[BUF_SIZE + 1];
+  int		number1, number2, length, final_length;
+
+  /* if the item name(s) that are compared begin with digit, try to get the
+     numbers */
+  if((isdigit(*name1)) || (isdigit(*name2)))
+    {
+      /* find out if the names are in the format <number>_<Item name> */
+      /* look for the first underscore right after the numbers in the first name */
+      underscore1 = name1;
+      while((*underscore1) && (isdigit(*underscore1)) && (*underscore1 != '_')) underscore1++;
+      /* look for the first underscore right after the numbers in the second name */
+      underscore2 = name2;
+      while((*underscore2) && (isdigit(*underscore2)) && (*underscore2 != '_')) underscore2++;
+      /* <number>_<Item name> takes precedence before <Item name> */
+      if((*underscore1 == '_') && (*underscore2 != '_')) return(-1);
+      else if((*underscore1 != '_') && (*underscore2 == '_')) return(1);
+      /* both names are in <number>_<Item name> format */
+      else if((*underscore1 == '_') && (*underscore2 == '_'))
+	{
+	  /* get the first number value */
+	  length = underscore1 - name1;
+	  final_length = (length < BUF_SIZE) ? length : BUF_SIZE;
+	  strncpy(buf, name1, final_length);
+	  buf[final_length] = '\0';
+	  number1 = atoi(buf);
+	  /* get the second number value */
+	  length = underscore2 - name2;
+	  final_length = (length < BUF_SIZE) ? length : BUF_SIZE;
+	  strncpy(buf, name2, final_length);
+	  buf[final_length] = '\0';
+	  number2 = atoi(buf);
+	  /* compare the two numbers - smaller goes before bigger */
+	  if(number1 < number2) return(-1);
+	  else if(number1 > number2) return(1);
+	  else return(0);
+	}
+    }
+  /* it was only a plain attack, the names are not in the format we want */
+  /* so we return 0 because we can't solve this comparison */
+  return(0);
+}
+#undef BUF_SIZE
+      
+
+/* Sort entries based on their names. A comes before Z. */
  int my_alphasort(struct direntry **d1, struct direntry **d2)
  {
-    char       *under1, *under2;
-    int                num1, num2, len, final_len;
-    char       buf[BUF_SIZE + 1];
-
-    /* if the item name(s) that are compared begin with digit, try to get the
-       numbers */
-    if(isdigit(*((*d1)->d_name)) || (isdigit(*((*d2)->d_name))))
-      {
-       /* find out if the names are in the format <number>_<Item name> */
-       under1 = (*d1)->d_name;
-       while((*under1) && (isdigit(*under1)) && (*under1 != '_')) under1++;
-       under2 = (*d2)->d_name;
-       while((*under2) && (isdigit(*under2)) && (*under2 != '_')) under2++;
+    int		result;
 
-       /* <number>_<Item name> takes precedence before <Item name> */
-       fprintf(stderr, "%s ?= %s : ", (*d1)->d_name, (*d2)->d_name);
-       if((*under1 == '_') && (!*under2)) fprintf(stderr, "-1\n");
-       else if((!*under2) && (*under2)) fprintf(stderr, "1\n");
-       if((*under1 == '_') && (!*under2)) return(-1);
-       else if((!*under2) && (*under2)) return(1);
-
-
-       /* both names are in format <number>_<Item name> */
-       else if((*under1 == '_') && (*under2 == '_'))
-         {
-           /* copy the number to buf */
-           strncpy(buf, (*d1)->d_name, (final_len = ((len = under1 -
-(*d1)->d_name) < BUF_SIZE ? len : BUF_SIZE)));
-           buf[final_len] = '\0';
-           num1 = atoi(buf);
-           /* copy the number to buf */
-           strncpy(buf, (*d2)->d_name, (final_len = ((len = under2 -
-(*d2)->d_name) < BUF_SIZE ? len : BUF_SIZE)));
-           buf[final_len] = '\0';
-           num2 = atoi(buf);
-           if(num1 < num2) return(-1);
-           else if(num1 > num2) return(1);
-           return(0);
-         }
-       /* it was only a plain attack, the names are not in the format we want */
-      }
-    return(strcmp((*d1)->d_name, (*d2)->d_name));
+    /* first sort by the numbers, if my_numbersort() returns 0
+       sort by item names */
+    if(!(result = my_numbersort((*d1)->d_name, (*d2)->d_name)))
+      return(strcmp((*d1)->d_name, (*d2)->d_name));
+    else
+      return(result);
  }
-#undef BUF_SIZE
  
 
 /* Sort entries based on their mtimes. Old entries come before new entries,
@@ -375,10 +390,17 @@
  */
 int my_datesort(struct direntry **d1, struct direntry **d2)
 {
-    int diff = (*d1)->d_mtime - (*d2)->d_mtime;
-    if (diff == 0)
-	diff = my_alphasort(d1, d2);
-    return diff;
+    int 	result;
+    
+    /* first sort by the numbers, if my_numbersort() returns 0
+       sort by date */
+    if(!(result = my_numbersort((*d1)->d_name, (*d2)->d_name)))
+      {
+	/* if the dates are the same, sort the items by their names */
+	if(!(result = (*d1)->d_mtime - (*d2)->d_mtime))
+	  result = my_alphasort(d1, d2);
+      }
+    return(result);
 }
 
 
diff -u -N -r AfterStep-KERNEL-1.5pre9/src/afterstep/configure.c AfterStep-KERNEL-1.5pre9-fuf/src/afterstep/configure.c
--- AfterStep-KERNEL-1.5pre9/src/afterstep/configure.c	Fri Aug 21 14:48:39 1998
+++ AfterStep-KERNEL-1.5pre9-fuf/src/afterstep/configure.c	Fri Aug 21 14:42:58 1998
@@ -2330,7 +2330,7 @@
  ***************************************************************************/
 
 const char *
-removeorderfromname (const char *name)
+remove_order_from_name (const char *name)
 {
   int under = 0;
 
@@ -2432,7 +2432,7 @@
 	{
 	  /* flag the entry as a directory */
 	  list[i]->d_mode = 1;
-	  if (!an_is_special_popup_name (removeorderfromname (list[i]->d_name)))
+	  if (!an_is_special_popup_name (remove_order_from_name (list[i]->d_name)))
 	    {
 	      sprintf (an_char, "%s/%s", parentpath, directory);
 	      /* save the directory ID for later */
@@ -2456,7 +2456,7 @@
   else
     fprintf (start_menu, "\nPopUp \"%d\"\n", parent_id);
 
-  fprintf (start_menu, " Title \"%s\"\n", removeorderfromname (directory));
+  fprintf (start_menu, " Title \"%s\"\n", remove_order_from_name (directory));
   if (Textures.flags & MenuMiniPixmaps)
     fprintf (start_menu, " MiniPixmap \"mini-menu.xpm\"\n");
 
@@ -2510,14 +2510,14 @@
 	  else
 #ifndef NO_AVAILABILITY_CHECK
 	    fprintf (start_menu, " Exec \"%s\" exec %s\n",
-		     list[i]->d_name, an_char);
+		     remove_order_from_name(list[i]->d_name), an_char);
 #else
 	    {
 	      if (is_executable_in_path (an_char))
 		fprintf (start_menu, " Exec \"%s\" exec %s\n",
-			 list[i]->d_name, an_char);
+			 remove_order_from_name(list[i]->d_name), an_char);
 	      else
-		fprintf (start_menu, " Nop \"%s\"\n", list[i]->d_name);
+		fprintf (start_menu, " Nop \"%s\"\n", remove_order_from_name(list[i]->d_name));
 	    }
 #endif
 	  fgets (an_char, 254, source);
@@ -2531,15 +2531,15 @@
       else if (list[i]->d_mode == 1)
 	{
 	  fprintf (start_menu, " PopUp \"%s\" %s\n",
-		   removeorderfromname (list[i]->d_name),
-		   removeorderfromname (list[i]->d_name));
+		   remove_order_from_name (list[i]->d_name),
+		   remove_order_from_name (list[i]->d_name));
 	  if (Textures.flags & MenuMiniPixmaps)
 	    fprintf (start_menu, " MiniPixmap \"mini-as.xpm\"\n");
 	}
       else
 	{
 	  fprintf (start_menu, " PopUp \"%s\" %d\n",
-		   removeorderfromname (list[i]->d_name), list[i]->d_mode);
+		   remove_order_from_name (list[i]->d_name), list[i]->d_mode);
 	  if (Textures.flags & MenuMiniPixmaps)
 	    fprintf (start_menu, " MiniPixmap \"mini-folder.xpm\"\n");
 	}
@@ -2574,7 +2574,7 @@
   for (i = 0; i < k; i++)
     {
       fprintf (start_menu, " %s \"%s\" %s/%s\n", command,
-	 removeorderfromname (list[i]->d_name), directory, list[i]->d_name);
+	 remove_order_from_name (list[i]->d_name), directory, list[i]->d_name);
       free (list[i]);
     }
   free (list);

--ibTvN161/egqYuK8
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="1.5pre9-02-fuf-allanon-window-warping.patch"

diff -u -N -r AfterStep-KERNEL-1.5pre9/include/afterstep.h AfterStep-KERNEL-1.5pre9-fuf/include/afterstep.h
--- AfterStep-KERNEL-1.5pre9/include/afterstep.h	Sun Aug 16 16:21:31 1998
+++ AfterStep-KERNEL-1.5pre9-fuf/include/afterstep.h	Fri Aug 21 16:52:47 1998
@@ -133,6 +133,8 @@
 #ifndef NO_SHAPE
     int wShaped;		/* is this a shaped window */
 #endif
+    int warp_index;		/* index of the window in the window list,
+				   changes when window is warped */
     int frame_x;		/* x position of frame */
     int frame_y;		/* y position of frame */
     int frame_width;		/* width of frame */
diff -u -N -r AfterStep-KERNEL-1.5pre9/include/misc.h AfterStep-KERNEL-1.5pre9-fuf/include/misc.h
--- AfterStep-KERNEL-1.5pre9/include/misc.h	Thu Aug 13 19:07:10 1998
+++ AfterStep-KERNEL-1.5pre9-fuf/include/misc.h	Sat Aug 22 00:34:17 1998
@@ -330,6 +330,8 @@
 
 #define UP 1
 #define DOWN 0
+void ChangeWarpIndex(const long, const int);
+ASWindow *GetNextWindow(const ASWindow *, const int);
 extern ASWindow *Circulate (ASWindow *, char *, Bool);
 void PasteSelection (void);
 void changeDesks (int, int);
diff -u -N -r AfterStep-KERNEL-1.5pre9/src/afterstep/add_window.c AfterStep-KERNEL-1.5pre9-fuf/src/afterstep/add_window.c
--- AfterStep-KERNEL-1.5pre9/src/afterstep/add_window.c	Sun Aug 16 20:40:23 1998
+++ AfterStep-KERNEL-1.5pre9-fuf/src/afterstep/add_window.c	Fri Aug 21 22:42:13 1998
@@ -74,6 +74,7 @@
 #include "../../include/afterstep.h"
 #include "../../include/misc.h"
 #include "../../include/screen.h"
+#include "../../include/parse.h"
 #include "../../include/module.h"
 
 #ifndef NO_SHAPE
@@ -81,6 +82,7 @@
 #include <X11/Xresource.h>
 #endif /* ! NO_SHAPE */
 
+extern int LastWarpIndex;
 char NoName[] = "Untitled";	/* name if no name is specified */
 
 /* Used to parse command line of clients for specific desk requests. */
@@ -423,6 +425,11 @@
       tmp_win->ShadowPixel = GetShadow (tmp_win->BackPixel);
       tmp_win->ReliefPixel = GetHilite (tmp_win->BackPixel);
     }
+
+  /* the newly created window will be on the top of the warp list */
+  tmp_win->warp_index = 0;
+  ChangeWarpIndex(++LastWarpIndex, F_WARP_F);
+
   /* add the window into the afterstep list */
   tmp_win->next = Scr.ASRoot.next;
   if (Scr.ASRoot.next != NULL)
diff -u -N -r AfterStep-KERNEL-1.5pre9/src/afterstep/configure.c AfterStep-KERNEL-1.5pre9-fuf/src/afterstep/configure.c
--- AfterStep-KERNEL-1.5pre9/src/afterstep/configure.c	Fri Aug 21 14:48:39 1998
+++ AfterStep-KERNEL-1.5pre9-fuf/src/afterstep/configure.c	Sat Aug 22 03:51:18 1998
@@ -178,6 +178,7 @@
 int DrawMenuBorders = 1;
 int TextureMenuItemsIndividually = 1;
 int AutoReverse = 0;
+int AutoTabThroughDesks = 0;
 int StartMenuSortMode = DEFAULTSTARTMENUSORT;
 int (*sort_func) (struct direntry **, struct direntry **) = NULL;
 
@@ -288,6 +289,7 @@
   {"Xzap", SetInts, (char **) &Xzap, (int *) &dummy},
   {"Yzap", SetInts, (char **) &Yzap, (int *) &dummy},
   {"AutoReverse", SetInts, (char **) &AutoReverse, (int *) &dummy},
+  {"AutoTabThroughDesks", SetInts, (char **) &AutoTabThroughDesks, (int *) &dummy},
 {"StartMenuSortMode", SetInts, (char **) &StartMenuSortMode, (int *) &dummy},
   {"DrawMenuBorders", SetInts, (char **) &DrawMenuBorders, (int *) &dummy},
 #ifdef NEWLOOK
@@ -1289,6 +1291,7 @@
     }
   StartMenuSortMode = 0;
   AutoReverse = 0;
+  AutoTabThroughDesks = 0;
   DoHandlePageing = True;
   Xzap = 12;
   Yzap = 12;
diff -u -N -r AfterStep-KERNEL-1.5pre9/src/afterstep/events.c AfterStep-KERNEL-1.5pre9-fuf/src/afterstep/events.c
--- AfterStep-KERNEL-1.5pre9/src/afterstep/events.c	Sun Aug 16 20:40:23 1998
+++ AfterStep-KERNEL-1.5pre9-fuf/src/afterstep/events.c	Mon Aug 24 14:40:07 1998
@@ -64,6 +64,10 @@
 int last_event_type = 0;
 Window last_event_window = 0;
 
+/* those are used for AutoReverse mode 2 */
+int warp_in_process = 0;
+int warping_direction = 0;
+
 #ifndef NO_SHAPE
 extern int ShapeEventBase;
 void HandleShapeNotify (void);
@@ -71,6 +75,38 @@
 
 Window PressedW;
 
+void warp_grab(ASWindow* t)
+{
+  /* we're grabbing all key presses and accept mouse cursor motion events so we
+     we will be able to tell when warp mode is finished */
+  XWindowAttributes attributes;
+  XGrabKey(dpy, AnyKey, AnyModifier, t->frame, True, GrabModeAsync, GrabModeAsync);
+  XGetWindowAttributes(dpy, t->frame, &attributes);
+  XSelectInput(dpy, t->frame, attributes.your_event_mask | PointerMotionMask);
+}
+
+void warp_ungrab(ASWindow* t, Bool finished)
+{
+  if (t != NULL)
+    {
+      XWindowAttributes attributes;
+      /* we can return to normal operation and receive only defined 
+         function keys */
+      XUngrabKey(dpy, AnyKey, AnyModifier, t->frame);
+      GrabKeys(t);
+      /* also don't accept key releases and pointer motions */
+      XGetWindowAttributes(dpy, t->frame, &attributes);
+      XSelectInput(dpy, t->frame, attributes.your_event_mask & ~PointerMotionMask);
+    }
+  XUngrabKeyboard(dpy, CurrentTime);
+  if (finished)
+    {
+      /* the window becomes the first one in the warp list now */
+      ChangeWarpIndex(t->warp_index, warping_direction);
+      warp_in_process = 0;
+    }
+}
+
 /***********************************************************************
  *
  *  Procedure:
@@ -80,7 +116,8 @@
 void
 DispatchEvent ()
 {
-  Window w = Event.xany.window;
+  int 			old_warp_in_process;
+  Window 		w = Event.xany.window;
 
   StashEventTime (&Event);
 
@@ -111,6 +148,8 @@
       HandleUnmapNotify ();
       break;
     case ButtonPress:
+      if ((Tmp_win != NULL) && (warp_in_process))
+	warp_ungrab(Tmp_win, True);
       HandleButtonPress ();
       break;
     case EnterNotify:
@@ -118,9 +157,24 @@
       break;
     case LeaveNotify:
       HandleLeaveNotify ();
+      /* if we're warping, then we must return to accept only normal events again
+	 in that window we left */
+      if ((warp_in_process) && (Tmp_win != NULL))
+	warp_ungrab(Tmp_win, False);
       break;
     case FocusIn:
       HandleFocusIn ();
+      if (Tmp_win != NULL)
+	{
+	  if (warp_in_process) 
+	    warp_grab(Tmp_win);
+	  else
+	    ChangeWarpIndex(Tmp_win->warp_index, F_WARP_F);
+	}
+      break;
+    case MotionNotify:
+      if ((warp_in_process) && (Tmp_win != NULL))
+	warp_ungrab(Tmp_win, True);
       break;
     case ConfigureRequest:
       HandleConfigureRequest ();
@@ -132,7 +186,12 @@
       HandlePropertyNotify ();
       break;
     case KeyPress:
+      old_warp_in_process = warp_in_process;
+      /* if a key has been pressed and it's not one of those that cause
+	 warping, we know the warping is finished */
       HandleKeyPress ();
+      if ((Tmp_win != NULL) && (old_warp_in_process) && (!warp_in_process))
+	warp_ungrab(Tmp_win, True);
       break;
     case ColormapNotify:
       HandleColormapNotify ();
@@ -308,6 +367,11 @@
 	   (key->mods == AnyModifier)) &&
 	  (key->cont & Context))
 	{
+	  /* check if the warp key was pressed */
+	  warp_in_process = ((key->func == F_WARP_B) || (key->func == F_WARP_F));
+	  if (warp_in_process)
+	    warping_direction = key->func;
+
 	  ExecuteFunction (key->func, key->action, Event.xany.window, Tmp_win,
 			   &Event, Context, key->val1, key->val2,
 			   key->val1_unit, key->val2_unit,
@@ -319,6 +383,9 @@
   /* if we get here, no function key was bound to the key.  Send it
    * to the client if it was in a window we know about.
    */
+  /* now we're sure that the warping is finished */
+  warp_in_process = 0;
+
   if (Tmp_win)
     {
       if (Event.xkey.window != Tmp_win->w)
diff -u -N -r AfterStep-KERNEL-1.5pre9/src/afterstep/functions.c AfterStep-KERNEL-1.5pre9-fuf/src/afterstep/functions.c
--- AfterStep-KERNEL-1.5pre9/src/afterstep/functions.c	Sun Aug 16 20:40:23 1998
+++ AfterStep-KERNEL-1.5pre9-fuf/src/afterstep/functions.c	Mon Aug 24 17:21:19 1998
@@ -62,11 +62,16 @@
 extern int menuFromFrameOrWindowOrTitlebar;
 extern int Xzap, Yzap;
 extern int AutoReverse;
+extern int AutoTabThroughDesks;
 extern int DoHandlePageing;
 
 extern char **g_argv;
 extern void InitVariables (int);
 
+/* the following variables are used for AutoReverse mode 2 */
+long LastWarpIndex = -1;
+long LastWarpedWindow = 0;
+
 /***********************************************************************
  *
  *  Procedure:
@@ -657,6 +662,16 @@
 
     case F_WARP_F:
     case F_WARP_B:
+      if (AutoReverse == 2)
+	{
+	  t = GetNextWindow(tmp_win, func);
+	  if (t)
+	    {
+	      LastWarpedWindow = t->warp_index;
+	      FocusOn(t, 0, False, 1);
+	    }
+	  break;
+	}
       if (AutoReverse == 1)
 	{
 	  if ((LastFunction != F_WARP_F) || (LastFunction != F_WARP_B))
@@ -678,6 +693,7 @@
 	    }
 	}
       else
+	/* AutoReverse == 0 */
 	{
 	  if (func == F_WARP_F)
 	    t = Circulate (tmp_win, action, UP);
@@ -694,8 +710,8 @@
 	}
       if (t)
 	FocusOn (t, 0, True, 0);
-      break;
 
+      break;
     case F_WAIT:
       {
 	Bool done = False;
@@ -909,6 +925,122 @@
   return;
 }
 
+
+void
+ChangeWarpIndex (const long current_win_warp_index, const int func)
+{
+  ASWindow 	*t;
+
+  /* if the cursor was not placed on any window and F_WARP_B was called,
+     no change to the warp list will be done */
+  if ((func == F_WARP_B) && (!current_win_warp_index)) return;
+  
+  /* go through the list of all windows and change their warp index */
+  for (t = Scr.ASRoot.next; t != NULL; t = t->next)
+    {
+      /* we're warping forwards */
+      if (func == F_WARP_F)
+	{
+	  /* if the window's warp_index is lower than of the current window
+	     it's increased (it's moved one position down in the list) */
+	  if (t->warp_index < current_win_warp_index)
+	    t->warp_index++;
+	  /* if we found the window with the proper warp_index we move the
+	     window to the top of the warp list */
+	  else if (t->warp_index == current_win_warp_index)
+	    t->warp_index = 0;
+	}
+      /* we're warping backwards */
+      else /* func == F_WARP_B */
+	{
+	  /* if the window's warp index is higher than of the current window,
+	     it's decreased (it's moved one position up in the list) */
+	  if (t->warp_index > current_win_warp_index)
+	    t->warp_index--;
+	  /* if we found the window with the proper warp_index we move the
+	     window to the top of the warp list */
+	  else if (t->warp_index == current_win_warp_index)
+	    t->warp_index = 0;
+	}
+    }
+}
+
+
+ASWindow *
+GetNextWindow(const ASWindow *current_win, const int func)
+{
+  ASWindow	*t;
+  ASWindow	*win_selected, *win_reverse_selected;
+  long		selected_warp, reverse_selected_warp;
+  long		look_for_warp;
+  int		found;
+
+  /* initial settings */
+  win_selected = NULL;
+  win_reverse_selected = NULL;
+  if ((func == F_WARP_F) || (current_win == NULL))
+    {
+      selected_warp = LastWarpIndex;
+      reverse_selected_warp = LastWarpIndex;
+    }
+  else /* (func == F_WARP_B) || (current_win == NULL) */
+    {
+      selected_warp = 0;
+      reverse_selected_warp = 0;
+    }
+  
+  /* if the mouse cursor wasn't placed on any window, we'll try to find the
+     most recent one */
+  if (current_win == NULL)
+    look_for_warp = 0;
+  else
+    look_for_warp = current_win->warp_index;
+
+  /* traverse through all the windows in the list and try to find the most
+     appropriate one */
+  found = 0;
+  for (t = Scr.ASRoot.next; t != NULL; t = t->next)
+    {
+      if (AutoTabThroughDesks)
+	{
+	  if (((Scr.flags & CirculateSkipIcons) && (t->flags & ICONIFIED)) ||
+	      (t->flags & CIRCULATESKIP) || 
+	      (t->flags & WINDOWLISTSKIP))
+	    continue;
+	}
+      else /* AutoTabThroughDesks == 0 */
+	{
+	  if (((Scr.flags & CirculateSkipIcons) && (t->flags & ICONIFIED)) ||
+	      (t->Desk != Scr.CurrentDesk) ||
+	      (t->flags & CIRCULATESKIP) || 
+	      (t->flags & WINDOWLISTSKIP))
+	    continue;
+	}
+      if (((func == F_WARP_F) &&
+	   (((current_win != NULL) && (t->warp_index > look_for_warp) && (t->warp_index <= selected_warp)) ||
+	    ((current_win == NULL) && (t->warp_index >= look_for_warp) && (t->warp_index < selected_warp)))) ||
+	  ((func == F_WARP_B) &&
+	   (((current_win != NULL) && (t->warp_index < look_for_warp) && (t->warp_index >= selected_warp)) ||
+	    ((current_win == NULL) && (t->warp_index >= look_for_warp) && (t->warp_index < selected_warp)))))
+	{
+	  selected_warp = t->warp_index;
+	  win_selected = t;
+	  found = 1;
+	}
+      else if (((func == F_WARP_F) && (t->warp_index < reverse_selected_warp)) || 
+	       ((func == F_WARP_B) && (t->warp_index > reverse_selected_warp)))
+	{
+	  reverse_selected_warp = t->warp_index;
+	  win_reverse_selected = t;
+	}
+    }
+  if (!found)
+    win_selected = win_reverse_selected;
+  
+  return (win_selected);
+}
+  
+  
 ASWindow *
 Circulate (ASWindow * tmp_win, char *action, Bool Direction)
 {
@@ -921,14 +1053,28 @@
   best = LONG_MIN;
   for (t = Scr.ASRoot.next; t != NULL; t = t->next)
     {
-      if ((t->circulate_sequence > best)
-	  && (t->Desk == Scr.CurrentDesk)
-	  && !(t->flags & CIRCULATESKIP)
-	  && (!(Scr.flags & CirculateSkipIcons) || !(t->flags & ICONIFIED))
-	  && (t->flags & BORDER))
+      if (AutoTabThroughDesks)
 	{
-	  best = t->circulate_sequence;
-	  tmp_win = t;
+	  if ((t->circulate_sequence > best) &&
+	      !(t->flags & CIRCULATESKIP) &&
+	      (!(Scr.flags & CirculateSkipIcons) || !(t->flags & ICONIFIED)) &&
+	      (t->flags & BORDER))
+	    {
+	      best = t->circulate_sequence;
+	      tmp_win = t;
+	    }
+	}
+      else /* AutoTabThroughDesks == 0 */
+	{
+	  if ((t->circulate_sequence > best) && 
+	      (t->Desk == Scr.CurrentDesk) &&
+	      !(t->flags & CIRCULATESKIP) &&
+	      (!(Scr.flags & CirculateSkipIcons) || !(t->flags & ICONIFIED)) &&
+	      (t->flags & BORDER))
+	    {
+	      best = t->circulate_sequence;
+	      tmp_win = t;
+	    }
 	}
     }
   if (tmp_win == NULL)
@@ -964,8 +1110,16 @@
 	}
       high = t->circulate_sequence;
 
-      if ((t->Desk != Scr.CurrentDesk) || (t->flags & CIRCULATESKIP))
-	continue;
+      if (AutoTabThroughDesks)
+	{
+	  if (t->flags & CIRCULATESKIP)
+	    continue;
+	}
+      else /* AutoTabThroughDesks == 0 */
+	{
+	  if ((t->Desk != Scr.CurrentDesk) || (t->flags & CIRCULATESKIP))
+	    continue;
+	}
 
       /* optional skip over icons */
       if ((t->flags & ICONIFIED) && (Scr.flags & CirculateSkipIcons))

--ibTvN161/egqYuK8--