added FbTk::CommandRegistry, decentralized command parsing, and made them auto-register

This commit is contained in:
markt 2007-12-13 05:48:00 +00:00
parent daca07edaf
commit 8b7464046c
33 changed files with 966 additions and 1114 deletions

View file

@ -1,5 +1,10 @@
(Format: Year/Month/Day)
Changes for 1.0.1:
*07/12/13:
* Moved command parsing code all over the place -- expect any patches that
add new commands to be broken (Mark, Simon)
Added FbTk/CommandRegistry.cc/hh
Removed FbCommandFactory.cc/hh CommandParser.cc/hh
*07/12/11:
* Added new resize modes for key command StartResizing: NearestEdge, Left,
Right, Top, Bottom (Mark)

View file

@ -26,7 +26,7 @@
#include "ToolTheme.hh"
#include "Screen.hh"
#include "CommandParser.hh"
#include "FbTk/CommandRegistry.hh"
#include "CommandDialog.hh"
#include "fluxbox.hh"
@ -128,7 +128,7 @@ public:
CommandDialog *dialog = new CommandDialog(*screen, "Edit Clock Format",
"SetResourceValue " + resourcename + " ");
FbTk::RefCount<FbTk::Command> cmd(CommandParser::instance().parseLine("reconfigure"));
FbTk::RefCount<FbTk::Command> cmd(FbTk::CommandRegistry::instance().parseLine("reconfigure"));
dialog->setPostCommand(cmd);
dialog->setText(screen->resourceManager().resourceValue(resourcename));
dialog->show();
@ -169,7 +169,7 @@ ClockTool::ClockTool(const FbTk::FbWindow &parent,
m_button.setGC(m_theme.textGC());
// setup menu
FbTk::RefCount<FbTk::Command> saverc(CommandParser::instance().parseLine("saverc"));
FbTk::RefCount<FbTk::Command> saverc(FbTk::CommandRegistry::instance().parseLine("saverc"));
FbTk::MenuItem *item = new ClockMenuItem(*this);
item->setCommand(saverc);
menu.insert(item);

View file

@ -27,7 +27,7 @@
#include "Screen.hh"
#include "FbWinFrameTheme.hh"
#include "WinClient.hh"
#include "CommandParser.hh"
#include "FbTk/CommandRegistry.hh"
#include "FocusControl.hh"
#include "fluxbox.hh"
@ -139,7 +139,7 @@ void CommandDialog::keyPressEvent(XKeyEvent &event) {
if (ks == XK_Return) {
hide(); // hide and return focus to a FluxboxWindow
// create command from line
auto_ptr<FbTk::Command> cmd(CommandParser::instance().
auto_ptr<FbTk::Command> cmd(FbTk::CommandRegistry::instance().
parseLine(m_precommand + m_textbox.text()));
if (cmd.get())
cmd->execute();
@ -170,8 +170,8 @@ void CommandDialog::tabComplete() {
return;
}
CommandParser::CommandFactoryMap::const_iterator it = CommandParser::instance().factorys().begin();
const CommandParser::CommandFactoryMap::const_iterator it_end = CommandParser::instance().factorys().end();
FbTk::CommandRegistry::CreatorMap::const_iterator it = FbTk::CommandRegistry::instance().commandMap().begin();
const FbTk::CommandRegistry::CreatorMap::const_iterator it_end = FbTk::CommandRegistry::instance().commandMap().end();
vector<string> matches;
for (; it != it_end; ++it) {
if ((*it).first.find(prefix) == 0) {

View file

@ -1,124 +0,0 @@
// CommandParser.cc for Fluxbox - an X11 Window manager
// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
// and Simon Bowden (rathnor at users.sourceforge.net)
//
// 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 "CommandParser.hh"
#include "FbTk/StringUtil.hh"
#include <vector>
using std::string;
using std::vector;
using FbTk::StringUtil::removeFirstWhitespace;
using FbTk::StringUtil::toLower;
CommandParser *CommandParser::s_singleton = 0;
CommandFactory::CommandFactory() {
}
CommandFactory::~CommandFactory() {
// remove all associations with this factory
CommandParser::instance().removeAssociation(*this);
}
void CommandFactory::addCommand(const std::string &command_name) {
CommandParser::instance().associateCommand(command_name, *this);
}
// ensure it is singleton
CommandParser::CommandParser() {
if (s_singleton != 0)
throw std::string("CommandParser currently meant ot be singleton");
}
CommandParser &CommandParser::instance() {
if (s_singleton == 0)
s_singleton = new CommandParser();
return *s_singleton;
}
FbTk::Command *CommandParser::parseLine(const std::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);
// we didn't find any matching command in default commands,
// so we search in the command creators modules for a
// matching command string
return toCommand(command, arguments, trusted);
}
FbTk::Command *CommandParser::toCommand(const std::string &command_str,
const std::string &arguments, bool trusted) {
if (m_commandfactorys[command_str] != 0)
return m_commandfactorys[command_str]->stringToCommand(command_str, arguments, trusted);
return 0;
}
void CommandParser::associateCommand(const std::string &command, CommandFactory &factory) {
// we shouldnt override other commands
if (m_commandfactorys[command] != 0)
return;
m_commandfactorys[command] = &factory;
}
void CommandParser::removeAssociation(CommandFactory &factory) {
// commands that are associated with the factory
vector<string> commands;
// find associations
CommandFactoryMap::iterator factory_it = m_commandfactorys.begin();
const CommandFactoryMap::iterator factory_it_end = m_commandfactorys.end();
for (; factory_it != factory_it_end; ++factory_it) {
if ((*factory_it).second == &factory)
commands.push_back((*factory_it).first);
}
// remove all associations
while (!commands.empty()) {
m_commandfactorys.erase(commands.back());
commands.pop_back();
}
if (m_commandfactorys.empty())
delete s_singleton;
}

View file

@ -1,81 +0,0 @@
// CommandParser.hh for Fluxbox - an X11 Window manager
// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
// and Simon Bowden (rathnor at users.sourceforge.net)
//
// 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 COMMANDPARSER_HH
#define COMMANDPARSER_HH
#include <string>
#include <map>
#include "RefCount.hh"
namespace FbTk {
class Command;
};
/// Creates commands from command and argument.
/// Used for modules to add new commands in compile/run time
class CommandFactory {
public:
CommandFactory();
virtual ~CommandFactory();
virtual FbTk::Command *stringToCommand(const std::string &command,
const std::string &arguments,
bool trusted) = 0;
protected:
void addCommand(const std::string &value);
};
/// Parses text into a command
class CommandParser {
public:
typedef std::map<std::string, CommandFactory *> CommandFactoryMap;
/// @return parses and returns a command matching the line
FbTk::Command *parseLine(const std::string &line, bool trusted = true);
CommandParser();
/// @return instance of command parser
static CommandParser &instance();
/// @return map of factorys
const CommandFactoryMap &factorys() const { return m_commandfactorys; }
private:
// so CommandFactory can associate it's commands
friend class CommandFactory;
/// associate a command with a factory
void associateCommand(const std::string &name, CommandFactory &factory);
/// remove all associations with the factory
void removeAssociation(CommandFactory &factory);
/// search for a command in our command factory map
FbTk::Command *toCommand(const std::string &command,
const std::string &arguments, bool trusted);
CommandFactoryMap m_commandfactorys; ///< a string to factory map
static CommandParser *s_singleton;
};
#endif // COMMANDPARSER_HH

View file

@ -31,6 +31,95 @@
#include "WinClient.hh"
#include "FocusControl.hh"
#include "FbTk/CommandRegistry.hh"
#include "FbTk/stringstream.hh"
#include "FbTk/StringUtil.hh"
#include <string>
#include <vector>
namespace {
FbTk::Command *createCurrentWindowCmd(const std::string &command,
const std::string &args, bool trusted) {
if (command == "minimizewindow" || command == "minimize" || command == "iconify")
return new CurrentWindowCmd(&FluxboxWindow::iconify);
else if (command == "maximizewindow" || command == "maximize")
return new CurrentWindowCmd(&FluxboxWindow::maximizeFull);
else if (command == "maximizevertical")
return new CurrentWindowCmd(&FluxboxWindow::maximizeVertical);
else if (command == "maximizehorizontal")
return new CurrentWindowCmd(&FluxboxWindow::maximizeHorizontal);
else if (command == "raise")
return new CurrentWindowCmd(&FluxboxWindow::raise);
else if (command == "raiselayer")
return new CurrentWindowCmd(&FluxboxWindow::raiseLayer);
else if (command == "lower")
return new CurrentWindowCmd(&FluxboxWindow::lower);
else if (command == "lowerlayer")
return new CurrentWindowCmd(&FluxboxWindow::lowerLayer);
else if (command == "activate" || command == "focus")
return new CurrentWindowCmd((void (FluxboxWindow::*)())&FluxboxWindow::focus);
else if (command == "close")
return new CurrentWindowCmd(&FluxboxWindow::close);
else if (command == "killwindow" || command == "kill")
return new CurrentWindowCmd(&FluxboxWindow::kill);
else if (command == "shade" || command == "shadewindow")
return new CurrentWindowCmd(&FluxboxWindow::shade);
else if (command == "shadeon" )
return new CurrentWindowCmd(&FluxboxWindow::shadeOn);
else if (command == "shadeoff" )
return new CurrentWindowCmd(&FluxboxWindow::shadeOff);
else if (command == "stick" || command == "stickwindow")
return new CurrentWindowCmd(&FluxboxWindow::stick);
else if (command == "toggledecor")
return new CurrentWindowCmd(&FluxboxWindow::toggleDecoration);
else if (command == "nexttab")
return new CurrentWindowCmd(&FluxboxWindow::nextClient);
else if (command == "prevtab")
return new CurrentWindowCmd(&FluxboxWindow::prevClient);
else if (command == "movetableft")
return new CurrentWindowCmd(&FluxboxWindow::moveClientLeft);
else if (command == "movetabright")
return new CurrentWindowCmd(&FluxboxWindow::moveClientRight);
else if (command == "detachclient")
return new CurrentWindowCmd(&FluxboxWindow::detachCurrentClient);
else if (command == "windowmenu")
return new CurrentWindowCmd(&FluxboxWindow::popupMenu);
return 0;
}
REGISTER_COMMAND_PARSER(minimizewindow, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(minimize, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(iconify, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(maximizewindow, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(maximize, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(maximizevertical, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(maximizehorizontal, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(raise, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(raiselayer, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(lower, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(lowerlayer, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(activate, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(focus, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(close, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(killwindow, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(kill, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(shade, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(shadewindow, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(shadeon, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(shadeoff, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(stick, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(stickwindow, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(toggledecor, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(nexttab, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(prevtab, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(movetableft, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(movetabright, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(detachclient, createCurrentWindowCmd);
REGISTER_COMMAND_PARSER(windowmenu, createCurrentWindowCmd);
}; // end anonymous namespace
void WindowHelperCmd::execute() {
if (WindowCmd<void>::window() || FocusControl::focusedFbWindow())
@ -68,6 +157,44 @@ void CurrentWindowCmd::real_execute() {
(fbwindow().*m_action)();
}
namespace {
FbTk::Command *parseIntCmd(const string &command, const string &args,
bool trusted) {
int num = (command == "sethead" ? 0 : 1);
FbTk_istringstream iss(args.c_str());
iss >> num;
if (command == "sethead")
return new SetHeadCmd(num);
else if (command == "tab")
return new GoToTabCmd(num);
else if (command == "sendtonextworkspace")
return new SendToNextWorkspaceCmd(num);
else if (command == "sendtoprevworkspace")
return new SendToPrevWorkspaceCmd(num);
else if (command == "taketonextworkspace")
return new TakeToNextWorkspaceCmd(num);
else if (command == "taketoprevworkspace")
return new TakeToPrevWorkspaceCmd(num);
else if (command == "sendtoworkspace")
// workspaces appear 1-indexed to the user, hence the minus 1
return new SendToWorkspaceCmd(num-1);
else if (command == "taketoworkspace")
return new TakeToWorkspaceCmd(num-1);
return 0;
}
REGISTER_COMMAND_PARSER(sethead, parseIntCmd);
REGISTER_COMMAND_PARSER(tab, parseIntCmd);
REGISTER_COMMAND_PARSER(sendtonextworkspace, parseIntCmd);
REGISTER_COMMAND_PARSER(sendtoprevworkspace, parseIntCmd);
REGISTER_COMMAND_PARSER(taketonextworkspace, parseIntCmd);
REGISTER_COMMAND_PARSER(taketoprevworkspace, parseIntCmd);
REGISTER_COMMAND_PARSER(sendtoworkspace, parseIntCmd);
REGISTER_COMMAND_PARSER(taketoworkspace, parseIntCmd);
}; // end anonymous namespace
void SetHeadCmd::real_execute() {
fbwindow().setOnHead(m_head);
}
@ -127,6 +254,8 @@ void GoToTabCmd::real_execute() {
(*it)->focus();
}
REGISTER_COMMAND(startmoving, StartMovingCmd);
void StartMovingCmd::real_execute() {
const XEvent &last = Fluxbox::instance()->lastEvent();
if (last.type == ButtonPress) {
@ -135,6 +264,41 @@ void StartMovingCmd::real_execute() {
}
}
FbTk::Command *StartResizingCmd::parse(const string &cmd, const string &args,
bool trusted) {
FluxboxWindow::ResizeModel mode = FluxboxWindow::DEFAULTRESIZE;
std::vector<string> tokens;
FbTk::StringUtil::stringtok<std::vector<string> >(tokens, args);
if (!tokens.empty()) {
string arg = FbTk::StringUtil::toLower(tokens[0]);
if (arg == "nearestcorner")
mode = FluxboxWindow::QUADRANTRESIZE;
else if (arg == "nearestedge")
mode = FluxboxWindow::NEARESTEDGERESIZE;
else if (arg == "center")
mode = FluxboxWindow::CENTERRESIZE;
else if (arg == "topleft")
mode = FluxboxWindow::TOPLEFTRESIZE;
else if (arg == "top")
mode = FluxboxWindow::TOPRESIZE;
else if (arg == "topright")
mode = FluxboxWindow::TOPRIGHTRESIZE;
else if (arg == "left")
mode = FluxboxWindow::LEFTRESIZE;
else if (arg == "right")
mode = FluxboxWindow::RIGHTRESIZE;
else if (arg == "bottomleft")
mode = FluxboxWindow::BOTTOMLEFTRESIZE;
else if (arg == "bottom")
mode = FluxboxWindow::BOTTOMRESIZE;
else if (arg == "bottomright")
mode = FluxboxWindow::BOTTOMRIGHTRESIZE;
}
return new StartResizingCmd(mode);
}
REGISTER_COMMAND_PARSER(startresizing, StartResizingCmd::parse);
void StartResizingCmd::real_execute() {
const XEvent &last = Fluxbox::instance()->lastEvent();
if (last.type == ButtonPress) {
@ -147,6 +311,33 @@ void StartResizingCmd::real_execute() {
}
}
FbTk::Command *MoveCmd::parse(const string &command, const string &args,
bool trusted) {
FbTk_istringstream is(args.c_str());
int dx = 0, dy = 0;
is >> dx >> dy;
if (command == "moveright")
dy = 0;
else if (command == "moveleft") {
dy = 0;
dx = -dx;
} else if (command == "movedown") {
dy = dx;
dx = 0;
} else if (command == "moveup") {
dy = -dx;
dx = 0;
}
return new MoveCmd(dx, dy);
}
REGISTER_COMMAND_PARSER(move, MoveCmd::parse);
REGISTER_COMMAND_PARSER(moveright, MoveCmd::parse);
REGISTER_COMMAND_PARSER(moveleft, MoveCmd::parse);
REGISTER_COMMAND_PARSER(moveup, MoveCmd::parse);
REGISTER_COMMAND_PARSER(movedown, MoveCmd::parse);
MoveCmd::MoveCmd(const int step_size_x, const int step_size_y) :
m_step_size_x(step_size_x), m_step_size_y(step_size_y) { }
@ -156,6 +347,28 @@ void MoveCmd::real_execute() {
fbwindow().y() + m_step_size_y);
}
FbTk::Command *ResizeCmd::parse(const string &command, const string &args,
bool trusted) {
FbTk_istringstream is(args.c_str());
int dx = 0, dy = 0;
is >> dx >> dy;
if (command == "resizehorizontal")
dy = 0;
else if (command == "resizevertical") {
dy = dx;
dx = 0;
}
if (command == "resizeto")
return new ResizeToCmd(dx, dy);
return new ResizeCmd(dx, dy);
}
REGISTER_COMMAND_PARSER(resize, ResizeCmd::parse);
REGISTER_COMMAND_PARSER(resizeto, ResizeCmd::parse);
REGISTER_COMMAND_PARSER(resizehorizontal, ResizeCmd::parse);
REGISTER_COMMAND_PARSER(resizevertical, ResizeCmd::parse);
ResizeCmd::ResizeCmd(const int step_size_x, const int step_size_y) :
m_step_size_x(step_size_x), m_step_size_y(step_size_y) { }
@ -170,6 +383,53 @@ void ResizeCmd::real_execute() {
fbwindow().resize(w, h);
}
FbTk::Command *MoveToCmd::parse(const string &cmd, const string &args,
bool trusted) {
typedef std::vector<string> StringTokens;
StringTokens tokens;
FbTk::StringUtil::stringtok<StringTokens>(tokens, args);
if (tokens.size() < 2)
return 0;
unsigned int refc = MoveToCmd::UPPER|MoveToCmd::LEFT;
int dx = 0, dy = 0;
if (tokens[0][0] == '*')
refc |= MoveToCmd::IGNORE_X;
else
dx = atoi(tokens[0].c_str());
if (tokens[1][0] == '*' && ! (refc & MoveToCmd::IGNORE_X))
refc |= MoveToCmd::IGNORE_Y;
else
dy = atoi(tokens[1].c_str());
if (tokens.size() >= 3) {
tokens[2] = FbTk::StringUtil::toLower(tokens[2]);
if (tokens[2] == "left" || tokens[2] == "upperleft" || tokens[2] == "lowerleft") {
refc |= MoveToCmd::LEFT;
refc &= ~MoveToCmd::RIGHT;
} else if (tokens[2] == "right" || tokens[2] == "upperright" || tokens[2] == "lowerright") {
refc |= MoveToCmd::RIGHT;
refc &= ~MoveToCmd::LEFT;
}
if (tokens[2] == "upper" || tokens[2] == "upperleft" || tokens[2] == "upperright") {
refc |= MoveToCmd::UPPER;
refc &= ~MoveToCmd::LOWER;
} else if (tokens[2] == "lower" || tokens[2] == "lowerleft" || tokens[2] == "lowerright") {
refc |= MoveToCmd::LOWER;
refc &= ~MoveToCmd::UPPER;
}
}
return new MoveToCmd(dx, dy, refc);
}
REGISTER_COMMAND_PARSER(moveto, MoveToCmd::parse);
MoveToCmd::MoveToCmd(const int step_size_x, const int step_size_y, const unsigned int refc) :
m_step_size_x(step_size_x), m_step_size_y(step_size_y), m_refc(refc) { }
@ -205,11 +465,40 @@ void ResizeToCmd::real_execute() {
fbwindow().resize(m_step_size_x, m_step_size_y);
}
REGISTER_COMMAND(fullscreen, FullscreenCmd);
FullscreenCmd::FullscreenCmd() { }
void FullscreenCmd::real_execute() {
fbwindow().setFullscreen(!fbwindow().isFullscreen());
}
FbTk::Command *SetAlphaCmd::parse(const string &command, const string &args,
bool trusted) {
typedef std::vector<string> StringTokens;
StringTokens tokens;
FbTk::StringUtil::stringtok<StringTokens>(tokens, args);
int focused, unfocused;
bool relative, un_rel;
if (tokens.empty()) { // set default alpha
focused = unfocused = 256;
relative = un_rel = false;
} else {
relative = un_rel = (tokens[0][0] == '+' || tokens[0][0] == '-');
focused = unfocused = atoi(tokens[0].c_str());
}
if (tokens.size() > 1) { // set different unfocused alpha
un_rel = (tokens[1][0] == '+' || tokens[1][0] == '-');
unfocused = atoi(tokens[1].c_str());
}
return new SetAlphaCmd(focused, relative, unfocused, un_rel);
}
REGISTER_COMMAND_PARSER(setalpha, SetAlphaCmd::parse);
SetAlphaCmd::SetAlphaCmd(int focused, bool relative,
int unfocused, bool un_relative) :
m_focus(focused), m_unfocus(unfocused),
@ -240,6 +529,8 @@ void SetAlphaCmd::real_execute() {
fbwindow().setUnfocusedAlpha(m_unfocus);
}
REGISTER_BOOLCOMMAND_WITH_ARGS(matches, MatchCmd);
bool MatchCmd::real_execute() {
return m_pat.match(winclient());
}

View file

@ -151,6 +151,8 @@ protected:
class StartResizingCmd: public WindowHelperCmd {
public:
explicit StartResizingCmd(FluxboxWindow::ResizeModel mode):m_mode(mode) { }
static FbTk::Command *parse(const std::string &command,
const std::string &args, bool trusted);
protected:
void real_execute();
private:
@ -161,6 +163,8 @@ private:
class MoveCmd: public WindowHelperCmd {
public:
explicit MoveCmd(const int step_size_x, const int step_size_y);
static FbTk::Command *parse(const std::string &command,
const std::string &args, bool trusted);
protected:
void real_execute();
@ -173,6 +177,8 @@ private:
class ResizeCmd: public WindowHelperCmd{
public:
explicit ResizeCmd(int step_size_x, int step_size_y);
static FbTk::Command *parse(const std::string &command,
const std::string &args, bool trusted);
protected:
void real_execute();
@ -194,6 +200,8 @@ public:
IGNORE_Y = 1 << 9
};
explicit MoveToCmd(const int step_size_x, const int step_size_y, const unsigned int refc);
static FbTk::Command *parse(const std::string &command,
const std::string &args, bool trusted);
protected:
void real_execute();
@ -224,6 +232,8 @@ protected:
class SetAlphaCmd: public WindowHelperCmd {
public:
SetAlphaCmd(int focus, bool rel, int unfocus, bool unrel);
static FbTk::Command *parse(const std::string &command,
const std::string &args, bool trusted);
protected:
void real_execute();
private:

View file

@ -1,833 +0,0 @@
// FbCommandFactory.cc for Fluxbox Window manager
// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
// and Simon Bowden (rathnor at users.sourceforge.net)
//
// 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 "FbCommandFactory.hh"
#include "FocusableList.hh"
#include "CurrentWindowCmd.hh"
#include "FbCommands.hh"
#include "Window.hh"
#include "WorkspaceCmd.hh"
#include "fluxbox.hh"
#include "SimpleCommand.hh"
#include "Screen.hh"
#include "FbTk/StringUtil.hh"
#include "FbTk/LogicCommands.hh"
#include "FbTk/MacroCommand.hh"
#include "FbTk/stringstream.hh"
#include <string>
#ifdef HAVE_CSTDIO
#include <cstdio>
#else
#include <stdio.h>
#endif
using std::string;
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;
namespace {
static int getint(const char *str, int defaultvalue) {
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() {
// setup commands that we can handle
const char* commands[] = {
"activate",
"addworkspace",
"arrangewindows",
"attach",
"bindkey",
"clientmenu",
"close",
"closeallwindows",
"commanddialog",
"cond",
"custommenu",
"deiconify",
"detachclient",
"export",
"exec",
"execcommand",
"execute",
"exit",
"focus",
"focusup",
"focusdown",
"focusleft",
"focusright",
"fullscreen",
"gotowindow",
"hidemenus",
"iconify",
"if",
"keymode",
"kill",
"killwindow",
"leftworkspace",
"lower",
"lowerlayer",
"macrocmd",
"maximize",
"maximizehorizontal",
"maximizevertical",
"maximizewindow",
"minimize",
"minimizewindow",
"moveto",
"move",
"movedown",
"moveleft",
"moveright",
"movetableft",
"movetabright",
"moveup",
"nextgroup",
"nexttab",
"nextwindow",
"nextworkspace",
"prevgroup",
"prevtab",
"prevwindow",
"prevworkspace",
"quit",
"raise",
"raiselayer",
"reconfig",
"reconfigure",
"reloadstyle",
"removelastworkspace",
"resizeto",
"resize",
"resizehorizontal",
"resizevertical",
"restart",
"rightworkspace",
"rootmenu",
"saverc",
"sendtoworkspace",
"sendtonextworkspace",
"sendtoprevworkspace",
"setalpha",
"setenv",
"sethead",
"setstyle",
"setworkspacename",
"setworkspacenamedialog",
"setresourcevalue",
"setresourcevaluedialog",
"shade",
"shadeon",
"shadeoff",
"shadewindow",
"showdesktop",
"startmoving",
"startresizing",
"stick",
"stickwindow",
"tab",
"taketoworkspace",
"taketonextworkspace",
"taketoprevworkspace",
"togglecmd",
"toggledecor",
"windowmenu",
"workspace",
/* NOTE: The following are DEPRECATED and subject to removal */
"workspace1",
"workspace2",
"workspace3",
"workspace4",
"workspace5",
"workspace6",
"workspace7",
"workspace8",
"workspace9",
"workspace10",
"workspace11",
"workspace12",
/* end note */
"workspacemenu",
0
};
for (int i=0; commands[i]; ++i)
addCommand(commands[i]);
}
FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
const std::string &arguments, bool trusted) {
using namespace FbCommands;
//
// WM commands
//
if (command == "restart" && trusted)
return new RestartFluxboxCmd(arguments);
else if (command == "reconfigure" || command == "reconfig")
return new ReconfigureFluxboxCmd();
else if (command == "setstyle")
return new SetStyleCmd(arguments);
else if (command == "reloadstyle")
return new ReloadStyleCmd();
else if (command == "keymode")
return new KeyModeCmd(arguments);
else if (command == "saverc")
return new SaveResources();
else if (command == "execcommand" || command == "execute" || command == "exec") {
if (!trusted) return 0;
return new ExecuteCmd(arguments); // execute command on key screen
} else if (command == "exit" || command == "quit")
return new ExitFluxboxCmd();
else if ((command == "setenv" || command == "export") && trusted) {
string name = arguments;
FbTk::StringUtil::removeFirstWhitespace(name);
FbTk::StringUtil::removeTrailingWhitespace(name);
size_t pos = name.find_first_of(command == "setenv" ? " \t" : "=");
if (pos == string::npos || pos == name.size())
return 0;
string value = name.substr(pos + 1);
name = name.substr(0, pos);
return new ExportCmd(name, value);
} else if (command == "commanddialog") // run specified fluxbox command
return new CommandDialogCmd();
else if (command == "bindkey" && trusted)
return new BindKeyCmd(arguments);
else if (command == "setresourcevalue" && trusted) {
// we need to parse arguments as:
// <remove whitespace here><resname><one whitespace><value>
string name = arguments;
FbTk::StringUtil::removeFirstWhitespace(name);
size_t pos = name.find_first_of(" \t");
// we need an argument to resource name
if (pos == std::string::npos || pos == name.size())
return 0;
// +1 so we only remove the first whitespace
// i.e so users can set space before workspace name and so on
string value = name.substr(pos + 1);
name = name.substr(0, pos);
return new SetResourceValueCmd(name, value);
} else if (command == "setresourcevaluedialog")
return new SetResourceValueDialogCmd();
else if (command == "addworkspace")
return new AddWorkspaceCmd();
else if (command == "removelastworkspace")
return new RemoveLastWorkspaceCmd();
//
// Current focused window commands
//
else if (command == "fullscreen")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new FullscreenCmd()), arguments);
else if (command == "minimizewindow" || command == "minimize" || command == "iconify")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::iconify)), arguments);
else if (command == "maximizewindow" || command == "maximize")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::maximizeFull)), arguments);
else if (command == "maximizevertical")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::maximizeVertical)), arguments);
else if (command == "maximizehorizontal")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::maximizeHorizontal)), arguments);
else if (command == "setalpha") {
typedef vector<string> StringTokens;
StringTokens tokens;
FbTk::StringUtil::stringtok<StringTokens>(tokens, arguments);
int focused, unfocused;
bool relative, un_rel;
if (tokens.empty()) { // set default alpha
focused = unfocused = 256;
relative = un_rel = false;
} else {
relative = un_rel = (tokens[0][0] == '+' || tokens[0][0] == '-');
focused = unfocused = atoi(tokens[0].c_str());
}
if (tokens.size() > 1) { // set different unfocused alpha
un_rel = (tokens[1][0] == '+' || tokens[1][0] == '-');
unfocused = atoi(tokens[1].c_str());
}
string pat;
string::size_type pos = arguments.find('(');
if (pos != string::npos && pos != arguments.size())
pat = arguments.c_str() + pos;
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") {
FluxboxWindow::ResizeModel mode = FluxboxWindow::DEFAULTRESIZE;
vector<string> tokens;
FbTk::StringUtil::stringtok<vector<string> >(tokens, arguments);
if (!tokens.empty()) {
string arg = FbTk::StringUtil::toLower(tokens[0]);
if (arg == "nearestcorner")
mode = FluxboxWindow::QUADRANTRESIZE;
else if (arg == "nearestedge")
mode = FluxboxWindow::NEARESTEDGERESIZE;
else if (arg == "center")
mode = FluxboxWindow::CENTERRESIZE;
else if (arg == "topleft")
mode = FluxboxWindow::TOPLEFTRESIZE;
else if (arg == "top")
mode = FluxboxWindow::TOPRESIZE;
else if (arg == "topright")
mode = FluxboxWindow::TOPRIGHTRESIZE;
else if (arg == "left")
mode = FluxboxWindow::LEFTRESIZE;
else if (arg == "right")
mode = FluxboxWindow::RIGHTRESIZE;
else if (arg == "bottomleft")
mode = FluxboxWindow::BOTTOMLEFTRESIZE;
else if (arg == "bottom")
mode = FluxboxWindow::BOTTOMRESIZE;
else if (arg == "bottomright")
mode = FluxboxWindow::BOTTOMRIGHTRESIZE;
}
return new StartResizingCmd(mode);
} else if (command == "resize" || command == "resizeto" ||
command == "resizehorizontal" || command == "resizevertical") {
FbTk_istringstream is(arguments.c_str());
int dx = 0, dy = 0;
is >> dx >> dy;
if (command == "resizehorizontal")
dy = 0;
else if (command == "resizevertical") {
dy = dx;
dx = 0;
}
string pat;
string::size_type pos = arguments.find('(');
if (pos != string::npos && pos != arguments.size())
pat = arguments.c_str() + pos;
FbTk::RefCount<FbTk::Command> cmd;
if (command == "resizeto")
cmd = new ResizeToCmd(dx, dy);
else
cmd = new ResizeCmd(dx, dy);
return new WindowListCmd(cmd, pat);
} else if (command == "moveto") {
typedef vector<string> StringTokens;
StringTokens tokens;
FbTk::StringUtil::stringtok<StringTokens>(tokens, arguments);
if (tokens.size() < 2) {
cerr<<"*** WARNING: missing arguments for MoveTo\n";
return NULL;
}
unsigned int refc = MoveToCmd::UPPER|MoveToCmd::LEFT;
int dx = 0;
int dy = 0;
if (tokens[0][0] == '*')
refc |= MoveToCmd::IGNORE_X;
else
dx = atoi(tokens[0].c_str());
if (tokens[1][0] == '*' && ! (refc & MoveToCmd::IGNORE_X))
refc |= MoveToCmd::IGNORE_Y;
else
dy = atoi(tokens[1].c_str());
if (tokens.size() >= 3) {
tokens[2] = FbTk::StringUtil::toLower(tokens[2]);
if (tokens[2] == "left" || tokens[2] == "upperleft" || tokens[2] == "lowerleft") {
refc |= MoveToCmd::LEFT;
refc &= ~MoveToCmd::RIGHT;
} else if (tokens[2] == "right" || tokens[2] == "upperright" || tokens[2] == "lowerright") {
refc |= MoveToCmd::RIGHT;
refc &= ~MoveToCmd::LEFT;
}
if (tokens[2] == "upper" || tokens[2] == "upperleft" || tokens[2] == "upperright") {
refc |= MoveToCmd::UPPER;
refc &= ~MoveToCmd::LOWER;
} else if (tokens[2] == "lower" || tokens[2] == "lowerleft" || tokens[2] == "lowerright") {
refc |= MoveToCmd::LOWER;
refc &= ~MoveToCmd::UPPER;
}
}
string pat;
string::size_type pos = arguments.find('(');
if (pos != string::npos && pos != arguments.size())
pat = arguments.c_str() + pos;
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") {
FbTk_istringstream is(arguments.c_str());
int dx = 0, dy = 0;
is >> dx >> dy;
if (command == "moveright")
dy = 0;
else if (command == "moveleft") {
dy = 0;
dx = -dx;
} else if (command == "movedown") {
dy = dx;
dx = 0;
} else if (command == "moveup") {
dy = -dx;
dx = 0;
}
string pat;
string::size_type pos = arguments.find('(');
if (pos != string::npos && pos != arguments.size())
pat = arguments.c_str() + pos;
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new MoveCmd(dx, dy)), pat);
} else if (command == "raise")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::raise)), arguments);
else if (command == "raiselayer")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::raiseLayer)), arguments);
else if (command == "lower")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::lower)), arguments);
else if (command == "lowerlayer")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::lowerLayer)), arguments);
else if (command == "activate" || command == "focus")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd((void (FluxboxWindow::*)())&FluxboxWindow::focus)), arguments);
else if (command == "close")
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<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::kill)), arguments);
else if (command == "shade" || command == "shadewindow")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::shade)), arguments);
else if (command == "shadeon" )
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::shadeOn)), arguments);
else if (command == "shadeoff" )
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::shadeOff)), arguments);
else if (command == "stick" || command == "stickwindow")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::stick)), arguments);
else if (command == "toggledecor")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::toggleDecoration)), arguments);
else if (command == "sethead") {
int num = 0;
string pat;
FbTk_istringstream iss(arguments.c_str());
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<FbTk::Command>(new SetHeadCmd(num)), pat);
} else if (command == "tab" || command == "sendtonextworkspace" ||
command == "sendtoprevworkspace" ||
command == "taketonextworkspace" ||
command == "taketoprevworkspace" ||
command == "sendtoworkspace" || command == "taketoworkspace") {
// workspaces appear 1-indexed to the user, hence the minus 1
int num = 1;
string pat;
FbTk_istringstream iss(arguments.c_str());
iss >> num;
string::size_type pos = arguments.find('(');
if (pos != string::npos && pos != arguments.size())
pat = arguments.c_str() + pos;
FbTk::RefCount<FbTk::Command> cmd;
if (command == "tab")
cmd = new GoToTabCmd(num);
else if (command == "sendtonextworkspace")
cmd = new SendToNextWorkspaceCmd(num);
else if (command == "sendtoprevworkspace")
cmd = new SendToPrevWorkspaceCmd(num);
else if (command == "taketonextworkspace")
cmd = new TakeToNextWorkspaceCmd(num);
else if (command == "taketoprevworkspace")
cmd = new TakeToPrevWorkspaceCmd(num);
else if (command == "sendtoworkspace")
cmd = new SendToWorkspaceCmd(num-1);
else
cmd = new TakeToWorkspaceCmd(num-1);
return new WindowListCmd(cmd, pat);
} else if (command == "nexttab")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::nextClient)), arguments);
else if (command == "prevtab")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::prevClient)), arguments);
else if (command == "movetableft")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::moveClientLeft)), arguments);
else if (command == "movetabright")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::moveClientRight)), arguments);
else if (command == "detachclient")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::detachCurrentClient)), arguments);
else if (command == "windowmenu")
return new CurrentWindowCmd(&FluxboxWindow::popupMenu);
//
// Workspace commands
//
else if (command == "nextworkspace")
return new NextWorkspaceCmd(getint(arguments.c_str(), 1));
else if (command == "prevworkspace")
return new PrevWorkspaceCmd(getint(arguments.c_str(), 1));
else if (command == "rightworkspace")
return new RightWorkspaceCmd(getint(arguments.c_str(), 1));
else if (command == "leftworkspace")
return new LeftWorkspaceCmd(getint(arguments.c_str(), 1));
else if (command == "workspace")
// workspaces appear 1-indexed to the user, hence the minus 1
return new JumpToWorkspaceCmd(getint(arguments.c_str(), 1) - 1);
else if (command.substr(0, 9) == "workspace" && command[9] >= '0' && command[9] <= '9') {
cerr<<"*** WARNING: 'Workspace<n>' actions are deprecated! Use 'Workspace <n>' instead"<<endl;
return new JumpToWorkspaceCmd(getint(command.substr(9).c_str(), 1) - 1);
} else if (command == "attach") {
int opts; // not used
string pat;
FocusableList::parseArgs(arguments, opts, pat);
return new AttachCmd(pat);
} else if (command == "nextwindow") {
int opts;
string pat;
FocusableList::parseArgs(arguments, opts, pat);
return new NextWindowCmd(opts, pat);
} else if (command == "nextgroup") {
int opts;
string pat;
FocusableList::parseArgs(arguments, opts, pat);
opts |= FocusableList::LIST_GROUPS;
return new NextWindowCmd(opts, pat);
} else if (command == "prevwindow") {
int opts;
string pat;
FocusableList::parseArgs(arguments, opts, pat);
return new PrevWindowCmd(opts, pat);
} else if (command == "prevgroup") {
int opts;
string pat;
FocusableList::parseArgs(arguments, opts, pat);
opts |= FocusableList::LIST_GROUPS;
return new PrevWindowCmd(opts, pat);
} else if (command == "gotowindow") {
int num, opts;
string args, pat;
FbTk_istringstream iss(arguments.c_str());
iss >> num;
string::size_type pos = arguments.find_first_of("({");
if (pos != string::npos && pos != arguments.size())
args = arguments.c_str() + pos;
FocusableList::parseArgs(args, opts, pat);
return new GoToWindowCmd(num, opts, pat);
} else if (command == "clientmenu") {
int opts;
string pat;
FocusableList::parseArgs(arguments, opts, pat);
return new ShowClientMenuCmd(opts, pat);
} else if (command == "focusup")
return new DirFocusCmd(FocusControl::FOCUSUP);
else if (command == "focusdown")
return new DirFocusCmd(FocusControl::FOCUSDOWN);
else if (command == "focusleft")
return new DirFocusCmd(FocusControl::FOCUSLEFT);
else if (command == "focusright")
return new DirFocusCmd(FocusControl::FOCUSRIGHT);
else if (command == "arrangewindows")
return new ArrangeWindowsCmd();
else if (command == "showdesktop")
return new ShowDesktopCmd();
else if (command == "hidemenus")
return new HideMenuCmd();
else if (command == "rootmenu")
return new ShowRootMenuCmd();
else if (command == "custommenu")
return new ShowCustomMenuCmd(arguments.c_str());
else if (command == "workspacemenu")
return new ShowWorkspaceMenuCmd();
else if (command == "setworkspacename") {
if (arguments.empty())
return new SetWorkspaceNameCmd("empty");
else
return new SetWorkspaceNameCmd(arguments);
}
else if (command == "setworkspacenamedialog")
return new WorkspaceNameDialogCmd();
//
// special commands
//
else if (command == "deiconify") {
FbTk_istringstream iss(arguments.c_str());
string mode;
string d;
DeiconifyCmd::Destination dest;
iss >> mode;
if (iss.fail())
mode="lastworkspace";
mode= FbTk::StringUtil::toLower(mode);
iss >> d;
if (iss.fail())
d="current";
d= FbTk::StringUtil::toLower(d);
if (d == "origin" )
dest= DeiconifyCmd::ORIGIN;
else if (d == "originquiet")
dest= DeiconifyCmd::ORIGINQUIET;
else
dest= DeiconifyCmd::CURRENT;
if ( mode == "all" )
return new DeiconifyCmd(DeiconifyCmd::ALL, dest);
else if ( mode == "allworkspace" )
return new DeiconifyCmd(DeiconifyCmd::ALLWORKSPACE, dest);
else if ( mode == "last" )
return new DeiconifyCmd(DeiconifyCmd::LAST, dest);
else // lastworkspace, default
return new DeiconifyCmd(DeiconifyCmd::LASTWORKSPACE, dest);
} else if (command == "macrocmd") {
string cmd;
int err= 0;
int parse_pos= 0;
FbTk::MacroCommand* macro= new FbTk::MacroCommand();
while (true) {
parse_pos+= err;
err= FbTk::StringUtil::getStringBetween(cmd, arguments.c_str() +
parse_pos,
'{', '}', " \t\n", true);
if ( err > 0 ) {
string c, a;
string::size_type first_pos =
FbTk::StringUtil::removeFirstWhitespace(cmd);
string::size_type second_pos =
cmd.find_first_of(" \t", first_pos);
if (second_pos != string::npos) {
a= cmd.substr(second_pos);
FbTk::StringUtil::removeFirstWhitespace(a);
cmd.erase(second_pos);
}
c= FbTk::StringUtil::toLower(cmd);
FbTk::Command* fbcmd= stringToCommand(c,a,trusted);
if (fbcmd) {
FbTk::RefCount<FbTk::Command> rfbcmd(fbcmd);
macro->add(rfbcmd);
}
} else
break;
}
if ( macro->size() > 0 )
return macro;
delete macro;
} else if (command == "togglecmd") {
string cmd;
int err= 0;
int parse_pos= 0;
FbTk::ToggleCommand* macro= new FbTk::ToggleCommand();
while (true) {
parse_pos+= err;
err= FbTk::StringUtil::getStringBetween(cmd, arguments.c_str() +
parse_pos,
'{', '}', " \t\n", true);
if ( err > 0 ) {
string c, a;
string::size_type first_pos =
FbTk::StringUtil::removeFirstWhitespace(cmd);
string::size_type second_pos=
cmd.find_first_of(" \t", first_pos);
if (second_pos != string::npos) {
a= cmd.substr(second_pos);
FbTk::StringUtil::removeFirstWhitespace(a);
cmd.erase(second_pos);
}
c= FbTk::StringUtil::toLower(cmd);
FbTk::Command* fbcmd= stringToCommand(c,a,trusted);
if (fbcmd) {
FbTk::RefCount<FbTk::Command> rfbcmd(fbcmd);
macro->add(rfbcmd);
}
} else
break;
}
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)
return 0;
t = CommandParser::instance().parseLine(cmd, trusted);
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 || *t == 0 && *f == 0)
return 0;
return new FbTk::IfCommand(cond, t, f);
}
return 0;
}

