Subject: (2nd try) Fixed - FvwmTaskBar patch to allow shortcut buttons

From: Ben Mathews <[email-masked]>
Date: Sun, 08 Sep 2002 21:58:33 -0400

Forgot to attach the attachment to the last one.  Here it is again, with 
the attachment! -------------

Attached is the fixed patch that allows shortcut buttons in FvwmTaskBar, 
as well as a couple of new positioning options.    It now does not crash 
when you declare a start button after a minibutton, and a problem with 
using StartMenu (instead of the spiffy new StartCommand) has also been 
fixed.  I have been beating it for a couple of hours now and it seems 
perfectly stable.

My additions (from the man page):

        *FvwmTaskBar: Button Title title, Icon icon, Action action
               Tells FvwmTaskBar to put a shortcut  minibutton  in
               the  taskbar  that  does  action when clicked.  The
               icon can have a caption denoted by title,  an  icon
               denoted  by icon, or a combination of the two.  The
               icons will appear to the  immediate  right  of  the
               start  button,  and  will  appear in the order that
               they are declared in the .fvwm2rc file.

        *FvwmTaskBar: WindowButtonsLeftMargin margin
               Specifies  the  space  (in pixels) between the left
               side of the left-most window button and  the  right
               side  of  the  start  button or right-most shortcut
               minibutton.  If this option is not  specified,  the
               default margin is 4.

        *FvwmTaskBar: WindowButtonsRightMargin margin
               Specifies  the  space (in pixels) between the right
               side of the right-most window button and  the  left
               side  of  the clock and tip window.  If this option
               is not specified, the default margin is 2.

        *FvwmTaskBar: StartButtonRightMargin margin
               Specifies the space (in pixels) between  the  right
               side  of  the start button and the left side of the
               left-most shortcut minibutton.  If this  option  is
               not specified, the default margin is 0.

Some sample lines from my fvwm2rc:

*FvwmTaskBar: WindowButtonsLeftMargin 1
*FvwmTaskBar: WindowButtonsRightMargin 0
*FvwmTaskBar: StartButtonRightMargin 2

*FvwmTaskBar: Button Title Mozilla, Action exec exec 
/usr/local/mozilla/mozilla
*FvwmTaskBar: Button Icon mini.term.xpm, Action exec exec xterm
*FvwmTaskBar: Button Title Freeamp, Icon mini.cd.xpm, Action exec exec 
freeamp

? patchfile
Index: AUTHORS
===================================================================
RCS file: /home/cvs/fvwm/fvwm/AUTHORS,v
retrieving revision 1.71
diff -u -r1.71 AUTHORS
--- AUTHORS	2002/08/20 00:15:16	1.71
+++ AUTHORS	2002/09/09 01:52:45
@@ -2,6 +2,9 @@
 Maintainers of GNU Software" (maintain.texi), the section called
 "Recording Changes".
 
+Ben Mathews:
+Modified FvwmTaskBar to allow shortcut buttons in the taskbar
+
 David Fries:
 WindowList option SortClassName.
 
@@ -220,7 +223,6 @@
 LEFT_MENUS option.  Added primitives: animated-moves, SetEnv, fix to
 Echo. Improve modules: Make FvwmM4 pass args on to m4, font-related
 seg-fault bug fix in FvwmButtons.
-
 
 Along with a cast of thousands (well, dozens) mentioned in old
 ChangeLog entries.  If you find your name below, please send an entry
Index: modules/FvwmTaskBar/ButtonArray.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmTaskBar/ButtonArray.c,v
retrieving revision 1.31
diff -u -r1.31 ButtonArray.c
--- modules/FvwmTaskBar/ButtonArray.c	2002/08/30 06:04:02	1.31
+++ modules/FvwmTaskBar/ButtonArray.c	2002/09/09 01:52:49
@@ -680,7 +680,7 @@
 /* -------------------------------------------------------------------------
     ButtonCoordinates - Compute the coordinates of a button (animation)
    ------------------------------------------------------------------------- */
-extern int StartButtonWidth;
+extern int  StartAndMiniButtonsWidth;
 void ButtonCoordinates(ButtonArray *array, int numbut, int *xc, int *yc)
 {
 	Button *temp;
@@ -702,7 +702,7 @@
 		}
 	}
 
-	*xc = x+StartButtonWidth+3;
+	*xc = x+ StartAndMiniButtonsWidth+3;
 	*yc = y;
 }
 
Index: modules/FvwmTaskBar/FvwmTaskBar.1
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmTaskBar/FvwmTaskBar.1,v
retrieving revision 1.32
diff -u -r1.32 FvwmTaskBar.1
--- modules/FvwmTaskBar/FvwmTaskBar.1	2002/06/28 21:51:20	1.32
+++ modules/FvwmTaskBar/FvwmTaskBar.1	2002/09/09 01:52:49
@@ -1,6 +1,6 @@
 .\" t
 .\" @(#)FvwmTaskBar.1	6/30/96
-.TH FvwmTaskBar 1 "25 April 2002" FVWM "FVWM Modules"
+.TH FvwmTaskBar 1 "9 September 2002" FVWM "FVWM Modules"
 .UC
 .SH NAME
 FvwmTaskBar \- the FVWM taskbar module
@@ -208,10 +208,32 @@
 the width or height of the button.  All this is done regardless of
 any quoting characters. To get a literal '$' use the string '$$'.
 
+.IP "*FvwmTaskBar: Button Title \fItitle\fP, Icon \fIicon\fP, Action \fIaction\fP"
+Tells FvwmTaskBar to put a shortcut minibutton in the taskbar that does
+\fIaction\fP when clicked.  The icon can have a caption denoted by \fItitle\fP,
+an icon denoted by \fIicon\fP, or a combination of the two.  The icons will
+appear to the immediate right of the start button, and will appear in the 
+order that they are declared in the .fvwm2rc file.
+
 .IP "*FvwmTaskBar: ButtonWidth \fIwidth\fP"
 Indicates the maximum width that window buttons should reach.
 (the minimum is hard coded at 32).
 
+.IP "*FvwmTaskBar: WindowButtonsLeftMargin \fImargin\fP"
+Specifies the space (in pixels) between the left side of the left-most window
+button and the right side of the start button or right-most shortcut 
+minibutton.  If this option is not specified, the default margin is 4.
+
+.IP "*FvwmTaskBar: WindowButtonsRightMargin \fImargin\fP"
+Specifies the space (in pixels) between the right side of the right-most 
+window button and the left side of the clock and tip window.  If this option 
+is not specified, the default margin is 2.
+
+.IP "*FvwmTaskBar: StartButtonRightMargin \fImargin\fP"
+Specifies the space (in pixels) between the right side of the start button 
+and the left side of the left-most shortcut minibutton.  If this option is 
+not specified, the default margin is 0.
+
 .IP "*FvwmTaskBar: 3DFvwm"
 By default the buttons use a special (asymmetric) 3D look. This option enables
 a more classical 3D look (Ie., a la fvwm).
@@ -372,6 +394,10 @@
 *FvwmTaskBar: StartName Start
 *FvwmTaskBar: StartMenu StartMenu
 *FvwmTaskBar: StartIcon mini-exp.xpm
+
+*FvwmTaskBar: Button Title Mozilla, Action exec exec /usr/local/mozilla/mozilla
+*FvwmTaskBar: Button Icon mini.term.xpm, Action exec exec xterm
+*FvwmTaskBar: Button Title Freeamp, Icon mini.cd.xpm, Action exec exec freeamp
 
 .sp
 .fi
Index: modules/FvwmTaskBar/FvwmTaskBar.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmTaskBar/FvwmTaskBar.c,v
retrieving revision 1.102
diff -u -r1.102 FvwmTaskBar.c
--- modules/FvwmTaskBar/FvwmTaskBar.c	2002/09/03 23:13:08	1.102
+++ modules/FvwmTaskBar/FvwmTaskBar.c	2002/09/09 01:52:53
@@ -170,6 +170,9 @@
 
 int UpdateInterval = 30;
 
