aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog18
-rw-r--r--src/CurrentWindowCmd.cc23
-rw-r--r--src/CurrentWindowCmd.hh26
-rw-r--r--src/FbCommandFactory.cc192
-rw-r--r--src/FbTk/Command.hh8
-rw-r--r--src/FbTk/LogicCommands.cc75
-rw-r--r--src/FbTk/LogicCommands.hh97
-rw-r--r--src/FbTk/Makefile.am1
-rw-r--r--src/FbTk/SimpleCommand.hh12
-rw-r--r--src/WorkspaceCmd.cc49
-rw-r--r--src/WorkspaceCmd.hh28
11 files changed, 486 insertions, 43 deletions
diff --git a/ChangeLog b/ChangeLog
index 95cce9a..18c51ed 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
1 (Format: Year/Month/Day) 1 (Format: Year/Month/Day)
2Changes for 1.0.1: 2Changes for 1.0.1:
3*07/11/22:
4 * Added conditional statements to key commands (Mark)
5 - for example, this will search for an open xterm window, cycle through
6 them if there are any, or else open one:
7 Mod4 t :If {Some Matches (xterm)} {NextWindow (xterm)} {Exec xterm}
8 - the syntax is :If {<test>} {<command if true>} {<command if false>}
9 - `Matches <pattern>' is currently the only test you can make; when used
10 alone, it tests the focused window or the clicked window for OnWindow
11 mouse events
12 - there are many ways to combine tests:
13 - `Some <test>' returns true if any open client matches <test>
14 - `Every <test>' returns true if every open client matches <test>
15 - `Not <test>' negates the value of <test>
16 - `Or {<test>} {<test>} ...' returns true if any of the tests is true
17 - `And {<test>} {<test>} ...' returns true if all of the tests are true
18 - `Xor {<test>} {<test>} ...' returns the boolean xor of the truth values
19 FbCommandFactory.cc CurrentWindowCmd.cc/hh WorkspaceCmd.cc/hh
20 FbTk/Command.hh FbTk/SimpleCommand.hh, added files FbTk/LogicCommands.cc/hh
3*07/11/16: 21*07/11/16:
4 * Added new key command :Focus [<pattern>] that focuses a window (e.g., using 22 * Added new key command :Focus [<pattern>] that focuses a window (e.g., using
5 OnWindow or specified using a window pattern) (Mark, thanks Tomas Janousek) 23 OnWindow or specified using a window pattern) (Mark, thanks Tomas Janousek)
diff --git a/src/CurrentWindowCmd.cc b/src/CurrentWindowCmd.cc
index 929be5d..a5265f9 100644
--- a/src/CurrentWindowCmd.cc
+++ b/src/CurrentWindowCmd.cc
@@ -33,20 +33,25 @@
33#include "FocusControl.hh" 33#include "FocusControl.hh"
34 34
35void WindowHelperCmd::execute() { 35void WindowHelperCmd::execute() {
36 m_win = 0;
37 if (WindowCmd<void>::window() || FocusControl::focusedFbWindow()) 36 if (WindowCmd<void>::window() || FocusControl::focusedFbWindow())
38 real_execute(); 37 real_execute();
39} 38}
40 39
41void WindowHelperCmd::execute(FluxboxWindow &win) { 40FluxboxWindow &WindowHelperCmd::fbwindow() {
42 m_win = &win; 41 // will exist from execute above
43 real_execute(); 42 FluxboxWindow *tmp = WindowCmd<void>::window();
43 if (tmp) return *tmp;
44 return *FocusControl::focusedFbWindow();
44} 45}
45 46
46FluxboxWindow &WindowHelperCmd::fbwindow() { 47bool WindowHelperBoolCmd::bool_execute() {
48 if (WindowCmd<void>::window() || FocusControl::focusedFbWindow())
49 return real_execute();
50 return false;
51}
52
53FluxboxWindow &WindowHelperBoolCmd::fbwindow() {
47 // will exist from execute above 54 // will exist from execute above
48 if (m_win)
49 return *m_win;
50 FluxboxWindow *tmp = WindowCmd<void>::window(); 55 FluxboxWindow *tmp = WindowCmd<void>::window();
51 if (tmp) return *tmp; 56 if (tmp) return *tmp;
52 return *FocusControl::focusedFbWindow(); 57 return *FocusControl::focusedFbWindow();
@@ -227,3 +232,7 @@ void SetAlphaCmd::real_execute() {
227 } else 232 } else
228 fbwindow().setUnfocusedAlpha(m_unfocus); 233 fbwindow().setUnfocusedAlpha(m_unfocus);
229} 234}
235
236bool MatchCmd::real_execute() {
237 return m_pat.match(fbwindow());
238}
diff --git a/src/CurrentWindowCmd.hh b/src/CurrentWindowCmd.hh
index 53dc7b8..e7370de 100644
--- a/src/CurrentWindowCmd.hh
+++ b/src/CurrentWindowCmd.hh
@@ -27,22 +27,30 @@
27 27
28#include "Command.hh" 28#include "Command.hh"
29#include "Window.hh" 29#include "Window.hh"
30#include "ClientPattern.hh"
30 31
31/// helper class for window commands 32/// helper class for window commands
32/// calls real_execute if there's a focused window or a window in button press/release window 33/// calls real_execute if there's a focused window or a window in button press/release window
33class WindowHelperCmd: public FbTk::Command { 34class WindowHelperCmd: public FbTk::Command {
34public: 35public:
35 explicit WindowHelperCmd(FluxboxWindow *win = 0): m_win(win) { } 36 explicit WindowHelperCmd() { }
36 37
37 void execute(); 38 void execute();
38 void execute(FluxboxWindow &fbwin);
39 39
40protected: 40protected:
41 FluxboxWindow &fbwindow(); 41 FluxboxWindow &fbwindow();
42 virtual void real_execute() = 0; 42 virtual void real_execute() = 0;
43};
43 44
44private: 45class WindowHelperBoolCmd: public FbTk::BoolCommand {
45 FluxboxWindow *m_win; 46public:
47 explicit WindowHelperBoolCmd() { }
48
49 bool bool_execute();
50
51protected:
52 FluxboxWindow &fbwindow();
53 virtual bool real_execute() = 0;
46}; 54};
47 55
48/// command that calls FluxboxWindow::<the function> on execute() 56/// command that calls FluxboxWindow::<the function> on execute()
@@ -221,4 +229,14 @@ private:
221 int m_focus, m_unfocus; 229 int m_focus, m_unfocus;
222 int m_relative, m_un_relative; 230 int m_relative, m_un_relative;
223}; 231};
232
233class MatchCmd: public WindowHelperBoolCmd {
234public:
235 MatchCmd(const std::string &pat): m_pat(pat.c_str()) { };
236protected:
237 bool real_execute();
238private:
239 ClientPattern m_pat;
240};
241
224#endif // CURRENTWINDOWCMD_HH 242#endif // CURRENTWINDOWCMD_HH
diff --git a/src/FbCommandFactory.cc b/src/FbCommandFactory.cc
index ce024eb..92099f2 100644
--- a/src/FbCommandFactory.cc
+++ b/src/FbCommandFactory.cc
@@ -34,6 +34,7 @@
34#include "Screen.hh" 34#include "Screen.hh"
35 35
36#include "FbTk/StringUtil.hh" 36#include "FbTk/StringUtil.hh"
37#include "FbTk/LogicCommands.hh"
37#include "FbTk/MacroCommand.hh" 38#include "FbTk/MacroCommand.hh"
38#include "FbTk/stringstream.hh" 39#include "FbTk/stringstream.hh"
39 40
@@ -50,6 +51,10 @@ using std::vector;
50using std::cerr; 51using std::cerr;
51using std::endl; 52using std::endl;
52 53
54using namespace FbTk;
55using FbTk::StringUtil::removeFirstWhitespace;
56using FbTk::StringUtil::toLower;
57
53// autoregister this module to command parser 58// autoregister this module to command parser
54FbCommandFactory FbCommandFactory::s_autoreg; 59FbCommandFactory FbCommandFactory::s_autoreg;
55 60
@@ -60,6 +65,109 @@ static int getint(const char *str, int defaultvalue) {
60 return defaultvalue; 65 return defaultvalue;
61} 66}
62 67
68BoolCommand *parseBoolCommand(string &line, bool trusted) {
69 // parse arguments and command
70 string command = line;
71 string arguments;
72 string::size_type first_pos = removeFirstWhitespace(command);
73 FbTk::StringUtil::removeTrailingWhitespace(command);
74 string::size_type second_pos = command.find_first_of(" \t", first_pos);
75 if (second_pos != string::npos) {
76 // ok we have arguments, parsing them here
77 arguments = command.substr(second_pos);
78 removeFirstWhitespace(arguments);
79 command.erase(second_pos); // remove argument from command
80 }
81
82 // now we have parsed command and arguments
83 command = toLower(command);
84
85 if (command == "matches") {
86 return new MatchCmd(arguments);
87 } else if (command == "some") {
88 BoolCommand *boolcmd = parseBoolCommand(arguments, trusted);
89 if (!boolcmd)
90 return 0;
91 return new SomeCmd(RefCount<BoolCommand>(boolcmd));
92 } else if (command == "every") {
93 BoolCommand *boolcmd = parseBoolCommand(arguments, trusted);
94 if (!boolcmd)
95 return 0;
96 return new EveryCmd(RefCount<BoolCommand>(boolcmd));
97 } else if (command == "not") {
98 BoolCommand *boolcmd = parseBoolCommand(arguments, trusted);
99 if (!boolcmd)
100 return 0;
101 RefCount<BoolCommand> ref(boolcmd);
102 return new NotCommand(ref);
103 } else if (command == "and") {
104 int pos = 0, err = 0;
105 AndCommand *andcmd = new AndCommand();
106 string cmd;
107
108 while (true) {
109 RefCount<BoolCommand> tmp(0);
110 err = StringUtil::getStringBetween(cmd, arguments.c_str() + pos,
111 '{', '}', " \t\n", true);
112 pos += err;
113 if (err == 0)
114 break;
115
116 tmp = parseBoolCommand(cmd, trusted);
117 if (*tmp)
118 andcmd->add(tmp);
119 }
120
121 if (andcmd->size() > 0)
122 return andcmd;
123 delete andcmd;
124 } else if (command == "or") {
125 int pos = 0, err = 0;
126 OrCommand *orcmd = new OrCommand();
127 string cmd;
128
129 while (true) {
130 RefCount<BoolCommand> tmp(0);
131 err = StringUtil::getStringBetween(cmd, arguments.c_str() + pos,
132 '{', '}', " \t\n", true);
133 pos += err;
134 if (err == 0)
135 break;
136
137 tmp = parseBoolCommand(cmd, trusted);
138 if (*tmp)
139 orcmd->add(tmp);
140 }
141
142 if (orcmd->size() > 0)
143 return orcmd;
144 delete orcmd;
145 } else if (command == "xor") {
146 int pos = 0, err = 0;
147 XorCommand *xorcmd = new XorCommand();
148 string cmd;
149
150 while (true) {
151 RefCount<BoolCommand> tmp(0);
152 err = StringUtil::getStringBetween(cmd, arguments.c_str() + pos,
153 '{', '}', " \t\n", true);
154 pos += err;
155 if (err == 0)
156 break;
157
158 tmp = parseBoolCommand(cmd, trusted);
159 if (*tmp)
160 xorcmd->add(tmp);
161 }
162
163 if (xorcmd->size() > 0)
164 return xorcmd;
165 delete xorcmd;
166 }
167
168 return 0;
169}
170
63}; // end anonymous namespace 171}; // end anonymous namespace
64 172
65FbCommandFactory::FbCommandFactory() { 173FbCommandFactory::FbCommandFactory() {
@@ -74,6 +182,7 @@ FbCommandFactory::FbCommandFactory() {
74 "close", 182 "close",
75 "closeallwindows", 183 "closeallwindows",
76 "commanddialog", 184 "commanddialog",
185 "cond",
77 "custommenu", 186 "custommenu",
78 "deiconify", 187 "deiconify",
79 "detachclient", 188 "detachclient",
@@ -91,6 +200,7 @@ FbCommandFactory::FbCommandFactory() {
91 "gotowindow", 200 "gotowindow",
92 "hidemenus", 201 "hidemenus",
93 "iconify", 202 "iconify",
203 "if",
94 "keymode", 204 "keymode",
95 "kill", 205 "kill",
96 "killwindow", 206 "killwindow",
@@ -246,15 +356,15 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
246 // Current focused window commands 356 // Current focused window commands
247 // 357 //
248 else if (command == "fullscreen") 358 else if (command == "fullscreen")
249 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new FullscreenCmd()), arguments); 359 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new FullscreenCmd()), arguments);
250 else if (command == "minimizewindow" || command == "minimize" || command == "iconify") 360 else if (command == "minimizewindow" || command == "minimize" || command == "iconify")
251 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::iconify)), arguments); 361 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::iconify)), arguments);
252 else if (command == "maximizewindow" || command == "maximize") 362 else if (command == "maximizewindow" || command == "maximize")
253 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::maximizeFull)), arguments); 363 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::maximizeFull)), arguments);
254 else if (command == "maximizevertical") 364 else if (command == "maximizevertical")
255 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::maximizeVertical)), arguments); 365 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::maximizeVertical)), arguments);
256 else if (command == "maximizehorizontal") 366 else if (command == "maximizehorizontal")
257 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::maximizeHorizontal)), arguments); 367 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::maximizeHorizontal)), arguments);
258 else if (command == "setalpha") { 368 else if (command == "setalpha") {
259 typedef vector<string> StringTokens; 369 typedef vector<string> StringTokens;
260 StringTokens tokens; 370 StringTokens tokens;
@@ -281,7 +391,7 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
281 if (pos != string::npos && pos != arguments.size()) 391 if (pos != string::npos && pos != arguments.size())
282 pat = arguments.c_str() + pos; 392 pat = arguments.c_str() + pos;
283 393
284 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new SetAlphaCmd(focused, relative, unfocused, un_rel)), pat); 394 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new SetAlphaCmd(focused, relative, unfocused, un_rel)), pat);
285 } else if (command == "startmoving") 395 } else if (command == "startmoving")
286 return new StartMovingCmd(); 396 return new StartMovingCmd();
287 else if (command == "startresizing") { 397 else if (command == "startresizing") {
@@ -331,7 +441,7 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
331 if (pos != string::npos && pos != arguments.size()) 441 if (pos != string::npos && pos != arguments.size())
332 pat = arguments.c_str() + pos; 442 pat = arguments.c_str() + pos;
333 443
334 FbTk::RefCount<WindowHelperCmd> cmd; 444 FbTk::RefCount<FbTk::Command> cmd;
335 if (command == "resizeto") 445 if (command == "resizeto")
336 cmd = new ResizeToCmd(dx, dy); 446 cmd = new ResizeToCmd(dx, dy);
337 else 447 else
@@ -386,7 +496,7 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
386 if (pos != string::npos && pos != arguments.size()) 496 if (pos != string::npos && pos != arguments.size())
387 pat = arguments.c_str() + pos; 497 pat = arguments.c_str() + pos;
388 498
389 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new MoveToCmd(dx, dy, refc)), pat); 499 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new MoveToCmd(dx, dy, refc)), pat);
390 } else if (command == "move" || command == "moveright" || 500 } else if (command == "move" || command == "moveright" ||
391 command == "moveleft" || command == "moveup" || 501 command == "moveleft" || command == "moveup" ||
392 command == "movedown") { 502 command == "movedown") {
@@ -412,29 +522,29 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
412 if (pos != string::npos && pos != arguments.size()) 522 if (pos != string::npos && pos != arguments.size())
413 pat = arguments.c_str() + pos; 523 pat = arguments.c_str() + pos;
414 524
415 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new MoveCmd(dx, dy)), pat); 525 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new MoveCmd(dx, dy)), pat);
416 } else if (command == "raise") 526 } else if (command == "raise")
417 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::raise)), arguments); 527 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::raise)), arguments);
418 else if (command == "raiselayer") 528 else if (command == "raiselayer")
419 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::raiseLayer)), arguments); 529 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::raiseLayer)), arguments);
420 else if (command == "lower") 530 else if (command == "lower")
421 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::lower)), arguments); 531 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::lower)), arguments);
422 else if (command == "lowerlayer") 532 else if (command == "lowerlayer")
423 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::lowerLayer)), arguments); 533 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::lowerLayer)), arguments);
424 else if (command == "activate" || command == "focus") 534 else if (command == "activate" || command == "focus")
425 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd((void (FluxboxWindow::*)())&FluxboxWindow::focus)), arguments); 535 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd((void (FluxboxWindow::*)())&FluxboxWindow::focus)), arguments);
426 else if (command == "close") 536 else if (command == "close")
427 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::close)), arguments); 537 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::close)), arguments);
428 else if (command == "closeallwindows") 538 else if (command == "closeallwindows")
429 return new CloseAllWindowsCmd(); 539 return new CloseAllWindowsCmd();
430 else if (command == "killwindow" || command == "kill") 540 else if (command == "killwindow" || command == "kill")
431 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::kill)), arguments); 541 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::kill)), arguments);
432 else if (command == "shade" || command == "shadewindow") 542 else if (command == "shade" || command == "shadewindow")
433 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::shade)), arguments); 543 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::shade)), arguments);
434 else if (command == "stick" || command == "stickwindow") 544 else if (command == "stick" || command == "stickwindow")
435 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::stick)), arguments); 545 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::stick)), arguments);
436 else if (command == "toggledecor") 546 else if (command == "toggledecor")
437 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::toggleDecoration)), arguments); 547 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::toggleDecoration)), arguments);
438 else if (command == "sethead") { 548 else if (command == "sethead") {
439 int num = 0; 549 int num = 0;
440 string pat; 550 string pat;
@@ -443,7 +553,7 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
443 string::size_type pos = arguments.find('('); 553 string::size_type pos = arguments.find('(');
444 if (pos != string::npos && pos != arguments.size()) 554 if (pos != string::npos && pos != arguments.size())
445 pat = arguments.c_str() + pos; 555 pat = arguments.c_str() + pos;
446 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new SetHeadCmd(num)), pat); 556 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new SetHeadCmd(num)), pat);
447 } else if (command == "tab" || command == "sendtonextworkspace" || 557 } else if (command == "tab" || command == "sendtonextworkspace" ||
448 command == "sendtoprevworkspace" || 558 command == "sendtoprevworkspace" ||
449 command == "taketonextworkspace" || 559 command == "taketonextworkspace" ||
@@ -457,7 +567,7 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
457 string::size_type pos = arguments.find('('); 567 string::size_type pos = arguments.find('(');
458 if (pos != string::npos && pos != arguments.size()) 568 if (pos != string::npos && pos != arguments.size())
459 pat = arguments.c_str() + pos; 569 pat = arguments.c_str() + pos;
460 FbTk::RefCount<WindowHelperCmd> cmd; 570 FbTk::RefCount<FbTk::Command> cmd;
461 571
462 if (command == "tab") 572 if (command == "tab")
463 cmd = new GoToTabCmd(num); 573 cmd = new GoToTabCmd(num);
@@ -475,15 +585,15 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
475 cmd = new TakeToWorkspaceCmd(num-1); 585 cmd = new TakeToWorkspaceCmd(num-1);
476 return new WindowListCmd(cmd, pat); 586 return new WindowListCmd(cmd, pat);
477 } else if (command == "nexttab") 587 } else if (command == "nexttab")
478 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::nextClient)), arguments); 588 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::nextClient)), arguments);
479 else if (command == "prevtab") 589 else if (command == "prevtab")
480 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::prevClient)), arguments); 590 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::prevClient)), arguments);
481 else if (command == "movetableft") 591 else if (command == "movetableft")
482 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::moveClientLeft)), arguments); 592 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::moveClientLeft)), arguments);
483 else if (command == "movetabright") 593 else if (command == "movetabright")
484 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::moveClientRight)), arguments); 594 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::moveClientRight)), arguments);
485 else if (command == "detachclient") 595 else if (command == "detachclient")
486 return new WindowListCmd(FbTk::RefCount<WindowHelperCmd>(new CurrentWindowCmd(&FluxboxWindow::detachCurrentClient)), arguments); 596 return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::detachCurrentClient)), arguments);
487 else if (command == "windowmenu") 597 else if (command == "windowmenu")
488 return new CurrentWindowCmd(&FluxboxWindow::popupMenu); 598 return new CurrentWindowCmd(&FluxboxWindow::popupMenu);
489 // 599 //
@@ -683,6 +793,36 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
683 return macro; 793 return macro;
684 794
685 delete macro; 795 delete macro;
796 } else if (command == "if" || command == "cond") {
797 string cmd;
798 int err = 0, pos = 0;
799 RefCount<BoolCommand> cond(0);
800 RefCount<Command> t(0), f(0);
801
802 err = FbTk::StringUtil::getStringBetween(cmd, arguments.c_str(),
803 '{', '}', " \t\n", true);
804 if (err > 0)
805 cond = parseBoolCommand(cmd, trusted);
806 if (err == 0 || *cond == 0)
807 return 0;
808
809 pos = err;
810 err = FbTk::StringUtil::getStringBetween(cmd, arguments.c_str() + pos,
811 '{', '}', " \t\n", true);
812 if (err > 0)
813 t = CommandParser::instance().parseLine(cmd, trusted);
814 if (err == 0 || *t == 0)
815 return 0;
816
817 pos += err;
818 err = FbTk::StringUtil::getStringBetween(cmd, arguments.c_str() + pos,
819 '{', '}', " \t\n", true);
820 if (err > 0)
821 f = CommandParser::instance().parseLine(cmd, trusted);
822 if (err == 0 || *f == 0)
823 return 0;
824
825 return new FbTk::IfCommand(cond, t, f);
686 } 826 }
687 return 0; 827 return 0;
688} 828}
diff --git a/src/FbTk/Command.hh b/src/FbTk/Command.hh
index 391aa78..5d38cb8 100644
--- a/src/FbTk/Command.hh
+++ b/src/FbTk/Command.hh
@@ -31,6 +31,14 @@ public:
31 virtual void execute() = 0; 31 virtual void execute() = 0;
32}; 32};
33 33
34/// Interface class for boolean commands
35class BoolCommand: public Command {
36public:
37 virtual ~BoolCommand() { }
38 virtual void execute() { bool_execute(); }
39 virtual bool bool_execute() = 0;
40};
41
34} // end namespace FbTk 42} // end namespace FbTk
35 43
36#endif // FBTK_COMMAND_HH 44#endif // FBTK_COMMAND_HH
diff --git a/src/FbTk/LogicCommands.cc b/src/FbTk/LogicCommands.cc
new file mode 100644
index 0000000..99b5b53
--- /dev/null
+++ b/src/FbTk/LogicCommands.cc
@@ -0,0 +1,75 @@
1// LogicCommands.cc for FbTk
2// Copyright (c) 2007 Fluxbox Team (fluxgen at fluxbox dot org)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22// $Id: $
23
24#include "LogicCommands.hh"
25
26namespace FbTk {
27
28void OrCommand::add(RefCount<BoolCommand> &com) {
29 m_commandlist.push_back(com);
30}
31
32size_t OrCommand::size() const {
33 return m_commandlist.size();
34}
35
36bool OrCommand::bool_execute() {
37 for (size_t i=0; i < m_commandlist.size(); ++i) {
38 if (m_commandlist[i]->bool_execute())
39 return true;
40 }
41 return false;
42}
43
44void AndCommand::add(RefCount<BoolCommand> &com) {
45 m_commandlist.push_back(com);
46}
47
48size_t AndCommand::size() const {
49 return m_commandlist.size();
50}
51
52bool AndCommand::bool_execute() {
53 for (size_t i=0; i < m_commandlist.size(); ++i) {
54 if (!m_commandlist[i]->bool_execute())
55 return false;
56 }
57 return true;
58}
59
60void XorCommand::add(RefCount<BoolCommand> &com) {
61 m_commandlist.push_back(com);
62}
63
64size_t XorCommand::size() const {
65 return m_commandlist.size();
66}
67
68bool XorCommand::bool_execute() {
69 bool ret = false;
70 for (size_t i=0; i < m_commandlist.size(); ++i)
71 ret ^= m_commandlist[i]->bool_execute();
72 return ret;
73}
74
75}; // end namespace FbTk
diff --git a/src/FbTk/LogicCommands.hh b/src/FbTk/LogicCommands.hh
new file mode 100644
index 0000000..a94dad8
--- /dev/null
+++ b/src/FbTk/LogicCommands.hh
@@ -0,0 +1,97 @@
1// LogicCommands.hh for FbTk
2// Copyright (c) 2007 Fluxbox Team (fluxgen at fluxbox dot org)
3//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in
12// all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
21
22// $Id: $
23
24#ifndef FBTK_LOGICCOMMANDS_HH
25#define FBTK_LOGICCOMMANDS_HH
26
27#include "Command.hh"
28#include "RefCount.hh"
29
30#include <vector>
31
32namespace FbTk {
33
34/// executes a boolcommand and uses the result to decide what to do
35class IfCommand: public Command {
36public:
37 IfCommand(RefCount<BoolCommand> &cond,
38 RefCount<Command> &t, RefCount<Command> &f):
39 m_cond(cond), m_t(t), m_f(f) { }
40 void execute() {
41 if (m_cond->bool_execute())
42 m_t->execute();
43 else
44 m_f->execute();
45 }
46
47private:
48 RefCount<BoolCommand> m_cond;
49 RefCount<Command> m_t, m_f;
50};
51
52/// executes a list of boolcommands until one is true
53class OrCommand: public BoolCommand {
54public:
55 void add(RefCount<BoolCommand> &com);
56 size_t size() const;
57 bool bool_execute();
58
59private:
60 std::vector<RefCount<BoolCommand> > m_commandlist;
61};
62
63/// executes a list of boolcommands until one is false
64class AndCommand: public BoolCommand {
65public:
66 void add(RefCount<BoolCommand> &com);
67 size_t size() const;
68 bool bool_execute();
69
70private:
71 std::vector<RefCount<BoolCommand> > m_commandlist;
72};
73
74/// executes a list of boolcommands, returning the parity
75class XorCommand: public BoolCommand {
76public:
77 void add(RefCount<BoolCommand> &com);
78 size_t size() const;
79 bool bool_execute();
80
81private:
82 std::vector<RefCount<BoolCommand> > m_commandlist;
83};
84
85/// executes a boolcommand and returns the negation
86class NotCommand: public BoolCommand {
87public:
88 NotCommand(RefCount<BoolCommand> &com): m_command(com) { }
89 bool bool_execute() { return !m_command->bool_execute(); }
90
91private:
92 RefCount<BoolCommand> m_command;
93};
94
95} // end namespace FbTk
96
97#endif // FBTK_LOGICCOMMANDS_HH
diff --git a/src/FbTk/Makefile.am b/src/FbTk/Makefile.am
index d98c8f6..2bf9da7 100644
--- a/src/FbTk/Makefile.am
+++ b/src/FbTk/Makefile.am
@@ -21,6 +21,7 @@ libFbTk_a_SOURCES = App.hh App.cc Color.cc Color.hh Command.hh \
21 FbWindow.hh FbWindow.cc Font.cc Font.hh FontImp.hh \ 21 FbWindow.hh FbWindow.cc Font.cc Font.hh FontImp.hh \
22 I18n.cc I18n.hh \ 22 I18n.cc I18n.hh \
23 ImageControl.hh ImageControl.cc \ 23 ImageControl.hh ImageControl.cc \
24 LogicCommands.hh LogicCommands.cc \
24 MacroCommand.hh MacroCommand.cc \ 25 MacroCommand.hh MacroCommand.cc \
25 Menu.hh Menu.cc MenuItem.hh MenuItem.cc \ 26 Menu.hh Menu.cc MenuItem.hh MenuItem.cc \
26 MultiButtonMenuItem.hh MultiButtonMenuItem.cc \ 27 MultiButtonMenuItem.hh MultiButtonMenuItem.cc \
diff --git a/src/FbTk/SimpleCommand.hh b/src/FbTk/SimpleCommand.hh
index 8cc7283..7ae91a5 100644
--- a/src/FbTk/SimpleCommand.hh
+++ b/src/FbTk/SimpleCommand.hh
@@ -39,6 +39,18 @@ private:
39 Action m_action; 39 Action m_action;
40}; 40};
41 41
42template <typename Receiver, typename ReturnType=bool>
43class SimpleBoolCommand: public BoolCommand {
44public:
45 typedef ReturnType (Receiver::* Action)();
46 SimpleBoolCommand(Receiver &r, Action a):
47 m_receiver(r), m_action(a) { }
48 bool bool_execute() { return (bool)(m_receiver.*m_action)(); }
49private:
50 Receiver &m_receiver;
51 Action m_action;
52};
53
42} // end namespace FbTk 54} // end namespace FbTk
43 55
44#endif // FBTK_SIMPLECOMMAND_HH 56#endif // FBTK_SIMPLECOMMAND_HH
diff --git a/src/WorkspaceCmd.cc b/src/WorkspaceCmd.cc
index 79ceb40..26f113d 100644
--- a/src/WorkspaceCmd.cc
+++ b/src/WorkspaceCmd.cc
@@ -30,6 +30,7 @@
30#include "fluxbox.hh" 30#include "fluxbox.hh"
31#include "WinClient.hh" 31#include "WinClient.hh"
32#include "FocusControl.hh" 32#include "FocusControl.hh"
33#include "WindowCmd.hh"
33 34
34#include "FbTk/KeyUtil.hh" 35#include "FbTk/KeyUtil.hh"
35 36
@@ -54,10 +55,54 @@ void WindowListCmd::execute() {
54 FocusControl::Focusables::iterator it = win_list.begin(), 55 FocusControl::Focusables::iterator it = win_list.begin(),
55 it_end = win_list.end(); 56 it_end = win_list.end();
56 for (; it != it_end; ++it) { 57 for (; it != it_end; ++it) {
57 if (m_pat.match(**it) && (*it)->fbwindow()) 58 if (m_pat.match(**it) && (*it)->fbwindow()) {
58 m_cmd->execute(*(*it)->fbwindow()); 59 WindowCmd<void>::setWindow((*it)->fbwindow());
60 m_cmd->execute();
61 }
62 }
63 }
64}
65
66bool SomeCmd::bool_execute() {
67 if (m_pat.error())
68 return m_cmd->bool_execute();
69
70 BScreen *screen = Fluxbox::instance()->keyScreen();
71 if (screen != 0) {
72 FocusControl::Focusables win_list(screen->focusControl().creationOrderList().clientList());
73
74 FocusControl::Focusables::iterator it = win_list.begin(),
75 it_end = win_list.end();
76 for (; it != it_end; ++it) {
77 WinClient *client = dynamic_cast<WinClient *>(*it);
78 if (!client) continue;
79 WindowCmd<void>::setClient(client);
80 if (m_cmd->bool_execute())
81 return true;
82 }
83 }
84 return false;
85}
86
87bool EveryCmd::bool_execute() {
88 if (m_pat.error())
89 return m_cmd->bool_execute();
90
91 BScreen *screen = Fluxbox::instance()->keyScreen();
92 if (screen != 0) {
93 FocusControl::Focusables win_list(screen->focusControl().creationOrderList().clientList());
94
95 FocusControl::Focusables::iterator it = win_list.begin(),
96 it_end = win_list.end();
97 for (; it != it_end; ++it) {
98 WinClient *client = dynamic_cast<WinClient *>(*it);
99 if (!client) continue;
100 WindowCmd<void>::setClient(client);
101 if (!m_cmd->bool_execute())
102 return false;
59 } 103 }
60 } 104 }
105 return true;
61} 106}
62 107
63void AttachCmd::execute() { 108void AttachCmd::execute() {
diff --git a/src/WorkspaceCmd.hh b/src/WorkspaceCmd.hh
index a530ae8..4f4545d 100644
--- a/src/WorkspaceCmd.hh
+++ b/src/WorkspaceCmd.hh
@@ -32,17 +32,37 @@
32 32
33#include "FbTk/RefCount.hh" 33#include "FbTk/RefCount.hh"
34 34
35class WindowHelperCmd;
36
37class WindowListCmd: public FbTk::Command { 35class WindowListCmd: public FbTk::Command {
38public: 36public:
39 WindowListCmd(FbTk::RefCount<WindowHelperCmd> cmd, const std::string &pat): 37 WindowListCmd(FbTk::RefCount<FbTk::Command> cmd, const std::string &pat):
40 m_cmd(cmd), m_pat(pat.c_str()) { } 38 m_cmd(cmd), m_pat(pat.c_str()) { }
41 39
42 void execute(); 40 void execute();
43 41
44private: 42private:
45 FbTk::RefCount<WindowHelperCmd> m_cmd; 43 FbTk::RefCount<FbTk::Command> m_cmd;
44 ClientPattern m_pat;
45};
46
47class SomeCmd: public FbTk::BoolCommand {
48public:
49 SomeCmd(FbTk::RefCount<FbTk::BoolCommand> cmd): m_cmd(cmd) { }
50
51 bool bool_execute();
52
53private:
54 FbTk::RefCount<FbTk::BoolCommand> m_cmd;
55 ClientPattern m_pat;
56};
57
58class EveryCmd: public FbTk::BoolCommand {
59public:
60 EveryCmd(FbTk::RefCount<FbTk::BoolCommand> cmd): m_cmd(cmd) { }
61
62 bool bool_execute();
63
64private:
65 FbTk::RefCount<FbTk::BoolCommand> m_cmd;
46 ClientPattern m_pat; 66 ClientPattern m_pat;
47}; 67};
48 68