Subject: Patch to 2.0.47d for FvwmWinList Sort+bugfixes - added manpage update.

From: Rocky - Rakesh Patel <[email-masked]>
Date: Fri, 10 Jul 1998 10:20:48 -0400 (EDT)

I forgot to update the man page in the patches that include the sorting
feature for FvwmWinList.  Below is the same set of patches to 2.0.47d
plus the man page update.

Rocky.

*** ButtonArray.c.ORIG	Mon Sep 23 20:04:56 1996
--- ButtonArray.c	Wed Jul  8 23:06:52 1998
***************
*** 175,180 ****
--- 175,250 ----
    return 1;
  }
  
+ /* [VS: Adding an update mechanism that will preserve alphabetical order.] */
+ 
+ /* 
+  * This finds a pointer to the memory location that points to the button
+  * we are seeking.  (I take the pointer of the location because it eliminates
+  * the special case involved with the head pointer.)
+  */
+ Button **ppBGetButton(ButtonArray *pBAArray, int iPos) {
+   Button **ppBTmp;
+ 
+   ppBTmp = &(pBAArray->head);
+   while (*ppBTmp != NULL && iPos != 0) {
+     ppBTmp = &((*ppBTmp)->next);
+     iPos--;
+   }
+   return(ppBTmp);
+ }
+ 
+ /******************************************************************************
+   UpdateButtonAlpha - Change the name/state/position of a button
+ ******************************************************************************/
+ int UpdateButtonAlpha(ButtonArray *pBAArray, int iOldPos, int iNewPos,
+ 		      char *pcTitle, int iUp) {
+ 
+   Button **ppBTmp, *pBTmp, *pBMove;
+ 
+   if (iOldPos == iNewPos)
+     return(UpdateButton(pBAArray, iOldPos, pcTitle, iUp));
+ 
+   ppBTmp = ppBGetButton(pBAArray, iOldPos);
+   pBMove = pBTmp = *ppBTmp;
+   if (pBTmp == NULL) return(-1);
+   *ppBTmp = pBTmp->next;
+ 
+   if (pcTitle != NULL) {
+     pBTmp->title = (char *) realloc(pBTmp->title, strlen(pcTitle) + 1);
+     strcpy(pBTmp->title, pcTitle);
+     pBTmp->tw=XTextWidth(ButtonFont, pcTitle, strlen(pcTitle));
+     pBTmp->truncatewidth = 0;
+   }
+   if ( iUp != -1) pBTmp->up = iUp;
+ 
+   if (iOldPos < iNewPos) {
+     while (pBTmp->next != NULL && iOldPos < iNewPos) {
+       pBTmp->needsupdate = 1;
+       pBTmp = pBTmp->next;
+       iOldPos++;
+     }
+   }
+ 
+   ppBTmp = ppBGetButton(pBAArray, iNewPos);
+   pBMove->next = *ppBTmp;
+   *ppBTmp = pBMove;
+ 
+   while (pBMove->next != NULL) {
+     if (iNewPos < iOldPos) {
+       pBMove->needsupdate = 1;
+       iNewPos++;
+     }
+     pBMove = pBMove->next;
+   }
+   if (iNewPos < iOldPos) pBMove->needsupdate = 1;
+ 
+   pBAArray->tail = pBMove;
+ 
+   return(1);
+ }
+ 
+ /* [VS: End of this change.] */
+ 
  /******************************************************************************
    UpdateButtonSet - Change colour set of a button
  ******************************************************************************/
***************
*** 337,343 ****
      }
  	else
  	{
! 		newx = 4;
  	}
  
    string=button->title;
--- 407,416 ----
      }
  	else
  	{
! 	  if (LeftJustify)
! 	      newx = 4;
! 	  else
! 	      newx=max((w-button->tw)/2,4);
  	}
  
    string=button->title;
*** FvwmWinList.c.ORIG	Thu Jul  2 13:14:04 1998
--- FvwmWinList.c	Wed Jul  8 23:27:46 1998
***************
*** 116,122 ****
        *ForeColor[MAX_COLOUR_SETS] = { "black" },
        *geometry="";
  char *font_string = "fixed";
! int UseSkipList=0,Anchor=1,UseIconNames=0,LeftJustify=0,TruncateLeft=1;
  
  long CurrentDesk = 0;
  int ShowCurrentDesk = 0;
--- 116,122 ----
        *ForeColor[MAX_COLOUR_SETS] = { "black" },
        *geometry="";
  char *font_string = "fixed";
! int UseSkipList=0,Anchor=1,UseIconNames=0,LeftJustify=0,TruncateLeft=1,Alpha=0;
  
  long CurrentDesk = 0;
  int ShowCurrentDesk = 0;
