aboutsummaryrefslogtreecommitdiff
path: root/src/Keys.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/Keys.cc')
-rw-r--r--src/Keys.cc302
1 files changed, 35 insertions, 267 deletions
diff --git a/src/Keys.cc b/src/Keys.cc
index 64ca79d..7de7d33 100644
--- a/src/Keys.cc
+++ b/src/Keys.cc
@@ -19,13 +19,15 @@
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE. 20// DEALINGS IN THE SOFTWARE.
21 21
22//$Id: Keys.cc,v 1.31 2003/06/15 11:38:35 rathnor Exp $ 22//$Id: Keys.cc,v 1.32 2003/06/30 14:57:14 fluxgen Exp $
23 23
24 24
25#include "Keys.hh" 25#include "Keys.hh"
26 26
27#include "StringUtil.hh" 27#include "StringUtil.hh"
28#include "App.hh" 28#include "App.hh"
29#include "Command.hh"
30#include "CommandParser.hh"
29 31
30#ifdef HAVE_CONFIG_H 32#ifdef HAVE_CONFIG_H
31#include "config.h" 33#include "config.h"
@@ -69,80 +71,6 @@
69 71
70using namespace std; 72using namespace std;
71 73
72Keys::t_actionstr Keys::m_actionlist[] = {
73 {"Minimize", ICONIFY},
74 {"Raise", RAISE},
75 {"Lower", LOWER},
76 {"RaiseLayer", RAISELAYER},
77 {"LowerLayer", LOWERLAYER},
78 {"TopLayer", TOPLAYER},
79 {"BottomLayer", BOTTOMLAYER},
80 {"AlwaysOnTop", TOPLAYER},
81 {"AlwaysOnBottom", BOTTOMLAYER},
82 {"Close", CLOSE},
83 {"AbortKeychain", ABORTKEYCHAIN},
84 {"Workspace", WORKSPACE},
85 {"Workspace1", WORKSPACE1},
86 {"Workspace2", WORKSPACE2},
87 {"Workspace3", WORKSPACE3},
88 {"Workspace4", WORKSPACE4},
89 {"Workspace5", WORKSPACE5},
90 {"Workspace6", WORKSPACE6},
91 {"Workspace7", WORKSPACE7},
92 {"Workspace8", WORKSPACE8},
93 {"Workspace9", WORKSPACE9},
94 {"Workspace10", WORKSPACE10},
95 {"Workspace11", WORKSPACE11},
96 {"Workspace12", WORKSPACE12},
97 {"SendToWorkspace", SENDTOWORKSPACE},
98 {"NextWorkspace", NEXTWORKSPACE},
99 {"PrevWorkspace", PREVWORKSPACE},
100 {"LeftWorkspace", LEFTWORKSPACE},
101 {"RightWorkspace", RIGHTWORKSPACE},
102 {"KillWindow", KILLWINDOW},
103 {"NextWindow", NEXTWINDOW},
104 {"PrevWindow", PREVWINDOW},
105 {"NextGroup", NEXTGROUP},
106 {"PrevGroup", PREVGROUP},
107 {"NextTab", NEXTTAB},
108 {"PrevTab", PREVTAB},
109 {"FirstTab", FIRSTTAB},
110 {"LastTab", LASTTAB},
111 {"MoveTabPrev", MOVETABPREV},
112 {"MoveTabNext", MOVETABNEXT},
113 {"AttachLast", ATTACHLAST},
114 {"DetachClient", DETACHCLIENT},
115 {"FocusUp", FOCUSUP},
116 {"FocusDown", FOCUSDOWN},
117 {"FocusLeft", FOCUSLEFT},
118 {"FocusRight", FOCUSRIGHT},
119 {"ShadeWindow", SHADE},
120 {"MaximizeWindow", MAXIMIZE},
121 {"StickWindow", STICK},
122 {"ExecCommand", EXECUTE},
123 {"MaximizeVertical", VERTMAX},
124 {"MaximizeHorizontal", HORIZMAX},
125 {"NudgeRight", NUDGERIGHT},
126 {"NudgeLeft", NUDGELEFT},
127 {"NudgeUp", NUDGEUP},
128 {"NudgeDown", NUDGEDOWN},
129 {"BigNudgeRight", BIGNUDGERIGHT},
130 {"BigNudgeLeft", BIGNUDGELEFT},
131 {"BigNudgeUp", BIGNUDGEUP},
132 {"BigNudgeDown", BIGNUDGEDOWN},
133 {"HorizontalIncrement", HORIZINC},
134 {"VerticalIncrement", VERTINC},
135 {"HorizontalDecrement", HORIZDEC},
136 {"VerticalDecrement", VERTDEC},
137 {"ToggleDecor", TOGGLEDECOR},
138 {"ToggleTab", TOGGLETAB},
139 {"RootMenu", ROOTMENU},
140 {"Reconfigure", RECONFIGURE},
141 {"Restart", RESTART},
142 {"Quit", QUIT},
143 {0, LASTKEYGRAB}
144};
145
146Keys::Keys(const char *filename): 74Keys::Keys(const char *filename):
147 m_capslock_mod(0), 75 m_capslock_mod(0),
148 m_numlock_mod(0), 76 m_numlock_mod(0),
@@ -232,7 +160,7 @@ bool Keys::load(const char *filename) {
232 160
233 for (unsigned int argc=0; argc<val.size(); argc++) { 161 for (unsigned int argc=0; argc<val.size(); argc++) {
234 162
235 if (val[argc][0] != ':') { 163 if (val[argc][0] != ':') { // parse key(s)
236 keyarg++; 164 keyarg++;
237 if (keyarg==1) //first arg is modifier 165 if (keyarg==1) //first arg is modifier
238 mod = getModifier(val[argc].c_str()); 166 mod = getModifier(val[argc].c_str());
@@ -260,127 +188,28 @@ bool Keys::load(const char *filename) {
260 } 188 }
261 } 189 }
262 190
263 } else { 191 } else { // parse command line
264
265 unsigned int i=0;
266
267 for (i=0; i< LASTKEYGRAB; i++) {
268 // +1 on the val[argc] because we dont want to compare the ':'
269 if (strcasecmp(m_actionlist[i].string, val[argc].c_str()+1) == 0) {
270 break;
271 }
272 }
273 192
274 if (i < LASTKEYGRAB ) { 193 // +1 to remove the first ':'
275 if (!current_key) { 194 last_key->m_command = CommandParser::instance().parseLine(val[argc].c_str() + 1);
276 cerr<<"Error on line: "<<line<<endl;
277 cerr<<linebuffer<<endl;
278 delete current_key;
279 current_key = 0;
280 last_key = 0;
281 break; //break out and read next line
282 }
283
284 //special case for grabAbortKeychain
285 if (m_actionlist[i].action == ABORTKEYCHAIN) {
286 if (last_key!=current_key)
287 cerr<<"Keys: "<<m_actionlist[i].string<<" cant be in chained mode"<<endl;
288 else if (m_abortkey)
289 cerr<<"Keys: "<<m_actionlist[i].string<<" is already bound."<<endl;
290 else
291 m_abortkey = new t_key(current_key->key, current_key->mod, ABORTKEYCHAIN);
292
293 delete current_key;
294 current_key = 0;
295 last_key = 0;
296 break; //break out and read next line
297 }
298
299 last_key->action = m_actionlist[i].action;
300
301 switch(last_key->action) {
302 case Keys::RESTART:
303 case Keys::EXECUTE: {
304 // skip past the command
305 const char *str =
306 FbTk::StringUtil::strcasestr(
307 linebuffer.c_str(),
308 getActionStr(last_key->action))
309 + strlen(getActionStr(last_key->action));
310
311 int i=0;
312 // skip past any trailing whitespace
313 while (str[i] == ' ' || str[i] == '\t')
314 ++i;
315
316 last_key->execcommand = str + i;
317 } break;
318 case WORKSPACE:
319 case SENDTOWORKSPACE:
320 if (argc + 1 < val.size())
321 last_key->param = atoi( val[argc+1].c_str());
322 else
323 last_key->param = 0;
324 break;
325 case NEXTGROUP:
326 case PREVGROUP:
327 if (argc + 1 < val.size())
328 last_key->param = atoi( val[argc+1].c_str()) ^ 1;
329 else
330 last_key->param = 1;
331 break;
332 case NEXTWINDOW:
333 case PREVWINDOW:
334 if (argc + 1 < val.size())
335 last_key->param = atoi( val[argc+1].c_str());
336 else
337 last_key->param = 0;
338 break;
339 case LEFTWORKSPACE:
340 case RIGHTWORKSPACE:
341 case NEXTWORKSPACE:
342 case PREVWORKSPACE:
343 if (argc + 1 < val.size())
344 last_key->param = atoi( val[argc+1].c_str());
345 else
346 last_key->param = 1;
347 break;
348 case NUDGERIGHT:
349 case NUDGELEFT:
350 case NUDGEUP:
351 case NUDGEDOWN:
352 if (argc + 1 < val.size())
353 last_key->param = atoi( val[argc+1].c_str());
354 else
355 last_key->param = 2;
356 break;
357 default:
358 break;
359 }
360 195
361 //add the keychain to list 196 if (*last_key->m_command == 0) {
197 cerr<<"File: "<<filename<<". Error on line: "<<line<<endl;
198 cerr<<"> "<<linebuffer<<endl;
199 } else {
200 // Add the keychain to list
362 if (!mergeTree(current_key)) 201 if (!mergeTree(current_key))
363 cerr<<"Keys: Failed to merge keytree!"<<endl; 202 cerr<<"Keys: Failed to merge keytree!"<<endl;
364
365 //clear keypointers now that we have them in m_keylist
366 delete current_key;
367 current_key = 0;
368 last_key = 0;
369
370 } else { //destroy list if no action is found
371#ifdef DEBUG
372 cerr<<"Didnt find action="<<val[argc]<<endl;
373#endif // DEBUG
374 //destroy current_key ... this will also destroy the last_key
375 delete current_key;
376 current_key = 0;
377 last_key = 0;
378 } 203 }
379 204
380 break; //dont process this linebuffer more 205 delete current_key;
206 current_key = 0;
207 last_key = 0;
208
209 break; // dont process this linebuffer more
381 } // end if 210 } // end if
382 } // end for 211 } // end for
383 } // end while 212 } // end while eof
384 213
385 return true; 214 return true;
386} 215}
@@ -484,15 +313,10 @@ unsigned int Keys::getKey(const char *keystr) {
484/** 313/**
485 @return the KeyAction of the XKeyEvent 314 @return the KeyAction of the XKeyEvent
486*/ 315*/
487Keys::KeyAction Keys::getAction(XKeyEvent *ke) { 316void Keys::doAction(XKeyEvent &ke) {
488 static t_key *next_key = 0; 317 static t_key *next_key = 0;
489 //remove numlock, capslock and scrolllock 318 // Remove numlock, capslock and scrolllock
490 ke->state = cleanMods(ke->state); 319 ke.state = cleanMods(ke.state);
491
492 if (m_abortkey && *m_abortkey==ke) { //abort current keychain
493 next_key = 0;
494 return m_abortkey->action;
495 }
496 320
497 if (!next_key) { 321 if (!next_key) {
498 322
@@ -502,11 +326,8 @@ Keys::KeyAction Keys::getAction(XKeyEvent *ke) {
502 next_key = m_keylist[i]; 326 next_key = m_keylist[i];
503 break; //end for-loop 327 break; //end for-loop
504 } else { 328 } else {
505 if (m_keylist[i]->action == Keys::EXECUTE || 329 if (*m_keylist[i]->m_command != 0)
506 m_keylist[i]->action == Keys::RESTART) 330 m_keylist[i]->m_command->execute();
507 m_execcmdstring = m_keylist[i]->execcommand; //update execcmdstring if action is grabExecute
508 m_param = m_keylist[i]->param;
509 return m_keylist[i]->action;
510 } 331 }
511 } 332 }
512 } 333 }
@@ -518,23 +339,17 @@ Keys::KeyAction Keys::getAction(XKeyEvent *ke) {
518 next_key = temp_key; 339 next_key = temp_key;
519 } else { 340 } else {
520 next_key = 0; 341 next_key = 0;
521 if (temp_key->action == Keys::EXECUTE || 342 if (*temp_key->m_command != 0)
522 temp_key->action == Keys::RESTART) 343 temp_key->m_command->execute();
523 m_execcmdstring = temp_key->execcommand; //update execcmdstring if action is grabExecute
524 return temp_key->action;
525 } 344 }
526 } else { 345 } else {
527 temp_key = next_key; 346 temp_key = next_key;
528 next_key = 0; 347 next_key = 0;
529 if (temp_key->action == Keys::EXECUTE || 348 if (*temp_key->m_command != 0)
530 temp_key->action == Keys::RESTART) 349 temp_key->m_command->execute();
531 m_execcmdstring = temp_key->execcommand; //update execcmdstring if action is grabExecute 350
532 return temp_key->action; 351 }
533 }
534
535 } 352 }
536
537 return Keys::LASTKEYGRAB;
538} 353}
539 354
540/** 355/**
@@ -547,51 +362,6 @@ bool Keys::reconfigure(const char *filename) {
547} 362}
548 363
549/** 364/**
550 Tries to find the action for the key
551 @return actionstring on success else 0 on failure
552*/
553const char *Keys::getActionStr(KeyAction action) {
554 for (unsigned int i=0; m_actionlist[i].string!=0 ; i++) {
555 if (m_actionlist[i].action == action)
556 return m_actionlist[i].string;
557 }
558
559 return 0;
560}
561
562#ifdef DEBUG
563/*
564 Debug function that show the
565 keytree. Starts with the rootlist
566*/
567void Keys::showTree() {
568 for (unsigned int i=0; i<m_keylist.size(); i++) {
569 if (m_keylist[i]) {
570 cerr<<i<<" ";
571 showKeyTree(m_keylist[i]);
572 } else
573 cerr<<"Null @ "<<i<<endl;
574 }
575}
576
577/**
578 Debug function to show t_key tree
579*/
580void Keys::showKeyTree(t_key *key, unsigned int w) {
581 for (unsigned int i=0; i<w+1; i++)
582 cerr<<"-";
583 if (!key->keylist.empty()) {
584 for (unsigned int i=0; i<key->keylist.size(); i++) {
585 cerr<<"( "<<(int)key->key<<" "<<(int)key->mod<<" )";
586 showKeyTree(key->keylist[i], 4);
587 cerr<<endl;
588 }
589 } else
590 cerr<<"( "<<(int)key->key<<" "<<(int)key->mod<<" ) {"<<getActionStr(key->action)<<"}"<<endl;
591}
592#endif //DEBUG
593
594/**
595 Merges two chains and binds new keys 365 Merges two chains and binds new keys
596 @return true on success else false. 366 @return true on success else false.
597*/ 367*/
@@ -601,7 +371,7 @@ bool Keys::mergeTree(t_key *newtree, t_key *basetree) {
601 for (; baselist_i<m_keylist.size(); baselist_i++) { 371 for (; baselist_i<m_keylist.size(); baselist_i++) {
602 if (m_keylist[baselist_i]->mod == newtree->mod && 372 if (m_keylist[baselist_i]->mod == newtree->mod &&
603 m_keylist[baselist_i]->key == newtree->key) { 373 m_keylist[baselist_i]->key == newtree->key) {
604 if (newtree->keylist.size() && m_keylist[baselist_i]->action == LASTKEYGRAB) { 374 if (newtree->keylist.size() && *m_keylist[baselist_i]->m_command == 0) {
605 //assumes the newtree only have one branch 375 //assumes the newtree only have one branch
606 return mergeTree(newtree->keylist[0], m_keylist[baselist_i]); 376 return mergeTree(newtree->keylist[0], m_keylist[baselist_i]);
607 } else 377 } else
@@ -642,19 +412,16 @@ bool Keys::mergeTree(t_key *newtree, t_key *basetree) {
642 return false; 412 return false;
643} 413}
644 414
645Keys::t_key::t_key(unsigned int key_, unsigned int mod_, KeyAction action_) { 415Keys::t_key::t_key(unsigned int key_, unsigned int mod_, FbTk::RefCount<FbTk::Command> command) {
646 action = action_;
647 key = key_; 416 key = key_;
648 mod = mod_; 417 mod = mod_;
649 param = 0; 418 m_command = command;
650} 419}
651 420
652Keys::t_key::t_key(t_key *k) { 421Keys::t_key::t_key(t_key *k) {
653 action = k->action;
654 key = k->key; 422 key = k->key;
655 mod = k->mod; 423 mod = k->mod;
656 execcommand = k->execcommand; 424 m_command = k->m_command;
657 param = k-> param;
658} 425}
659 426
660Keys::t_key::~t_key() { 427Keys::t_key::~t_key() {
@@ -665,6 +432,7 @@ Keys::t_key::~t_key() {
665 keylist.pop_back(); 432 keylist.pop_back();
666 } 433 }
667 } 434 }
435
668} 436}
669 437
670/** 438/**