Hi,

i updated the previous patch - basically minimal code-formatting and 
documentation 
changes.

To test the new monitoring feature i recommend the follwing parameter
line:
---
src/mrxvt -dlevel 3 -dmask all -cf ./share/mrxvtrc.sample -path ./share/
---
Debugging output should provide detailed information about the
behavior of the patch.

>From my point of view, the visual notification is currently not
optimal - maybe modifying the color of the tab or the tabtitle would
be a better idea.

Best regards
Marc Schoechlin
Index: src/rxvtlib.h
===================================================================
--- src/rxvtlib.h	(revision 290)
+++ src/rxvtlib.h	(working copy)
@@ -716,6 +716,17 @@
 					   that have scrolled without a refresh
 					   request */
 
+    short	    monitor_tab;	/* monitor tab
+					   0/NULL == off
+					   1      == monitor for silence
+					   2      == monitor for activity
+					   3      == automatic discovery of monitor type
+					 */
+
+    int		    monitor_nbytes_read;	/* number of bytes read since monitor-start */
+    struct	    timeval monitor_start;	/* epoch time of monitor starttime of the tab */
+
+
     /*
      * Moved from hidden: want_refresh needs to be local to each tab.
      * want_full_refresh, refresh_type (except for SMOOTH_REFRESH), and
@@ -788,6 +799,7 @@
     MacroFnCopy,
     MacroFnPaste,
     MacroFnPasteFile,
+    MacroFnMonitorTab,
     MacroFnToggleSubwin,
     MacroFnFont,
     MacroFnToggleVeryBold,
Index: src/xdefaults.c
===================================================================
--- src/xdefaults.c	(revision 290)
+++ src/xdefaults.c	(working copy)
@@ -245,6 +245,10 @@
 	    "Duration (ms) of the visual bell", 0),
     STRG( Rs_bellCommand, "bellCommand", "blc",
 	"string", "command to execute instead of beeping", 0),
+    STRG( Rs_monitorCommand, "monitorCommand", "mcmd",
+	"string", "command to execute if activity/inactivity was detected while monitoring", 0),
+    STRG( Rs_monitorTimeout, "monitorTimeout", "mto", "number",
+	"timeout in milliseconds for tab-monitoring", 0),
 # if ! defined(NO_MAPALERT) && defined(MAPALERT_OPTION)
     BOOL( "mapAlert", NULL, Opt_mapAlert, NULL ),
 # endif
Index: src/rxvt.h
===================================================================
--- src/rxvt.h	(revision 290)
+++ src/rxvt.h	(working copy)
@@ -1184,6 +1184,8 @@
     Rs_bellCommand,
     Rs_vBellDuration,
 #endif
+    Rs_monitorCommand,
+    Rs_monitorTimeout,
     Rs_desktop,
 #ifndef NO_BACKSPACE_KEY
     Rs_backspace_key,
Index: src/command.c
===================================================================
--- src/command.c	(revision 290)
+++ src/command.c	(working copy)
@@ -1764,6 +1764,7 @@
 rxvt_read_child_cmdfd (rxvt_t* r, int page, unsigned int count)
 {
     int		    n = 0, bread = 0;
+    struct	    timeval  tp;
 
     while( count )
     {
@@ -1826,12 +1827,112 @@
 	}
     }	/* while (count) */
 
+    /* update lastupdate time if output was produced */
+    gettimeofday( &tp, NULL);
+    if (bread != 0)
+    {
+     rxvt_dbgmsg ((DBG_DEBUG, DBG_COMMAND,  "output produced on epoch %i\n", tp.tv_sec));
+     PVTS(r, page)->monitor_nbytes_read += bread;
+    }
+
     PVTS(r, page)->nbytes_last_read = bread;
     return bread;
 }
 