***************
*** 268,274 ****
  ******************************************************************************/
  void ProcessMessage(unsigned long type,unsigned long *body)
  {
!   int redraw=0,i;
    long flags;
    char *name,*string;
    static current_focus=-1;
--- 268,274 ----
  ******************************************************************************/
  void ProcessMessage(unsigned long type,unsigned long *body)
  {
!   int redraw=0,i, iOldPos, iNewPos;
    long flags;
    char *name,*string;
    static current_focus=-1;
***************
*** 301,308 ****
  	break;
        }
  
!       if (!(body[8]&WINDOWLISTSKIP) || !UseSkipList)
          AddItem(&windows,body[0],body[8], body[7] /* desk */);
        break;
      case M_DESTROY_WINDOW:
        if ((i=DeleteItem(&windows,body[0]))==-1) break;
--- 301,317 ----
  	break;
        }
  
! 
! /* [VS: If we are preserving alphabetical order, we need to add a button]
!    [VS: as soon as we know there is a need for one.] */
! 
!       if (!(body[8]&WINDOWLISTSKIP) || !UseSkipList) {
          AddItem(&windows,body[0],body[8], body[7] /* desk */);
+         if (Alpha) AddButton(&buttons,"", NULL ,1);
+       }
+ 
+ /* [VS: End of this change.] */
+ 
        break;
      case M_DESTROY_WINDOW:
        if ((i=DeleteItem(&windows,body[0]))==-1) break;
***************
*** 335,349 ****
      case M_ICON_NAME:
        if ((type==M_ICON_NAME && !UseIconNames) || 
            (type==M_WINDOW_NAME && UseIconNames)) break;
!       if ((i=UpdateItemName(&windows,body[0],(char *)&body[3]))==-1) break;
!       string=(char *)&body[3];
!       name=makename(string,ItemFlags(&windows,body[0]));
!       if (UpdateButton(&buttons,i,name,-1)==-1)
!       {
! 	AddButton(&buttons, name, NULL, 1);
! 	UpdateButtonSet(&buttons,i,ItemFlags(&windows,body[0])&ICONIFIED?1:0);
!         UpdateButtonDesk(&buttons,i,ItemDesk(&windows, body[0]));
        }
        free(name);
        if (WindowIsUp) AdjustWindow();
        redraw=1;
--- 344,375 ----
      case M_ICON_NAME:
        if ((type==M_ICON_NAME && !UseIconNames) || 
            (type==M_WINDOW_NAME && UseIconNames)) break;
! /* [VS: More stuff for the alphabetical ordering of buttons.] */
! 
!       if (Alpha) {
!         if (UpdateItemNameAlpha(&windows,body[0],(char *)&body[3], &iOldPos,
! 				&iNewPos) == -1) break;
! 
!         string=(char *)&body[3];
!         name=makename(string, ItemFlags(&windows,body[0]));
! 	UpdateButtonAlpha(&buttons, iOldPos, iNewPos, name, -1);
!         UpdateButtonSet(&buttons, iNewPos,ItemFlags(&windows, body[0]) &ICONIFIED?1:0);
!         UpdateButtonDesk(&buttons,iNewPos,ItemDesk(&windows, body[0]));
!       }
!       else {
! 	if ((i=UpdateItemName(&windows,body[0],(char *)&body[3]))==-1) break;
! 	string=(char *)&body[3];
! 	name=makename(string,ItemFlags(&windows,body[0]));
! 	if (UpdateButton(&buttons,i,name,-1)==-1)
! 	  {
! 	    AddButton(&buttons, name, NULL, 1);
! 	    UpdateButtonSet(&buttons,i,ItemFlags(&windows,body[0])&ICONIFIED?1:0);
! 	    UpdateButtonDesk(&buttons,i,ItemDesk(&windows, body[0]));
! 	  }
        }
+ 
+ /* [VS: End of this change.] */
+ 
        free(name);
        if (WindowIsUp) AdjustWindow();
        redraw=1;
***************
*** 572,577 ****
--- 598,608 ----
                                  Clength+8)==0) MinWidth=atoi(&tline[Clength+8]);
            else if(mystrncasecmp(tline,CatString3(Module, "MaxWidth",""),
                                  Clength+8)==0) MaxWidth=atoi(&tline[Clength+8]);
+ /* [VS: How about making the items alphabetically ordered?] */
+           else if(mystrncasecmp(tline,CatString3(Module, "AlphaOrder",""),
+                                 Clength+10)==0) Alpha=1;
+ /* [VS: End of this change.] */
+ 
  	}
        GetConfigLine(Fvwm_fd,&tline);
      }
