
From_____________________________________________________________________
| Dave Thomas - Devteq Ltd - 18 Thames St - Windsor - Berks SL4 1PL - UK |
| Tel: +44 753 830333  - Fax: +44 753 831645  - email: dave@devteq.co.uk |
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The diffs below add a new .fvwmrc command, 'TitleTime', which lets you
specify the format of the title line of the _active_ window. As well
as fixed text, you can use strftime style substitutions. You can also
place the normal window title using '%%s'.

Rather than hack the setitimer stuff, I decided to use the select
timer. The logic is that if autoraisedelay is set, then the window
title will have just been redrawn with the correct time anyway. If its
not set, then we can just set a timer on the select in My_XNextEvent.

I can't test it many configurations (I've got Linux & xfree here), but
it seems fairly fail-safe (famous last words).

Anyway, yours to do with as you please.

*** 1.1	1993/10/22 10:16:19
--- fvwm.1	1993/10/22 10:18:42
***************
*** 194,199 ****
--- 194,219 ----
  Makes \fIfvwm\fP use font \fIfontname\fP instead of "fixed" for the window 
  title bar.
  
+ .IP "TitleTime \fIformatstring\fP"
+ \fITitleTime\fP allows you to specify a format string for the title
+ of the window that currently has focus. The \fIformatstring\fP
+ argument is a \fBstrftime\fP (MAN3) format string, allowing arbitrary
+ text and time/date substitutions to be made. The string \fI%%s\fP will
+ be replaced by the window's name. Ths the line
+ .sp
+ .in +5
+     TitleTime %a %d  [ %%s ]  %H:%M
+ .sp
+ .in -5
+ might cause the title of the window with focus to be
+ .sp
+ .in +5
+     Wed 17  [ MyWindow ]  12:34
+ .in -5
+ .sp
+ The time will be updated whenever the window title is redisplayed, and
+ every minute.
+ 
  .IP "PagerFont \fIfontname\fP"
  Makes \fIfvwm\fP use font \fIfontname\fP for writing window icon names into the
  window's representation in the pager. If this option is omitted, no
*** 1.1	1993/10/22 10:16:10
--- system.fvwmrc	1993/10/22 10:18:42
***************
*** 11,16 ****
--- 11,21 ----
  
  PagerBackColor		#5c54c0
  
+ # You can set the active window's title to contain arbitrary text and/
+ # or the time (using strftime formats)
+ 
+ TitleTime		%a %d   [ %%s ]   %H:%M
+ 
  ############################################################################
  # Now the fonts - one for menus/icons, another for window titles
  Font			-adobe-helvetica-medium-r-*-*-*-120-*-*-*-*-*-*
*** 1.1	1993/10/22 10:17:40
--- screen.h	1993/10/22 10:18:42
***************
*** 151,156 ****
--- 151,158 ----
    int AutoRaiseDelay;          /* Delay between setting focus and raising win*/
    int ScrollResistance;        /* resistance to scrolling in desktop */
    int MoveResistance;          /* res to moving windows over viewport edge */
+   char *pTitleTimeString;      /* DT - points to strftime format string  */
+ 			       /*      to use to title windows */
  } ScreenInfo;
  
  extern ScreenInfo Scr;
*** 1.1	1993/10/22 10:16:28
--- borders.c	1993/10/22 10:47:54
***************
*** 375,380 ****
--- 375,383 ----
    int hor_off, w;
    GC ReliefGC,ShadowGC;
    Pixel Forecolor, BackColor;
+   char *pTitle;
+   static char *pTitleBuff = 0;
+   static size_t titleBuffLen = 0;
  
    if(!(t->flags & TITLE))
      return;
***************
*** 395,408 ****
      }
    flush_expose(t->title_w);
  
-   w=XTextWidth(Scr.WindowFont.font,t->name,strlen(t->name));
-   hor_off = (t->title_width - w)/2;
-   
    NewFontAndColor(Scr.WindowFont.font->fid,Forecolor, BackColor);
  
    if(NewTitle)
      XClearWindow(dpy,t->title_w);
  
    /* for mono, we clear an area in the title bar where the window
     * title goes, so that its more legible. For color, no need */
    if(Scr.d_depth<2)
--- 398,437 ----
      }
    flush_expose(t->title_w);
  
    NewFontAndColor(Scr.WindowFont.font->fid,Forecolor, BackColor);
  
+   pTitle = t->name;
+  
+   /* DT - add the time to the title if present and this window has focus */
+   /* We do a little jig with the format. We assume it to contain the     */
+   /* string '%%s' someplace. This gets converted to '%s' by strftime,    */
+   /* and that gets replaced by the window name by the sprintf.           */
+  
+   if (onoroff && Scr.pTitleTimeString) {  
+     char tmpBuff[200];
+     time_t now;
+     struct tm *pTM;
+     int len;
+ 
+     (void)time(&now);
+     pTM = localtime(&now);
+     len = strftime(tmpBuff, sizeof(tmpBuff)-1, Scr.pTitleTimeString, pTM);
+     len += strlen(t->name);
+     if (len > titleBuffLen) {
+       pTitleBuff = (char *)realloc((void *)pTitleBuff, len+2);
+       titleBuffLen = len;
+     }
+     sprintf(pTitleBuff, tmpBuff, t->name);
+     pTitle = pTitleBuff;
+     NewTitle = TRUE;
+   }
+ 
    if(NewTitle)
      XClearWindow(dpy,t->title_w);
  
