Subject: FVWM: fvwm2 sorted WindowList

From: Robert Tsai <[email-masked]>
Date: Tue, 13 May 1997 18:19:25 -0700 (PDT)

</lurk>

My first contribution to the internet. This patch displays the WindowList
function (not the FvwmWinList module) alphabetized by window/icon name
rather than by hotkey. It makes it easier to find the window you are
looking for. 

The patch is a context diff to be applied to fvwm-2.0.45, included to this
e-mail as a MIME attachment.

There is a function AddToMenu0, which is identical to the original
AddToMenu, with the addition of a boolean 'sort' argument. The original
AddToMenu gets #define'd to AddToMenu0(false), and a new macro
SortedAddToMenu gets #define'd to AddToMenu0(true). The new code is in
menus.c. The menus.h diff reflects the new #define's and AddToMenu0
header, and the windows.c diff reflects the use of SortedAddToMenu. 

<lurk>

--Rob
=================================== Speaking only for myself, of course ==
Robert Tsai                                          IBM Products Division
[email-masked]                           500 Oracle Parkway, M/S 2op4
tel. 415-506-9319, fax 415-506-7409               Redwood Shores, CA 94065
*** fvwm.orig/menus.c	Mon Jan 20 08:56:11 1997
--- fvwm/menus.c	Mon May 12 00:20:02 1997
***************
*** 1180,1191 ****
   *	item	- the text to appear in the menu
   *	action	- the string to possibly execute
   *	func	- the numeric function
   *
   * ckh - need to add boolean to say whether or not to expand for pixmaps,
   *       so built in window list can handle windows w/ * and % in title.
   *
   ***********************************************************************/