View file

@ -1,35 +0,0 @@
// FbCommandFactory.hh for Fluxbox Window manager
// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
// and Simon Bowden (rathnor at users.sourceforge.net)
//
// 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 "CommandParser.hh"
class FbCommandFactory: public CommandFactory {
public:
FbTk::Command *stringToCommand(const std::string &command,
const std::string &arguments, bool trusted);
private:
FbCommandFactory();
static FbCommandFactory s_autoreg; ///< autoregister variable
};

View file

@ -33,6 +33,9 @@
#include "FbTk/Theme.hh"
#include "FbTk/Menu.hh"
#include "FbTk/CommandRegistry.hh"
#include "FbTk/StringUtil.hh"
#include "FbTk/stringstream.hh"
#include <sys/types.h>
#include <unistd.h>
@ -120,6 +123,10 @@ void showMenu(const BScreen &screen, FbTk::Menu &menu) {
namespace FbCommands {
REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(exec, FbCommands::ExecuteCmd);
REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(execute, FbCommands::ExecuteCmd);
REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(execcommand, FbCommands::ExecuteCmd);
ExecuteCmd::ExecuteCmd(const string &cmd, int screen_num):m_cmd(cmd), m_screen_num(screen_num) {
}
@ -169,6 +176,27 @@ int ExecuteCmd::run() {
return pid; // compiler happy -> we are happy ;)
}
FbTk::Command *ExportCmd::parse(const string &command, const string &args,
bool trusted) {
string name = args;
FbTk::StringUtil::removeFirstWhitespace(name);
if (command != "setresourcevalue")
FbTk::StringUtil::removeTrailingWhitespace(name);
size_t pos = name.find_first_of(command == "export" ? "=" : " \t");
if (pos == string::npos || pos == name.size() || !trusted)
return 0;
string value = name.substr(pos + 1);
name = name.substr(0, pos);
if (command == "setresourcevalue")
return new SetResourceValueCmd(name, value);
return new ExportCmd(name, value);
}
REGISTER_COMMAND_PARSER(setenv, ExportCmd::parse);
REGISTER_COMMAND_PARSER(export, ExportCmd::parse);
REGISTER_COMMAND_PARSER(setresourcevalue, ExportCmd::parse);
ExportCmd::ExportCmd(const string& name, const string& value) :
m_name(name), m_value(value) {
}
@ -205,15 +233,21 @@ void ExportCmd::execute() {
}
}
REGISTER_COMMAND(exit, FbCommands::ExitFluxboxCmd);
REGISTER_COMMAND(quit, FbCommands::ExitFluxboxCmd);
void ExitFluxboxCmd::execute() {
Fluxbox::instance()->shutdown();
}
REGISTER_COMMAND(saverc, FbCommands::SaveResources);
void SaveResources::execute() {
Fluxbox::instance()->save_rc();
}
REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(restart, FbCommands::RestartFluxboxCmd);
RestartFluxboxCmd::RestartFluxboxCmd(const string &cmd):m_cmd(cmd){
}
@ -224,16 +258,22 @@ void RestartFluxboxCmd::execute() {
Fluxbox::instance()->restart(m_cmd.c_str());
}
REGISTER_COMMAND(reconfigure, FbCommands::ReconfigureFluxboxCmd);
REGISTER_COMMAND(reconfig, FbCommands::ReconfigureFluxboxCmd);
void ReconfigureFluxboxCmd::execute() {
Fluxbox::instance()->reconfigure();
}
REGISTER_COMMAND(reloadstyle, FbCommands::ReloadStyleCmd);
void ReloadStyleCmd::execute() {
SetStyleCmd cmd(Fluxbox::instance()->getStyleFilename());
cmd.execute();
}
REGISTER_COMMAND_WITH_ARGS(setstyle, FbCommands::SetStyleCmd);
SetStyleCmd::SetStyleCmd(const string &filename):m_filename(filename) {
}
@ -245,6 +285,8 @@ void SetStyleCmd::execute() {
Fluxbox::instance()->getStyleOverlayFilename());
}
REGISTER_COMMAND_WITH_ARGS(keymode, FbCommands::KeyModeCmd);
KeyModeCmd::KeyModeCmd(const string &arguments):m_keymode(arguments),m_end_args("None Escape") {
string::size_type second_pos = m_keymode.find_first_of(" \t", 0);
if (second_pos != string::npos) {
@ -260,10 +302,22 @@ void KeyModeCmd::execute() {
Fluxbox::instance()->keys()->keyMode(m_keymode);
}
REGISTER_COMMAND(hidemenus, FbCommands::HideMenuCmd);
void HideMenuCmd::execute() {
FbTk::Menu::hideShownMenu();
}
FbTk::Command *ShowClientMenuCmd::parse(const string &command,
const string &args, bool trusted) {
int opts;
string pat;
FocusableList::parseArgs(args, opts, pat);
return new ShowClientMenuCmd(opts, pat);
}
REGISTER_COMMAND_PARSER(clientmenu, ShowClientMenuCmd::parse);
void ShowClientMenuCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen == 0)
@ -285,6 +339,8 @@ void ShowClientMenuCmd::execute() {
::showMenu(*screen, **m_menu);
}
REGISTER_COMMAND_WITH_ARGS(custommenu, FbCommands::ShowCustomMenuCmd);
ShowCustomMenuCmd::ShowCustomMenuCmd(const string &arguments) : custom_menu_file(arguments) {}
void ShowCustomMenuCmd::execute() {
@ -298,6 +354,8 @@ void ShowCustomMenuCmd::execute() {
::showMenu(*screen, **m_menu);
}
REGISTER_COMMAND(rootmenu, FbCommands::ShowRootMenuCmd);
void ShowRootMenuCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen == 0)
@ -306,6 +364,8 @@ void ShowRootMenuCmd::execute() {
::showMenu(*screen, screen->rootMenu());
}
REGISTER_COMMAND(workspacemenu, FbCommands::ShowWorkspaceMenuCmd);
void ShowWorkspaceMenuCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen == 0)
@ -314,10 +374,13 @@ void ShowWorkspaceMenuCmd::execute() {
::showMenu(*screen, screen->workspaceMenu());
}
REGISTER_COMMAND_WITH_ARGS(setworkspacename, FbCommands::SetWorkspaceNameCmd);
SetWorkspaceNameCmd::SetWorkspaceNameCmd(const string &name, int spaceid):
m_name(name), m_workspace(spaceid) { }
m_name(name), m_workspace(spaceid) {
if (name.empty())
m_name = "empty";
}
void SetWorkspaceNameCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
@ -340,6 +403,8 @@ void SetWorkspaceNameCmd::execute() {
Fluxbox::instance()->save_rc();
}
REGISTER_COMMAND(setworkspacenamedialog, FbCommands::WorkspaceNameDialogCmd);
void WorkspaceNameDialogCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
@ -351,6 +416,8 @@ void WorkspaceNameDialogCmd::execute() {
win->show();
}
REGISTER_COMMAND(commanddialog, FbCommands::CommandDialogCmd);
void CommandDialogCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen == 0)
@ -376,6 +443,8 @@ void SetResourceValueCmd::execute() {
Fluxbox::instance()->save_rc();
}
REGISTER_COMMAND(setresourcevaluedialog, FbCommands::SetResourceValueDialogCmd);
void SetResourceValueDialogCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen == 0)
@ -385,6 +454,8 @@ void SetResourceValueDialogCmd::execute() {
win->show();
};
REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(bindkey, FbCommands::BindKeyCmd);
BindKeyCmd::BindKeyCmd(const string &keybind):m_keybind(keybind) { }
void BindKeyCmd::execute() {
@ -398,6 +469,41 @@ void BindKeyCmd::execute() {
}
}
FbTk::Command *DeiconifyCmd::parse(const string &command, const string &args,
bool trusted) {
FbTk_istringstream iss(args.c_str());
string mode;
string d;
Destination dest;
iss >> mode;
if (iss.fail())
mode="lastworkspace";
mode= FbTk::StringUtil::toLower(mode);
iss >> d;
if (iss.fail())
d="current";
d = FbTk::StringUtil::toLower(d);
if (d == "origin" )
dest = ORIGIN;
else if (d == "originquiet")
dest = ORIGINQUIET;
else
dest = CURRENT;
if (mode == "all")
return new DeiconifyCmd(DeiconifyCmd::ALL, dest);
else if (mode == "allworkspace")
return new DeiconifyCmd(DeiconifyCmd::ALLWORKSPACE, dest);
else if (mode == "last")
return new DeiconifyCmd(DeiconifyCmd::LAST, dest);
// lastworkspace, default
return new DeiconifyCmd(DeiconifyCmd::LASTWORKSPACE, dest);
}
REGISTER_COMMAND_PARSER(deiconify, DeiconifyCmd::parse);
DeiconifyCmd::DeiconifyCmd(Mode mode,
Destination dest) : m_mode(mode), m_dest(dest) { }