+int whichButton = -1; 
+Bool startButtonPressed = FALSE;
+
 ButtonArray buttons;
 List windows;
 
@@ -226,10 +229,11 @@
 extern TipStruct Tip;
 
 /* Imported from Start */
-extern int StartButtonWidth, StartButtonHeight;
-extern char *StartPopup;
-extern char *StartCommand;
-
+extern int StartAndMiniButtonsWidth, StartAndMiniButtonsHeight;
+extern StartAndMiniButtonItem *First_Start_Button;
+extern StartAndMiniButtonItem *Last_Start_Button;
+extern int WindowButtonsLeftMargin;
+extern int WindowButtonsRightMargin;
 char *ImagePath = NULL;
 char *XineramaConfig = NULL;
 static int fscreen = 0;
@@ -360,9 +364,9 @@
   StartButtonInit(RowHeight);
 
   /* init the array of buttons */
-  InitArray(&buttons, StartButtonWidth + 4, 0,
-		      win_width - stwin_width - 8 - StartButtonWidth -10,
-		      RowHeight, button_width);
+  InitArray(&buttons, StartAndMiniButtonsWidth + WindowButtonsLeftMargin, 0,
+	    win_width - stwin_width - StartAndMiniButtonsWidth - WindowButtonsLeftMargin
+	    - WindowButtonsRightMargin, RowHeight, button_width);
   InitList(&windows);
 
   /* Request a list of all windows,
@@ -559,7 +563,9 @@
 	  XResizeWindow(dpy, win, win_width, win_height);
 
 	UpdateArray(&buttons, -1, -1,
-		    win_width - stwin_width - 8 - StartButtonWidth -10,-1, -1);
+		    win_width - stwin_width - StartAndMiniButtonsWidth
+		    - WindowButtonsLeftMargin - WindowButtonsRightMargin,
+		    -1, -1);
 	ArrangeButtonArray (&buttons);
       }
       if (AutoStick && win_is_shaded != IS_SHADED(cfgpacket))
@@ -1274,7 +1280,7 @@
   int  num, bx, by, trunc;
   char *name;
 
-  if (MouseInStartButton(x, y)) {
+  if (MouseInStartButton(x, y, &whichButton, &startButtonPressed)) {
     if (Tip.type != START_TIP) PopupTipWindow(3, 0, "Click here to start");
     Tip.type = START_TIP;
   }
@@ -1338,9 +1344,10 @@
     case ButtonRelease:
       NewTimestamp = Event.xbutton.time;
       num = WhichButton(&buttons, Event.xbutton.x, Event.xbutton.y);
+      StartButtonUpdate(NULL, -1, BUTTON_UP);
       if (num == -1) {
-	if (MouseInStartButton(Event.xbutton.x, Event.xbutton.y))
-	  StartButtonUpdate(NULL, BUTTON_UP);
+	if (MouseInStartButton(Event.xbutton.x, Event.xbutton.y, &whichButton, &startButtonPressed))
+	  StartButtonUpdate(NULL, whichButton, BUTTON_UP);
       } else {
 	ButReleased = ButPressed; /* Avoid race fvwm pipe */
 	if (Event.xbutton.button >= 1 &&
@@ -1369,8 +1376,8 @@
 	}
       }
 