+/* INTPROTO */
+void
+rxvt_monitor_tab(rxvt_t* r,int i)
+{
 
+    struct timeval  tp;
+    struct timeval  monitor_timeout_time;
 
+    short  execute_action = 0;
+    int	   monitor_timeout = 2000;
+    
+    /* return, if no monitoring is activated */
+    if ((IS_NULL(&PVTS(r, i)->monitor_tab)) || (PVTS(r, i)->monitor_tab == 0))
+    {
+      return;
+    }
+    monitor_timeout_time = PVTS(r, i)->monitor_start;
+    /* set configured monitor_timeout milliseconds , if configured */
+    if( r->h->rs[Rs_monitorTimeout] )
+    {
+	monitor_timeout = atoi( r->h->rs[Rs_monitorTimeout] );
+    }
+    monitor_timeout_time.tv_sec += (int) monitor_timeout/1000;
+    monitor_timeout_time.tv_usec += (monitor_timeout - (((int) monitor_timeout/1000) * 1000)) * 1000;
+
+    /* get current epoch time */
+    gettimeofday( &tp, NULL);
+
+    /* monitor-type "AUTO" : determine which type of monitoring is needed */
+    if ((PVTS(r, i)->monitor_tab == 3) && (timercmp(&monitor_timeout_time,&tp, <)))
+    {
+
+       //printf(">%i %i %i\n",PVTS(r, i)->monitor_nbytes_read, PVTS(r, i)->monitor_start.tv_sec , tp.tv_sec);
+
+       if(PVTS(r, i)->monitor_nbytes_read > 0)
+       {
+	   PVTS(r, i)->monitor_tab = 2;
+	   rxvt_msg (DBG_INFO, DBG_MACROS,  "Macro MonitorTab: decided to monitor inactivity on tab %i", i);
+       }
+       else
+       {
+	   PVTS(r, i)->monitor_tab = 1;
+	   rxvt_msg (DBG_INFO, DBG_MACROS,  "Macro MonitorTab: decided to monitor activity on tab %i", i);
+       }
+       AVTS(r)->monitor_nbytes_read = 0 ;
+       PVTS(r, i)->monitor_start = tp;
+    }
+    /* monitor-type "INACTIVITY" : detect inactivity */
+    else if ((PVTS(r, i)->monitor_tab == 2) && 
+	     (timercmp(&monitor_timeout_time,&tp, <)))
+    {
+	    /* activity detected */
+	    if (PVTS( r, i)->monitor_nbytes_read == 0)
+	    {
+	       rxvt_msg (DBG_INFO, DBG_MACROS,  "Macro MonitorTab: detected inactivity on tab %i", i);
+	       //printf("detected inactivity: %i %i %i\n",i,PVTS( r, i)->monitor_start.tv_sec,tp.tv_sec);
+	       execute_action = 1;
+	    }
+	    /* no activity detected, restarting monitoring */
+	    else
+	    {
+	       AVTS(r)->monitor_nbytes_read = 0 ;
+	       PVTS(r, i)->monitor_start = tp;
+	    }
+    }
+    /* monitor-type "ACTIVITY" : detect activity */
+    else if ((PVTS(r, i)->monitor_tab == 1) &&
+	     (PVTS( r, i)->monitor_nbytes_read != 0))
+    {
+	    rxvt_msg (DBG_INFO, DBG_MACROS,  "Macro MonitorTab: detected activity on tab %i", i);
+	   //printf("detected activity: %i %i\n",i,PVTS( r, i)->nbytes_last_read);
+	   execute_action = 1;
+    }
+
+    /* perform a action if activity/inactivity was detected */
+    if (execute_action == 1)
+    {
+
+	   /* highlight the tabbar */
+	   rxvt_tabbar_highlight_tab (r, i, False);
+
+	   /* ding - ring the bell */
+	   rxvt_scr_bell(r,i);
+
+	   /* execute a command if configured */
+	   if( r->h->rs[Rs_monitorCommand] && *r->h->rs[Rs_monitorCommand] )
+		     rxvt_async_exec( r, r->h->rs[Rs_monitorCommand] );
+
+	   /* disable monitoring */
+	   PVTS(r, i)->monitor_tab = 0;
+    }
+}
+
+
 /* INTPROTO */
 void
 rxvt_process_children_cmdfd( rxvt_t* r, fd_set* p_readfds )
