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)
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:
* Don't let transient windows steal focus from other programs (Mark)
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
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
template <typename Container>
static void

View file

@ -38,10 +38,11 @@ using std::vector;
void FocusableList::parseArgs(const string &in, int &opts, string &pat) {
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
pat = in.c_str() + err;
pat = in.c_str() + (err > 0 ? err : 0);
// now parse the options
vector<string> args;

View file

@ -35,6 +35,7 @@
#include "FbTk/KeyUtil.hh"
#include "FbTk/ObjectRegistry.hh"
#include "FbTk/stringstream.hh"
#include "FbTk/StringUtil.hh"
#ifdef HAVE_CMATH
#include <cmath>
@ -43,30 +44,58 @@
#endif
#include <algorithm>
#include <functional>
#include <vector>
using std::string;
using FbTk::Command;
using FbTk::BoolCommand;
void WindowListCmd::execute() {
if (m_pat.error()) {
m_cmd->execute();
return;
REGISTER_OBJECT_PARSER(map, WindowListCmd::parse, Command);
REGISTER_OBJECT_PARSER(foreach, WindowListCmd::parse, Command);
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();
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(),
it_end = win_list.end();
FocusableList::Focusables::iterator it = win_list.begin(),
it_end = win_list.end();
// save old value, so we can restore it later
WinClient *old = WindowCmd<void>::client();
for (; it != it_end; ++it) {
if (m_pat.match(**it) && (*it)->fbwindow()) {
if (typeid(**it) == typeid(FluxboxWindow))
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();
}
}
WindowCmd<void>::setClient(old);
}

View file

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