all repos — fluxbox @ 675bc5d66aa08311e99cb00cf836d16a910a73df

custom fork of the fluxbox windowmanager

added conditional statements to keys file
markt markt
commit

675bc5d66aa08311e99cb00cf836d16a910a73df

parent

08ebff4b319f51b4263cded0bb9c04103bcd9c3a

M ChangeLogChangeLog

@@ -1,5 +1,23 @@

(Format: Year/Month/Day) Changes for 1.0.1: +*07/11/22: + * Added conditional statements to key commands (Mark) + - for example, this will search for an open xterm window, cycle through + them if there are any, or else open one: + Mod4 t :If {Some Matches (xterm)} {NextWindow (xterm)} {Exec xterm} + - the syntax is :If {<test>} {<command if true>} {<command if false>} + - `Matches <pattern>' is currently the only test you can make; when used + alone, it tests the focused window or the clicked window for OnWindow + mouse events + - there are many ways to combine tests: + - `Some <test>' returns true if any open client matches <test> + - `Every <test>' returns true if every open client matches <test> + - `Not <test>' negates the value of <test> + - `Or {<test>} {<test>} ...' returns true if any of the tests is true + - `And {<test>} {<test>} ...' returns true if all of the tests are true + - `Xor {<test>} {<test>} ...' returns the boolean xor of the truth values + FbCommandFactory.cc CurrentWindowCmd.cc/hh WorkspaceCmd.cc/hh + FbTk/Command.hh FbTk/SimpleCommand.hh, added files FbTk/LogicCommands.cc/hh *07/11/16: * Added new key command :Focus [<pattern>] that focuses a window (e.g., using OnWindow or specified using a window pattern) (Mark, thanks Tomas Janousek)
M src/CurrentWindowCmd.ccsrc/CurrentWindowCmd.cc

@@ -33,20 +33,25 @@

#include "FocusControl.hh" void WindowHelperCmd::execute() { - m_win = 0; if (WindowCmd<void>::window() || FocusControl::focusedFbWindow()) real_execute(); } -void WindowHelperCmd::execute(FluxboxWindow &win) { - m_win = &win; - real_execute(); +FluxboxWindow &WindowHelperCmd::fbwindow() { + // will exist from execute above + FluxboxWindow *tmp = WindowCmd<void>::window(); + if (tmp) return *tmp; + return *FocusControl::focusedFbWindow(); +} + +bool WindowHelperBoolCmd::bool_execute() { + if (WindowCmd<void>::window() || FocusControl::focusedFbWindow()) + return real_execute(); + return false; } -FluxboxWindow &WindowHelperCmd::fbwindow() { +FluxboxWindow &WindowHelperBoolCmd::fbwindow() { // will exist from execute above - if (m_win) - return *m_win; FluxboxWindow *tmp = WindowCmd<void>::window(); if (tmp) return *tmp; return *FocusControl::focusedFbWindow();

@@ -227,3 +232,7 @@ fbwindow().setUnfocusedAlpha(new_alpha);

} else fbwindow().setUnfocusedAlpha(m_unfocus); } + +bool MatchCmd::real_execute() { + return m_pat.match(fbwindow()); +}
M src/CurrentWindowCmd.hhsrc/CurrentWindowCmd.hh

@@ -27,22 +27,30 @@ #define CURRENTWINDOWCMD_HH

#include "Command.hh" #include "Window.hh" +#include "ClientPattern.hh" /// helper class for window commands /// calls real_execute if there's a focused window or a window in button press/release window class WindowHelperCmd: public FbTk::Command { public: - explicit WindowHelperCmd(FluxboxWindow *win = 0): m_win(win) { } + explicit WindowHelperCmd() { } void execute(); - void execute(FluxboxWindow &fbwin); protected: FluxboxWindow &fbwindow(); virtual void real_execute() = 0; +}; -private: - FluxboxWindow *m_win; +class WindowHelperBoolCmd: public FbTk::BoolCommand { +public: + explicit WindowHelperBoolCmd() { } + + bool bool_execute(); + +protected: + FluxboxWindow &fbwindow(); + virtual bool real_execute() = 0; }; /// command that calls FluxboxWindow::<the function> on execute()

@@ -221,4 +229,14 @@ private:

int m_focus, m_unfocus; int m_relative, m_un_relative; }; + +class MatchCmd: public WindowHelperBoolCmd { +public: + MatchCmd(const std::string &pat): m_pat(pat.c_str()) { }; +protected: + bool real_execute(); +private: + ClientPattern m_pat; +}; + #endif // CURRENTWINDOWCMD_HH
M src/FbCommandFactory.ccsrc/FbCommandFactory.cc

@@ -34,6 +34,7 @@ #include "SimpleCommand.hh"

#include "Screen.hh" #include "FbTk/StringUtil.hh" +#include "FbTk/LogicCommands.hh" #include "FbTk/MacroCommand.hh" #include "FbTk/stringstream.hh"

@@ -50,6 +51,10 @@ using std::vector;

using std::cerr; using std::endl; +using namespace FbTk; +using FbTk::StringUtil::removeFirstWhitespace; +using FbTk::StringUtil::toLower; + // autoregister this module to command parser FbCommandFactory FbCommandFactory::s_autoreg;

@@ -60,6 +65,109 @@ sscanf(str, "%d", &defaultvalue);

return defaultvalue; } +BoolCommand *parseBoolCommand(string &line, bool trusted) { + // parse arguments and command + string command = line; + string arguments; + string::size_type first_pos = removeFirstWhitespace(command); + FbTk::StringUtil::removeTrailingWhitespace(command); + string::size_type second_pos = command.find_first_of(" \t", first_pos); + if (second_pos != string::npos) { + // ok we have arguments, parsing them here + arguments = command.substr(second_pos); + removeFirstWhitespace(arguments); + command.erase(second_pos); // remove argument from command + } + + // now we have parsed command and arguments + command = toLower(command); + + if (command == "matches") { + return new MatchCmd(arguments); + } else if (command == "some") { + BoolCommand *boolcmd = parseBoolCommand(arguments, trusted); + if (!boolcmd) + return 0; + return new SomeCmd(RefCount<BoolCommand>(boolcmd)); + } else if (command == "every") { + BoolCommand *boolcmd = parseBoolCommand(arguments, trusted); + if (!boolcmd) + return 0; + return new EveryCmd(RefCount<BoolCommand>(boolcmd)); + } else if (command == "not") { + BoolCommand *boolcmd = parseBoolCommand(arguments, trusted); + if (!boolcmd) + return 0; + RefCount<BoolCommand> ref(boolcmd); + return new NotCommand(ref); + } else if (command == "and") { + int pos = 0, err = 0; + AndCommand *andcmd = new AndCommand(); + string cmd; + + while (true) { + RefCount<BoolCommand> tmp(0); + err = StringUtil::getStringBetween(cmd, arguments.c_str() + pos, + '{', '}', " \t\n", true); + pos += err; + if (err == 0) + break; + + tmp = parseBoolCommand(cmd, trusted); + if (*tmp) + andcmd->add(tmp); + } + + if (andcmd->size() > 0) + return andcmd; + delete andcmd; + } else if (command == "or") { + int pos = 0, err = 0; + OrCommand *orcmd = new OrCommand(); + string cmd; + + while (true) { + RefCount<BoolCommand> tmp(0); + err = StringUtil::getStringBetween(cmd, arguments.c_str() + pos, + '{', '}', " \t\n", true); + pos += err; + if (err == 0) + break; + + tmp = parseBoolCommand(cmd, trusted); + if (*tmp) + orcmd->add(tmp); + } + + if (orcmd->size() > 0) + return orcmd; + delete orcmd; + } else if (command == "xor") { + int pos = 0, err = 0; + XorCommand *xorcmd = new XorCommand(); + string cmd; + + while (true) { + RefCount<BoolCommand> tmp(0); + err = StringUtil::getStringBetween(cmd, arguments.c_str() + pos, + '{', '}', " \t\n", true); + pos += err; + if (err == 0) + break; + + tmp = parseBoolCommand(cmd, trusted); + if (*tmp) + xorcmd->add(tmp); + } + + if (xorcmd->size() > 0) + return xorcmd; + delete xorcmd; + } + + return 0; +} + }; // end anonymous namespace FbCommandFactory::FbCommandFactory() {

@@ -74,6 +182,7 @@ "clientmenu",

"close", "closeallwindows", "commanddialog", + "cond", "custommenu", "deiconify", "detachclient",

@@ -91,6 +200,7 @@ "fullscreen",

"gotowindow", "hidemenus", "iconify", + "if", "keymode", "kill", "killwindow",

@@ -246,15 +356,15 @@ //

// Current focused window commands // else if (command == "fullscreen") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new FullscreenCmd()), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new FullscreenCmd()), arguments); else if (command == "minimizewindow" || command == "minimize" || command == "iconify") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::iconify)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::iconify)), arguments); else if (command == "maximizewindow" || command == "maximize") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::maximizeFull)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::maximizeFull)), arguments); else if (command == "maximizevertical") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::maximizeVertical)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::maximizeVertical)), arguments); else if (command == "maximizehorizontal") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::maximizeHorizontal)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::maximizeHorizontal)), arguments); else if (command == "setalpha") { typedef vector<string> StringTokens; StringTokens tokens;

@@ -281,7 +391,7 @@ string::size_type pos = arguments.find('(');

if (pos != string::npos && pos != arguments.size()) pat = arguments.c_str() + pos; - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new SetAlphaCmd(focused, relative, unfocused, un_rel)), pat); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new SetAlphaCmd(focused, relative, unfocused, un_rel)), pat); } else if (command == "startmoving") return new StartMovingCmd(); else if (command == "startresizing") {

@@ -331,7 +441,7 @@ string::size_type pos = arguments.find('(');

if (pos != string::npos && pos != arguments.size()) pat = arguments.c_str() + pos; - FbTk::RefCount<WindowHelperCmd> cmd; + FbTk::RefCount<FbTk::Command> cmd; if (command == "resizeto") cmd = new ResizeToCmd(dx, dy); else

@@ -386,7 +496,7 @@ string::size_type pos = arguments.find('(');

if (pos != string::npos && pos != arguments.size()) pat = arguments.c_str() + pos; - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new MoveToCmd(dx, dy, refc)), pat); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new MoveToCmd(dx, dy, refc)), pat); } else if (command == "move" || command == "moveright" || command == "moveleft" || command == "moveup" || command == "movedown") {

@@ -412,29 +522,29 @@ string::size_type pos = arguments.find('(');

if (pos != string::npos && pos != arguments.size()) pat = arguments.c_str() + pos; - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new MoveCmd(dx, dy)), pat); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new MoveCmd(dx, dy)), pat); } else if (command == "raise") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::raise)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::raise)), arguments); else if (command == "raiselayer") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::raiseLayer)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::raiseLayer)), arguments); else if (command == "lower") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::lower)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::lower)), arguments); else if (command == "lowerlayer") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::lowerLayer)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::lowerLayer)), arguments); else if (command == "activate" || command == "focus") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd((void (FluxboxWindow::*)())&FluxboxWindow::focus)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd((void (FluxboxWindow::*)())&FluxboxWindow::focus)), arguments); else if (command == "close") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::close)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::close)), arguments); else if (command == "closeallwindows") return new CloseAllWindowsCmd(); else if (command == "killwindow" || command == "kill") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::kill)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::kill)), arguments); else if (command == "shade" || command == "shadewindow") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::shade)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::shade)), arguments); else if (command == "stick" || command == "stickwindow") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::stick)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::stick)), arguments); else if (command == "toggledecor") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::toggleDecoration)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::toggleDecoration)), arguments); else if (command == "sethead") { int num = 0; string pat;

@@ -443,7 +553,7 @@ iss >> num;

string::size_type pos = arguments.find('('); if (pos != string::npos && pos != arguments.size()) pat = arguments.c_str() + pos; - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new SetHeadCmd(num)), pat); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new SetHeadCmd(num)), pat); } else if (command == "tab" || command == "sendtonextworkspace" || command == "sendtoprevworkspace" || command == "taketonextworkspace" ||

@@ -457,7 +567,7 @@ iss >> num;

string::size_type pos = arguments.find('('); if (pos != string::npos && pos != arguments.size()) pat = arguments.c_str() + pos; - FbTk::RefCount<WindowHelperCmd> cmd; + FbTk::RefCount<FbTk::Command> cmd; if (command == "tab") cmd = new GoToTabCmd(num);

@@ -475,15 +585,15 @@ else

cmd = new TakeToWorkspaceCmd(num-1); return new WindowListCmd(cmd, pat); } else if (command == "nexttab") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::nextClient)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::nextClient)), arguments); else if (command == "prevtab") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::prevClient)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::prevClient)), arguments); else if (command == "movetableft") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::moveClientLeft)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::moveClientLeft)), arguments); else if (command == "movetabright") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::moveClientRight)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::moveClientRight)), arguments); else if (command == "detachclient") - return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::detachCurrentClient)), arguments); + return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::detachCurrentClient)), arguments); else if (command == "windowmenu") return new CurrentWindowCmd(&FluxboxWindow::popupMenu); //

@@ -683,6 +793,36 @@ if ( macro->size() > 0 )

return macro; delete macro; + } else if (command == "if" || command == "cond") { + string cmd; + int err = 0, pos = 0; + RefCount<BoolCommand> cond(0); + RefCount<Command> t(0), f(0); + + err = FbTk::StringUtil::getStringBetween(cmd, arguments.c_str(), + '{', '}', " \t\n", true); + if (err > 0) + cond = parseBoolCommand(cmd, trusted); + if (err == 0 || *cond == 0) + return 0; + + pos = err; + err = FbTk::StringUtil::getStringBetween(cmd, arguments.c_str() + pos, + '{', '}', " \t\n", true); + if (err > 0) + t = CommandParser::instance().parseLine(cmd, trusted); + if (err == 0 || *t == 0) + return 0; + + pos += err; + err = FbTk::StringUtil::getStringBetween(cmd, arguments.c_str() + pos, + '{', '}', " \t\n", true); + if (err > 0) + f = CommandParser::instance().parseLine(cmd, trusted); + if (err == 0 || *f == 0) + return 0; + + return new FbTk::IfCommand(cond, t, f); } return 0; }
M src/FbTk/Command.hhsrc/FbTk/Command.hh

@@ -31,6 +31,14 @@ virtual ~Command() { }

virtual void execute() = 0; }; +/// Interface class for boolean commands +class BoolCommand: public Command { +public: + virtual ~BoolCommand() { } + virtual void execute() { bool_execute(); } + virtual bool bool_execute() = 0; +}; + } // end namespace FbTk #endif // FBTK_COMMAND_HH
A src/FbTk/LogicCommands.cc

@@ -0,0 +1,75 @@

+// LogicCommands.cc for FbTk +// Copyright (c) 2007 Fluxbox Team (fluxgen at fluxbox dot org) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +// $Id: $ + +#include "LogicCommands.hh" + +namespace FbTk { + +void OrCommand::add(RefCount<BoolCommand> &com) { + m_commandlist.push_back(com); +} + +size_t OrCommand::size() const { + return m_commandlist.size(); +} + +bool OrCommand::bool_execute() { + for (size_t i=0; i < m_commandlist.size(); ++i) { + if (m_commandlist[i]->bool_execute()) + return true; + } + return false; +} + +void AndCommand::add(RefCount<BoolCommand> &com) { + m_commandlist.push_back(com); +} + +size_t AndCommand::size() const { + return m_commandlist.size(); +} + +bool AndCommand::bool_execute() { + for (size_t i=0; i < m_commandlist.size(); ++i) { + if (!m_commandlist[i]->bool_execute()) + return false; + } + return true; +} + +void XorCommand::add(RefCount<BoolCommand> &com) { + m_commandlist.push_back(com); +} + +size_t XorCommand::size() const { + return m_commandlist.size(); +} + +bool XorCommand::bool_execute() { + bool ret = false; + for (size_t i=0; i < m_commandlist.size(); ++i) + ret ^= m_commandlist[i]->bool_execute(); + return ret; +} + +}; // end namespace FbTk
A src/FbTk/LogicCommands.hh

@@ -0,0 +1,97 @@

+// LogicCommands.hh for FbTk +// Copyright (c) 2007 Fluxbox Team (fluxgen at fluxbox dot org) +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +// $Id: $ + +#ifndef FBTK_LOGICCOMMANDS_HH +#define FBTK_LOGICCOMMANDS_HH + +#include "Command.hh" +#include "RefCount.hh" + +#include <vector> + +namespace FbTk { + +/// executes a boolcommand and uses the result to decide what to do +class IfCommand: public Command { +public: + IfCommand(RefCount<BoolCommand> &cond, + RefCount<Command> &t, RefCount<Command> &f): + m_cond(cond), m_t(t), m_f(f) { } + void execute() { + if (m_cond->bool_execute()) + m_t->execute(); + else + m_f->execute(); + } + +private: + RefCount<BoolCommand> m_cond; + RefCount<Command> m_t, m_f; +}; + +/// executes a list of boolcommands until one is true +class OrCommand: public BoolCommand { +public: + void add(RefCount<BoolCommand> &com); + size_t size() const; + bool bool_execute(); + +private: + std::vector<RefCount<BoolCommand> > m_commandlist; +}; + +/// executes a list of boolcommands until one is false +class AndCommand: public BoolCommand { +public: + void add(RefCount<BoolCommand> &com); + size_t size() const; + bool bool_execute(); + +private: + std::vector<RefCount<BoolCommand> > m_commandlist; +}; + +/// executes a list of boolcommands, returning the parity +class XorCommand: public BoolCommand { +public: + void add(RefCount<BoolCommand> &com); + size_t size() const; + bool bool_execute(); + +private: + std::vector<RefCount<BoolCommand> > m_commandlist; +}; + +/// executes a boolcommand and returns the negation +class NotCommand: public BoolCommand { +public: + NotCommand(RefCount<BoolCommand> &com): m_command(com) { } + bool bool_execute() { return !m_command->bool_execute(); } + +private: + RefCount<BoolCommand> m_command; +}; + +} // end namespace FbTk + +#endif // FBTK_LOGICCOMMANDS_HH
M src/FbTk/Makefile.amsrc/FbTk/Makefile.am

@@ -21,6 +21,7 @@ EventHandler.hh EventManager.hh EventManager.cc \

FbWindow.hh FbWindow.cc Font.cc Font.hh FontImp.hh \ I18n.cc I18n.hh \ ImageControl.hh ImageControl.cc \ + LogicCommands.hh LogicCommands.cc \ MacroCommand.hh MacroCommand.cc \ Menu.hh Menu.cc MenuItem.hh MenuItem.cc \ MultiButtonMenuItem.hh MultiButtonMenuItem.cc \
M src/FbTk/SimpleCommand.hhsrc/FbTk/SimpleCommand.hh

@@ -39,6 +39,18 @@ Receiver &m_receiver;

Action m_action; }; +template <typename Receiver, typename ReturnType=bool> +class SimpleBoolCommand: public BoolCommand { +public: + typedef ReturnType (Receiver::* Action)(); + SimpleBoolCommand(Receiver &r, Action a): + m_receiver(r), m_action(a) { } + bool bool_execute() { return (bool)(m_receiver.*m_action)(); } +private: + Receiver &m_receiver; + Action m_action; +}; + } // end namespace FbTk #endif // FBTK_SIMPLECOMMAND_HH
M src/WorkspaceCmd.ccsrc/WorkspaceCmd.cc

@@ -30,6 +30,7 @@ #include "Screen.hh"

#include "fluxbox.hh" #include "WinClient.hh" #include "FocusControl.hh" +#include "WindowCmd.hh" #include "FbTk/KeyUtil.hh"

@@ -54,10 +55,54 @@

FocusControl::Focusables::iterator it = win_list.begin(), it_end = win_list.end(); for (; it != it_end; ++it) { - if (m_pat.match(**it) && (*it)->fbwindow()) - m_cmd->execute(*(*it)->fbwindow()); + if (m_pat.match(**it) && (*it)->fbwindow()) { + WindowCmd<void>::setWindow((*it)->fbwindow()); + m_cmd->execute(); + } + } + } +} + +bool SomeCmd::bool_execute() { + if (m_pat.error()) + return m_cmd->bool_execute(); + + BScreen *screen = Fluxbox::instance()->keyScreen(); + if (screen != 0) { + FocusControl::Focusables win_list(screen->focusControl().creationOrderList().clientList()); + + FocusControl::Focusables::iterator it = win_list.begin(), + it_end = win_list.end(); + for (; it != it_end; ++it) { + WinClient *client = dynamic_cast<WinClient *>(*it); + if (!client) continue; + WindowCmd<void>::setClient(client); + if (m_cmd->bool_execute()) + return true; } } + return false; +} + +bool EveryCmd::bool_execute() { + if (m_pat.error()) + return m_cmd->bool_execute(); + + BScreen *screen = Fluxbox::instance()->keyScreen(); + if (screen != 0) { + FocusControl::Focusables win_list(screen->focusControl().creationOrderList().clientList()); + + FocusControl::Focusables::iterator it = win_list.begin(), + it_end = win_list.end(); + for (; it != it_end; ++it) { + WinClient *client = dynamic_cast<WinClient *>(*it); + if (!client) continue; + WindowCmd<void>::setClient(client); + if (!m_cmd->bool_execute()) + return false; + } + } + return true; } void AttachCmd::execute() {
M src/WorkspaceCmd.hhsrc/WorkspaceCmd.hh

@@ -32,17 +32,37 @@ #include "FocusControl.hh"

#include "FbTk/RefCount.hh" -class WindowHelperCmd; - class WindowListCmd: public FbTk::Command { public: - WindowListCmd(FbTk::RefCount<WindowHelperCmd> cmd, const std::string &pat): + WindowListCmd(FbTk::RefCount<FbTk::Command> cmd, const std::string &pat): m_cmd(cmd), m_pat(pat.c_str()) { } void execute(); private: - FbTk::RefCount<WindowHelperCmd> m_cmd; + FbTk::RefCount<FbTk::Command> m_cmd; + ClientPattern m_pat; +}; + +class SomeCmd: public FbTk::BoolCommand { +public: + SomeCmd(FbTk::RefCount<FbTk::BoolCommand> cmd): m_cmd(cmd) { } + + bool bool_execute(); + +private: + FbTk::RefCount<FbTk::BoolCommand> m_cmd; + ClientPattern m_pat; +}; + +class EveryCmd: public FbTk::BoolCommand { +public: + EveryCmd(FbTk::RefCount<FbTk::BoolCommand> cmd): m_cmd(cmd) { } + + bool bool_execute(); + +private: + FbTk::RefCount<FbTk::BoolCommand> m_cmd; ClientPattern m_pat; };