all repos — fluxbox @ 03dce043b78103a977bd6c48b81bb1b462aaac5f

custom fork of the fluxbox windowmanager

added ForEach key command
Mark Tiefenbruck mark@fluxbox.org
commit

03dce043b78103a977bd6c48b81bb1b462aaac5f

parent

b90a7e21a9f56f8e9f92c7ec357cbf683e6fd712

5 files changed, 79 insertions(+), 14 deletions(-)

jump to
M ChangeLogChangeLog

@@ -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
M src/FbTk/StringUtil.hhsrc/FbTk/StringUtil.hh

@@ -67,6 +67,27 @@

/// 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
M src/FocusableList.ccsrc/FocusableList.cc

@@ -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;
M src/WorkspaceCmd.ccsrc/WorkspaceCmd.cc

@@ -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 @@ #include <math.h>

#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); }
M src/WorkspaceCmd.hhsrc/WorkspaceCmd.hh

@@ -36,14 +36,18 @@ #include <string>

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 {