***************
*** 718,757 ****
    {
      if (Anchor)
      {
!       if (win_grav==SouthEastGravity || win_grav==NorthEastGravity)
!         win_x-=(new_width-win_width);
  
!       if (win_grav==SouthEastGravity || win_grav==SouthWestGravity)
!         win_y-=(new_height-win_height);
! 
! #if 0
!       if(RESIZE_BUG_HACK)
        {
!         if (win_grav==SouthEastGravity || win_grav==NorthEastGravity)
! 		win_x+= win_border - 2;
! 	else
! 		win_x-=win_border;
! 
! 	if (win_grav==SouthEastGravity || win_grav==SouthWestGravity)
! 		win_y+=win_border - 2;
! 	else	
! 		win_y-=win_border;
!       }
! #else /* ckh - need to come up w/ better way to calculate win_x & _y */
!         if (win_grav==SouthEastGravity || win_grav==NorthEastGravity)
! 		win_x+= win_border-3;
! 	else
! 		win_x-=win_border;
! 
! 	if (win_grav==SouthEastGravity || win_grav==SouthWestGravity)
! 		win_y+=win_border-3;
! 	else	
! 		win_y-=win_border;
! #endif /* 0 */
  
!       XMoveResizeWindow(dpy,win,win_x+win_border,win_y+win_title+win_border,
!         new_width,new_height);
  
      }
      else
        XResizeWindow(dpy, win, new_width,new_height);
--- 749,794 ----
    {
      if (Anchor)
      {
!       static int x1, x2, y1 , y2;
!       int new_x, new_y;
!       static int gothints = 0;
!       XSizeHints hints;
  
!       if ( !gothints )
        {
!         XGetNormalHints(dpy,win,&hints);
! 
!         x1 = (hints.x < 0 ? 0 : hints.x);
!         x2 = ScreenWidth - x1 - hints.width;
!         if ( x2 < 0 ) x2 = 0;
  
!         y1 = (hints.y < 0 ? 0 : hints.y);
!         y2 = ScreenHeight - y1 - hints.height;
!         if( y2 < 0 ) y2 = 0;
! 
!         gothints = 1;
!       }
  
+       if ( win_grav == NorthEastGravity || win_grav == SouthEastGravity)
+         new_x = ScreenWidth - x2 - win_border*2 - new_width;
+       else
+         new_x = x1;
+ 
+       if ( win_grav == SouthEastGravity || win_grav == SouthWestGravity)
+         new_y = ScreenHeight - y2 - win_border*2 - new_height;
+       else
+         new_y = y1;
+   
+       if ( win_border > 0 )
+       {
+         new_x += win_border+1;
+         new_y += win_border+1;
+       }
+       if ( win_title > 0)
+       {
+         new_y += win_title+1;
+       }
+       XMoveResizeWindow(dpy,win,new_x, new_y, new_width,new_height);
      }
      else
        XResizeWindow(dpy, win, new_width,new_height);
***************
*** 776,785 ****
  {
  char *ptr;
    ptr=safemalloc(strlen(string)+3);
!   if (flags&ICONIFIED) strcpy(ptr,"(");
    else strcpy(ptr,"");
    strcat(ptr,string);
!   if (flags&ICONIFIED) strcat(ptr,")");
    return ptr;
  }
  
--- 813,830 ----
  {
  char *ptr;
    ptr=safemalloc(strlen(string)+3);
! 
! /* [VS: I don't like the addition of parens around items that are iconified.]*/
! /* [VS: They should really not appear if the colors are defined to be] */
! /* [VS: different.] */
! /*  if (flags&ICONIFIED) strcpy(ptr,"("); */
!   if (fore[0] == fore[1] && back[0] == back[1] && (flags&ICONIFIED))
!     strcpy(ptr,"(");
    else strcpy(ptr,"");
    strcat(ptr,string);
! /*  if (flags&ICONIFIED) strcpy(ptr,")"); */
!   if (fore[0] == fore[1] && back[0] == back[1] && (flags&ICONIFIED))
!     strcat(ptr,")");
    return ptr;
  }
  
***************
*** 865,870 ****
--- 910,918 ----
    win_x=hints.x;
    win_y=hints.y;
  
+ /*
+   [VS: Had to move this earlier in the initialization.]
+ 
  
    for (i = 0; i != MAX_COLOUR_SETS; i++)
    if(d_depth < 2)
***************
*** 878,883 ****
--- 926,934 ----
      fore[i] = GetColor(ForeColor[i] == NULL ? ForeColor[0] : ForeColor[i]);
    }
  
+   [VS: End of this change.]
+ */
+ 
    win=XCreateSimpleWindow(dpy,Root,hints.x,hints.y,hints.width,hints.height,1,
      fore[0],back[0]);
  
***************
*** 955,960 ****
--- 1006,1013 ----
  ******************************************************************************/
  void StartMeUp()
  {
+   int i;
+ 
    if (!(dpy = XOpenDisplay("")))
    {
      fprintf(stderr,"%s: can't open display %s", Module,
***************
*** 977,982 ****
--- 1030,1057 ----
    fontheight = ButtonFont->ascent+ButtonFont->descent;
  
    win_width=XTextWidth(ButtonFont,"XXXXXXXXXXXXXXX",10);
+ 
+ /*
+   [VS: I moved this here to initialize the color information earlier.]
+   [VS: The window list (along with all the window names) was created]
+   [VS: before the colors are generated.  Since I am trying to decide]
+   [VS: to use text or color clues to visually differentiate between]
+   [VS: iconified and uniconified windows, I moved it up in the processing. ]
+ */
+ 
+   for (i = 0; i != MAX_COLOUR_SETS; i++)
+   if(d_depth < 2)
+   {
+     back[i] = GetColor("white");
+     fore[i] = GetColor("black");
+   }
+   else
+   {
+     back[i] = GetColor(BackColor[i] == NULL ? BackColor[0] : BackColor[i]);
+     fore[i] = GetColor(ForeColor[i] == NULL ? ForeColor[0] : ForeColor[i]);
+   }
+ 
+ /* [VS: End of this change.] */
  
  }
  
*** FvwmWinList.man.ORIG	Tue Jan  6 09:19:55 1998
--- FvwmWinList.man	Fri Jul 10 09:55:45 1998
***************
*** 120,125 ****
--- 120,132 ----
  supported \fIresponse\fPs are any fvwm built-in commands, including modules
  and functions.
  
+ .IP "*FvwmWinListAlphaOrder"
+ Enable case sensitive sorting of entries in the FvwmWinList window.
+ If the foreground/background colors used for iconified and open windows
+ are different, then this feature will disable the use if parenthesis around
+ the name in order to properly sort the entries.
+ 
+ 
  .SH SAMPLE CONFIGURATION
  The following are excepts from a .fvwmrc file which describe FvwmWinList
  initialization commands:
*** List.c.ORIG	Mon Sep 23 20:01:58 1996
--- List.c	Wed Jul  8 23:29:48 1998
***************
*** 129,134 ****
--- 129,173 ----
    return 0;
  }
  
+ /* [VS: Adding an update mechanism that will preserve alphabetical order.] */
+ 
+ /******************************************************************************
+   UpdateItemNameAlpha - Update the item in the list, setting name, flags and
+                         ordering as necessary.
+ ******************************************************************************/
+ int UpdateItemNameAlpha(List *pLList, long lID, char *pcString, int *piOldPos,
+ 			int *piNewPos) {
+   Item **ppITmp, *pITmp;
+ 
+   *piOldPos = *piNewPos = 0;
+ 
+   ppITmp = &(pLList->head);
+   while (*ppITmp != NULL && (*ppITmp)->id != lID) {
+     ppITmp = &((*ppITmp)->next);
+     (*piOldPos)++;
+   }
+   pITmp = *ppITmp;
+   if (pITmp == NULL) return(-1);
+   *ppITmp = pITmp->next;
+ 
+   UpdateString(&pITmp->name, pcString);
+ 
+   ppITmp = &(pLList->head);
+   while (*ppITmp != NULL && strcmp(pITmp->name, (*ppITmp)->name) > 0) {
+     ppITmp = &((*ppITmp)->next);
+     (*piNewPos)++;
+   }
+   pITmp->next = *ppITmp;
+   *ppITmp = pITmp;
+ 
+   while (pITmp->next != NULL) pITmp = pITmp->next;
+   pLList->tail = pITmp;
+ 
+   return(1);
+ }
+ 
+ /* [VS: End of this change.] */
+ 
  int UpdateItemFlags(List *list, long id, long flags)
  {
  Item *temp;
*** List.h.ORIG	Wed May 22 06:24:27 1996
--- List.h	Wed Jul  8 23:30:13 1998
***************
*** 35,40 ****
--- 35,46 ----
  int FindItemDesk(List *list, long id, long desk);
  
  int UpdateItemName(List *list, long id, char *string);
+ 
+ /* [VS: I added a function that would allow alphabetically sorted items.] */
+ int UpdateItemNameAlpha(List *pLList, long lID, char *pcString, int *piOldPos,
+ 			int *piNewPos);
+ /* [VS: End of this change.] */
+ 
  int UpdateItemDesk(List *list, long id, long desk);
  int UpdateItemFlags(List *list, long id, long flags);
  void FreeItem(Item *ptr);

                             Rakesh B. Patel
                         [email-masked]
                           Network Operations
                       Telecommunications Division
              Rutgers University Computing Services (RUCS)
                             +1 732-445-3436

Love is an ocean of emotions, entirely surrounded by expenses.
				-Thomas Robert Dewar
But it's worth it.
	- Rakesh Patel
--
Visit the official FVWM web page at <URL:http://www.hpc.uh.edu/fvwm/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked].