diff options
author | Mathias Gumz <akira at fluxbox dot org> | 2009-12-18 07:05:07 (GMT) |
---|---|---|
committer | Mathias Gumz <akira at fluxbox dot org> | 2009-12-18 07:05:07 (GMT) |
commit | 46261a8284730a16d664fa89423fc5728ed284b4 (patch) | |
tree | c81d7962fe924f5bfca44dc0254304cb537544b9 /src/Keys.cc | |
parent | 79859c94482e4602eb22c35b988027ab199734a6 (diff) | |
download | fluxbox-46261a8284730a16d664fa89423fc5728ed284b4.zip fluxbox-46261a8284730a16d664fa89423fc5728ed284b4.tar.bz2 |
implemented 'MoveN' and 'ClickN' support in keys file.
the hardcoded 'OnTitlebar Mouse1 :Raise' (see Window.cc, FluxboxWindow::buttonPressEvent())
is disabled for now, should be added to fluxbox-update_configs
Diffstat (limited to 'src/Keys.cc')
-rw-r--r-- | src/Keys.cc | 110 |
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 | ||
107 | using FbTk::STLUtil::destroyAndClearSecond; | 107 | using FbTk::STLUtil::destroyAndClearSecond; |
108 | 108 | ||
109 | namespace { | ||
110 | |||
111 | // candidate for FbTk::StringUtil ? | ||
112 | int 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' |
110 | class Keys::t_key { | 132 | class Keys::t_key { |
111 | public: | 133 | public: |
@@ -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; |