-      if (MouseInStartButton(Event.xbutton.x, Event.xbutton.y)) {
-	StartButtonUpdate(NULL, BUTTON_UP);
+      if (MouseInStartButton(Event.xbutton.x, Event.xbutton.y, &whichButton, &startButtonPressed)) {
+	StartButtonUpdate(NULL, whichButton, BUTTON_UP);
 	redraw = 0;
 	usleep(50000);
       }
@@ -1387,8 +1394,8 @@
     case ButtonPress:
       NewTimestamp = Event.xbutton.time;
       RadioButton(&buttons, -1, BUTTON_UP); /* no windows focused anymore */
-      if (MouseInStartButton(Event.xbutton.x, Event.xbutton.y)) {
-	StartButtonUpdate(NULL, BUTTON_DOWN);
+      if (MouseInStartButton(Event.xbutton.x, Event.xbutton.y, &whichButton, &startButtonPressed)) {
+	StartButtonUpdate(NULL, whichButton, BUTTON_DOWN);
 	x = win_x;
 	if (win_y < Midline) {
 	  /* bar in top half of the screen */
@@ -1397,17 +1404,16 @@
 	  /* bar in bottom of the screen */
 	  y = win_y - screen_g.height;
 	}
-	if (StartCommand != NULL)
+	if ((First_Start_Button->buttonStartCommand != NULL) && (startButtonPressed))
 	{
 	  rectangle r;
 	  Window tmpw;
-
 	  r.x = 0;
 	  r.y = 0;
-	  r.width = StartButtonWidth;
-	  r.height = StartButtonHeight;
+	  r.width = StartAndMiniButtonsWidth;
+	  r.height = StartAndMiniButtonsHeight;
 	  XTranslateCoordinates(dpy, win, Root, r.x, r.y, &r.x, &r.y, &tmpw);
-	  tmp = module_expand_action(dpy, screen, StartCommand, &r, NULL, NULL);
+	  tmp = module_expand_action(dpy, screen, First_Start_Button->buttonStartCommand, &r, NULL, NULL);  
 	  if (tmp)
 	  {
 	    SendText(Fvwm_fd, tmp, 0);
@@ -1415,22 +1421,19 @@
 	  }
 	  else
 	  {
-	    SendText(Fvwm_fd, StartCommand, 0);
+	    SendText(Fvwm_fd, First_Start_Button->buttonStartCommand, 0);
 	  }
 	}
-	if (StartPopup != NULL)
+	else
 	{
-	  tmp = (char *)safemalloc(strlen(StartPopup) + 7);
-	  sprintf(tmp,"Popup %s", StartPopup);
+	  tmp = (char *)safemalloc(50 * sizeof(char));  // fix this later
+	  getButtonCommand(whichButton, tmp);
 	  SendText(Fvwm_fd, tmp, 0);
 	  free(tmp);
 	}
-	if (StartPopup == NULL && StartCommand == NULL)
-	{
-	  SendText(Fvwm_fd, "Popup StartMenu", 0);
-	}
+
       } else {
-	StartButtonUpdate(NULL, BUTTON_UP);
+	StartButtonUpdate(NULL, whichButton, BUTTON_UP);
 	if (MouseInMail(Event.xbutton.x, Event.xbutton.y)) {
 	  HandleMailClick(Event);
 	} else {
@@ -1522,13 +1525,13 @@
 
     case MotionNotify:
       NewTimestamp = Event.xmotion.time;
-      if (MouseInStartButton(Event.xmotion.x, Event.xbutton.y)) {
+      if (MouseInStartButton(Event.xmotion.x, Event.xbutton.y, &whichButton, &startButtonPressed)) {
 	if (SomeButtonDown(Event.xmotion.state))
-	  redraw = StartButtonUpdate(NULL, BUTTON_DOWN) ? 0 : -1;
+	  redraw = StartButtonUpdate(NULL, -1, BUTTON_DOWN) ? 0 : -1;
 	CheckForTip(Event.xmotion.x, Event.xmotion.y);
 	break;
       }
-      redraw = StartButtonUpdate(NULL, BUTTON_UP) ? 0 : -1;
+      redraw = StartButtonUpdate(NULL, -1, BUTTON_UP) ? 0 : -1;
       num = WhichButton(&buttons, Event.xmotion.x, Event.xmotion.y);
       if (!HighlightFocus) {
 	if (SomeButtonDown(Event.xmotion.state) && num != ButPressed) {
Index: modules/FvwmTaskBar/Start.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmTaskBar/Start.c,v
retrieving revision 1.16
diff -u -r1.16 Start.c
--- modules/FvwmTaskBar/Start.c	2002/08/11 08:17:19	1.16
+++ modules/FvwmTaskBar/Start.c	2002/09/09 01:52:54
@@ -16,12 +16,14 @@
 /* Start ;-) button handling */
 
 #include <X11/Xlib.h>
+#include <stdio.h>
 
 #include "libs/fvwmlib.h"
 #include "libs/Flocale.h"
 #include "libs/Picture.h"
 #include "ButtonArray.h"
 #include "Mallocs.h"
+#include "Start.h"
 
 extern Display *dpy;
 extern Window Root, win;
@@ -31,12 +33,19 @@
 extern int ColorLimit;
 
 Button *StartButton;
-int StartButtonWidth, StartButtonHeight;
+int StartAndMiniButtonsWidth = 0;
+int StartAndMiniButtonsHeight = 0;
+int WindowButtonsLeftMargin = 4;  // default value is 4
+int WindowButtonsRightMargin = 2;  // default value is 2
+int StartButtonRightMargin = 0;  // default value is 0
+Bool StartButtonOpensAboveTaskBar = FALSE;
 char *StartName     = NULL,
      *StartCommand  = NULL,
      *StartPopup    = NULL,
      *StartIconName = NULL;
 
+StartAndMiniButtonItem *First_Start_Button = NULL;
+StartAndMiniButtonItem *Last_Start_Button = NULL;
 
 static char *startopts[] =
 {
@@ -44,6 +53,10 @@
   "StartMenu",
   "StartIcon",
   "StartCommand",
+  "Button",
+  "WindowButtonsLeftMargin",
+  "WindowButtonsRightMargin",
+  "StartButtonRightMargin",
   NULL
 };
 
@@ -51,7 +64,11 @@
 {
   char *rest;
   char *option;
-  int i;
+  int i, j, k;
+  int titleRecorded = 0, iconRecorded = 0, actionRecorded = 0;
+  char *tokens[100];  // This seems really big
+  char *strtok_ptr;
+  StartAndMiniButtonItem *tempPtr;
 
   option = tline + Clength;
   i = GetTokenIndex(option, startopts, -1, &rest);
@@ -60,17 +77,153 @@
   switch(i)
   {
   case 0: /* StartName */
-    CopyString(&StartName, rest);
+    if (First_Start_Button == NULL)
+    {
+      First_Start_Button = Last_Start_Button = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
+      StartAndMiniButtonItemInit(First_Start_Button);
+      First_Start_Button->isStartButton = TRUE;
+    }
+    else if (First_Start_Button->isStartButton == FALSE)  // shortcut button has been declared before start button
+    {
+      tempPtr = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
+      tempPtr->tail = First_Start_Button;
+      First_Start_Button = tempPtr;
+      StartAndMiniButtonItemInit(First_Start_Button);
+      First_Start_Button->isStartButton = TRUE;      
+    }
+    else if (First_Start_Button->buttonCaption  != NULL)  // declarin caption twice, ignore
+      break;
+    First_Start_Button->buttonCaption = safemalloc(strlen(rest) * sizeof(char));
+    CopyString(&(First_Start_Button->buttonCaption), rest);    
     break;
   case 1: /* StartMenu */
-    CopyString(&StartPopup, rest);
+    if (First_Start_Button == NULL)
+    {
+      First_Start_Button = Last_Start_Button = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
+      StartAndMiniButtonItemInit(First_Start_Button);
+      First_Start_Button->isStartButton = TRUE;
+    }
+    else if (First_Start_Button->isStartButton == FALSE)  // shortcut button has been declared before start button
+    {
+      tempPtr = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
+      tempPtr->tail = First_Start_Button;
+      First_Start_Button = tempPtr;
+      StartAndMiniButtonItemInit(First_Start_Button);
+      First_Start_Button->isStartButton = TRUE;      
+    }
+    else if (First_Start_Button->buttonCommand  != NULL)  // declaring command twice, ignore
+      break;
+    First_Start_Button->buttonCommand = safemalloc(strlen(rest) * sizeof(char));
+    CopyString(&(First_Start_Button->buttonCommand), rest);   
     break;
   case 2: /* StartIcon */
-    CopyString(&StartIconName, rest);
-    break;
+    if (First_Start_Button == NULL)
+    {
+      First_Start_Button = Last_Start_Button = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
+      StartAndMiniButtonItemInit(First_Start_Button);
+      First_Start_Button->isStartButton = TRUE;
+    }
+    else if (First_Start_Button->isStartButton == FALSE)  // shortcut button has been declared before start button
+    {
+      tempPtr = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
+      tempPtr->tail = First_Start_Button;
+      First_Start_Button = tempPtr;
+      StartAndMiniButtonItemInit(First_Start_Button);
+      First_Start_Button->isStartButton = TRUE;      
+    }
+    else if (First_Start_Button->buttonIconFileName != NULL)  // declaring icon twice, ignore
+      break;
+    First_Start_Button->buttonIconFileName = safemalloc(strlen(rest) * sizeof(char));
+    CopyString(&(First_Start_Button->buttonIconFileName), rest);   
+   break;
   case 3: /* StartCommand */
-    CopyString(&StartCommand, rest);
+    if (First_Start_Button == NULL)
+    {
+      First_Start_Button = Last_Start_Button = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
+      StartAndMiniButtonItemInit(First_Start_Button);
+      First_Start_Button->isStartButton = TRUE;
+    }
+    else if (First_Start_Button->isStartButton == FALSE)  // shortcut button has been declared before start button
+    {
+      tempPtr = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
+      tempPtr->tail = First_Start_Button;
+      First_Start_Button = tempPtr;
+      StartAndMiniButtonItemInit(First_Start_Button);
+      First_Start_Button->isStartButton = TRUE;      
+    }
+    else if (First_Start_Button->buttonIconFileName != NULL)  // declaring icon twice, ignore
+      break;
+    First_Start_Button->buttonStartCommand = safemalloc(strlen(rest) * sizeof(char));
+    CopyString(&(First_Start_Button->buttonStartCommand), rest);   
+    break;
+  case 4:
+    if (Last_Start_Button == NULL) 
+      First_Start_Button = Last_Start_Button = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
+    else
+    {  
+      Last_Start_Button->tail = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
+      Last_Start_Button = Last_Start_Button->tail;
+    }
+
+    StartAndMiniButtonItemInit(Last_Start_Button);
+    j=0;
+    titleRecorded = iconRecorded = actionRecorded = 0;
+    tokens[j++] = strtok_r(rest, ",", &strtok_ptr);
+    while((tokens[j++] = strtok_r(NULL, ",", &strtok_ptr)))
+      while(*(tokens[j-1])==' ')
+	tokens[j-1]+=sizeof(char);
+    j--;
+
+    for(k=0;k<j;k++)
+    {
+      if (strncmp(tokens[k], "Title", 5)==0)
+      {
+	tokens[j+1] = tokens[k] + ((sizeof(char))*5);
+	while(*(tokens[j+1])==' ')
+	  tokens[j+1]+=sizeof(char);
+	Last_Start_Button->buttonCaption = (char *) safemalloc(sizeof(char) * (strlen(tokens[j+1])));
+        CopyString(&(Last_Start_Button->buttonCaption), tokens[j+1]);
+	titleRecorded=1;
+      }	
+      else if (strncmp(tokens[k], "Icon", 4)==0)
+      {
+	tokens[j+1] = tokens[k] + ((sizeof(char))*4);
+	while(*(tokens[j+1])==' ')
+	  tokens[j+1]+=sizeof(char);
+	Last_Start_Button->buttonIconFileName = (char *) safemalloc(sizeof(char) * (strlen(tokens[j+1])));
+	CopyString(&(Last_Start_Button->buttonIconFileName),tokens[j+1] );
+	iconRecorded = 1;
+      }
+      else if (strncmp(tokens[k], "Action", 6)==0)
+      {
+	tokens[j+1] = tokens[k] + ((sizeof(char))*6);
+	while(*(tokens[j+1])==' ')
+	  tokens[j+1]+=sizeof(char);
+	Last_Start_Button->buttonCommand = (char *) safemalloc(sizeof(char) * (strlen(tokens[j+1])));
+	CopyString(&(Last_Start_Button->buttonCommand), tokens[j+1]);
+	actionRecorded = 1;
+      }
+    }
+    if (titleRecorded==0)
+      CopyString(&(Last_Start_Button->buttonCaption), "\0");
+    if (iconRecorded==0)
+      CopyString(&(Last_Start_Button->buttonIconFileName), "\0");
+    if (actionRecorded==0)
+      CopyString(&(Last_Start_Button->buttonCommand), "\0");
+    break;
+
+  case 5: /* WindowButtonsLeftMargin */
+    if(atoi(rest)>=0)
+      WindowButtonsLeftMargin = atoi(rest);
     break;
+  case 6: /* WindowButtonsRightMargin */
+    if(atoi(rest)>=0)
+      WindowButtonsRightMargin = atoi(rest);
+    break;
+  case 7: /* StartButtonRightMargin */
+    if(atoi(rest)>=0)
+      StartButtonRightMargin = atoi(rest);
+    break;
   default:
     /* unknown option */
     return False;
@@ -84,43 +237,183 @@
   FvwmPicture *p = NULL;
   int pw;
   FvwmPictureAttributes fpa;
+  StartAndMiniButtonItem *tempPtr;
 
   fpa.mask = FPAM_NO_ALLOC_PIXELS;
   /* some defaults */
-  if (StartName  == NULL)
-    UpdateString(&StartName, "Start");
-  if (StartIconName == NULL)
-    UpdateString(&StartIconName, "mini-start.xpm");
+  if (First_Start_Button->isStartButton == TRUE)
+  {
+    if (First_Start_Button->buttonCaption == NULL)
+      UpdateString(&(First_Start_Button->buttonCaption), "Start");
+    if (First_Start_Button->buttonIconFileName == NULL)
+      UpdateString(&(First_Start_Button->buttonIconFileName), "mini-start.xpm");
+  }
 
-  p = PGetFvwmPicture(dpy, win, ImagePath, StartIconName, fpa);
+  tempPtr = First_Start_Button;
 
-  StartButton = (Button *)ButtonNew(StartName, p, BUTTON_UP,0);
-  if (p != NULL) pw = p->width+3; else pw = 0;
-  StartButtonWidth = FlocaleTextWidth(FButtonFont, StartName, strlen(StartName))
-    + pw + 14;
-  StartButtonHeight = height;
+  while(tempPtr != NULL)
+  {
+    p = PGetFvwmPicture(dpy, win, ImagePath, tempPtr->buttonIconFileName, fpa);
+
+    if (p != NULL && strlen(tempPtr->buttonCaption) != 0)  // icon and title
+      pw = p->width + 12;
+    else if (p != NULL) // just icon
+      pw = p->width + 8; 
+    else // just caption
+      pw = 10;
+
+    tempPtr->buttonItem = (Button *)ButtonNew(tempPtr->buttonCaption, p, BUTTON_UP,0);
+    tempPtr->width = FlocaleTextWidth(FButtonFont, tempPtr->buttonCaption, strlen(tempPtr->buttonCaption)) + pw; 
+    tempPtr->height = height;
+    StartAndMiniButtonsWidth += tempPtr->width;
+    StartAndMiniButtonsWidth += StartButtonRightMargin;
+    tempPtr=tempPtr->tail;
+  }
+
+    First_Start_Button->height = height;
+    StartAndMiniButtonsHeight = First_Start_Button->height;
 }
 
-int StartButtonUpdate(const char *title, int state)
+int StartButtonUpdate(const char *title, int index, int state)
 {
+  int i=0;
+  StartAndMiniButtonItem *tempPtr = First_Start_Button;
 #if 0
   if (title != NULL)
     ConsoleMessage("Updating StartTitle not supported yet...\n");
-  ButtonUpdate(StartButton, title, state);
+  if(index != -1)
+  {
+    for(i=0; i<index; i++)
+      tempPtr = tempPtr->tail;      
+    ButtonUpdate(tempPtr->buttonItem, title, state);
+  }
+  else
+    while(tempPtr != NULL)
+    {
+      ButtonUpdate(tempPtr->buttonItem, title, state);
+      tempPtr = tempPtr->tail;
+    }
+
 #else
-  ButtonUpdate(StartButton, NULL, state);
+  if(index != -1)
+  {
+    for(i=0; i<index; i++)
+      tempPtr = tempPtr->tail;      
+    ButtonUpdate(tempPtr->buttonItem, title, state);
+  }
+  else
+    while(tempPtr != NULL)
+    {
+      ButtonUpdate(tempPtr->buttonItem, title, state);
+      tempPtr = tempPtr->tail;
+    }
+
 #endif
-  return StartButton->needsupdate;
+  tempPtr = First_Start_Button;
+  while(tempPtr != NULL)
+  {
+    if (tempPtr->buttonItem->needsupdate)
+      return 1;
+    tempPtr = tempPtr->tail;    
+  }
+  return 0;
 }
 
+
 void StartButtonDraw(int force)
+{
+  int tempsum, j, i = 0;
+  StartAndMiniButtonItem *tempPtr = First_Start_Button;
+  StartAndMiniButtonItem *tempPtr2 = First_Start_Button;
+
+  while(tempPtr != NULL)
+  {
+    if(tempPtr->buttonItem->needsupdate || force)
+    {
+      tempsum = 0;
+      j=0;
+      tempPtr2 = First_Start_Button;
+      while((tempPtr2 != NULL) && (j<i))
+      {
+	tempsum+=tempPtr2->width;
+	tempPtr2 = tempPtr2->tail;	
+	j++;
+      }
+      if (!(tempPtr->isStartButton))
+	ButtonDraw(tempPtr->buttonItem, tempsum+StartButtonRightMargin, 0, tempPtr->width, First_Start_Button->height);
+      else
+	ButtonDraw(tempPtr->buttonItem, tempsum, 0, tempPtr->width, First_Start_Button->height);
+    }
+    tempPtr = tempPtr->tail;
+    i++;
+  }
+}
+
+// Returns 1 if in the start or a minibutton, 0 if not; index of button pressed put in startButtonPressed
+int MouseInStartButton(int x, int y, int *whichButton, Bool *startButtonPressed)
 {
-  if (StartButton->needsupdate || force)
-    ButtonDraw(StartButton, 0, 0, StartButtonWidth, StartButtonHeight);
+  int i=0, j=0;
+  int tempsum = 0;
+
+  StartAndMiniButtonItem *tempPtr = First_Start_Button;
+  StartAndMiniButtonItem *tempPtr2 = First_Start_Button;
+  *startButtonPressed = FALSE;
+
+  while(tempPtr != NULL)
+    {
+      tempsum = 0;
+      j = 0;
+      tempPtr2 = First_Start_Button;
+      while((tempPtr2 != NULL) && (j<i))
+      {
+	tempsum+=tempPtr2->width;
+	tempPtr2 = tempPtr2->tail;	
+	j++;
+      }     
+      if (x >= tempsum && x < tempsum+tempPtr->width && y > 0 && y < First_Start_Button->height)
+      {
+	*whichButton = i;
+	if(tempPtr->isStartButton)
+	  *startButtonPressed = TRUE;	  
+	return 1;
+      }
+      tempPtr = tempPtr->tail;
+      i++;
+    }
+  *whichButton = -1;
+  return 0;
+}
+
+void getButtonCommand(int whichButton, char *tmp)
+{
+  int i=0;
+  StartAndMiniButtonItem *tempPtr = First_Start_Button;
+
+  for(i=0; i<whichButton; i++)
+    tempPtr = tempPtr->tail;
+
+  if(tempPtr->isStartButton)
+      if (tempPtr->buttonCommand != NULL)
+	sprintf(tmp,"Popup %s rectangle $widthx$height+$left+$top 0 -100m", tempPtr->buttonCommand);
+      else if (tempPtr->buttonStartCommand != NULL)
+	sprintf(tmp,"%s", tempPtr->buttonStartCommand);
+      else
+	sprintf(tmp,"Popup StarMenu");
+  else
+      sprintf(tmp,"%s", tempPtr->buttonCommand);
 }
 
-int MouseInStartButton(int x, int y)
+void StartAndMiniButtonItemInit(StartAndMiniButtonItem *item)
 {
-  return (x > 0 && x < StartButtonWidth &&
-	  y > 0 && y < StartButtonHeight);
+  item->head = NULL;
+  item->tail = NULL;
+  item->index = 0;
+  item->width = 0;
+  item->height = 0;
+  item->isStartButton = FALSE;
+  item->buttonItem = NULL;
+  item->buttonCommand = NULL;
+  item->buttonStartCommand = NULL;
+  item->buttonCaption = NULL;
+  item->buttonIconFileName = NULL;  
 }
Index: modules/FvwmTaskBar/Start.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmTaskBar/Start.h,v
retrieving revision 1.8
diff -u -r1.8 Start.h
--- modules/FvwmTaskBar/Start.h	2002/06/26 13:42:51	1.8
+++ modules/FvwmTaskBar/Start.h	2002/09/09 01:52:54
@@ -20,10 +20,24 @@
 #ifndef START_H
 #define START_H
 
+typedef struct startAndMiniButtonItem {
+  struct startAndMiniButtonItem *head, *tail;
+  int index;
+  Button *buttonItem;
+  int width, height;
+  Bool isStartButton; 
+  char *buttonCommand;
+  char *buttonStartCommand;
+  char *buttonCaption;
+  char *buttonIconFileName;
+} StartAndMiniButtonItem;
+
 extern Bool StartButtonParseConfig(char *tline);
 extern void StartButtonInit(int height);
-extern int StartButtonUpdate(const char *title, int state);
+extern void StartAndMiniButtonItemInit(StartAndMiniButtonItem *item);
+extern void AddStartAndMiniButtonItem(StartAndMiniButtonItem *item);
+extern int StartButtonUpdate(const char *title, int index, int state);
 extern void StartButtonDraw(int force);
-extern int  MouseInStartButton(int x, int y);
-
+extern int  MouseInStartButton(int x, int y, int *whichButton, Bool *startButtonPressed);
+extern void getButtonCommand(int whichButton, char *tmp);
 #endif

---

From: Dominik Vogt <[email-masked]>
Date: Thu, 12 Sep 2002 22:15:47 +0200

> fixed.  I have been beating it for a couple of hours now and it seems 

I have applied the patch to the latest CVS code.  Can you please
make another patch for the NEWS file and modules/ChangeLog?

[snip]

> *FvwmTaskBar: Button Title Freeamp, Icon mini.cd.xpm, Action exec exec 

Works nicely.  I noticed a few cosmetical quirks and a real bug:

 * When the tip window pops up over such a button, it contains the
   text "Click here to start" as if the pointer was over the Start
   button.  The position isn't correct either.  I guess there
   should be no tip window at all by default but you can specify a
   text to display in the button definition, e.g.

     *FvwmTaskBar: Button Icon mini.term.xpm, Tip "Start xterm", \\
      Action exec exec xterm

   But that's not critical.  To reproduce, add

     *FvwmTaskBar: ShowTips

   to your config file.

 * A bug:  press a mouse button over one of these sub buttons.
   It is then drawn pressed in.  Now drag the pointer a bit with
   the button still down ==> all parts of the extended start
   buttons are drawn pressed in.

 * The action is invoked when the button is released, not when
   it's pressed as in most other parts of fvwm, e.g. window
   titles and FvwmButtons.

 * When I use

     *FvwmTaskBar: AutoStick

   and press the Start button, the task bar vanishes.  It's on
   neither of my four pages, but it's still in the process list.

Bye

Dominik ^_^  ^_^

 --
Dominik Vogt, [email-masked]
Reply-To: [email-masked]
--
Visit the official FVWM web page at <URL:http://www.fvwm.org/>.
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]

---

From: Ben Mathews <[email-masked]>
Date: Thu, 12 Sep 2002 18:41:30 -0400

>    it's pressed as in most other parts of fvwm, e.g. window

Are you saying that action should be invoked when the button is 
released, not when it is pressed?

I am using the latest CVS source and I am seeing that the start button 
launches on release, but the minibuttons launch their applications on 
the press, not the release.  Which part needs to be changed?

 >    neither of my four pages, but it's still in the process list.

I am using the latest CVS source and can't replicate this.  Can you send 
me a fvwm2rc and/or explicit instructions on how to do this.

Thanks.

Ben Mathews

---

From: Mikhael Goikhman <[email-masked]>
Date: Fri, 13 Sep 2002 05:30:33 +0000

> +StartAndMiniButtonItem *Last_Start_Button = NULL;

I would rename "WindowButtons" and "MiniButtons" in config and code to
"LaunchButtons".

Regards,
Mikhael.

---

From: Dominik Vogt <[email-masked]>
Date: Fri, 13 Sep 2002 11:35:15 +0200

> released, not when it is pressed?

Yes.

> the press, not the release.  Which part needs to be changed?

In general, triggering something when pressing a button is only
good for buttons that open a menu (like the Start button) because
you can always close the menu without doing anything.  So only the
launch buttons should work on button release.

> me a fvwm2rc and/or explicit instructions on how to do this.

I'll make a minimal config later.

Bye

Dominik ^_^  ^_^

 --
Dominik Vogt, mail: [email-masked], phone: 0721/91374-382
Schlund + Partner AG, Erbprinzenstr. 4-12, D-76133 Karlsruhe
--
Visit the official FVWM web page at <URL:http://www.fvwm.org/>.
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]

---

From: Ben Mathews <[email-masked]>
Date: Sun, 15 Sep 2002 21:01:00 -0400

Patchfile is attached that fixes the bugs listed below except for the 
last one.  See notes below.  It was done at 9pm EST (02:00 GMT, I think).

Ben Mathews

> make another patch for the NEWS file and modules/ChangeLog?

Done

>    text to display in the button definition, e.g.

Fixed

>    buttons are drawn pressed in.

Fixed

>    it's pressed as in most other parts of fvwm, e.g. window

Fixed

>    neither of my four pages, but it's still in the process list.

Still awaiting a fvwmrc file and/or explicit directions to replicate 
this.  I can't get this behavior.  Works fine for me.
? patchfile
? modules/FvwmTaskBar.bu
Index: NEWS
===================================================================
RCS file: /home/cvs/fvwm/fvwm/NEWS,v
retrieving revision 1.413
diff -u -r1.413 NEWS
--- NEWS	2002/09/15 20:26:25	1.413
+++ NEWS	2002/09/16 00:53:09
@@ -5,6 +5,11 @@
 
 Changes in *unstable* development release 2.5.4 (not released yet)
 
+* FvwmTaskBar may now include mini launchbuttons using the Button
+  command.  Also has new options for spacing the buttons:
+  WindowButtonsLeftMargin, WindowButtonsRightMargin, and
+  StartButtonRightMargin.  See man page for details.
+
 * Style switches can be prefixed with '!' to inverse their meaning.
   For example, "Style * Sticky" is the same as "Style * !Slippery".
   This works *only* for pairs of styles that take no arguments and
Index: modules/ChangeLog
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/ChangeLog,v
retrieving revision 1.930
diff -u -r1.930 ChangeLog
--- modules/ChangeLog	2002/09/15 20:27:10	1.930
+++ modules/ChangeLog	2002/09/16 00:53:24
@@ -1,3 +1,16 @@
+2002-09-15 Ben Mathews <[email-masked]>
+
+	* AUTHORS:
+	* FvwmTaskBar/Start.h:
+	* FvwmTaskBar/Start.c:
+	* FvwmTaskBar/FvwmTaskBar.c:
+	* FvwmTaskBar/ButtonArray.c:
+	* FvwmTaskBar/FvwmTaskBar.1:
+	FvwmTaskBar may now include shortcut minibuttons using the Button
+	command.  Also has new options for spacing the buttons:
+	WindowButtonsLeftMargin, WindowButtonsRightMargin, and
+	StartButtonRightMargin.
+
 2002-09-15  olicha  <[email-masked]>
 
 	* FvwmPager/x_pager.c (update_pr_transparent_subwindows):
Index: modules/FvwmTaskBar/ButtonArray.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmTaskBar/ButtonArray.c,v
retrieving revision 1.32
diff -u -r1.32 ButtonArray.c
--- modules/FvwmTaskBar/ButtonArray.c	2002/09/12 20:26:28	1.32
+++ modules/FvwmTaskBar/ButtonArray.c	2002/09/16 00:53:27
@@ -680,7 +680,7 @@
 /* -------------------------------------------------------------------------
     ButtonCoordinates - Compute the coordinates of a button (animation)
    ------------------------------------------------------------------------- */
-extern int  StartAndMiniButtonsWidth;
+extern int  StartAndLaunchButtonsWidth;
 void ButtonCoordinates(ButtonArray *array, int numbut, int *xc, int *yc)
 {
 	Button *temp;
@@ -702,7 +702,7 @@
 		}
 	}
 
-	*xc = x+ StartAndMiniButtonsWidth+3;
+	*xc = x+ StartAndLaunchButtonsWidth+3;
 	*yc = y;
 }
 
Index: modules/FvwmTaskBar/FvwmTaskBar.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmTaskBar/FvwmTaskBar.c,v
retrieving revision 1.103
diff -u -r1.103 FvwmTaskBar.c
--- modules/FvwmTaskBar/FvwmTaskBar.c	2002/09/12 20:26:28	1.103
+++ modules/FvwmTaskBar/FvwmTaskBar.c	2002/09/16 00:53:31
@@ -218,6 +218,7 @@
 rectangle global_scr_g;
 
 int NRows, RowHeight, Midline;
+int ButtonPressed;
 
 #define COUNT_LIMIT    10000
 long DeskNumber;               /* Added by Balaji R */
@@ -229,9 +230,9 @@
 extern TipStruct Tip;
 
 /* Imported from Start */
-extern int StartAndMiniButtonsWidth, StartAndMiniButtonsHeight;
-extern StartAndMiniButtonItem *First_Start_Button;
-extern StartAndMiniButtonItem *Last_Start_Button;
+extern int StartAndLaunchButtonsWidth, StartAndLaunchButtonsHeight;
+extern StartAndLaunchButtonItem *First_Start_Button;
+extern StartAndLaunchButtonItem *Last_Start_Button;
 extern int WindowButtonsLeftMargin;
 extern int WindowButtonsRightMargin;
 char *ImagePath = NULL;
@@ -364,8 +365,8 @@
   StartButtonInit(RowHeight);
 
   /* init the array of buttons */
-  InitArray(&buttons, StartAndMiniButtonsWidth + WindowButtonsLeftMargin, 0,
-	    win_width - stwin_width - StartAndMiniButtonsWidth - WindowButtonsLeftMargin
+  InitArray(&buttons, StartAndLaunchButtonsWidth + WindowButtonsLeftMargin, 0,
+	    win_width - stwin_width - StartAndLaunchButtonsWidth - WindowButtonsLeftMargin
 	    - WindowButtonsRightMargin, RowHeight, button_width);
   InitList(&windows);
 
@@ -563,7 +564,7 @@
 
 	UpdateArray(&buttons, -1, -1,
-		    win_width - stwin_width - StartAndMiniButtonsWidth
+		    win_width - stwin_width - StartAndLaunchButtonsWidth
 		    - WindowButtonsLeftMargin - WindowButtonsRightMargin,
 		    -1, -1);
 	ArrangeButtonArray (&buttons);
@@ -1281,8 +1282,13 @@
   char *name;
 
   if (MouseInStartButton(x, y, &whichButton, &startButtonPressed)) {
-    if (Tip.type != START_TIP) PopupTipWindow(3, 0, "Click here to start");
-    Tip.type = START_TIP;
+    if((!whichButton) && (First_Start_Button->isStartButton))
+    {
+      if (Tip.type != START_TIP) PopupTipWindow(3, 0, "Click here to start");
+      Tip.type = START_TIP;
+    }
+    else
+      Tip.type = NO_TIP;
   }
   else if (MouseInMail(x, y)) {
     if (Tip.type != MAIL_TIP) CreateMailTipWindow();
@@ -1345,10 +1351,46 @@
       NewTimestamp = Event.xbutton.time;
       num = WhichButton(&buttons, Event.xbutton.x, Event.xbutton.y);
       StartButtonUpdate(NULL, -1, BUTTON_UP);
-      if (num == -1) {
+      if (num == -1) 
+      {
 	if (MouseInStartButton(Event.xbutton.x, Event.xbutton.y, &whichButton, &startButtonPressed))
+	{
 	  StartButtonUpdate(NULL, whichButton, BUTTON_UP);
-      } else {
+
+	  if (whichButton == ButtonPressed)
+	  {
+	    if ((First_Start_Button->buttonStartCommand != NULL) && (startButtonPressed))
+	    {
+	      rectangle r;
+	      Window tmpw;
+	      r.x = 0;
+	      r.y = 0;
+	      r.width = StartAndLaunchButtonsWidth;
+	      r.height = StartAndLaunchButtonsHeight;
+	      XTranslateCoordinates(dpy, win, Root, r.x, r.y, &r.x, &r.y, &tmpw);
+	      tmp = module_expand_action(dpy, screen, First_Start_Button->buttonStartCommand, &r, NULL, NULL);  
+	      if (tmp)
+	      {
+		SendText(Fvwm_fd, tmp, 0);
+		free(tmp);
+	      }
+	      else
+	      {
+		SendText(Fvwm_fd, First_Start_Button->buttonStartCommand, 0);
+	      }
+	    }
+	    else
+	    {
+	      tmp = (char *)safemalloc(100 * sizeof(char));  // fix this later
+	      getButtonCommand(whichButton, tmp);
+	      SendText(Fvwm_fd, tmp, 0);
+	      free(tmp);
+	    }
+	  }
+	}
+      } 
+      else 
+      {
 	ButReleased = ButPressed; /* Avoid race fvwm pipe */
 	if (Event.xbutton.button >= 1 &&
 	    Event.xbutton.button <= NUMBER_OF_MOUSE_BUTTONS)
@@ -1394,8 +1436,10 @@
     case ButtonPress:
       NewTimestamp = Event.xbutton.time;
       RadioButton(&buttons, -1, BUTTON_UP); /* no windows focused anymore */
-      if (MouseInStartButton(Event.xbutton.x, Event.xbutton.y, &whichButton, &startButtonPressed)) {
+      if (MouseInStartButton(Event.xbutton.x, Event.xbutton.y, &whichButton, &startButtonPressed))
+      {
 	StartButtonUpdate(NULL, whichButton, BUTTON_DOWN);
+	ButtonPressed = whichButton;
 	x = win_x;
 	if (win_y < Midline) {
 	  /* bar in top half of the screen */
@@ -1404,34 +1448,6 @@
 	  /* bar in bottom of the screen */
 	  y = win_y - screen_g.height;
 	}
-	if ((First_Start_Button->buttonStartCommand != NULL) && (startButtonPressed))
-	{
-	  rectangle r;
-	  Window tmpw;
-	  r.x = 0;
-	  r.y = 0;
-	  r.width = StartAndMiniButtonsWidth;
-	  r.height = StartAndMiniButtonsHeight;
-	  XTranslateCoordinates(dpy, win, Root, r.x, r.y, &r.x, &r.y, &tmpw);
-	  tmp = module_expand_action(dpy, screen, First_Start_Button->buttonStartCommand, &r, NULL, NULL);  
-	  if (tmp)
-	  {
-	    SendText(Fvwm_fd, tmp, 0);
-	    free(tmp);
-	  }
-	  else
-	  {
-	    SendText(Fvwm_fd, First_Start_Button->buttonStartCommand, 0);
-	  }
-	}
-	else
-	{
-	  tmp = (char *)safemalloc(50 * sizeof(char));  // fix this later
-	  getButtonCommand(whichButton, tmp);
-	  SendText(Fvwm_fd, tmp, 0);
-	  free(tmp);
-	}
-
       } else {
 	StartButtonUpdate(NULL, whichButton, BUTTON_UP);
 	if (MouseInMail(Event.xbutton.x, Event.xbutton.y)) {
@@ -1526,12 +1542,12 @@
     case MotionNotify:
       NewTimestamp = Event.xmotion.time;
       if (MouseInStartButton(Event.xmotion.x, Event.xbutton.y, &whichButton, &startButtonPressed)) {
-	if (SomeButtonDown(Event.xmotion.state))
-	  redraw = StartButtonUpdate(NULL, -1, BUTTON_DOWN) ? 0 : -1;
+	//if (SomeButtonDown(Event.xmotion.state))
+	//redraw = StartButtonUpdate(NULL, -1, BUTTON_DOWN) ? 0 : -1;
 	CheckForTip(Event.xmotion.x, Event.xmotion.y);
 	break;
       }
-      redraw = StartButtonUpdate(NULL, -1, BUTTON_UP) ? 0 : -1;
+      //redraw = StartButtonUpdate(NULL, buttonPressed, BUTTON_UP) ? 0 : -1;
       num = WhichButton(&buttons, Event.xmotion.x, Event.xmotion.y);
       if (!HighlightFocus) {
 	if (SomeButtonDown(Event.xmotion.state) && num != ButPressed) {
Index: modules/FvwmTaskBar/Start.c
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmTaskBar/Start.c,v
retrieving revision 1.17
diff -u -r1.17 Start.c
--- modules/FvwmTaskBar/Start.c	2002/09/12 20:26:28	1.17
+++ modules/FvwmTaskBar/Start.c	2002/09/16 00:53:32
@@ -33,8 +33,8 @@
 extern int ColorLimit;
 
 Button *StartButton;
-int StartAndMiniButtonsWidth = 0;
-int StartAndMiniButtonsHeight = 0;
+int StartAndLaunchButtonsWidth = 0;
+int StartAndLaunchButtonsHeight = 0;
 int WindowButtonsLeftMargin = 4;  // default value is 4
 int WindowButtonsRightMargin = 2;  // default value is 2
 int StartButtonRightMargin = 0;  // default value is 0
@@ -44,8 +44,8 @@
      *StartPopup    = NULL,
      *StartIconName = NULL;
 
-StartAndMiniButtonItem *First_Start_Button = NULL;
-StartAndMiniButtonItem *Last_Start_Button = NULL;
+StartAndLaunchButtonItem *First_Start_Button = NULL;
+StartAndLaunchButtonItem *Last_Start_Button = NULL;
 
 static char *startopts[] =
 {
@@ -68,7 +68,7 @@
   int titleRecorded = 0, iconRecorded = 0, actionRecorded = 0;
   char *tokens[100];  // This seems really big
   char *strtok_ptr;
-  StartAndMiniButtonItem *tempPtr;
+  StartAndLaunchButtonItem *tempPtr;
 
   option = tline + Clength;
   i = GetTokenIndex(option, startopts, -1, &rest);
@@ -79,16 +79,16 @@
   case 0: /* StartName */
     if (First_Start_Button == NULL)
     {
-      First_Start_Button = Last_Start_Button = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
-      StartAndMiniButtonItemInit(First_Start_Button);
+      First_Start_Button = Last_Start_Button = (StartAndLaunchButtonItem*) safemalloc(sizeof(StartAndLaunchButtonItem));
+      StartAndLaunchButtonItemInit(First_Start_Button);
       First_Start_Button->isStartButton = TRUE;
     }
     else if (First_Start_Button->isStartButton == FALSE)  // shortcut button has been declared before start button
     {
-      tempPtr = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
+      tempPtr = (StartAndLaunchButtonItem*) safemalloc(sizeof(StartAndLaunchButtonItem));
       tempPtr->tail = First_Start_Button;
       First_Start_Button = tempPtr;
-      StartAndMiniButtonItemInit(First_Start_Button);
+      StartAndLaunchButtonItemInit(First_Start_Button);
       First_Start_Button->isStartButton = TRUE;      
     }
     else if (First_Start_Button->buttonCaption  != NULL)  // declarin caption twice, ignore
@@ -99,16 +99,16 @@
   case 1: /* StartMenu */
     if (First_Start_Button == NULL)
     {
-      First_Start_Button = Last_Start_Button = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
-      StartAndMiniButtonItemInit(First_Start_Button);
+      First_Start_Button = Last_Start_Button = (StartAndLaunchButtonItem*) safemalloc(sizeof(StartAndLaunchButtonItem));
+      StartAndLaunchButtonItemInit(First_Start_Button);
       First_Start_Button->isStartButton = TRUE;
     }
     else if (First_Start_Button->isStartButton == FALSE)  // shortcut button has been declared before start button
     {
-      tempPtr = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
+      tempPtr = (StartAndLaunchButtonItem*) safemalloc(sizeof(StartAndLaunchButtonItem));
       tempPtr->tail = First_Start_Button;
       First_Start_Button = tempPtr;
-      StartAndMiniButtonItemInit(First_Start_Button);
+      StartAndLaunchButtonItemInit(First_Start_Button);
       First_Start_Button->isStartButton = TRUE;      
     }
     else if (First_Start_Button->buttonCommand  != NULL)  // declaring command twice, ignore
@@ -119,16 +119,16 @@
   case 2: /* StartIcon */
     if (First_Start_Button == NULL)
     {
-      First_Start_Button = Last_Start_Button = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
-      StartAndMiniButtonItemInit(First_Start_Button);
+      First_Start_Button = Last_Start_Button = (StartAndLaunchButtonItem*) safemalloc(sizeof(StartAndLaunchButtonItem));
+      StartAndLaunchButtonItemInit(First_Start_Button);
       First_Start_Button->isStartButton = TRUE;
     }
     else if (First_Start_Button->isStartButton == FALSE)  // shortcut button has been declared before start button
     {
-      tempPtr = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
+      tempPtr = (StartAndLaunchButtonItem*) safemalloc(sizeof(StartAndLaunchButtonItem));
       tempPtr->tail = First_Start_Button;
       First_Start_Button = tempPtr;
-      StartAndMiniButtonItemInit(First_Start_Button);
+      StartAndLaunchButtonItemInit(First_Start_Button);
       First_Start_Button->isStartButton = TRUE;      
     }
     else if (First_Start_Button->buttonIconFileName != NULL)  // declaring icon twice, ignore
@@ -139,16 +139,16 @@
   case 3: /* StartCommand */
     if (First_Start_Button == NULL)
     {
-      First_Start_Button = Last_Start_Button = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
-      StartAndMiniButtonItemInit(First_Start_Button);
+      First_Start_Button = Last_Start_Button = (StartAndLaunchButtonItem*) safemalloc(sizeof(StartAndLaunchButtonItem));
+      StartAndLaunchButtonItemInit(First_Start_Button);
       First_Start_Button->isStartButton = TRUE;
     }
     else if (First_Start_Button->isStartButton == FALSE)  // shortcut button has been declared before start button
     {
-      tempPtr = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
+      tempPtr = (StartAndLaunchButtonItem*) safemalloc(sizeof(StartAndLaunchButtonItem));
       tempPtr->tail = First_Start_Button;
       First_Start_Button = tempPtr;
-      StartAndMiniButtonItemInit(First_Start_Button);
+      StartAndLaunchButtonItemInit(First_Start_Button);
       First_Start_Button->isStartButton = TRUE;      
     }
     else if (First_Start_Button->buttonIconFileName != NULL)  // declaring icon twice, ignore
@@ -158,14 +158,14 @@
     break;
   case 4:
     if (Last_Start_Button == NULL) 
-      First_Start_Button = Last_Start_Button = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
+      First_Start_Button = Last_Start_Button = (StartAndLaunchButtonItem*) safemalloc(sizeof(StartAndLaunchButtonItem));
     else
     {  
-      Last_Start_Button->tail = (StartAndMiniButtonItem*) safemalloc(sizeof(StartAndMiniButtonItem));
+      Last_Start_Button->tail = (StartAndLaunchButtonItem*) safemalloc(sizeof(StartAndLaunchButtonItem));
       Last_Start_Button = Last_Start_Button->tail;
     }
 
-    StartAndMiniButtonItemInit(Last_Start_Button);
+    StartAndLaunchButtonItemInit(Last_Start_Button);
     j=0;
     titleRecorded = iconRecorded = actionRecorded = 0;
     tokens[j++] = strtok_r(rest, ",", &strtok_ptr);
@@ -237,7 +237,7 @@
   FvwmPicture *p = NULL;
   int pw;
   FvwmPictureAttributes fpa;
-  StartAndMiniButtonItem *tempPtr;
+  StartAndLaunchButtonItem *tempPtr;
 
   fpa.mask = FPAM_NO_ALLOC_PIXELS;
   /* some defaults */
@@ -265,19 +265,19 @@
     tempPtr->buttonItem = (Button *)ButtonNew(tempPtr->buttonCaption, p, BUTTON_UP,0);
     tempPtr->width = FlocaleTextWidth(FButtonFont, tempPtr->buttonCaption, strlen(tempPtr->buttonCaption)) + pw; 
     tempPtr->height = height;
-    StartAndMiniButtonsWidth += tempPtr->width;
-    StartAndMiniButtonsWidth += StartButtonRightMargin;
+    StartAndLaunchButtonsWidth += tempPtr->width;
+    StartAndLaunchButtonsWidth += StartButtonRightMargin;
     tempPtr=tempPtr->tail;
   }
 
     First_Start_Button->height = height;
-    StartAndMiniButtonsHeight = First_Start_Button->height;
+    StartAndLaunchButtonsHeight = First_Start_Button->height;
 }
 
 int StartButtonUpdate(const char *title, int index, int state)
 {
   int i=0;
-  StartAndMiniButtonItem *tempPtr = First_Start_Button;
+  StartAndLaunchButtonItem *tempPtr = First_Start_Button;
 #if 0
   if (title != NULL)
     ConsoleMessage("Updating StartTitle not supported yet...\n");
@@ -323,8 +323,8 @@
 void StartButtonDraw(int force)
 {
   int tempsum, j, i = 0;
-  StartAndMiniButtonItem *tempPtr = First_Start_Button;
-  StartAndMiniButtonItem *tempPtr2 = First_Start_Button;
+  StartAndLaunchButtonItem *tempPtr = First_Start_Button;
+  StartAndLaunchButtonItem *tempPtr2 = First_Start_Button;
 
   while(tempPtr != NULL)
   {
@@ -355,8 +355,8 @@
   int i=0, j=0;
   int tempsum = 0;
 
-  StartAndMiniButtonItem *tempPtr = First_Start_Button;
-  StartAndMiniButtonItem *tempPtr2 = First_Start_Button;
+  StartAndLaunchButtonItem *tempPtr = First_Start_Button;
+  StartAndLaunchButtonItem *tempPtr2 = First_Start_Button;
   *startButtonPressed = FALSE;
 
   while(tempPtr != NULL)
@@ -387,7 +387,7 @@
 void getButtonCommand(int whichButton, char *tmp)
 {
   int i=0;
-  StartAndMiniButtonItem *tempPtr = First_Start_Button;
+  StartAndLaunchButtonItem *tempPtr = First_Start_Button;
 
   for(i=0; i<whichButton; i++)
     tempPtr = tempPtr->tail;
@@ -400,10 +400,10 @@
       else
 	sprintf(tmp,"Popup StarMenu");
   else
-      sprintf(tmp,"%s", tempPtr->buttonCommand);
+    sprintf(tmp,"%s", tempPtr->buttonCommand);
 }
 
-void StartAndMiniButtonItemInit(StartAndMiniButtonItem *item)
+void StartAndLaunchButtonItemInit(StartAndLaunchButtonItem *item)
 {
   item->head = NULL;
   item->tail = NULL;
@@ -416,4 +416,5 @@
   item->buttonStartCommand = NULL;
   item->buttonCaption = NULL;
   item->buttonIconFileName = NULL;  
+  item->buttonToolTip = NULL;
 }
Index: modules/FvwmTaskBar/Start.h
===================================================================
RCS file: /home/cvs/fvwm/fvwm/modules/FvwmTaskBar/Start.h,v
retrieving revision 1.9
diff -u -r1.9 Start.h
--- modules/FvwmTaskBar/Start.h	2002/09/12 20:26:28	1.9
+++ modules/FvwmTaskBar/Start.h	2002/09/16 00:53:32
@@ -20,8 +20,8 @@
 #ifndef START_H
 #define START_H
 
-typedef struct startAndMiniButtonItem {
-  struct startAndMiniButtonItem *head, *tail;
+typedef struct startAndLaunchButtonItem {
+  struct startAndLaunchButtonItem *head, *tail;
   int index;
   Button *buttonItem;
   int width, height;
@@ -30,12 +30,13 @@
   char *buttonStartCommand;
   char *buttonCaption;
   char *buttonIconFileName;
-} StartAndMiniButtonItem;
+  char *buttonToolTip;
+} StartAndLaunchButtonItem;
 
 extern Bool StartButtonParseConfig(char *tline);
 extern void StartButtonInit(int height);
-extern void StartAndMiniButtonItemInit(StartAndMiniButtonItem *item);
-extern void AddStartAndMiniButtonItem(StartAndMiniButtonItem *item);
+extern void StartAndLaunchButtonItemInit(StartAndLaunchButtonItem *item);
+extern void AddStartAndLaunchButtonItem(StartAndLaunchButtonItem *item);
 extern int StartButtonUpdate(const char *title, int index, int state);
 extern void StartButtonDraw(int force);
 extern int  MouseInStartButton(int x, int y, int *whichButton, Bool *startButtonPressed);

---

From: Dominik Vogt <[email-masked]>
Date: Mon, 16 Sep 2002 11:26:47 +0200

> >   it's pressed as in most other parts of fvwm, e.g. window

Um, but now the start button menu is also opened on button
release instead of button press.  Act on release is only required
for the additional buttons.

> this.  I can't get this behavior.  Works fine for me.

I can't reproduce it anymore.  If it happens again, I'll try to pin
it down.

Bye

Dominik ^_^  ^_^

---

From: Ben Mathews <[email-masked]>
Date: Mon, 16 Sep 2002 06:17:52 -0400

> for the additional buttons.

I just installed 2.5.3 and the start button launches on release, not on 
push.  I assumed that this was the correct behavior.  Has it changed 
between 2.5.3 and 2.5.4?

Ben

---

From: Dominik Vogt <[email-masked]>
Date: Mon, 16 Sep 2002 13:10:09 +0200

> push.  I assumed that this was the correct behavior.  Has it changed 

Surely not.  But didn't you say tha start button was triggered
when pressed in earlier versions?  I'm only concerned about not
changing the behaviour.

Bye

Dominik ^_^  ^_^

---

From: Ben Mathews <[email-masked]>
Date: Mon, 16 Sep 2002 21:07:51 -0400

> when pressed in earlier versions?  I'm only concerned about not

I don't think I said that, but if I did, it was in error.  As far as I 
can see, the start button behavior has not changed.

Ben