1
// FbCommandFactory.cc for Fluxbox Window manager
2
// Copyright (c) 2003 - 2005 Henrik Kinnunen (fluxgen at fluxbox dot org)
3
// and Simon Bowden (rathnor at users.sourceforge.net)
5
// Permission is hereby granted, free of charge, to any person obtaining a
6
// copy of this software and associated documentation files (the "Software"),
7
// to deal in the Software without restriction, including without limitation
8
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
// and/or sell copies of the Software, and to permit persons to whom the
10
// Software is furnished to do so, subject to the following conditions:
12
// The above copyright notice and this permission notice shall be included in
13
// all copies or substantial portions of the Software.
15
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
// DEALINGS IN THE SOFTWARE.
23
// $Id: FbCommandFactory.cc 4051 2005-06-15 15:17:48Z mathias $
25
#include "FbCommandFactory.hh"
27
#include "CurrentWindowCmd.hh"
28
#include "FbCommands.hh"
30
#include "WorkspaceCmd.hh"
32
#include "SimpleCommand.hh"
35
#include "FbTk/StringUtil.hh"
36
#include "FbTk/MacroCommand.hh"
37
#include "FbTk/stringstream.hh"
44
// autoregister this module to command parser
45
FbCommandFactory FbCommandFactory::s_autoreg;
48
FbCommandFactory::FbCommandFactory() {
49
// setup commands that we can handle
50
const char* commands[] = {
112
"sendtonextworkspace",
113
"sendtoprevworkspace",
116
"setworkspacenamedialog",
118
"setresourcevaluedialog",
126
"taketonextworkspace",
127
"taketoprevworkspace",
131
/* NOTE: The following are DEPRECATED and subject to removal */
149
for (int i=0;; ++i) {
150
if (commands[i] == 0)
152
addCommand(commands[i]);
157
FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
158
const std::string &arguments) {
159
using namespace FbCommands;
163
if (command == "restart")
164
return new RestartFluxboxCmd(arguments);
165
else if (command == "reconfigure" || command == "reconfig")
166
return new ReconfigureFluxboxCmd();
167
else if (command == "setstyle")
168
return new SetStyleCmd(arguments);
169
else if (command == "reloadstyle")
170
return new ReloadStyleCmd();
171
else if (command == "saverc")
172
return new SaveResources();
173
else if (command == "execcommand" || command == "execute" || command == "exec")
174
return new ExecuteCmd(arguments); // execute command on key screen
175
else if (command == "exit")
176
return new ExitFluxboxCmd();
177
else if (command == "setenv" || command == "export") {
179
std::string name = arguments;
180
FbTk::StringUtil::removeFirstWhitespace(name);
181
FbTk::StringUtil::removeTrailingWhitespace(name);
182
size_t pos = name.find_first_of(command == "setenv" ? " \t" : "=");
183
if (pos == std::string::npos || pos == name.size())
186
std::string value = name.substr(pos + 1);
187
name = name.substr(0, pos);
188
return new ExportCmd(name, value);
190
else if (command == "quit")
191
return new FbTk::SimpleCommand<Fluxbox>(*Fluxbox::instance(), &Fluxbox::shutdown);
192
else if (command == "commanddialog") // run specified fluxbox command
193
return new CommandDialogCmd();
194
else if (command == "bindkey")
195
return new BindKeyCmd(arguments);
196
else if (command == "setresourcevalue") {
197
// we need to parse arguments as:
198
// <remove whitespace here><resname><one whitespace><value>
199
string name = arguments;
200
FbTk::StringUtil::removeFirstWhitespace(name);
201
size_t pos = name.find_first_of(" \t");
202
// we need an argument to resource name
203
if (pos == std::string::npos || pos == name.size())
205
// +1 so we only remove the first whitespace
206
// i.e so users can set space before workspace name and so on
207
string value = name.substr(pos + 1);
208
name = name.substr(0, pos);
209
return new SetResourceValueCmd(name, value);
210
} else if (command == "setresourcevaluedialog")
211
return new SetResourceValueDialogCmd();
213
// Current focused window commands
215
else if (command == "fullscreen")
216
return new FullscreenCmd();
217
else if (command == "minimizewindow" || command == "minimize" || command == "iconify")
218
return new CurrentWindowCmd(&FluxboxWindow::iconify);
219
else if (command == "maximizewindow" || command == "maximize")
220
return new CurrentWindowCmd(&FluxboxWindow::maximizeFull);
221
else if (command == "maximizevertical")
222
return new CurrentWindowCmd(&FluxboxWindow::maximizeVertical);
223
else if (command == "maximizehorizontal")
224
return new CurrentWindowCmd(&FluxboxWindow::maximizeHorizontal);
225
else if (command == "resize") {
226
FbTk_istringstream is(arguments.c_str());
229
return new ResizeCmd(dx, dy);
231
else if (command == "resizeto") {
232
FbTk_istringstream is(arguments.c_str());
235
return new ResizeToCmd(dx, dy);
237
else if (command == "resizehorizontal")
238
return new ResizeCmd(atoi(arguments.c_str()),0);
239
else if (command == "resizevertical")
240
return new ResizeCmd(0,atoi(arguments.c_str()));
241
else if (command == "moveto") {
242
typedef std::vector<std::string> StringTokens;
244
FbTk::StringUtil::stringtok<StringTokens>(tokens, arguments);
246
if (tokens.size() < 2) {
247
cerr<<"*** WARNING: missing arguments for MoveTo\n";
251
unsigned int refc = MoveToCmd::UPPER|MoveToCmd::LEFT;
255
if (tokens[0][0] == '*')
256
refc |= MoveToCmd::IGNORE_X;
258
dx = atoi(tokens[0].c_str());
260
if (tokens[1][0] == '*' && ! (refc & MoveToCmd::IGNORE_X))
261
refc |= MoveToCmd::IGNORE_Y;
263
dy = atoi(tokens[1].c_str());
265
if (tokens.size() >= 3) {
266
tokens[2] = FbTk::StringUtil::toLower(tokens[2]);
267
if (tokens[2] == "left" || tokens[2] == "upperleft" || tokens[2] == "lowerleft") {
268
refc |= MoveToCmd::LEFT;
269
refc &= ~MoveToCmd::RIGHT;
270
} else if (tokens[2] == "right" || tokens[2] == "upperright" || tokens[2] == "lowerright") {
271
refc |= MoveToCmd::RIGHT;
272
refc &= ~MoveToCmd::LEFT;
275
if (tokens[2] == "upper" || tokens[2] == "upperleft" || tokens[2] == "upperright") {
276
refc |= MoveToCmd::UPPER;
277
refc &= ~MoveToCmd::LOWER;
278
} else if (tokens[2] == "lower" || tokens[2] == "lowerleft" || tokens[2] == "lowerright") {
279
refc |= MoveToCmd::LOWER;
280
refc &= ~MoveToCmd::UPPER;
284
return new MoveToCmd(dx, dy, refc);
286
else if (command == "move") {
287
FbTk_istringstream is(arguments.c_str());
290
return new MoveCmd(dx, dy);
292
else if (command == "moveright")
293
return new MoveCmd(atoi(arguments.c_str()),0);
294
else if (command == "moveleft")
295
return new MoveCmd(-atoi(arguments.c_str()),0);
296
else if (command == "moveup")
297
return new MoveCmd(0,-atoi(arguments.c_str()));
298
else if (command == "movedown")
299
return new MoveCmd(0,atoi(arguments.c_str()));
300
else if (command == "raise")
301
return new CurrentWindowCmd(&FluxboxWindow::raise);
302
else if (command == "raiselayer")
303
return new CurrentWindowCmd(&FluxboxWindow::raiseLayer);
304
else if (command == "lower")
305
return new CurrentWindowCmd(&FluxboxWindow::lower);
306
else if (command == "lowerlayer")
307
return new CurrentWindowCmd(&FluxboxWindow::lowerLayer);
308
else if (command == "close")
309
return new CurrentWindowCmd(&FluxboxWindow::close);
310
else if (command == "shade" || command == "shadewindow")
311
return new CurrentWindowCmd(&FluxboxWindow::shade);
312
else if (command == "stick" || command == "stickwindow")
313
return new CurrentWindowCmd(&FluxboxWindow::stick);
314
else if (command == "toggledecor")
315
return new CurrentWindowCmd(&FluxboxWindow::toggleDecoration);
316
else if (command == "sethead")
317
return new SetHeadCmd(atoi(arguments.c_str()));
318
else if (command == "sendtoworkspace")
319
return new SendToWorkspaceCmd(atoi(arguments.c_str()) - 1); // make 1-indexed to user
320
else if (command == "sendtonextworkspace")
321
return new SendToNextWorkspaceCmd(atoi(arguments.c_str()));
322
else if (command == "sendtoprevworkspace")
323
return new SendToPrevWorkspaceCmd(atoi(arguments.c_str()));
324
else if (command == "taketoworkspace")
325
return new TakeToWorkspaceCmd(atoi(arguments.c_str()) - 1);
326
else if (command == "taketonextworkspace")
327
return new TakeToNextWorkspaceCmd(atoi(arguments.c_str()));
328
else if (command == "taketoprevworkspace")
329
return new TakeToPrevWorkspaceCmd(atoi(arguments.c_str()));
330
else if (command == "killwindow" || command == "kill")
331
return new KillWindowCmd();
332
else if (command == "tab") {
335
if (!arguments.empty())
336
num = atoi(arguments.c_str());
337
return new GoToTabCmd(num);
338
} else if (command == "nexttab")
339
return new CurrentWindowCmd(&FluxboxWindow::nextClient);
340
else if (command == "prevtab")
341
return new CurrentWindowCmd(&FluxboxWindow::prevClient);
342
else if (command == "movetableft")
343
return new CurrentWindowCmd(&FluxboxWindow::moveClientLeft);
344
else if (command == "movetabright")
345
return new CurrentWindowCmd(&FluxboxWindow::moveClientRight);
346
else if (command == "detachclient")
347
return new CurrentWindowCmd(&FluxboxWindow::detachCurrentClient);
348
else if (command == "windowmenu")
349
return new CurrentWindowCmd(&FluxboxWindow::popupMenu);
351
// Workspace commands
353
else if (command == "nextworkspace" && arguments.empty())
354
return new NextWorkspaceCmd();
355
else if (command == "prevworkspace" && arguments.empty())
356
return new PrevWorkspaceCmd();
357
else if (command == "rightworkspace")
358
return new RightWorkspaceCmd(atoi(arguments.c_str()));
359
else if (command == "leftworkspace")
360
return new LeftWorkspaceCmd(atoi(arguments.c_str()));
361
else if (command == "workspace") {
362
int num = 1; // workspaces appear 1-indexed to the user
363
if (!arguments.empty())
364
num = atoi(arguments.c_str());
365
return new JumpToWorkspaceCmd(num-1);
366
} if (command.substr(0, 9) == "workspace" && command[9] >= '0' && command[9] <= '9') {
367
cerr<<"*** WARNING: 'Workspace<n>' actions are deprecated! Use 'Workspace <n>' instead"<<endl;
369
num = atoi(command.substr(9).c_str());
370
return new JumpToWorkspaceCmd(num-1);
372
} else if (command == "nextwindow")
373
return new NextWindowCmd(atoi(arguments.c_str()));
374
else if (command == "prevwindow")
375
return new PrevWindowCmd(atoi(arguments.c_str()));
376
else if (command == "focusup")
377
return new DirFocusCmd(BScreen::FOCUSUP);
378
else if (command == "focusdown")
379
return new DirFocusCmd(BScreen::FOCUSDOWN);
380
else if (command == "focusleft")
381
return new DirFocusCmd(BScreen::FOCUSLEFT);
382
else if (command == "focusright")
383
return new DirFocusCmd(BScreen::FOCUSRIGHT);
384
else if (command == "nextgroup")
385
return new NextWindowCmd(atoi(arguments.c_str()) ^ BScreen::CYCLEGROUPS);
386
else if (command == "prevgroup")
387
return new PrevWindowCmd(atoi(arguments.c_str()) ^ BScreen::CYCLEGROUPS);
388
else if (command == "arrangewindows")
389
return new ArrangeWindowsCmd();
390
else if (command == "showdesktop")
391
return new ShowDesktopCmd();
392
else if (command == "rootmenu")
393
return new ShowRootMenuCmd();
394
else if (command == "workspacemenu")
395
return new ShowWorkspaceMenuCmd();
396
else if (command == "setworkspacename") {
397
if (arguments.empty())
398
return new SetWorkspaceNameCmd("empty");
400
return new SetWorkspaceNameCmd(arguments);
402
else if (command == "setworkspacenamedialog")
403
return new WorkspaceNameDialogCmd();
407
else if (command == "deiconify") {
409
FbTk_istringstream iss(arguments.c_str());
412
DeiconifyCmd::Destination dest;
416
mode="lastworkspace";
417
mode= FbTk::StringUtil::toLower(mode);
422
d= FbTk::StringUtil::toLower(d);
424
dest= DeiconifyCmd::ORIGIN;
425
else if (d == "originquiet")
426
dest= DeiconifyCmd::ORIGINQUIET;
428
dest= DeiconifyCmd::CURRENT;
431
return new DeiconifyCmd(DeiconifyCmd::ALL, dest);
432
else if ( mode == "allworkspace" )
433
return new DeiconifyCmd(DeiconifyCmd::ALLWORKSPACE, dest);
434
else if ( mode == "last" )
435
return new DeiconifyCmd(DeiconifyCmd::LAST, dest);
436
else // lastworkspace, default
437
return new DeiconifyCmd(DeiconifyCmd::LASTWORKSPACE, dest);
439
} else if (command == "macrocmd") {
443
FbTk::MacroCommand* macro= new FbTk::MacroCommand();
447
err= FbTk::StringUtil::getStringBetween(cmd, arguments.c_str() + parse_pos,
448
'{', '}', " \t\n", true);
451
std::string::size_type first_pos = FbTk::StringUtil::removeFirstWhitespace(cmd);
452
std::string::size_type second_pos= cmd.find_first_of(" \t", first_pos);
453
if (second_pos != std::string::npos) {
454
a= cmd.substr(second_pos);
455
FbTk::StringUtil::removeFirstWhitespace(a);
456
cmd.erase(second_pos);
458
c= FbTk::StringUtil::toLower(cmd);
460
FbTk::Command* fbcmd= stringToCommand(c,a);
462
FbTk::RefCount<FbTk::Command> rfbcmd(fbcmd);
470
if ( macro->size() > 0 )