added ForEach key command

This commit is contained in:
Mark Tiefenbruck 2007-12-20 12:23:56 -08:00
parent b90a7e21a9
commit 03dce043b7
5 changed files with 79 additions and 14 deletions

View file

@ -1,5 +1,15 @@
(Format: Year/Month/Day) (Format: Year/Month/Day)
Changes for 1.0.1: Changes for 1.0.1:
*07/12/20:
* Added new key command :ForEach (or :Map) (Mark)
- :ForEach {<command>} [{ [{<list opts>}] [<bool command>] }]
- For example, the following command will shade all windows on the current
workspace: ForEach {shade} {{groups} Matches (workspace=[current])}
- <list opts> can be any combination of `static' and `groups' where static
means windows are listed in creation order, and groups means individual
tabs are not considered separately
- This replaces syntax such as `:Minimize (layer)', which no longer works
WorkspaceCmd.cc/hh
*07/12/19: *07/12/19:
* Don't let transient windows steal focus from other programs (Mark) * Don't let transient windows steal focus from other programs (Mark)
Window.cc Window.cc

View file

@ -67,6 +67,27 @@ std::string::size_type removeTrailingWhitespace(std::string &str);
/// splits input at first non-leading whitespace and returns both parts /// splits input at first non-leading whitespace and returns both parts
void getFirstWord(const std::string &in, std::string &first, std::string &rest); void getFirstWord(const std::string &in, std::string &first, std::string &rest);
template <typename Container>
static void stringTokensBetween(Container &container, const std::string &in,
std::string &rest, char first, char last,
const char *ok_chars = " \t\n", bool allow_nesting = true) {
std::string token;
int err = 0, pos = 0;
while (true) {
err = getStringBetween(token, in.c_str() + pos, first, last, ok_chars,
allow_nesting);
if (err == 0)
break;
container.push_back(token);
pos += err;
}
rest = in.c_str() + pos;
}
/// Breaks a string into tokens /// Breaks a string into tokens
template <typename Container> template <typename Container>
static void static void

View file

@ -38,10 +38,11 @@ using std::vector;
void FocusableList::parseArgs(const string &in, int &opts, string &pat) { void FocusableList::parseArgs(const string &in, int &opts, string &pat) {
string options; string options;
int err = FbTk::StringUtil::getStringBetween(options, in.c_str(), '{', '}'); int err = FbTk::StringUtil::getStringBetween(options, in.c_str(), '{', '}',
" \t\n");
// the rest of the string is a ClientPattern // the rest of the string is a ClientPattern
pat = in.c_str() + err; pat = in.c_str() + (err > 0 ? err : 0);
// now parse the options // now parse the options
vector<string> args; vector<string> args;

View file

@ -35,6 +35,7 @@
#include "FbTk/KeyUtil.hh" #include "FbTk/KeyUtil.hh"
#include "FbTk/ObjectRegistry.hh" #include "FbTk/ObjectRegistry.hh"
#include "FbTk/stringstream.hh" #include "FbTk/stringstream.hh"
#include "FbTk/StringUtil.hh"
#ifdef HAVE_CMATH #ifdef HAVE_CMATH
#include <cmath> #include <cmath>
@ -43,31 +44,59 @@
#endif #endif
#include <algorithm> #include <algorithm>
#include <functional> #include <functional>
#include <vector>
using std::string; using std::string;
using FbTk::Command; using FbTk::Command;
using FbTk::BoolCommand; using FbTk::BoolCommand;
void WindowListCmd::execute() { REGISTER_OBJECT_PARSER(map, WindowListCmd::parse, Command);
if (m_pat.error()) { REGISTER_OBJECT_PARSER(foreach, WindowListCmd::parse, Command);
m_cmd->execute();
return; FbTk::Command *WindowListCmd::parse(const string &command, const string &args,
bool trusted) {
FbTk::Command *cmd = 0;
FbTk::BoolCommand *filter = 0;
std::vector<string> tokens;
int opts;
string pat;
FbTk::StringUtil::stringTokensBetween(tokens, args, pat, '{', '}');
if (tokens.empty())
return 0;
cmd = FbTk::ObjectRegistry<Command>::instance().parse(tokens[0], trusted);
if (!cmd)
return 0;
if (tokens.size() > 1) {
FocusableList::parseArgs(tokens[1], opts, pat);
filter = FbTk::ObjectRegistry<BoolCommand>::instance().parse(pat,
trusted);
} }
return new WindowListCmd(FbTk::RefCount<Command>(cmd), opts,
FbTk::RefCount<BoolCommand>(filter));
}
void WindowListCmd::execute() {
BScreen *screen = Fluxbox::instance()->keyScreen(); BScreen *screen = Fluxbox::instance()->keyScreen();
if (screen != 0) { if (screen != 0) {
FocusControl::Focusables win_list(screen->focusControl().creationOrderWinList().clientList()); FocusableList::Focusables win_list(FocusableList::getListFromOptions(*screen, m_opts)->clientList());
FocusControl::Focusables::iterator it = win_list.begin(), FocusableList::Focusables::iterator it = win_list.begin(),
it_end = win_list.end(); it_end = win_list.end();
// save old value, so we can restore it later // save old value, so we can restore it later
WinClient *old = WindowCmd<void>::client(); WinClient *old = WindowCmd<void>::client();
for (; it != it_end; ++it) { for (; it != it_end; ++it) {
if (m_pat.match(**it) && (*it)->fbwindow()) { if (typeid(**it) == typeid(FluxboxWindow))
WindowCmd<void>::setWindow((*it)->fbwindow()); WindowCmd<void>::setWindow((*it)->fbwindow());
else if (typeid(**it) == typeid(WinClient))
WindowCmd<void>::setClient(dynamic_cast<WinClient *>(*it));
if (!*m_filter || m_filter->bool_execute())
m_cmd->execute(); m_cmd->execute();
} }
}
WindowCmd<void>::setClient(old); WindowCmd<void>::setClient(old);
} }
} }

View file

@ -36,14 +36,18 @@
class WindowListCmd: public FbTk::Command { class WindowListCmd: public FbTk::Command {
public: public:
WindowListCmd(FbTk::RefCount<FbTk::Command> cmd, const std::string &pat): WindowListCmd(FbTk::RefCount<FbTk::Command> cmd, int opts,
m_cmd(cmd), m_pat(pat.c_str()) { } FbTk::RefCount<FbTk::BoolCommand> filter):
m_cmd(cmd), m_opts(opts), m_filter(filter) { }
void execute(); void execute();
static FbTk::Command *parse(const std::string &command,
const std::string &args, bool trusted);
private: private:
FbTk::RefCount<FbTk::Command> m_cmd; FbTk::RefCount<FbTk::Command> m_cmd;
ClientPattern m_pat; int m_opts;
FbTk::RefCount<FbTk::BoolCommand> m_filter;
}; };
class SomeCmd: public FbTk::BoolCommand { class SomeCmd: public FbTk::BoolCommand {