! void AddToMenu(MenuRoot *menu, char *item, char *action)
  {
    MenuItem *tmp;
    char *start,*end;
--- 1180,1192 ----
   *	item	- the text to appear in the menu
   *	action	- the string to possibly execute
   *	func	- the numeric function
+  *	sort    - whether or not to sort by item title (not hotkey)
   *
   * ckh - need to add boolean to say whether or not to expand for pixmaps,
   *       so built in window list can handle windows w/ * and % in title.
   *
   ***********************************************************************/
! void AddToMenu0(MenuRoot *menu, char *item, char *action, int sort)
  {
    MenuItem *tmp;
    char *start,*end;
***************
*** 1195,1210 ****
  
    tmp = (MenuItem *)safemalloc(sizeof(MenuItem));
    if (menu->first == NULL)
!     {
!       menu->first = tmp;
        tmp->prev = NULL;
      }
    else
!     {
!       menu->last->next = tmp;
!       tmp->prev = menu->last;
!     }
!   menu->last = tmp;
    tmp->picture=NULL;
    tmp->lpicture=NULL;
  
--- 1196,1292 ----
  
    tmp = (MenuItem *)safemalloc(sizeof(MenuItem));
    if (menu->first == NULL)
!     {				/* first menu item */
        tmp->prev = NULL;
+       tmp->next = NULL;
+       menu->first = tmp;
+       menu->last = tmp;
      }
    else
!     {				/* add new menu item */
!       if (sort)
! 	{			/* sorted insert */
! 	  MenuItem *p = menu->first->next; /* skip the title */
! 
! 	  /* [email-masked]: For some reason, fvwm2 occasionally
!              coredumps when I use a dynamically-allocated
!              item_string. I can get the coredump by repeatedly
!              invoking WindowList while running Netscape 3.01 Gold or
!              editres, but I can't figure out why. (This is for
!              Slackware 3.2 (Linux 2.0.29)). Thus, I #undef
!              _MALLOC_ITEM_STRING to use a static array. The code is
!              cleaner anyway, since it then requires no cleanup. 128
!              chars should be enough for any window titles. I haven't
!              tried reproducing the coredump on Solaris 2.4, because
!              losing my WM and having to re-login is somewhat
!              disruptive ;) */
! #undef _MALLOC_ITEM_STRING
! #ifdef _MALLOC_ITEM_STRING
! 	  char *ch, *item_string; /* to determine sort order */
! #else
! 	  char *ch, item_string[128]; /* to determine sort order */
! #endif
! 	  int index;
! 	  
! #ifdef _MALLOC_ITEM_STRING
! 	  item_string = (char *) safemalloc (sizeof (char) * strlen (item));
! 	  strcpy (item_string, item);
! #else
! 	  strncpy (item_string, item, sizeof (item_string));
! 	  item_string [sizeof (item_string) - 1] = 0;
! #endif
! 
! 	  /* remove the '&' hotkey markers */
! 	  while ((ch = strchr (item_string, '&')))
! 	    {
! 	      while (*ch)
! 		{
! 		  *ch = *(ch + 1);
! 		  ch++;
! 		}
! 	    }
! 
! 	  /* [email-masked]: This is an ugly hack to determine
! 	     whether or not this is a WindowList menu. For WindowList
! 	     menus, we want to sort by window/icon title rather than
! 	     first character, so we skip over the hotkey
! 	     characters. */
! 	  index = item_string[1] == '.' ? 4 : 0;
! 
! 	  /* find point before which to insert new item */
! 	  while (p && strcmp (&item_string[index], &p->item[index]) >= 0)
! 	    p = p->next;
! 
! #ifdef _MALLOC_ITEM_STRING
! 	  if (item_string)
! 	    free (item_string);	/* cleanup */
! #endif
! 
! 	  if (p)
! 	    {			/* insert new item before p */
! 	      tmp->prev = p->prev;
! 	      tmp->next = p;
! 	      tmp->prev->next = tmp;
! 	      tmp->next->prev = tmp;
! 	    }
! 	  else
! 	    {			/* add to end, just like unsorted insert */
! 	      tmp->prev = menu->last;
! 	      tmp->next = NULL;
! 	      tmp->prev->next = tmp;
! 
! 	      menu->last = tmp;	/* last menu pointer */
! 	    }
! 	} /* sorted insert */
!       else
! 	{			/* unsorted insert */
! 	  tmp->prev = menu->last;
! 	  tmp->next = NULL;
! 	  tmp->prev->next = tmp;
! 
! 	  menu->last = tmp;	/* last menu pointer */
! 	} /* unsorted insert */
!     } /* add new menu item */
    tmp->picture=NULL;
    tmp->lpicture=NULL;
  
***************
*** 1257,1263 ****
      tmp->strlen2 = 0;
  
    tmp->action = stripcpy(action);
-   tmp->next = NULL;
    tmp->state = 0;
    tmp->func_type = find_func_type(tmp->action);
    tmp->item_num = menu->items++;
--- 1339,1344 ----
*** fvwm.orig/misc.h	Mon Dec 23 14:07:47 1996
--- fvwm/misc.h	Sun May 11 23:24:11 1997
***************
*** 223,229 ****
  extern Bool       GrabEm(int);
  extern void       UngrabEm(void);
  extern MenuRoot   *NewMenuRoot(char *name, int function_or_popup);
! extern void       AddToMenu(MenuRoot *, char *, char *);
  extern void       MakeMenu(MenuRoot *);
  extern void       CaptureAllWindows(void);
  extern void       SetTimer(int);
--- 223,231 ----
  extern Bool       GrabEm(int);
  extern void       UngrabEm(void);
  extern MenuRoot   *NewMenuRoot(char *name, int function_or_popup);
! extern void       AddToMenu0(MenuRoot *, char *, char *, int);
! #define AddToMenu(menu, item, action) AddToMenu0 (menu, item, action, 0)
! #define SortedAddToMenu(menu, item, action) AddToMenu0 (menu, item, action, 1)
  extern void       MakeMenu(MenuRoot *);
  extern void       CaptureAllWindows(void);
  extern void       SetTimer(int);
*** fvwm.orig/windows.c	Tue Jan 14 14:09:00 1997
--- fvwm/windows.c	Mon May 12 00:09:02 1997
***************
*** 226,232 ****
            sprintf(tlabel,"%s %ld",func,t->w);
          else
            sprintf(tlabel,"WindowListFunc %ld",t->w);
!         AddToMenu(mr, t_hot, tlabel);
  #ifdef MINI_ICONS
          /* Add the title pixmap */
          if (t->mini_icon) {
--- 226,232 ----
            sprintf(tlabel,"%s %ld",func,t->w);
          else
            sprintf(tlabel,"WindowListFunc %ld",t->w);
!         SortedAddToMenu(mr, t_hot, tlabel); /* [email-masked] */
  #ifdef MINI_ICONS
          /* Add the title pixmap */
          if (t->mini_icon) {