View file

@ -57,6 +57,8 @@ class ExportCmd : public FbTk::Command {
public:
ExportCmd(const std::string& name, const std::string& value);
void execute();
static FbTk::Command *parse(const std::string &command,
const std::string &args, bool trusted);
private:
std::string m_name;
std::string m_value;
@ -121,6 +123,8 @@ public:
ShowClientMenuCmd(int option, std::string &pat):
m_option(option|FocusableList::LIST_GROUPS), m_pat(pat.c_str()) { }
void execute();
static FbTk::Command *parse(const std::string &command,
const std::string &args, bool trusted);
private:
const int m_option;
const ClientPattern m_pat;
@ -208,6 +212,8 @@ public:
DeiconifyCmd(Mode mode= LASTWORKSPACE,
Destination dest= CURRENT);
void execute();
static FbTk::Command *parse(const std::string &command,
const std::string &args, bool trusted);
private:
Mode m_mode;
Destination m_dest;

View file

@ -0,0 +1,92 @@
// CommandRegistry.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 "CommandRegistry.hh"
#include "Command.hh"
#include "StringUtil.hh"
#include <iostream>
namespace FbTk {
CommandRegistry &CommandRegistry::instance() {
static CommandRegistry s_instance;
return s_instance;
}
bool CommandRegistry::registerCommand(string name,
CreateFunction createFunction) {
name = StringUtil::toLower(name);
m_commandCreators[name] = createFunction;
return true;
}
bool CommandRegistry::registerBoolCommand(string name,
BoolCreateFunction createFunction) {
name = StringUtil::toLower(name);
m_boolcommandCreators[name] = createFunction;
return true;
}
Command *CommandRegistry::parseLine(const string &line, bool trusted) const {
// parse args and command
string command, args;
StringUtil::getFirstWord(line, command, args);
// now we have parsed command and args
command = StringUtil::toLower(command);
return getCommand(command, args, trusted);
}
BoolCommand *CommandRegistry::parseBoolLine(const string &line, bool trusted) const {
// parse args and command
string command, args;
StringUtil::getFirstWord(line, command, args);
// now we have parsed command and args
command = StringUtil::toLower(command);
return getBoolCommand(command, args, trusted);
}
Command *CommandRegistry::getCommand(const string &name, const string &args,
bool trusted) const {
string lc = StringUtil::toLower(name);
CreatorMap::const_iterator it = m_commandCreators.find(lc.c_str());
if (it == m_commandCreators.end())
return 0;
else
return it->second(name, args, trusted);
}
BoolCommand *CommandRegistry::getBoolCommand(const string &name,
const string &args, bool trusted) const {
string lc = StringUtil::toLower(name);
BoolCreatorMap::const_iterator it = m_boolcommandCreators.find(lc.c_str());
if (it == m_boolcommandCreators.end())
return 0;
else
return it->second(name, args, trusted);
}
}; // end namespace FbTk

130
src/FbTk/CommandRegistry.hh Normal file
View file

@ -0,0 +1,130 @@
// CommandRegistry.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 COMMANDREGISTRY_HH
#define COMMANDREGISTRY_HH
#include <string>
#include <map>
using std::string;
namespace FbTk {
class Command;
class BoolCommand;
#define REGISTER_COMMAND_PARSER(name, parser) \
namespace { \
static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, parser); \
}
#define REGISTER_BOOLCOMMAND_PARSER(name, parser) \
namespace { \
static const bool p_register_##name = FbTk::CommandRegistry::instance().registerBoolCommand(#name, parser); \
}
/* Include some basic command creators */
template <typename Cmd, typename Ret>
Ret *CommandCreator(const string &name, const string &args, bool trusted) {
return new Cmd();
}
#define REGISTER_COMMAND(name, classname) \
namespace { \
static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, FbTk::CommandCreator<classname, FbTk::Command>); \
}
template <typename Cmd, typename Ret>
Ret *CommandCreatorWithArgs(const string &name, const string &args,
bool trusted) {
return new Cmd(args);
}
#define REGISTER_COMMAND_WITH_ARGS(name, classname) \
namespace { \
static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, FbTk::CommandCreatorWithArgs<classname, FbTk::Command>); \
}
#define REGISTER_BOOLCOMMAND_WITH_ARGS(name, classname) \
namespace { \
static const bool p_register_##name = FbTk::CommandRegistry::instance().registerBoolCommand(#name, FbTk::CommandCreatorWithArgs<classname, FbTk::BoolCommand>); \
}
template <typename Cmd, typename Ret>
Ret *UntrustedCommandCreator(const string &name, const string &args,
bool trusted) {
if (!trusted) return 0;
return new Cmd();
}
#define REGISTER_UNTRUSTED_COMMAND(name, classname) \
namespace { \
static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, FbTk::UntrustedCommandCreator<classname, FbTk::Command>); \
}
template <typename Cmd, typename Ret>
Ret * UntrustedCommandCreatorWithArgs(const string &name, const string &args,
bool trusted) {
if (!trusted) return 0;
return new Cmd(args);
}
#define REGISTER_UNTRUSTED_COMMAND_WITH_ARGS(name, classname) \
namespace { \
static const bool p_register_##name = FbTk::CommandRegistry::instance().registerCommand(#name, FbTk::UntrustedCommandCreatorWithArgs<classname, FbTk::Command>); \
}
/* Not built to be virtual at the moment */
class CommandRegistry {
public:
typedef Command * CreateFunction(const string &name, const string &args, bool trusted);
typedef BoolCommand * BoolCreateFunction(const string &name,
const string &args, bool trusted);
typedef std::map<string, CreateFunction *> CreatorMap;
typedef std::map<string, BoolCreateFunction *> BoolCreatorMap;
static CommandRegistry &instance();
Command *parseLine(const string &line, bool trusted = true) const;
BoolCommand *parseBoolLine(const string &line, bool trusted = true) const;
Command *getCommand(const string &name, const string &args, bool trusted) const;
BoolCommand *getBoolCommand(const string &name, const string &args,
bool trusted) const;
/* Note: the ownership of this object passes to this class */
bool registerCommand(string name, CreateFunction createFunction);
bool registerBoolCommand(string name, BoolCreateFunction bcf);
const CreatorMap commandMap() const { return m_commandCreators; }
private:
CommandRegistry() {}
~CommandRegistry() {}
CreatorMap m_commandCreators;
BoolCreatorMap m_boolcommandCreators;
};
}; // end namespace FbTk
#endif // COMMANDREGISTRY_HH

