Hi,
this patch (see attachment) implements a tab monitoring facility for mrxvt.
The implementation of this feature is not yet finished and i'm still not very
experienced in programming C - so suggestions, ideas and testers are very
welcome :-)
A excerpt of the manpage:
---
MonitorTab [ACIVITY|INACTIVITY|AUTO]
Monitor the current tab-window for ACTIVITY or INACTIVITY or
automatically detect the type of monitoring using the AUTO option.
The amount time which is used to detect the type of monitoring
or tab-inactivity can be specified by the 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 monitorCommand option.
monitorTimeout 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 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.
monitorCommand command
Specifies a command which will be executed if a activity or inactivity
event is
raised by the MonitorTab macro.
---
Monitoring for INACTIVITY seems currently not working in all situations - but i
had
no time so far analyze this problem....
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,99 @@
}
} /* 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 +1934,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 +2263,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 */
@@ -2348,7 +2441,7 @@
if( r->fifo_fd != -1 )
FD_SET( r->fifo_fd, &readfds );
#endif
-
+
rxvt_dbgmsg(( DBG_DEBUG, DBG_COMMAND,
"Calling select (timeout %06luu)...",
quick_timeout ? value.tv_sec * 1000000 + value.tv_usec : 0
@@ -6568,8 +6661,8 @@
if( limit < 0 )
/* Integer overflow */
limit = INT_MAX;
-
-
+
+
/*
* Process as much input from the tab as is available. Keep a count of the
* (approximate) number of lines we have scrolled, so we know when to
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,59 @@
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)
@@ -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 iniactivity 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 +
-------------------------------------------------------------------------
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