added conditional statements to keys file

This commit is contained in:
markt 2007-11-22 04:07:57 +00:00
parent 08ebff4b31
commit 675bc5d66a
11 changed files with 487 additions and 44 deletions

View file

@ -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)

View file

@ -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
if (m_win)
return *m_win;
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 &WindowHelperBoolCmd::fbwindow() {
// will exist from execute above
FluxboxWindow *tmp = WindowCmd<void>::window();
if (tmp) return *tmp;
return *FocusControl::focusedFbWindow();
@ -227,3 +232,7 @@ void SetAlphaCmd::real_execute() {
} else
fbwindow().setUnfocusedAlpha(m_unfocus);
}
bool MatchCmd::real_execute() {
return m_pat.match(fbwindow());
}

View file

@ -27,22 +27,30 @@
#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

View file

@ -34,6 +34,7 @@
#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 @@ static int getint(const char *str, int 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 @@ FbCommandFactory::FbCommandFactory() {
"close",
"closeallwindows",
"commanddialog",
"cond",
"custommenu",
"deiconify",
"detachclient",
@ -91,6 +200,7 @@ FbCommandFactory::FbCommandFactory() {
"gotowindow",
"hidemenus",
"iconify",
"if",
"keymode",
"kill",
"killwindow",
@ -246,15 +356,15 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
// 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 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
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 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
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 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
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 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
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 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
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 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
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 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
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 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
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;
}

View file

@ -31,6 +31,14 @@ public:
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

75
src/FbTk/LogicCommands.cc Normal file
View file

@ -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

97
src/FbTk/LogicCommands.hh Normal file
View file

@ -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

View file

@ -21,6 +21,7 @@ libFbTk_a_SOURCES = App.hh App.cc Color.cc Color.hh Command.hh \
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 \

View file

@ -39,6 +39,18 @@ private:
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

View file

@ -30,6 +30,7 @@
#include "fluxbox.hh"
#include "WinClient.hh"
#include "FocusControl.hh"
#include "WindowCmd.hh"
#include "FbTk/KeyUtil.hh"
@ -54,12 +55,56 @@ void WindowListCmd::execute() {
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() {
BScreen *screen = Fluxbox::instance()->keyScreen();
if (screen != 0) {

View file

@ -32,17 +32,37 @@
#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;
};