fluxbox/src/FbCommandFactory.cc
mathias 12dff3d3a9 added "Fullscreen" - command, removes borders and maximizes to
the full screen ... hence the name :)
2005-03-23 20:36:12 +00:00

428 lines
15 KiB
C++

// FbCommandFactory.cc for Fluxbox Window manager
// Copyright (c) 2003 - 2005 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 "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/MacroCommand.hh"
#include "FbTk/stringstream.hh"
#include <string>
using namespace std;
// autoregister this module to command parser
FbCommandFactory FbCommandFactory::s_autoreg;
FbCommandFactory::FbCommandFactory() {
// setup commands that we can handle
const char* commands[] = {
"arrangewindows",
"bindkey",
"close",
"commanddialog",
"deiconify",
"detachclient",
"export",
"exec",
"execcommand",
"execute",
"exit",
"focusup",
"focusdown",
"focusleft",
"focusright",
"fullscreen",
"iconify",
"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",
"resizeto",
"resize",
"resizehorizontal",
"resizevertical",
"restart",
"rightworkspace",
"rootmenu",
"saverc",
"setenv",
"sethead",
"sendtoworkspace",
"sendtonextworkspace",
"sendtoprevworkspace",
"setstyle",
"setworkspacename",
"setworkspacenamedialog",
"setresourcevalue",
"setresourcevaluedialog",
"shade",
"shadewindow",
"showdesktop",
"stick",
"stickwindow",
"tab",
"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;; ++i) {
if (commands[i] == 0)
break;
addCommand(commands[i]);
}
}
FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
const std::string &arguments) {
using namespace FbCommands;
//
// WM commands
//
if (command == "restart")
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 == "saverc")
return new SaveResources();
else if (command == "execcommand" || command == "execute" || command == "exec")
return new ExecuteCmd(arguments); // execute command on key screen
else if (command == "exit")
return new ExitFluxboxCmd();
else if (command == "setenv" || command == "export") {
std::string name = arguments;
FbTk::StringUtil::removeFirstWhitespace(name);
FbTk::StringUtil::removeTrailingWhitespace(name);
size_t pos = name.find_first_of(command == "setenv" ? " \t" : "=");
if (pos == std::string::npos || pos == name.size())
return 0;
std::string value = name.substr(pos + 1);
name = name.substr(0, pos);
return new ExportCmd(name, value);
}
else if (command == "quit")
return new FbTk::SimpleCommand<Fluxbox>(*Fluxbox::instance(), &Fluxbox::shutdown);
else if (command == "commanddialog") // run specified fluxbox command
return new CommandDialogCmd();
else if (command == "bindkey")
return new BindKeyCmd(arguments);
else if (command == "setresourcevalue") {
// 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();
//
// Current focused window commands
//
else if (command == "fullscreen")
return new FullscreenCmd();
else 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 == "resize") {
FbTk_istringstream is(arguments.c_str());
int dx = 0, dy = 0;
is >> dx >> dy;
return new ResizeCmd(dx, dy);
}
else if (command == "resizeto") {
FbTk_istringstream is(arguments.c_str());
int dx = 0, dy = 0;
is >> dx >> dy;
return new ResizeToCmd(dx, dy);
}
else if (command == "resizehorizontal")
return new ResizeCmd(atoi(arguments.c_str()),0);
else if (command == "resizevertical")
return new ResizeCmd(0,atoi(arguments.c_str()));
else if (command == "moveto") {
FbTk_istringstream is(arguments.c_str());
int dx = 0, dy = 0;
is >> dx >> dy;
return new MoveToCmd(dx,dy);
}
else if (command == "move") {
FbTk_istringstream is(arguments.c_str());
int dx = 0, dy = 0;
is >> dx >> dy;
return new MoveCmd(dx, dy);
}
else if (command == "moveright")
return new MoveCmd(atoi(arguments.c_str()),0);
else if (command == "moveleft")
return new MoveCmd(-atoi(arguments.c_str()),0);
else if (command == "moveup")
return new MoveCmd(0,-atoi(arguments.c_str()));
else if (command == "movedown")
return new MoveCmd(0,atoi(arguments.c_str()));
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 == "close")
return new CurrentWindowCmd(&FluxboxWindow::close);
else if (command == "shade" || command == "shadewindow")
return new CurrentWindowCmd(&FluxboxWindow::shade);
else if (command == "stick" || command == "stickwindow")
return new CurrentWindowCmd(&FluxboxWindow::stick);
else if (command == "toggledecor")
return new CurrentWindowCmd(&FluxboxWindow::toggleDecoration);
else if (command == "sethead")
return new SetHeadCmd(atoi(arguments.c_str()));
else if (command == "sendtoworkspace")
return new SendToWorkspaceCmd(atoi(arguments.c_str()) - 1); // make 1-indexed to user
else if (command == "sendtonextworkspace")
return new SendToNextWorkspaceCmd(atoi(arguments.c_str()));
else if (command == "sendtoprevworkspace")
return new SendToPrevWorkspaceCmd(atoi(arguments.c_str()));
else if (command == "killwindow" || command == "kill")
return new KillWindowCmd();
else if (command == "tab") {
// XXX
int num = 1;
if (!arguments.empty())
num = atoi(arguments.c_str());
return new GoToTabCmd(num);
} 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);
//
// Workspace commands
//
else if (command == "nextworkspace" && arguments.empty())
return new NextWorkspaceCmd();
else if (command == "prevworkspace" && arguments.empty())
return new PrevWorkspaceCmd();
else if (command == "rightworkspace")
return new RightWorkspaceCmd(atoi(arguments.c_str()));
else if (command == "leftworkspace")
return new LeftWorkspaceCmd(atoi(arguments.c_str()));
else if (command == "workspace") {
int num = 1; // workspaces appear 1-indexed to the user
if (!arguments.empty())
num = atoi(arguments.c_str());
return new JumpToWorkspaceCmd(num-1);
} if (command.substr(0, 9) == "workspace" && command[9] >= '0' && command[9] <= '9') {
cerr<<"*** WARNING: 'Workspace<n>' actions are deprecated! Use 'Workspace <n>' instead"<<endl;
int num = 1;
num = atoi(command.substr(9).c_str());
return new JumpToWorkspaceCmd(num-1);
} else if (command == "nextwindow")
return new NextWindowCmd(atoi(arguments.c_str()));
else if (command == "prevwindow")
return new PrevWindowCmd(atoi(arguments.c_str()));
else if (command == "focusup")
return new DirFocusCmd(BScreen::FOCUSUP);
else if (command == "focusdown")
return new DirFocusCmd(BScreen::FOCUSDOWN);
else if (command == "focusleft")
return new DirFocusCmd(BScreen::FOCUSLEFT);
else if (command == "focusright")
return new DirFocusCmd(BScreen::FOCUSRIGHT);
else if (command == "nextgroup")
return new NextWindowCmd(atoi(arguments.c_str()) ^ BScreen::CYCLEGROUPS);
else if (command == "prevgroup")
return new PrevWindowCmd(atoi(arguments.c_str()) ^ BScreen::CYCLEGROUPS);
else if (command == "arrangewindows")
return new ArrangeWindowsCmd();
else if (command == "showdesktop")
return new ShowDesktopCmd();
else if (command == "rootmenu")
return new ShowRootMenuCmd();
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);
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") {
std::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 ) {
std::string c, a;
std::string::size_type first_pos = FbTk::StringUtil::removeFirstWhitespace(cmd);
std::string::size_type second_pos= cmd.find_first_of(" \t", first_pos);
if (second_pos != std::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);
if (fbcmd) {
FbTk::RefCount<FbTk::Command> rfbcmd(fbcmd);
macro->add(rfbcmd);
}
}
else
break;
}
if ( macro->size() > 0 )
return macro;
delete macro;
}
return 0;
}