@@ -1846,6 +1947,8 @@
     {
 	unsigned int	count, bufsiz;
 
+	/* check for activity */
+        rxvt_monitor_tab(r,i);
 
 	/* check next file descriptor if this one has nothing to read in. */
 	if (!FD_ISSET(PVTS(r, i)->cmd_fd, p_readfds))
@@ -2173,6 +2276,9 @@
     /* loop until we can return something */
     for(;;)
     {
+	/* check for inactivity */
+	for (i = 0; i <= LTAB(r); i ++)
+	    rxvt_monitor_tab(r,i);
 
 #if defined(POINTER_BLANK) || defined(CURSOR_BLINK) || defined(TRANSPARENT)
 	/* presume == 0 implies time not yet retrieved */
Index: src/macros.c
===================================================================
--- src/macros.c	(revision 290)
+++ src/macros.c	(working copy)
@@ -42,6 +42,7 @@
     "Copy",		    /* Copy selection */
     "Paste",		    /* Paste selection */
     "PasteFile",	    /* Paste the content of a file */
+    "MonitorTab",	    /* Monitor tab for activity/inactivity */
     "ToggleSubwin",	    /* Toggle subwindows (scroll / menu / tabbar) */
     "ResizeFont",	    /* Resize terminal font */
     "ToggleVeryBold",	    /* Toggle use of bold font for colored text */
@@ -1076,7 +1077,66 @@
 	   break;
 	}
 
+	case MacroFnMonitorTab:
+	{
+	    struct timeval  tp;
+	    if (NOT_NULL(ev))
+	    {
+		if( NOT_NULL(astr) && *astr )
+		{
+		    short doit = 0;
 
+		    /* which monitoring type do we need ? */
+		    if(strcmp ("ACTIVITY", astr) == 0)
+		    {
+		      AVTS(r)->monitor_tab = (AVTS(r)->monitor_tab == 1) ? 0 : 1;
+		      doit = 1;
+		      rxvt_msg (DBG_INFO, DBG_MACROS,  "Macro %s ACTIVITY : activity monitoring request on tab %i.",
+			macroNames[action->type], AVTS(r)->vts_idx );
+		    }
+		    else if (strcmp ("INACTIVITY", astr) == 0)
+		    {
+		      AVTS(r)->monitor_tab = (AVTS(r)->monitor_tab == 2) ? 0 : 2;
+		      doit = 1;
+		      rxvt_msg (DBG_INFO, DBG_MACROS,  "Macro %s INACTIVITY : inactivity monitoring request on tab %i.",
+		 	 macroNames[action->type], AVTS(r)->vts_idx );
+		    }
+		    else if (strcmp ("AUTO", astr) == 0)
+		    {
+		      AVTS(r)->monitor_tab = (AVTS(r)->monitor_tab == 3) ? 0 : 3;
+		      doit = 1;
+		      rxvt_msg (DBG_INFO, DBG_MACROS,  
+			 "Macro %s AUTO : request for automatic (in-)activity monitoring on tab %i.",
+		 	 macroNames[action->type], AVTS(r)->vts_idx );
+		    }
+		    else
+		    {
+		      rxvt_msg (DBG_INFO, DBG_MACROS,  "Macro %s requires argument or invalid argument provided.",
+		 	 macroNames[action->type] );
+		      break;
+		    }
+		    /* activating/deactivating the macro */
+		    if (doit != 0)
+		    {
+		      if (AVTS(r)->monitor_tab == 0 )
+		      {
+			  rxvt_msg (DBG_INFO, DBG_MACROS,  "Macro %s was already active, deactivating previous macro call.",
+			     macroNames[action->type] );
+		      }else
+		      {
+			  AVTS(r)->monitor_nbytes_read = 0;
+			  gettimeofday( &AVTS(r)->monitor_start , NULL);
+		      }
+		    }
+		}
+	    }
+	    else
+	    {
+		retval = -1;
+	    }
+	    break;
+	}
+
 	case MacroFnToggleSubwin:
 	    rxvt_toggle_subwin( r, (unsigned char*) astr);
 	    break;
Index: share/submenus.menu
===================================================================
--- share/submenus.menu	(revision 290)
+++ share/submenus.menu	(working copy)
@@ -53,6 +53,11 @@
 {Show right tab}{Ctrl-Shift-l}	    GotoTab +1
 ./Switch to tab/*
 ../
+./Monitor tab/*
+{activity}			    MonitorTab ACTIVITY
+{inactivity}			    MonitorTab INACTIVITY
+{detect}			    MonitorTab AUTO
+../
 {-}
 {Move tab left}{Ctrl-Shift-<}	    MoveTab -1
 {Move tab right}{Ctrl-Shift->}	    MoveTab +1
Index: share/mrxvtrc
===================================================================
--- share/mrxvtrc	(revision 290)
+++ share/mrxvtrc	(working copy)
@@ -196,6 +196,13 @@
 
 Mrxvt.macro.Shift+Delete:		SetTitle
 
+# Monitor tabs for activity or inactivity
+# (alternate arguments for MonitorTab macro : "INACTIVITY" / "ACTIVITY")
+Mrxvt.macro.Ctrl+Shift+a:	MonitorTab AUTO
+#Mrxvt.monitorTimeout:          2000
+#Mrxvt.monitorCommand:          play ~/.ding_sound.wav
+
+             
 #
 # Mrxvt Console: Enable the useFifo option, and then open a console in a new
 # tab. Anything typed there is executed as a macro. When done (on clean exit),
Index: share/mrxvtrc.sample
===================================================================
--- share/mrxvtrc.sample	(revision 290)
+++ share/mrxvtrc.sample	(working copy)
@@ -71,6 +71,13 @@
 # Mrxvt.tabbarPixmap:		tabbarbg.png
 # Mrxvt.tabUsePixmap:		false
 
+# Monitor tabs for activity or inactivity
+# (alternate arguments for MonitorTab macro : "INACTIVITY" / "ACTIVITY")
+Mrxvt.macro.Ctrl+Shift+a:   MonitorTab AUTO
+#Mrxvt.monitorTimeout:          2000
+#Mrxvt.monitorCommand:          play ~/.ding_sound.wav
+
+
 #
 # ---------------------- SCROLLING / SCROLLBAR OPTIONS ----------------------- #
 #
Index: doc/mrxvt.1
===================================================================
--- doc/mrxvt.1	(revision 290)
+++ doc/mrxvt.1	(working copy)
@@ -62,7 +62,7 @@
 .Pp
 The primary features of
 .Nm
-include (but are not limited to) multiple tabs, dynamically changeable tab titles, customisable command for each tab, input broadcasting, true translucent window, fast pseudo transparency with tinting, user supplied background images (XPM, JPEG, PNG), off-focus fading, text shadow, multiple style (NeXT, Rxvt, Xterm, SGI, Plain) scrollbars, XIM, multi-language support (Chinese, Korean, Japanese), freetype font and logging.
+include (but are not limited to) multiple tabs, dynamically changeable tab titles, customizable command for each tab, input broadcasting, true translucent window, fast pseudo transparency with tinting, user supplied background images (XPM, JPEG, PNG), off-focus fading, text shadow, multiple style (NeXT, Rxvt, Xterm, SGI, Plain) scrollbars, XIM, multi-language support (Chinese, Korean, Japanese), freetype font and logging.
 .Pp
 .
 The default
@@ -1198,6 +1198,19 @@
 .It Cm vBellDuration Ar ms
 Amount of time (in milliseconds) to flash the screen if using a visual bell.
 .
+.It Cm monitorTimeout Ar ms
+Amount of time (in milliseconds) to detect the type of monitoring type or tab-inactivity.
+Default value is 2000 ms this causes that mrxvt is waiting 2 seconds after invoking the 
+.Ic MonitorTab
+macro with argument "AUTO" or "INACTIVITY" to determine if or what type a notification is 
+needed. The detection of "ACTIVITY" does not make use of the configuration value.
+.
+.It Cm monitorCommand Ar command
+Specifies a command which will be executed if a activity or inactivity event is raised
+by the
+.Ic MonitorTab
+macro.
+.
 .It Cm veryBright Ar True Ns | Ns Ar False
 If true, and if
 .Cm boldColors
@@ -1704,6 +1717,21 @@
 or any other terminal based program (i.e. somthing like a bash-profile
 or sequence of administration commands).
 .\" ------------------------------------------------------------
+.It Ic MonitorTab Ar [ACIVITY|INACTIVITY|AUTO]
+Monitor the current tab-window for  
+.Ar ACTIVITY
+or
+.Ar INACTIVITY
+or automatically detect the type of monitoring using the 
+.Ar AUTO
+option. The amount time which is used to detect the type of monitoring or tab-inactivity
+can be specified by the
+.Ic monitorTimeout
+option. The detection of activity or inactivity is signaled by highlighting the tab of the event and ringing
+the system bell. Additionally it is possible to execute a dedicated command using the
+.Ic monitorCommand
+option.
+.\" ------------------------------------------------------------
 .It Ic ToggleSubwin Op Oo Ar + Ns | Ns Ar - Oc Ns Op Ar b Ns | Ns Ar m Ns | Ns Ar s Ns | Ns Ar t
 Toggle visibility of sub-windows. If the argument begins with a
 .Sq +
@@ -2049,5 +2077,6 @@
 .
 .An "Terminator" < Ns Mt [EMAIL PROTECTED] Ns >
 .An "Gautam Iyer" < Ns Mt [EMAIL PROTECTED] Ns >
+.An "Marc Schoechlin" < Ns Mt [EMAIL PROTECTED] Ns >
 .
 .
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Materm-devel mailing list
Materm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/materm-devel
mrxvt home page: http://materm.sourceforge.net

Reply via email to