Index: src/fluxbox.cc =================================================================== RCS file: /cvsroot/fluxbox/fluxbox/src/fluxbox.cc,v retrieving revision 1.234 diff -a -b -B -p -u -r1.234 fluxbox.cc --- src/fluxbox.cc 3 Mar 2004 12:53:06 -0000 1.234 +++ src/fluxbox.cc 12 Mar 2004 13:54:19 -0000 @@ -1781,7 +1781,13 @@ bool Fluxbox::menuTimestampsChanged() co for (; it != it_end; ++it) { struct stat buf; - if (! stat((*it)->filename.c_str(), &buf)) { + // its a dynamic menuentry and the time is up + if ((*it)->timestamp < 0 ) { + time_t current_time; + time(¤t_time); + if (current_time + (*it)->timestamp >= 0) + return true; + } else if (! stat((*it)->filename.c_str(), &buf)) { if ((*it)->timestamp != buf.st_ctime) return true; } else @@ -1826,7 +1832,7 @@ void Fluxbox::real_rereadMenu() { for_each(m_screen_list.begin(), m_screen_list.end(), mem_fun(&BScreen::rereadMenu)); } -void Fluxbox::saveMenuFilename(const char *filename) { +void Fluxbox::saveMenuFilename(const char *filename, int timeout) { if (filename == 0) return; @@ -1844,11 +1850,16 @@ void Fluxbox::saveMenuFilename(const cha if (! found) { struct stat buf; - if (! stat(filename, &buf)) { + if (! stat(filename, &buf) || timeout > 0) { + time_t current_time; + time(¤t_time); + MenuTimestamp *ts = new MenuTimestamp; ts->filename = filename; - ts->timestamp = buf.st_ctime; + + // a [incommand] creates a faked timestamp + ts->timestamp = (timeout == 0 ? buf.st_ctime : -(current_time + timeout)); m_menu_timestamps.push_back(ts); } Index: src/fluxbox.hh =================================================================== RCS file: /cvsroot/fluxbox/fluxbox/src/fluxbox.hh,v retrieving revision 1.83 diff -a -b -B -p -u -r1.83 fluxbox.hh --- src/fluxbox.hh 10 Feb 2004 18:45:57 -0000 1.83 +++ src/fluxbox.hh 12 Mar 2004 13:54:19 -0000 @@ -162,7 +162,7 @@ public: void loadRootCommand(BScreen &scr); void loadTitlebar(); void saveStyleFilename(const char *val) { m_rc_stylefile = (val == 0 ? "" : val); } - void saveMenuFilename(const char *); + void saveMenuFilename(const char *, int timeout= 0); void clearMenuFilenames(); void saveTitlebarFilename(const char *); void saveSlitlistFilename(const char *val) { m_rc_slitlistfile = (val == 0 ? "" : val); } Index: src/Screen.hh =================================================================== RCS file: /cvsroot/fluxbox/fluxbox/src/Screen.hh,v retrieving revision 1.134 diff -a -b -B -p -u -r1.134 Screen.hh --- src/Screen.hh 19 Jan 2004 18:28:58 -0000 1.134 +++ src/Screen.hh 12 Mar 2004 13:54:19 -0000 @@ -347,7 +347,7 @@ private: void setupConfigmenu(FbTk::Menu &menu); void createStyleMenu(FbTk::Menu &menu, const char *label, const char *directory); - bool parseMenuFile(std::ifstream &filestream, FbTk::Menu &menu, int &row); + bool parseMenuFile(std::istream &filestream, FbTk::Menu &menu, int &row); void initMenu(); Index: src/Screen.cc =================================================================== RCS file: /cvsroot/fluxbox/fluxbox/src/Screen.cc,v retrieving revision 1.268 diff -a -b -B -p -u -r1.268 Screen.cc --- src/Screen.cc 27 Feb 2004 12:32:54 -0000 1.268 +++ src/Screen.cc 12 Mar 2004 13:54:21 -0000 @@ -116,6 +116,15 @@ extern "C" { #include #include #include +#ifdef HAVE_SSTREAM +#include +#define FB_istringstream std::istringstream +#elif HAVE_STRSTREAM +#include +#define FB_istringstream std::istrstream +#else +#error "You dont have sstream or strstream headers!" +#endif // HAVE_STRSTREAM using namespace std; @@ -1863,7 +1872,7 @@ void BScreen::initMenu() { } /// looks through a menufile and adds correct items to the root-menu. -bool BScreen::parseMenuFile(ifstream &file, FbTk::Menu &menu, int &row) { +bool BScreen::parseMenuFile(istream &file, FbTk::Menu &menu, int &row) { string line; FbTk::RefCount @@ -1996,6 +2005,26 @@ bool BScreen::parseMenuFile(ifstream &fi } } // end of else 'x' } // end of include + else if ( str_key == "includeexec") { // [includeexec] (timeout) {command} + if (str_label.empty()) { + fprintf(stderr, + i18n-> + getMessage(FBNLS::ScreenSet, FBNLS::ScreenINCLUDEError, + "BScreen::parseMenuFile: [includeexec] error, " + "no timeout defined\n")); + cerr<<"Row: "< + getMessage(FBNLS::ScreenSet, FBNLS::ScreenINCLUDEError, + "BScreen::parseMenuFile: [includeexec] error, " + "no command defined\n")); + } else { + FB_istringstream pipestream(FbTk::StringUtil::pipeCommandToString(str_cmd)); + if(!parseMenuFile(pipestream, menu, row)) + Fluxbox::instance()->saveMenuFilename(str_label.c_str(), atoi(str_label.c_str())); + } // end of else 'x' + } // end of includeexec else if (str_key == "submenu") { // sub if (!str_label.size()) { fprintf(stderr, Index: src/FbTk/StringUtil.cc =================================================================== RCS file: /cvsroot/fluxbox/fluxbox/src/FbTk/StringUtil.cc,v retrieving revision 1.10 diff -a -b -B -p -u -r1.10 StringUtil.cc --- src/FbTk/StringUtil.cc 28 Feb 2004 10:46:02 -0000 1.10 +++ src/FbTk/StringUtil.cc 12 Mar 2004 13:54:21 -0000 @@ -31,15 +31,27 @@ #include #include -using namespace std; +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif // HAVE_CONFIG_H + +#ifdef HAVE_SSTREAM +#include +#define FB_ostringstream std::ostringstream +#elif HAVE_STRSTREAM +#include +#define FB_ostringstream std::ostrstream +#else +#error "You dont have sstream or strstream headers!" +#endif // HAVE_STRSTREAM namespace FbTk { namespace StringUtil { /** - Takes a pointer to string *s as an argument, - creates a new string n, copies s to n and + Takes a pointer to std::string *s as an argument, + creates a new std::string n, copies s to n and returns a pointer to n. */ char *strdup(const char *s) { @@ -50,7 +62,7 @@ char *strdup(const char *s) { } /** - Tries to find a string in another and + Tries to find a std::string in another and ignoring the case of the characters Returns 0 on success else pointer to str. */ @@ -73,8 +85,8 @@ const char *strcasestr(const char *str, if ~ then expand it to home of user returns expanded filename */ -string expandFilename(const std::string &filename) { - string retval; +std::string expandFilename(const std::string &filename) { + std::string retval; size_t pos = filename.find_first_not_of(" \t"); if (pos != std::string::npos && filename[pos] == '~') { retval = getenv("HOME"); @@ -89,25 +101,25 @@ string expandFilename(const std::string } /** - @return string from last "." to end of string + @return std::string from last "." to end of std::string */ -string findExtension(const std::string &filename) { +std::string findExtension(const std::string &filename) { //get start of extension std::string::size_type start_pos = filename.find_last_of("."); if (start_pos == std::string::npos && start_pos != filename.size()) return ""; - // return from last . to end of string + // return from last . to end of std::string return filename.substr(start_pos + 1); } /** - Parses a string between "first" and "last" characters + Parses a std::string between "first" and "last" characters and ignoring ok_chars as whitespaces. The value is returned in "out". Returns negative value on error and this value is the position - in the in-string where the error occured. + in the in-std::string where the error occured. Returns positive value on success and this value is - for the position + 1 in the in-string where the "last"-char value + for the position + 1 in the in-std::string where the "last"-char value was found. */ int getStringBetween(std::string& out, const char *instr, const char first, const char last, @@ -154,7 +166,7 @@ int getStringBetween(std::string& out, c } } - out = in.substr(i+1, j-i-1); //copy the string between first and last + out = in.substr(i+1, j-i-1); //copy the std::string between first and last //return value to last character return (j+1+total_add); } @@ -178,25 +190,73 @@ std::string basename(const std::string & return filename; } -string::size_type removeFirstWhitespace(std::string &str) { - string::size_type first_pos = str.find_first_not_of(" \t"); - if (first_pos != string::npos) +std::string::size_type removeFirstWhitespace(std::string &str) { + std::string::size_type first_pos = str.find_first_not_of(" \t"); + if (first_pos != std::string::npos) str.erase(0, first_pos); return first_pos; } -string::size_type removeTrailingWhitespace(std::string &str) { +std::string::size_type removeTrailingWhitespace(std::string &str) { // strip trailing whitespace - string::size_type first_pos = str.find_last_not_of(" \t"); - if (first_pos != string::npos) { - string::size_type last_pos = str.find_first_of(" \t", first_pos); - while (last_pos != string::npos) { + std::string::size_type first_pos = str.find_last_not_of(" \t"); + if (first_pos != std::string::npos) { + std::string::size_type last_pos = str.find_first_of(" \t", first_pos); + while (last_pos != std::string::npos) { str.erase(last_pos); last_pos = str.find_first_of(" \t", last_pos); } } return first_pos; +} + + +/** Executes a Command and pipes the output to a std::string */ +std::string pipeCommandToString(const std::string command) +{ + enum + { + READ_END= 0, WRITE_END= 1, + STDIN= 0, STDOUT= 1, STDERR= 2 + }; + + int pid, outpipe[2], errpipe[2]; + + if (pipe(outpipe) < 0) + perror("couldnt open outpipe"); + + if (pipe(errpipe) < 0) + perror("couldnt open errpipe"); + + if ((pid= fork()) < 0) + perror("couldnt fork child"); + + if (pid == 0) // the child ... + { + if (dup2(outpipe[ WRITE_END ], STDOUT) < 0) + perror("couldnt redirect STDOUT"); + + if (dup2(errpipe[ WRITE_END ], STDERR) < 0) + perror("couldnt redirect STDERR"); + + close(outpipe[READ_END]); + close(errpipe[READ_END]); + execl("/bin/sh", "/bin/sh", "-c", command.c_str(), 0); + } + else // the old process + { + close(outpipe[WRITE_END]); + FB_ostringstream oss; + int c; + FILE* stream= fdopen(outpipe[READ_END], "r"); + while ((c= fgetc(stream)) != EOF) + oss << static_cast(c); + fclose(stream); + return oss.str(); + } + + return ""; } }; // end namespace StringUtil Index: src/FbTk/StringUtil.hh =================================================================== RCS file: /cvsroot/fluxbox/fluxbox/src/FbTk/StringUtil.hh,v retrieving revision 1.8 diff -a -b -B -p -u -r1.8 StringUtil.hh --- src/FbTk/StringUtil.hh 16 Dec 2003 17:06:52 -0000 1.8 +++ src/FbTk/StringUtil.hh 12 Mar 2004 13:54:21 -0000 @@ -89,6 +89,8 @@ stringtok (Container &container, std::st } } +std::string pipeCommandToString(const std::string command); + } // end namespace StringUtil } // end namespace FbTk