+   w=XTextWidth(Scr.WindowFont.font,pTitle,strlen(pTitle));
+   hor_off = (t->title_width - w)/2;
+   
    /* for mono, we clear an area in the title bar where the window
     * title goes, so that its more legible. For color, no need */
    if(Scr.d_depth<2)
***************
*** 422,428 ****
  		  ReliefGC, ShadowGC);
    
    XDrawString (dpy, t->title_w,Scr.FontGC,hor_off, Scr.WindowFont.y+1, 
! 	       t->name, strlen(t->name));
  }
  
  
--- 451,457 ----
  		  ReliefGC, ShadowGC);
    
    XDrawString (dpy, t->title_w,Scr.FontGC,hor_off, Scr.WindowFont.y+1, 
! 	       pTitle, strlen(pTitle));
  }
  
  
*** 1.1	1993/10/22 10:16:45
--- configure.c	1993/10/22 10:18:43
***************
*** 93,98 ****
--- 93,99 ----
  {
    {"Font",              assign_string,  &Scr.StdFont.name, (int *)0},
    {"WindowFont",        assign_string,  &Scr.WindowFont.name, (int *)0},
+   {"TitleTime",         assign_string,  &Scr.pTitleTimeString, (int *)0},
    {"StdForeColor",      assign_string,  &Stdfore, (int *)0},
    {"StdBackColor",      assign_string,  &Stdback, (int *)0},
    {"HiForeColor",       assign_string,  &Hifore, (int *)0},
*** 1.1	1993/10/22 10:16:50
--- events.c	1993/10/22 10:29:30
***************
*** 1365,1370 ****
--- 1365,1373 ----
   *
   * Waits for next X event, or for an auto-raise timeout.
   *
+  * Modified (dave@devteq.co.uk) - if there's a title_time string,
+  * then set a timeout for the next minute boundary.
+  *
   ****************************************************************************/
  void My_XNextEvent(Display *dpy, XEvent *event)
  {
***************
*** 1371,1376 ****
--- 1374,1381 ----
    struct itimerval value;
    fd_set in_fdset;
    Window child;
+   Bool   fTitleTiming = FALSE;
+   int    fds;
  
    if(XPending(dpy))
      {
***************
*** 1384,1392 ****
    FD_SET(x_fd,&in_fdset);
    if((value.it_value.tv_usec != 0)||
       (value.it_value.tv_sec != 0))
!     select(fd_width,&in_fdset, 0, 0, &value.it_value);
!   else
!     select(fd_width,&in_fdset, 0, 0, NULL);
  
    if(alarmed)
      {
--- 1389,1434 ----
    FD_SET(x_fd,&in_fdset);
    if((value.it_value.tv_usec != 0)||
       (value.it_value.tv_sec != 0))
!     fds = select(fd_width,&in_fdset, 0, 0, &value.it_value);
!   else {			/* DT - check for title timing */
!     if (Scr.pTitleTimeString) {	/* yup - how long til next minute? */
!       time_t secsToNextMin, now;
!       (void)time(&now);
!       secsToNextMin = 60 - (now % 60);
!       value.it_value.tv_usec = 500000; /* touch of rounding up */
!       value.it_value.tv_sec  = secsToNextMin;
!       value.it_interval.tv_usec = 0;
!       value.it_interval.tv_sec  = 0;
!       fTitleTiming = TRUE;
!     }
! 
!     fds = select(fd_width,&in_fdset, 0, 0, 
! 		 fTitleTiming ? &value.it_value : NULL);
!   }
! 
!   /* Now we've a problem. If the select timed didn't quite time out,
!      but there's less than 500mS to run, then we won't catch it next time.
!      POSIX says the it_value field should be decremented by select, but not
!      all Unices to this (Linux does). So, although the test below won't 
!      blow up, it can cause us to miss time events.
!   */
! 
!   if (fTitleTiming) {
! 
!     if ((fds == 0) || ((value.it_value.tv_sec == 0) &&
! 		       (value.it_value.tv_usec <= 500000))) {
!       
!       XQueryPointer(dpy,Scr.Root,&JunkRoot,&child,&JunkX,&JunkY,&JunkX, 
! 		    &JunkY,&JunkMask );
! 
!       if((Scr.Focus != NULL)&&(child == Scr.Focus->lead_w))
! 	{
! 	  if (Scr.Focus->flags & TITLE)
! 	    SetTitleBar(Scr.Focus, TRUE,TRUE);
! 	}
! 
!     }
!   }
  
    if(alarmed)
      {



