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

Reply via email to