View file

@ -23,8 +23,101 @@
#include "LogicCommands.hh"
#include "CommandRegistry.hh"
#include "StringUtil.hh"
using FbTk::StringUtil::removeFirstWhitespace;
using FbTk::StringUtil::toLower;
using std::string;
namespace FbTk {
namespace {
template <typename M>
M *addCommands(M *macro, const string &args, bool trusted) {
int pos = 0, err = 0;
string cmd;
while (true) {
RefCount<BoolCommand> tmp(0);
err = StringUtil::getStringBetween(cmd, args.c_str() + pos,
'{', '}', " \t\n", true);
pos += err;
if (err == 0)
break;
tmp = CommandRegistry::instance().parseBoolLine(cmd, trusted);
if (*tmp)
macro->add(tmp);
}
if (macro->size() > 0)
return macro;
delete macro;
return 0;
}
BoolCommand *parseLogicCommand(const string &command, const string &args,
bool trusted) {
if (command == "not") {
BoolCommand *boolcmd =
CommandRegistry::instance().parseBoolLine(args, trusted);
if (!boolcmd)
return 0;
RefCount<BoolCommand> ref(boolcmd);
return new NotCommand(ref);
} else if (command == "and")
return addCommands<AndCommand>(new AndCommand(), args, trusted);
else if (command == "or")
return addCommands<OrCommand>(new OrCommand(), args, trusted);
else if (command == "xor")
return addCommands<XorCommand>(new XorCommand(), args, trusted);
return 0;
}
REGISTER_BOOLCOMMAND_PARSER(not, parseLogicCommand);
REGISTER_BOOLCOMMAND_PARSER(and, parseLogicCommand);
REGISTER_BOOLCOMMAND_PARSER(or, parseLogicCommand);
REGISTER_BOOLCOMMAND_PARSER(xor, parseLogicCommand);
}; // end anonymous namespace
Command *IfCommand::parse(const std::string &command, const std::string &args,
bool trusted) {
std::string cmd;
int err = 0, pos = 0;
RefCount<BoolCommand> cond(0);
RefCount<Command> t(0), f(0);
err = StringUtil::getStringBetween(cmd, args.c_str(),
'{', '}', " \t\n", true);
if (err > 0)
cond = CommandRegistry::instance().parseBoolLine(cmd, trusted);
if (err == 0 || *cond == 0)
return 0;
pos = err;
err = StringUtil::getStringBetween(cmd, args.c_str() + pos,
'{', '}', " \t\n", true);
if (err == 0)
return 0;
t = CommandRegistry::instance().parseLine(cmd, trusted);
pos += err;
err = StringUtil::getStringBetween(cmd, args.c_str() + pos,
'{', '}', " \t\n", true);
if (err > 0)
f = CommandRegistry::instance().parseLine(cmd, trusted);
if (err == 0 || *t == 0 && *f == 0)
return 0;
return new IfCommand(cond, t, f);
}
REGISTER_COMMAND_PARSER(if, IfCommand::parse);
REGISTER_COMMAND_PARSER(cond, IfCommand::parse);
void OrCommand::add(RefCount<BoolCommand> &com) {
m_commandlist.push_back(com);
}

View file

@ -27,6 +27,7 @@
#include "Command.hh"
#include "RefCount.hh"
#include <string>
#include <vector>
namespace FbTk {
@ -43,7 +44,8 @@ public:
} else
if (*m_f) m_f->execute();
}
static Command *parse(const std::string &cmd, const std::string &args,
bool trusted);
private:
RefCount<BoolCommand> m_cond;
RefCount<Command> m_t, m_f;

