summaryrefslogtreecommitdiff
path: root/src/Keys.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/Keys.cc')
-rw-r--r--src/Keys.cc110
1 files changed, 67 insertions, 43 deletions
diff --git a/src/Keys.cc b/src/Keys.cc
index 0b8efe5..935d54b 100644
--- a/src/Keys.cc
+++ b/src/Keys.cc
@@ -106,6 +106,28 @@ using std::pair;
106 106
107using FbTk::STLUtil::destroyAndClearSecond; 107using FbTk::STLUtil::destroyAndClearSecond;
108 108
109namespace {
110
111// candidate for FbTk::StringUtil ?
112int extractKeyFromString(const std::string& in, const char* start_pattern, unsigned int& key) {
113
114 int ret = 0;
115
116 if (strstr(in.c_str(), start_pattern) != 0) {
117
118 unsigned int tmp_key = 0;
119 if (FbTk::StringUtil::extractNumber(in.substr(strlen(start_pattern)), tmp_key)) {
120
121 key = tmp_key;
122 ret = 1;
123 }
124 }
125
126 return ret;
127}
128
129} // end of anonymouse namespace
130
109// helper class 'keytree' 131// helper class 'keytree'
110class Keys::t_key { 132class Keys::t_key {
111public: 133public:
@@ -254,10 +276,12 @@ void Keys::grabWindow(Window win) {
254 if ((win_it->second & Keys::GLOBAL) > 0 && (*it)->type == KeyPress) 276 if ((win_it->second & Keys::GLOBAL) > 0 && (*it)->type == KeyPress)
255 FbTk::KeyUtil::grabKey((*it)->key, (*it)->mod, win); 277 FbTk::KeyUtil::grabKey((*it)->key, (*it)->mod, win);
256 // ON_DESKTOP buttons don't need to be grabbed 278 // ON_DESKTOP buttons don't need to be grabbed
257 else if ((win_it->second & (*it)->context & ~Keys::ON_DESKTOP) > 0 && 279 else if ((win_it->second & (*it)->context & ~Keys::ON_DESKTOP) > 0) {
258 (*it)->type == ButtonPress) 280
259 FbTk::KeyUtil::grabButton((*it)->key, (*it)->mod, win, 281 if ((*it)->type == ButtonPress || (*it)->type == ButtonRelease || (*it)->type == MotionNotify) {
260 ButtonPressMask|ButtonReleaseMask); 282 FbTk::KeyUtil::grabButton((*it)->key, (*it)->mod, win, ButtonPressMask|ButtonReleaseMask|ButtonMotionMask);
283 }
284 }
261 } 285 }
262} 286}
263 287
@@ -363,85 +387,84 @@ bool Keys::addBinding(const string &linebuffer) {
363 // for each argument 387 // for each argument
364 for (; argc < val.size(); argc++) { 388 for (; argc < val.size(); argc++) {
365 389
366 if (val[argc][0] != ':') { // parse key(s) 390 std::string arg = FbTk::StringUtil::toLower(val[argc]);
391
392 if (arg[0] != ':') { // parse key(s)
367 393
368 int tmpmod = FbTk::KeyUtil::getModifier(val[argc].c_str()); 394 int tmpmod = FbTk::KeyUtil::getModifier(arg.c_str());
369 if(tmpmod) 395 if(tmpmod)
370 mod |= tmpmod; //If it's a modifier 396 mod |= tmpmod; //If it's a modifier
371 else if (strcasecmp("ondesktop", val[argc].c_str()) == 0) 397 else if (arg == "ondesktop")
372 context |= ON_DESKTOP; 398 context |= ON_DESKTOP;
373 else if (strcasecmp("ontoolbar", val[argc].c_str()) == 0) 399 else if (arg == "ontoolbar")
374 context |= ON_TOOLBAR; 400 context |= ON_TOOLBAR;
375 else if (strcasecmp("onwindow", val[argc].c_str()) == 0) 401 else if (arg == "onwindow")
376 context |= ON_WINDOW; 402 context |= ON_WINDOW;
377 else if (strcasecmp("ontitlebar", val[argc].c_str()) == 0) 403 else if (arg == "ontitlebar")
378 context |= ON_TITLEBAR; 404 context |= ON_TITLEBAR;
379 else if (strcasecmp("double", val[argc].c_str()) == 0) 405 else if (arg == "double")
380 isdouble = true; 406 isdouble = true;
381 else if (strcasecmp("NONE",val[argc].c_str())) { 407 else if (arg != "none") {
382 // check if it's a mouse button 408 if (arg == "focusin") {
383 if (strcasecmp("focusin", val[argc].c_str()) == 0) {
384 context = ON_WINDOW; 409 context = ON_WINDOW;
385 mod = key = 0; 410 mod = key = 0;
386 type = FocusIn; 411 type = FocusIn;
387 } else if (strcasecmp("focusout", val[argc].c_str()) == 0) { 412 } else if (arg == "focusout") {
388 context = ON_WINDOW; 413 context = ON_WINDOW;
389 mod = key = 0; 414 mod = key = 0;
390 type = FocusOut; 415 type = FocusOut;
391 } else if (strcasecmp("changeworkspace", 416 } else if (arg == "changeworkspace") {
392 val[argc].c_str()) == 0) {
393 context = ON_DESKTOP; 417 context = ON_DESKTOP;
394 mod = key = 0; 418 mod = key = 0;
395 type = FocusIn; 419 type = FocusIn;
396 } else if (strcasecmp("mouseover", val[argc].c_str()) == 0) { 420 } else if (arg == "mouseover") {
397 type = EnterNotify; 421 type = EnterNotify;
398 if (!(context & (ON_WINDOW|ON_TOOLBAR))) 422 if (!(context & (ON_WINDOW|ON_TOOLBAR)))
399 context |= ON_WINDOW; 423 context |= ON_WINDOW;
400 key = 0; 424 key = 0;
401 } else if (strcasecmp("mouseout", val[argc].c_str()) == 0) { 425 } else if (arg == "mouseout") {
402 type = LeaveNotify; 426 type = LeaveNotify;
403 if (!(context & (ON_WINDOW|ON_TOOLBAR))) 427 if (!(context & (ON_WINDOW|ON_TOOLBAR)))
404 context |= ON_WINDOW; 428 context |= ON_WINDOW;
405 key = 0; 429 key = 0;
406 } else if (strcasecmp(val[argc].substr(0,5).c_str(), 430
407 "mouse") == 0 && 431 // check if it's a mouse button
408 val[argc].length() > 5) { 432 } else if (extractKeyFromString(arg, "mouse", key)) {
409 type = ButtonPress; 433 type = ButtonPress;
410 key = atoi(val[argc].substr(5, 434
411 val[argc].length()-5).c_str());
412 // fluxconf mangles things like OnWindow Mouse# to Mouse#ow 435 // fluxconf mangles things like OnWindow Mouse# to Mouse#ow
413 if (strstr(val[argc].c_str(), "top")) 436 if (strstr(arg.c_str(), "top"))
414 context = ON_DESKTOP; 437 context = ON_DESKTOP;
415 else if (strstr(val[argc].c_str(), "ebar")) 438 else if (strstr(arg.c_str(), "ebar"))
416 context = ON_TITLEBAR; 439 context = ON_TITLEBAR;
417 else if (strstr(val[argc].c_str(), "bar")) 440 else if (strstr(arg.c_str(), "bar"))
418 context = ON_TOOLBAR; 441 context = ON_TOOLBAR;
419 else if (strstr(val[argc].c_str(), "ow")) 442 else if (strstr(arg.c_str(), "ow"))
420 context = ON_WINDOW; 443 context = ON_WINDOW;
444 } else if (extractKeyFromString(arg, "click", key)) {
445 type = ButtonRelease;
446 } else if (extractKeyFromString(arg, "move", key)) {
447 type = MotionNotify;
448
449 } else if (key = FbTk::KeyUtil::getKey(val[argc].c_str())) { // convert from string symbol
450 type = KeyPress;
451
421 // keycode covers the following three two-byte cases: 452 // keycode covers the following three two-byte cases:
422 // 0x - hex 453 // 0x - hex
423 // +[1-9] - number between +1 and +9 454 // +[1-9] - number between +1 and +9
424 // numbers 10 and above 455 // numbers 10 and above
425 // 456 //
426 } else if (!val[argc].empty() && ((isdigit(val[argc][0]) && 457 } else {
427 (isdigit(val[argc][1]) || val[argc][1] == 'x')) || 458 FbTk::StringUtil::extractNumber(arg, key);
428 (val[argc][0] == '+' && isdigit(val[argc][1])))) {
429
430 key = strtoul(val[argc].c_str(), NULL, 0);
431 type = KeyPress;
432
433 if (errno == EINVAL || errno == ERANGE)
434 key = 0;
435
436 } else { // convert from string symbol
437 key = FbTk::KeyUtil::getKey(val[argc].c_str());
438 type = KeyPress; 459 type = KeyPress;
439 } 460 }
440 461
441 if (key == 0 && (type == KeyPress || type == ButtonPress)) 462 if (key == 0 && (type == KeyPress || type == ButtonPress || type == ButtonRelease))
442 return false; 463 return false;
464
443 if (type != ButtonPress) 465 if (type != ButtonPress)
444 isdouble = false; 466 isdouble = false;
467
445 if (!first_new_key) { 468 if (!first_new_key) {
446 first_new_keylist = current_key; 469 first_new_keylist = current_key;
447 current_key = current_key->find(type, mod, key, context, 470 current_key = current_key->find(type, mod, key, context,
@@ -470,7 +493,7 @@ bool Keys::addBinding(const string &linebuffer) {
470 return false; 493 return false;
471 494
472 const char *str = FbTk::StringUtil::strcasestr(linebuffer.c_str(), 495 const char *str = FbTk::StringUtil::strcasestr(linebuffer.c_str(),
473 val[argc].c_str()); 496 val[argc].c_str());
474 if (str) // +1 to skip ':' 497 if (str) // +1 to skip ':'
475 current_key->m_command = FbTk::CommandParser<void>::instance().parse(str + 1); 498 current_key->m_command = FbTk::CommandParser<void>::instance().parse(str + 1);
476 499
@@ -504,10 +527,11 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key,
504 bool isdouble = false; 527 bool isdouble = false;
505 528
506 if (type == ButtonPress) { 529 if (type == ButtonPress) {
507 if (time > last_button_time) 530 if (time > last_button_time) {
508 double_click = (time - last_button_time < 531 double_click = (time - last_button_time <
509 Fluxbox::instance()->getDoubleClickInterval()) && 532 Fluxbox::instance()->getDoubleClickInterval()) &&
510 last_button == key; 533 last_button == key;
534 }
511 last_button_time = time; 535 last_button_time = time;
512 last_button = key; 536 last_button = key;
513 isdouble = double_click; 537 isdouble = double_click;