Subject: FVWM: FvwmWinList patches to 2.0.47b and a bug/question on 2.0.47b FvwmButtons.

From: Rocky - Rakesh Patel <[email-masked]>
Date: Tue, 30 Jun 1998 17:45:45 -0400 (EDT)

At the end of this message are the FvwmWinList patches to 2.0.47b for
sorting and the geometry fix for the problem that becomes visible when
using the sorting option. [Diffs are relative to the FvwmButtons
directory].

When converting over to 2.0.47b, I suddenly ran into a problem with
FvwmButtons where the icons do not appear [only the title appears for
some reason - woth 2.0.46 the icon appears]. The syntax I use in my
.fvwm2rc is :

ModulePath /usr/local/lib/X11/fvwm2
PixmapPath /usr/local/X11/include/X11/pixmaps:/td/nog/unix/X/images
IconPath /usr/local/X11/include/X11/bitmaps

DestroyModuleConfig FvwmButtons

*FvwmButtonsRows 2

############################################################################
# FvwmButtons
#
# Colors
*FvwmButtonsFore Black
*FvwmButtonsBack #908090

# Font 
# *FvwmButtonsFont      6x9
*FvwmButtonsFont -adobe-helvetica-bold-r-*-*-11-*-*-*-*-*-*-*

# Geometry-- really likes to pick its own size, but giving a position is OK
*FvwmButtonsGeometry -0-0

# Layout: specify rows or columns, not both
#*FvwmButtonsColumns 9
*FvwmButtonsRows 2

# Define the buttons to use.....
# *FvwmButtons (9x2, Swallow "FvwmPager")
*FvwmButtons Netscape mini-nscape.xpm Exec /usr/local/netscape/netscape
*FvwmButtons Remedy     remedy.xpm      Exec LD_LIBRARY_PATH=/td/nog/unix/solaris/lib /usr/local/bin/aruser
*FvwmButtons Mail       mail2.xpm       Exec messages
*FvwmButtons Xterm      xterm-sun.xpm   Exec xterm -T `hostname`
*FvwmButtons Lock       xlock.xpm       Exec /usr/local/X11R5/bin/xlock -mode blank
*FvwmButtons Telnet     xterm-sun.xpm   Module FvwmForm Telnet
*FvwmButtons Kxrsh      xterm-sun.xpm   Module FvwmForm Kxrsh
*FvwmButtons Xrsh       xterm-sun.xpm   Module FvwmForm Xrsh
*FvwmButtons eKtelnet   xterm-sun.xpm   Module FvwmForm eKtelnet
*FvwmButtons Quit       exit.xpm        Popup "Quit-Verify"

Any suggestions as to why the title only appears with the new FvwmButtons code?

Here are the FvwmWinList patches:

*** ButtonArray.c.ORIG	Mon Sep 23 20:04:56 1996
--- ButtonArray.c	Tue Jun 30 15:50:32 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
  ******************************************************************************/
***************
*** 335,343 ****
  
      newx += button->p.width+4;
      }
! 	else
  	{
! 		newx = 4;
  	}
  
    string=button->title;
--- 405,416 ----
  
      newx += button->p.width+4;
      }
!     else
  	{
! 	   if ( LeftJustify)
! 	     newx = 4;
! 	   else
! 	     newx=max((w-button->tw)/2,4);
  	}
  
    string=button->title;
*** ButtonArray.h.ORIG	Wed May 22 06:24:25 1996
--- ButtonArray.h	Tue Jun 30 15:50:55 1998
***************
*** 38,43 ****
--- 38,50 ----
  void UpdateArray(ButtonArray *array,int x,int y,int w, int h);
  int AddButton(ButtonArray *array, char *title, Picture *p,int up);
  int UpdateButton(ButtonArray *array, int butnum, char *title, int up);
+ 
+ /* [VS: I added two functions that would allow alphabetically sorted items.] */
+ Button **ppBGetButton(ButtonArray *pBAArray, int iPos);
+ int UpdateButtonAlpha(ButtonArray *pBAArray, int iOldPos, int iNewPos,
+ 		      char *pcTitle, int iUp);
+ /* [VS: End of this change.] */
+ 
  int UpdateButtonPicture(ButtonArray *array, int butnum, Picture *p);
  int UpdateButtonSet(ButtonArray *array, int butnum, int set);
  void RemoveButton(ButtonArray *array, int butnum);
*** FvwmWinList.c.ORIG	Mon Jan 26 16:02:46 1998
--- FvwmWinList.c	Tue Jun 30 15:57:05 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);
      }
***************
*** 716,727 ****
    new_height=(total*(fontheight+6+1)-1);
    if (WindowIsUp && (new_height!=win_height  || new_width!=win_width))
    {
!     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
--- 747,758 ----
    new_height=(total*(fontheight+6+1)-1);
    if (WindowIsUp && (new_height!=win_height  || new_width!=win_width))
    {
!     if (Anchor && win_grav != NorthWestGravity && win_grav != StaticGravity)
      {
!       if (win_x > 0 && (win_grav==SouthEastGravity || win_grav==NorthEastGravity))
          win_x-=(new_width-win_width);
  
!       if (win_y> 0 && (win_grav==SouthEastGravity || win_grav==SouthWestGravity))
          win_y-=(new_height-win_height);
  
  #if 0
***************
*** 738,757 ****
  		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);
--- 769,787 ----
  		win_y-=win_border;
        }
  #else /* ckh - need to come up w/ better way to calculate win_x & _y */
!       {
! 	int movedy = win_y, movedx = win_x ;
!   
! 	if ( win_y >= 0 )
! 	  movedy+=win_border+win_title+1;
! 	if ( win_x >= 0 )
! 	  movedx+=win_border+1;
  
! 	XMoveResizeWindow(dpy,win,movedx,
! 			movedy, new_width,new_height);
!       }
  #endif /* 0 */
  
      }
      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;
  }
  
--- 806,823 ----
  {
  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 ****
--- 903,911 ----
    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 ****
--- 919,927 ----
      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 ****
--- 999,1006 ----
  ******************************************************************************/
  void StartMeUp()
  {
+   int i;
+ 
    if (!(dpy = XOpenDisplay("")))
    {
      fprintf(stderr,"%s: can't open display %s", Module,
***************
*** 977,982 ****
--- 1023,1050 ----
    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.] */
  
  }
  
*** List.c.ORIG	Mon Sep 23 20:01:58 1996
--- List.c	Tue Jun 30 15:52:06 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	Tue Jun 30 15:52:10 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" in the body of a
message to [email-masked].
To report problems, send mail to [email-masked].