View file

@ -23,8 +23,56 @@
#include "MacroCommand.hh"
#include "CommandRegistry.hh"
#include "StringUtil.hh"
#include <string>
namespace FbTk {
namespace {
template <typename M>
M *addCommands(M *macro, const std::string &args, bool trusted) {
std::string cmd;
int err = 0;
int pos = 0;
while (true) {
RefCount<Command> next(0);
pos += err;
err = StringUtil::getStringBetween(cmd, args.c_str() + pos,
'{', '}', " \t\n", true);
if (err == 0)
break;
if (err > 0)
next = CommandRegistry::instance().parseLine(cmd, trusted);
if (*next != 0)
macro->add(next);
}
if (macro->size() > 0)
return macro;
delete macro;
return 0;
}
Command *parseMacroCmd(const std::string &command, const std::string &args,
bool trusted) {
if (command == "macrocmd")
return addCommands<MacroCommand>(new MacroCommand, args, trusted);
else if (command == "togglecmd")
return addCommands<ToggleCommand>(new ToggleCommand, args, trusted);
return 0;
}
REGISTER_COMMAND_PARSER(macrocmd, parseMacroCmd);
REGISTER_COMMAND_PARSER(togglecmd, parseMacroCmd);
}; // end anonymous namespace
void MacroCommand::add(RefCount<Command> &com) {
m_commandlist.push_back(com);
}

View file

@ -16,6 +16,7 @@ imlib2_SOURCE= ImageImlib2.hh ImageImlib2.cc
endif
libFbTk_a_SOURCES = App.hh App.cc Color.cc Color.hh Command.hh \
CommandRegistry.hh CommandRegistry.cc \
FileUtil.hh FileUtil.cc \
EventHandler.hh EventManager.hh EventManager.cc \
FbWindow.hh FbWindow.cc Font.cc Font.hh FontImp.hh \

View file

@ -233,6 +233,18 @@ string::size_type removeTrailingWhitespace(string &str) {
return first_pos;
}
void getFirstWord(const std::string &in, std::string &word, std::string &rest) {
word = in;
string::size_type first_pos = StringUtil::removeFirstWhitespace(word);
string::size_type second_pos = word.find_first_of(" \t", first_pos);
if (second_pos != string::npos) {
rest = word.substr(second_pos);
word.erase(second_pos);
removeFirstWhitespace(rest);
removeTrailingWhitespace(rest);
}
}
}; // end namespace StringUtil
}; // end namespace FbTk

View file

@ -64,6 +64,9 @@ std::string basename(const std::string &basename);
std::string::size_type removeFirstWhitespace(std::string &str);
std::string::size_type removeTrailingWhitespace(std::string &str);
/// removes the first part of a string and returns the two pieces
void getFirstWord(const std::string &in, std::string &first, std::string &rest);
/// Breaks a string into tokens
template <typename Container>
static void

View file

@ -33,7 +33,7 @@
#include "Workspace.hh"
#include "FbMenu.hh"
#include "BoolMenuItem.hh"
#include "CommandParser.hh"
#include "FbTk/CommandRegistry.hh"
#include "WinClient.hh"
#include "FocusControl.hh"
#include "FbCommands.hh"
@ -282,7 +282,7 @@ IconbarTool::IconbarTool(const FbTk::FbWindow &parent, IconbarTheme &theme,
// setup use pixmap item to reconfig iconbar and save resource on click
MacroCommand *save_and_reconfig = new MacroCommand();
RefCount<Command> reconfig(new SimpleCommand<IconbarTool>(*this, &IconbarTool::renderTheme));
RefCount<Command> save(CommandParser::instance().parseLine("saverc"));
RefCount<Command> save(FbTk::CommandRegistry::instance().parseLine("saverc"));
save_and_reconfig->add(reconfig);
save_and_reconfig->add(save);
RefCount<Command> s_and_reconfig(save_and_reconfig);

View file

@ -32,7 +32,7 @@
#include "FbTk/App.hh"
#include "FbTk/Command.hh"
#include "CommandParser.hh"
#include "FbTk/CommandRegistry.hh"
#include "FbTk/I18n.hh"
#ifdef HAVE_CONFIG_H
@ -395,7 +395,7 @@ bool Keys::addBinding(const string &linebuffer) {
const char *str = FbTk::StringUtil::strcasestr(linebuffer.c_str(),
val[argc].c_str() + 1); // +1 to skip ':'
if (str)
current_key->m_command = CommandParser::instance().parseLine(str);
current_key->m_command = FbTk::CommandRegistry::instance().parseLine(str);
if (!str || *current_key->m_command == 0 || mod) {
delete first_new_key;

View file

@ -64,7 +64,7 @@ private:
/// Create a layer menu inside from the given menu
class LayerMenu : public ToggleMenu {
public:
LayerMenu(MenuTheme &tm, FbTk::ImageControl &imgctrl,
LayerMenu(class MenuTheme &tm, FbTk::ImageControl &imgctrl,
FbTk::XLayer &layer, LayerObject *item, bool save_rc);
void show();
};

View file

@ -118,8 +118,6 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \
Xutil.hh Xutil.cc \
CurrentWindowCmd.hh CurrentWindowCmd.cc \
WorkspaceCmd.hh WorkspaceCmd.cc \
CommandParser.hh CommandParser.cc \
FbCommandFactory.hh FbCommandFactory.cc \
Shape.hh Shape.cc \
MenuTheme.hh MenuTheme.cc \
Container.hh Container.cc \
@ -156,4 +154,4 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \
${REMEMBER_SOURCE} ${TOOLBAR_SOURCE}
LDADD=FbTk/libFbTk.a defaults.$(OBJEXT)
LDADD=FbTk/libFbTk.a FbTk/LogicCommands.o defaults.$(OBJEXT)

View file

@ -26,7 +26,7 @@
#include "defaults.hh"
#include "Screen.hh"
#include "CommandParser.hh"
#include "FbTk/CommandRegistry.hh"
#include "fluxbox.hh"
#include "Window.hh"
#include "WindowCmd.hh"
@ -247,7 +247,7 @@ static void translateMenuItem(Parser &parse, ParseItem &pitem, FbTk::StringConve
else
menu.insert(str_label, submenu);
} else if (str_key == "exit") { // exit
FbTk::RefCount<FbTk::Command> exit_cmd(CommandParser::instance().parseLine("exit"));
FbTk::RefCount<FbTk::Command> exit_cmd(FbTk::CommandRegistry::instance().parseLine("exit"));
if (str_label.empty())
menu.insert(_FB_XTEXT(Menu, Exit, "Exit", "Exit Command"), exit_cmd);
else
@ -255,8 +255,8 @@ static void translateMenuItem(Parser &parse, ParseItem &pitem, FbTk::StringConve
} else if (str_key == "exec") {
// execute and hide menu
using namespace FbTk;
RefCount<Command> exec_cmd(CommandParser::instance().parseLine("exec " + str_cmd));
RefCount<Command> hide_menu(CommandParser::instance().parseLine("hidemenus"));
RefCount<Command> exec_cmd(FbTk::CommandRegistry::instance().parseLine("exec " + str_cmd));
RefCount<Command> hide_menu(FbTk::CommandRegistry::instance().parseLine("hidemenus"));
MacroCommand *exec_and_hide = new FbTk::MacroCommand();
exec_and_hide->add(hide_menu);
exec_and_hide->add(exec_cmd);
@ -264,8 +264,8 @@ static void translateMenuItem(Parser &parse, ParseItem &pitem, FbTk::StringConve
menu.insert(str_label, exec_and_hide_cmd);
} else if (str_key == "macrocmd") {
using namespace FbTk;
RefCount<Command> macro_cmd(CommandParser::instance().parseLine("macrocmd " + str_cmd));
RefCount<Command> hide_menu(CommandParser::instance().parseLine("hidemenus"));
RefCount<Command> macro_cmd(FbTk::CommandRegistry::instance().parseLine("macrocmd " + str_cmd));
RefCount<Command> hide_menu(FbTk::CommandRegistry::instance().parseLine("hidemenus"));
MacroCommand *exec_and_hide = new FbTk::MacroCommand();
exec_and_hide->add(hide_menu);
exec_and_hide->add(macro_cmd);
@ -364,7 +364,7 @@ static void translateMenuItem(Parser &parse, ParseItem &pitem, FbTk::StringConve
else { // ok, if we didn't find any special menu item we try with command parser
// we need to attach command with arguments so command parser can parse it
string line = str_key + " " + str_cmd;
FbTk::RefCount<FbTk::Command> command(CommandParser::instance().parseLine(line));
FbTk::RefCount<FbTk::Command> command(FbTk::CommandRegistry::instance().parseLine(line));
if (*command != 0) {
// special NLS default labels
if (str_label.empty()) {

View file

@ -60,7 +60,7 @@
#include "WinClient.hh"
#include "FbWinFrame.hh"
#include "Strut.hh"
#include "CommandParser.hh"
#include "FbTk/CommandRegistry.hh"
#include "AtomHandler.hh"
#include "HeadArea.hh"
#include "FbCommands.hh"
@ -815,7 +815,7 @@ void BScreen::propertyNotify(Atom atom) {
&ret_bytes_after, (unsigned char **)&str);
}
FbTk::RefCount<FbTk::Command> cmd(CommandParser::instance().parseLine(str, false));
FbTk::RefCount<FbTk::Command> cmd(FbTk::CommandRegistry::instance().parseLine(str, false));
if (cmd.get())
cmd->execute();
XFree(str);
@ -1531,9 +1531,9 @@ void BScreen::initMenu() {
if (m_rootmenu.get() == 0) {
_FB_USES_NLS;
m_rootmenu.reset(createMenu(_FB_XTEXT(Menu, DefaultRootMenu, "Fluxbox default menu", "Title of fallback root menu")));
FbTk::RefCount<FbTk::Command> restart_fb(CommandParser::instance().parseLine("restart"));
FbTk::RefCount<FbTk::Command> exit_fb(CommandParser::instance().parseLine("exit"));
FbTk::RefCount<FbTk::Command> execute_xterm(CommandParser::instance().parseLine("exec xterm"));
FbTk::RefCount<FbTk::Command> restart_fb(FbTk::CommandRegistry::instance().parseLine("restart"));
FbTk::RefCount<FbTk::Command> exit_fb(FbTk::CommandRegistry::instance().parseLine("exit"));
FbTk::RefCount<FbTk::Command> execute_xterm(FbTk::CommandRegistry::instance().parseLine("exec xterm"));
m_rootmenu->setInternalMenu();
m_rootmenu->insert("xterm", execute_xterm);
m_rootmenu->insert(_FB_XTEXT(Menu, Restart, "Restart", "Restart command"),
@ -1578,7 +1578,7 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
FbTk::RefCount<FbTk::Command> saverc_cmd(new FbTk::SimpleCommand<Fluxbox>(
*Fluxbox::instance(),
&Fluxbox::save_rc));
FbTk::RefCount<FbTk::Command> reconf_cmd(CommandParser::instance().parseLine("reconfigure"));
FbTk::RefCount<FbTk::Command> reconf_cmd(FbTk::CommandRegistry::instance().parseLine("reconfigure"));
FbTk::RefCount<FbTk::Command> reconftabs_cmd(new FbTk::SimpleCommand<BScreen>(
*this,

View file

@ -177,7 +177,7 @@ private:
FbTk::Resource<Slit::Placement> m_rc_placement;
FbTk::Resource<Slit::Direction> m_rc_direction;
FbTk::Resource<int> m_rc_alpha, m_rc_on_head;
FbTk::Resource<Layer> m_rc_layernum;
FbTk::Resource<class Layer> m_rc_layernum;
};

View file

@ -32,7 +32,7 @@
*/
class ToggleMenu: public FbMenu {
public:
ToggleMenu(MenuTheme &tm, FbTk::ImageControl &imgctrl,
ToggleMenu(class MenuTheme &tm, FbTk::ImageControl &imgctrl,
FbTk::XLayer &layer):FbMenu(tm, imgctrl, layer)
{}
virtual ~ToggleMenu() {}

View file

@ -36,7 +36,7 @@
#include "WorkspaceNameTheme.hh"
#include "ButtonTheme.hh"
#include "CommandParser.hh"
#include "FbTk/CommandRegistry.hh"
#include "Screen.hh"
#include "Toolbar.hh"
#include "fluxbox.hh"
@ -107,7 +107,7 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow &
} else if (name == "nextworkspace" ||
name == "prevworkspace") {
FbTk::RefCount<FbTk::Command> cmd(CommandParser::instance().parseLine(name));
FbTk::RefCount<FbTk::Command> cmd(FbTk::CommandRegistry::instance().parseLine(name));
if (*cmd == 0) // we need a command
return 0;
@ -127,7 +127,7 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow &
} else if (name == "nextwindow" ||
name == "prevwindow") {
FbTk::RefCount<FbTk::Command> cmd(CommandParser::instance().parseLine(name));
FbTk::RefCount<FbTk::Command> cmd(FbTk::CommandRegistry::instance().parseLine(name));
if (*cmd == 0) // we need a command
return 0;

View file

@ -44,7 +44,7 @@
#endif // XINERAMA
#include "Strut.hh"
#include "CommandParser.hh"
#include "FbTk/CommandRegistry.hh"
#include "Layer.hh"
#include "FbTk/I18n.hh"
@ -823,7 +823,7 @@ void Toolbar::setupMenus(bool skip_new_placement) {
"Toolbar", "Title of Toolbar menu"));
RefCommand reconfig_toolbar(new ToolbarCommand(*this, &Toolbar::reconfigure));
RefCommand save_resources(CommandParser::instance().parseLine("saverc"));
RefCommand save_resources(FbTk::CommandRegistry::instance().parseLine("saverc"));
MacroCommand *toolbar_menuitem_macro = new MacroCommand();
toolbar_menuitem_macro->add(reconfig_toolbar);
toolbar_menuitem_macro->add(save_resources);

View file

@ -178,7 +178,7 @@ private:
FbTk::Resource<bool> m_rc_auto_hide, m_rc_maximize_over, m_rc_visible;
FbTk::Resource<int> m_rc_width_percent;
FbTk::Resource<int> m_rc_alpha;
FbTk::Resource<Layer> m_rc_layernum;
FbTk::Resource<class Layer> m_rc_layernum;
FbTk::Resource<int> m_rc_on_head;
FbTk::Resource<Placement> m_rc_placement;
FbTk::Resource<int> m_rc_height;

View file

@ -33,6 +33,8 @@
#include "WindowCmd.hh"
#include "FbTk/KeyUtil.hh"
#include "FbTk/CommandRegistry.hh"
#include "FbTk/stringstream.hh"
#ifdef HAVE_CMATH
#include <cmath>
@ -42,6 +44,8 @@
#include <algorithm>
#include <functional>
using std::string;
void WindowListCmd::execute() {
if (m_pat.error()) {
m_cmd->execute();
@ -66,6 +70,20 @@ void WindowListCmd::execute() {
}
}
FbTk::BoolCommand *SomeCmd::parse(const string &command, const string &args,
bool trusted) {
BoolCommand *boolcmd =
FbTk::CommandRegistry::instance().parseBoolLine(args, trusted);
if (!boolcmd)
return 0;
if (command == "some")
return new SomeCmd(FbTk::RefCount<FbTk::BoolCommand>(boolcmd));
return new EveryCmd(FbTk::RefCount<FbTk::BoolCommand>(boolcmd));
}
REGISTER_BOOLCOMMAND_PARSER(some, SomeCmd::parse);
REGISTER_BOOLCOMMAND_PARSER(every, SomeCmd::parse);
bool SomeCmd::bool_execute() {
BScreen *screen = Fluxbox::instance()->keyScreen();
if (screen != 0) {
@ -108,6 +126,37 @@ bool EveryCmd::bool_execute() {
return true;
}
namespace {
FbTk::Command *parseWindowList(const string &command,
const string &args, bool trusted) {
int opts;
string pat;
FocusableList::parseArgs(args, opts, pat);
if (command == "attach")
return new AttachCmd(pat);
else if (command == "nextwindow")
return new NextWindowCmd(opts, pat);
else if (command == "nextgroup") {
opts |= FocusableList::LIST_GROUPS;
return new NextWindowCmd(opts, pat);
} else if (command == "prevwindow")
return new PrevWindowCmd(opts, pat);
else if (command == "prevgroup") {
opts |= FocusableList::LIST_GROUPS;
return new PrevWindowCmd(opts, pat);
}
return 0;
}
REGISTER_COMMAND_PARSER(attach, parseWindowList);
REGISTER_COMMAND_PARSER(nextwindow, parseWindowList);
REGISTER_COMMAND_PARSER(nextgroup, parseWindowList);
REGISTER_COMMAND_PARSER(prevwindow, parseWindowList);
REGISTER_COMMAND_PARSER(prevgroup, parseWindowList);
}; // end anonymous namespace
void AttachCmd::execute() {
BScreen *screen = Fluxbox::instance()->keyScreen();
if (screen != 0) {
@ -140,6 +189,21 @@ void PrevWindowCmd::execute() {
screen->cycleFocus(m_option, &m_pat, true);
}
FbTk::Command *GoToWindowCmd::parse(const string &command,
const string &arguments, bool trusted) {
int num, opts;
string args, pat;
FbTk_istringstream iss(arguments.c_str());
iss >> num;
string::size_type pos = arguments.find_first_of("({");
if (pos != string::npos && pos != arguments.size())
args = arguments.c_str() + pos;
FocusableList::parseArgs(args, opts, pat);
return new GoToWindowCmd(num, opts, pat);
}
REGISTER_COMMAND_PARSER(gotowindow, GoToWindowCmd::parse);
void GoToWindowCmd::execute() {
BScreen *screen = Fluxbox::instance()->keyScreen();
if (screen != 0) {
@ -149,6 +213,24 @@ void GoToWindowCmd::execute() {
}
}
FbTk::Command *DirFocusCmd::parse(const string &command,
const string &args, bool trusted) {
if (command == "focusup")
return new DirFocusCmd(FocusControl::FOCUSUP);
else if (command == "focusdown")
return new DirFocusCmd(FocusControl::FOCUSDOWN);
else if (command == "focusleft")
return new DirFocusCmd(FocusControl::FOCUSLEFT);
else if (command == "focusright")
return new DirFocusCmd(FocusControl::FOCUSRIGHT);
return 0;
}
REGISTER_COMMAND_PARSER(focusup, DirFocusCmd::parse);
REGISTER_COMMAND_PARSER(focusdown, DirFocusCmd::parse);
REGISTER_COMMAND_PARSER(focusleft, DirFocusCmd::parse);
REGISTER_COMMAND_PARSER(focusright, DirFocusCmd::parse);
void DirFocusCmd::execute() {
BScreen *screen = Fluxbox::instance()->keyScreen();
if (screen == 0)
@ -159,18 +241,51 @@ void DirFocusCmd::execute() {
screen->focusControl().dirFocus(*win, m_dir);
}
REGISTER_COMMAND(addworkspace, AddWorkspaceCmd);
void AddWorkspaceCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen != 0)
screen->addWorkspace();
}
REGISTER_COMMAND(removelastworkspace, RemoveLastWorkspaceCmd);
void RemoveLastWorkspaceCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen != 0)
screen->removeLastWorkspace();
}
namespace {
FbTk::Command *parseIntCmd(const string &command, const string &args,
bool trusted) {
int num = 1;
FbTk_istringstream iss(args.c_str());
iss >> num;
if (command == "nextworkspace")
return new NextWorkspaceCmd(num);
else if (command == "prevworkspace")
return new PrevWorkspaceCmd(num);
else if (command == "rightworkspace")
return new RightWorkspaceCmd(num);
else if (command == "leftworkspace")
return new LeftWorkspaceCmd(num);
else if (command == "workspace")
// workspaces appear 1-indexed to the user, hence the minus 1
return new JumpToWorkspaceCmd(num - 1);
return 0;
}
REGISTER_COMMAND_PARSER(nextworkspace, parseIntCmd);
REGISTER_COMMAND_PARSER(prevworkspace, parseIntCmd);
REGISTER_COMMAND_PARSER(rightworkspace, parseIntCmd);
REGISTER_COMMAND_PARSER(leftworkspace, parseIntCmd);
REGISTER_COMMAND_PARSER(workspace, parseIntCmd);
}; // end anonymous namespace
void NextWorkspaceCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen != 0)
@ -210,6 +325,7 @@ void JumpToWorkspaceCmd::execute() {
}
}
REGISTER_COMMAND(arrangewindows, ArrangeWindowsCmd);
/**
try to arrange the windows on the current workspace in a 'clever' way.
@ -335,6 +451,8 @@ void ArrangeWindowsCmd::execute() {
}
}
REGISTER_COMMAND(showdesktop, ShowDesktopCmd);
void ShowDesktopCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen == 0)
@ -349,6 +467,8 @@ void ShowDesktopCmd::execute() {
}
}
REGISTER_COMMAND(closeallwindows, CloseAllWindowsCmd);
void CloseAllWindowsCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen == 0)

View file

@ -32,6 +32,8 @@
#include "FbTk/RefCount.hh"
#include <string>
class WindowListCmd: public FbTk::Command {
public:
WindowListCmd(FbTk::RefCount<FbTk::Command> cmd, const std::string &pat):
@ -49,6 +51,8 @@ public:
SomeCmd(FbTk::RefCount<FbTk::BoolCommand> cmd): m_cmd(cmd) { }
bool bool_execute();
static FbTk::BoolCommand *parse(const std::string &command,
const std::string &args, bool trusted);
private:
FbTk::RefCount<FbTk::BoolCommand> m_cmd;
@ -97,6 +101,8 @@ public:
GoToWindowCmd(int num, int option, std::string &pat):
m_num(num), m_option(option), m_pat(pat.c_str()) { }
void execute();
static FbTk::Command *parse(const std::string &command,
const std::string &args, bool trusted);
private:
const int m_num;
const int m_option;
@ -107,6 +113,8 @@ class DirFocusCmd: public FbTk::Command {
public:
explicit DirFocusCmd(const FocusControl::FocusDir dir): m_dir(dir) { }
void execute();
static FbTk::Command *parse(const std::string &command,
const std::string &args, bool trusted);
private:
const FocusControl::FocusDir m_dir;
};

View file

@ -27,7 +27,7 @@
#include "Workspace.hh"
#include "WorkspaceCmd.hh"
#include "MenuCreator.hh"
#include "CommandParser.hh"
#include "FbTk/CommandRegistry.hh"
#include "FbCommands.hh"
#include "Layer.hh"
@ -147,7 +147,7 @@ void WorkspaceMenu::init(BScreen &screen) {
remove_workspace_macro->add(saverc_cmd);
RefCount<Command> remove_last_cmd(remove_workspace_macro);
RefCount<Command> start_edit(CommandParser::instance().parseLine("setworkspacenamedialog"));
RefCount<Command> start_edit(FbTk::CommandRegistry::instance().parseLine("setworkspacenamedialog"));
insert(new FbTk::MenuSeparator());
insert(_FB_XTEXT(Workspace, NewWorkspace, "New Workspace", "Add a new workspace"),