#include <bindings.hh>
Collaboration diagram for ob::Bindings:
Public Types | |
typedef std::vector< std::string > | StringVect |
A list of strings. | |
Public Methods | |
Bindings () | |
Initializes an Bindings object. | |
virtual | ~Bindings () |
Destroys the Bindings object. | |
bool | translate (const std::string &str, Binding &b, bool askey=true) const |
Translates a binding string into the actual Binding. | |
bool | addKey (const StringVect &keylist, PyObject *callback) |
Adds a new key binding. | |
void | removeAllKeys () |
Removes all key bindings. | |
void | fireKey (int screen, unsigned int modifiers, unsigned int key, Time time, KeyAction::KA action) |
void | setResetKey (const std::string &key) |
void | grabKeys (bool grab) |
bool | grabKeyboard (int screen, PyObject *callback) |
void | ungrabKeyboard () |
bool | grabPointer (int screen) |
void | ungrabPointer () |
bool | addButton (const std::string &but, MouseContext::MC context, MouseAction::MA action, PyObject *callback) |
void | grabButtons (bool grab, Client *client) |
void | removeAllButtons () |
Removes all button bindings. | |
void | fireButton (MouseData *data) |
bool | addEvent (EventAction::EA action, PyObject *callback) |
Bind a callback for an event. | |
bool | removeEvent (EventAction::EA action, PyObject *callback) |
Unbind the callback function from an event. | |
void | removeAllEvents () |
Remove all callback functions. | |
void | fireEvent (EventData *data) |
Private Types | |
typedef std::list< ButtonBinding * > | ButtonBindingList |
Private Methods | |
KeyBindingTree * | find (KeyBindingTree *search, bool *conflict) const |
KeyBindingTree * | buildtree (const StringVect &keylist, PyObject *callback) const |
void | assimilate (KeyBindingTree *node) |
void | grabButton (bool grab, const Binding &b, MouseContext::MC context, Client *client) |
Static Private Methods | |
void | resetChains (Bindings *self) |
Private Attributes | |
KeyBindingTree | _keytree |
KeyBindingTree * | _curpos |
Binding | _resetkey |
otk::Timer * | _timer |
ButtonBindingList | _buttons [MouseContext::NUM_MOUSE_CONTEXT] |
CallbackList | _eventlist [EventAction::NUM_EVENTS] |
PyObject * | _keybgrab_callback |
|
Definition at line 79 of file bindings.hh. |
|
A list of strings.
Definition at line 61 of file bindings.hh. Referenced by ob::kbind(). |
|
Initializes an Bindings object.
Definition at line 147 of file bindings.cc.
00148 : _curpos(&_keytree), 00149 _resetkey(0,0), 00150 _timer((otk::Timer *) 0), 00151 _keybgrab_callback(0) 00152 { 00153 // setResetKey("C-g"); // set the default reset key 00154 } |
|
Destroys the Bindings object.
Definition at line 157 of file bindings.cc. References _timer, removeAllEvents(), and removeAllKeys().
00158 { 00159 if (_timer) 00160 delete _timer; 00161 00162 removeAllKeys(); 00163 //removeAllButtons(); // this is done by each client as they are unmanaged 00164 removeAllEvents(); 00165 } |
|
Definition at line 480 of file bindings.cc. References _buttons, ob::ButtonBinding::binding, ob::ButtonBinding::callbacks, ob::Screen::clients, grabButton(), ob::Binding::key, ob::Binding::modifiers, ob::openbox, ob::Openbox::screen(), and translate().
00482 { 00483 assert(context >= 0 && context < MouseContext::NUM_MOUSE_CONTEXT); 00484 assert(action >= 0 && action < MouseAction::NUM_MOUSE_ACTION); 00485 00486 Binding b(0,0); 00487 if (!translate(but, b, false)) 00488 return false; 00489 00490 ButtonBindingList::iterator it, end = _buttons[context].end(); 00491 00492 // look for a duplicate binding 00493 for (it = _buttons[context].begin(); it != end; ++it) 00494 if ((*it)->binding.key == b.key && 00495 (*it)->binding.modifiers == b.modifiers) { 00496 break; 00497 } 00498 00499 ButtonBinding *bind; 00500 00501 // the binding didnt exist yet, add it 00502 if (it == end) { 00503 bind = new ButtonBinding(); 00504 bind->binding.key = b.key; 00505 bind->binding.modifiers = b.modifiers; 00506 _buttons[context].push_back(bind); 00507 // grab the button on all clients 00508 for (int sn = 0; sn < ScreenCount(**otk::display); ++sn) { 00509 Screen *s = openbox->screen(sn); 00510 if (!s) continue; // not managed 00511 Client::List::iterator c_it, c_end = s->clients.end(); 00512 for (c_it = s->clients.begin(); c_it != c_end; ++c_it) { 00513 grabButton(true, bind->binding, context, *c_it); 00514 } 00515 } 00516 } else 00517 bind = *it; 00518 bind->callbacks[action].push_back(callback); 00519 Py_INCREF(callback); 00520 return true; 00521 } |
|
Bind a callback for an event.
Definition at line 604 of file bindings.cc. References _eventlist.
00605 { 00606 if (action < 0 || action >= EventAction::NUM_EVENTS) { 00607 return false; 00608 } 00609 #ifdef XKB 00610 if (action == EventAction::Bell && _eventlist[action].empty()) 00611 XkbSelectEvents(**otk::display, XkbUseCoreKbd, 00612 XkbBellNotifyMask, XkbBellNotifyMask); 00613 #endif // XKB 00614 _eventlist[action].push_back(callback); 00615 Py_INCREF(callback); 00616 return true; 00617 } |
|
Adds a new key binding. A binding will fail to be added if the binding already exists (as part of a chain or not), or if any of the strings in the keylist are invalid.
Definition at line 227 of file bindings.cc. References assimilate(), buildtree(), ob::KeyBindingTree::callbacks, ob::destroytree(), find(), and grabKeys().
00228 { 00229 KeyBindingTree *tree, *t; 00230 bool conflict; 00231 00232 if (!(tree = buildtree(keylist, callback))) 00233 return false; // invalid binding requested 00234 00235 t = find(tree, &conflict); 00236 if (conflict) { 00237 // conflicts with another binding 00238 destroytree(tree); 00239 return false; 00240 } 00241 00242 if (t) { 00243 // already bound to something 00244 t->callbacks.push_back(callback); 00245 destroytree(tree); 00246 } else { 00247 // grab the server here to make sure no key pressed go missed 00248 otk::display->grab(); 00249 grabKeys(false); 00250 00251 // assimilate this built tree into the main tree 00252 assimilate(tree); // assimilation destroys/uses the tree 00253 00254 grabKeys(true); 00255 otk::display->ungrab(); 00256 } 00257 00258 Py_INCREF(callback); 00259 00260 return true; 00261 } |
|
Definition at line 168 of file bindings.cc. References _keytree, ob::KeyBindingTree::binding, ob::KeyBindingTree::first_child, and ob::KeyBindingTree::next_sibling. Referenced by addKey().
00169 { 00170 KeyBindingTree *a, *b, *tmp, *last; 00171 00172 if (!_keytree.first_child) { 00173 // there are no nodes at this level yet 00174 _keytree.first_child = node; 00175 } else { 00176 a = _keytree.first_child; 00177 last = a; 00178 b = node; 00179 while (a) { 00180 last = a; 00181 if (a->binding != b->binding) { 00182 a = a->next_sibling; 00183 } else { 00184 tmp = b; 00185 b = b->first_child; 00186 delete tmp; 00187 a = a->first_child; 00188 } 00189 } 00190 if (last->binding != b->binding) 00191 last->next_sibling = b; 00192 else { 00193 last->first_child = b->first_child; 00194 delete b; 00195 } 00196 } 00197 } |
|
Definition at line 120 of file bindings.cc. References ob::destroytree(), ob::KeyBindingTree, and translate(). Referenced by addKey().
00122 { 00123 if (keylist.empty()) return 0; // nothing in the list.. return 0 00124 00125 KeyBindingTree *ret = 0, *p; 00126 00127 StringVect::const_reverse_iterator it, end = keylist.rend(); 00128 for (it = keylist.rbegin(); it != end; ++it) { 00129 p = ret; 00130 ret = new KeyBindingTree(); 00131 if (!p) { 00132 // this is the first built node, the bottom node of the tree 00133 ret->chain = false; 00134 ret->callbacks.push_back(callback); 00135 } 00136 ret->first_child = p; 00137 if (!translate(*it, ret->binding)) { 00138 destroytree(ret); 00139 ret = 0; 00140 break; 00141 } 00142 } 00143 return ret; 00144 } |
|
Definition at line 200 of file bindings.cc. References _keytree, ob::KeyBindingTree::binding, ob::KeyBindingTree::chain, ob::KeyBindingTree::first_child, and ob::KeyBindingTree::next_sibling. Referenced by addKey().
00201 { 00202 *conflict = false; 00203 KeyBindingTree *a, *b; 00204 a = _keytree.first_child; 00205 b = search; 00206 while (a && b) { 00207 if (a->binding != b->binding) { 00208 a = a->next_sibling; 00209 } else { 00210 if (a->chain == b->chain) { 00211 if (!a->chain) { 00212 // found it! (return the actual id, not the search's) 00213 return a; 00214 } 00215 } else { 00216 *conflict = true; 00217 return 0; // the chain status' don't match (conflict!) 00218 } 00219 b = b->first_child; 00220 a = a->first_child; 00221 } 00222 } 00223 return 0; // it just isn't in here 00224 } |
|
Definition at line 585 of file bindings.cc. References _buttons, ob::MouseData::action, ob::MouseData::button, ob::MouseData::context, ob::python_callback(), ob::MouseData::state, and ob::MouseData::time. Referenced by ob::Actions::buttonPressHandler(), ob::Actions::buttonReleaseHandler(), and ob::Actions::motionHandler().
00586 { 00587 if (data->context == MouseContext::Window) { 00588 // Replay the event, so it goes to the client 00589 XAllowEvents(**otk::display, ReplayPointer, data->time); 00590 } 00591 00592 ButtonBindingList::iterator it, end = _buttons[data->context].end(); 00593 for (it = _buttons[data->context].begin(); it != end; ++it) 00594 if ((*it)->binding.key == data->button && 00595 (*it)->binding.modifiers == data->state) { 00596 CallbackList::iterator c_it,c_end = (*it)->callbacks[data->action].end(); 00597 for (c_it = (*it)->callbacks[data->action].begin(); 00598 c_it != c_end; ++c_it) 00599 python_callback(*c_it, data); 00600 } 00601 } |
|
Definition at line 651 of file bindings.cc. References _eventlist, ob::EventData::action, and ob::python_callback(). Referenced by ob::Actions::enterHandler(), ob::Client::fireUrgent(), ob::Actions::leaveHandler(), ob::Screen::manageWindow(), ob::Screen::Screen(), ob::Openbox::setFocusedClient(), ob::Screen::unmanageWindow(), and ob::Screen::~Screen().
00652 { 00653 CallbackList::iterator c_it, c_end = _eventlist[data->action].end(); 00654 for (c_it = _eventlist[data->action].begin(); c_it != c_end; ++c_it) 00655 python_callback(*c_it, data); 00656 } |
|
Definition at line 420 of file bindings.cc. References _curpos, _resetkey, _timer, ob::KeyBindingTree::binding, ob::KeyBindingTree::callbacks, ob::KeyBindingTree::chain, ob::KeyBindingTree::first_child, ob::Openbox::focusedClient(), grabKeys(), ob::Binding::key, ob::Binding::modifiers, ob::KeyBindingTree::next_sibling, ob::openbox, ob::python_callback(), and resetChains().
00422 { 00423 if (_keybgrab_callback) { 00424 Client *c = openbox->focusedClient(); 00425 KeyData data(screen, c, time, modifiers, key, action); 00426 python_callback(_keybgrab_callback, &data); 00427 } 00428 00429 // KeyRelease events only occur during keyboard grabs 00430 if (action == KeyAction::Release) return; 00431 00432 if (key == _resetkey.key && modifiers == _resetkey.modifiers) { 00433 resetChains(this); 00434 } else { 00435 KeyBindingTree *p = _curpos->first_child; 00436 while (p) { 00437 if (p->binding.key == key && p->binding.modifiers == modifiers) { 00438 if (p->chain) { 00439 if (_timer) 00440 delete _timer; 00441 _timer = new otk::Timer(5000, // 5 second timeout 00442 (otk::Timer::TimeoutHandler)resetChains, 00443 this); 00444 // grab the server here to make sure no key presses get missed 00445 otk::display->grab(); 00446 grabKeys(false); 00447 _curpos = p; 00448 grabKeys(true); 00449 otk::display->ungrab(); 00450 } else { 00451 Client *c = openbox->focusedClient(); 00452 KeyData data(screen, c, time, modifiers, key, action); 00453 CallbackList::iterator it, end = p->callbacks.end(); 00454 for (it = p->callbacks.begin(); it != end; ++it) 00455 python_callback(*it, &data); 00456 resetChains(this); 00457 } 00458 break; 00459 } 00460 p = p->next_sibling; 00461 } 00462 } 00463 } |
|
Definition at line 547 of file bindings.cc. References ob::Client::frame, ob::Binding::key, ob::Binding::modifiers, ob::Frame::plate(), and otk::Widget::window(). Referenced by addButton(), grabButtons(), and removeAllButtons().
00549 { 00550 Window win; 00551 int mode = GrabModeAsync; 00552 unsigned int mask; 00553 switch(context) { 00554 case MouseContext::Frame: 00555 win = client->frame->window(); 00556 mask = ButtonPressMask | ButtonMotionMask | ButtonReleaseMask; 00557 break; 00558 case MouseContext::Window: 00559 win = client->frame->plate(); 00560 mode = GrabModeSync; // this is handled in fireButton 00561 mask = ButtonPressMask; // can't catch more than this with Sync mode 00562 // the release event is manufactured by the 00563 // master buttonPressHandler 00564 break; 00565 default: 00566 // any other elements already get button events, don't grab on them 00567 return; 00568 } 00569 if (grab) 00570 otk::display->grabButton(b.key, b.modifiers, win, false, mask, mode, 00571 GrabModeAsync, None, None, false); 00572 else 00573 otk::display->ungrabButton(b.key, b.modifiers, win); 00574 } |
|
Definition at line 576 of file bindings.cc. References _buttons, and grabButton(). Referenced by ob::Screen::manageWindow(), and ob::Screen::unmanageWindow().
00577 { 00578 for (int i = 0; i < MouseContext::NUM_MOUSE_CONTEXT; ++i) { 00579 ButtonBindingList::iterator it, end = _buttons[i].end(); 00580 for (it = _buttons[i].begin(); it != end; ++it) 00581 grabButton(grab, (*it)->binding, (MouseContext::MC)i, client); 00582 } 00583 } |
|
Definition at line 375 of file bindings.cc. References _keybgrab_callback, ob::openbox, and ob::Openbox::screen().
00376 { 00377 assert(callback); 00378 if (_keybgrab_callback) return false; // already grabbed 00379 00380 if (!openbox->screen(screen)) 00381 return false; // the screen is not managed 00382 00383 Window root = otk::display->screenInfo(screen)->rootWindow(); 00384 if (XGrabKeyboard(**otk::display, root, false, GrabModeAsync, 00385 GrabModeAsync, CurrentTime)) 00386 return false; 00387 _keybgrab_callback = callback; 00388 return true; 00389 } |
|
Definition at line 343 of file bindings.cc. References _curpos, _resetkey, ob::KeyBindingTree::binding, ob::KeyBindingTree::first_child, ob::Binding::key, ob::Binding::modifiers, ob::KeyBindingTree::next_sibling, ob::openbox, and ob::Openbox::screen(). Referenced by addKey(), fireKey(), ob::Openbox::Openbox(), removeAllKeys(), resetChains(), and setResetKey().
00344 { 00345 for (int i = 0; i < ScreenCount(**otk::display); ++i) { 00346 Screen *sc = openbox->screen(i); 00347 if (!sc) continue; // not a managed screen 00348 Window root = otk::display->screenInfo(i)->rootWindow(); 00349 00350 KeyBindingTree *p = _curpos->first_child; 00351 while (p) { 00352 if (grab) { 00353 otk::display->grabKey(p->binding.key, p->binding.modifiers, 00354 root, false, GrabModeAsync, GrabModeAsync, 00355 false); 00356 } 00357 else 00358 otk::display->ungrabKey(p->binding.key, p->binding.modifiers, 00359 root); 00360 p = p->next_sibling; 00361 } 00362 00363 if (_resetkey.key) 00364 if (grab) 00365 otk::display->grabKey(_resetkey.key, _resetkey.modifiers, 00366 root, false, GrabModeAsync, GrabModeAsync, 00367 false); 00368 else 00369 otk::display->ungrabKey(_resetkey.key, _resetkey.modifiers, 00370 root); 00371 } 00372 } |
|
Definition at line 402 of file bindings.cc. References ob::openbox, and ob::Openbox::screen().
00403 { 00404 if (!openbox->screen(screen)) 00405 return false; // the screen is not managed 00406 00407 Window root = otk::display->screenInfo(screen)->rootWindow(); 00408 XGrabPointer(**otk::display, root, false, 0, GrabModeAsync, 00409 GrabModeAsync, None, None, CurrentTime); 00410 return true; 00411 } |
|
Removes all button bindings.
Definition at line 523 of file bindings.cc. References _buttons, ob::Screen::clients, grabButton(), ob::openbox, and ob::Openbox::screen().
00524 { 00525 for (int i = 0; i < MouseContext::NUM_MOUSE_CONTEXT; ++i) { 00526 ButtonBindingList::iterator it, end = _buttons[i].end(); 00527 for (it = _buttons[i].begin(); it != end; ++it) { 00528 for (int a = 0; a < MouseAction::NUM_MOUSE_ACTION; ++a) { 00529 while (!(*it)->callbacks[a].empty()) { 00530 Py_XDECREF((*it)->callbacks[a].front()); 00531 (*it)->callbacks[a].pop_front(); 00532 } 00533 } 00534 // ungrab the button on all clients 00535 for (int sn = 0; sn < ScreenCount(**otk::display); ++sn) { 00536 Screen *s = openbox->screen(sn); 00537 if (!s) continue; // not managed 00538 Client::List::iterator c_it, c_end = s->clients.end(); 00539 for (c_it = s->clients.begin(); c_it != c_end; ++c_it) { 00540 grabButton(false, (*it)->binding, (MouseContext::MC)i, *c_it); 00541 } 00542 } 00543 } 00544 } 00545 } |
|
Remove all callback functions.
Definition at line 641 of file bindings.cc. References _eventlist. Referenced by ~Bindings().
00642 { 00643 for (int i = 0; i < EventAction::NUM_EVENTS; ++i) { 00644 while (!_eventlist[i].empty()) { 00645 Py_XDECREF(_eventlist[i].front()); 00646 _eventlist[i].pop_front(); 00647 } 00648 } 00649 } |
|
Removes all key bindings.
Definition at line 332 of file bindings.cc. References _keytree, ob::KeyBindingTree::first_child, grabKeys(), and ob::remove_branch(). Referenced by ~Bindings().
|
|
Unbind the callback function from an event.
Definition at line 619 of file bindings.cc. References _eventlist.
00620 { 00621 if (action < 0 || action >= EventAction::NUM_EVENTS) { 00622 return false; 00623 } 00624 00625 CallbackList::iterator it = std::find(_eventlist[action].begin(), 00626 _eventlist[action].end(), 00627 callback); 00628 if (it != _eventlist[action].end()) { 00629 Py_XDECREF(*it); 00630 _eventlist[action].erase(it); 00631 #ifdef XKB 00632 if (action == EventAction::Bell && _eventlist[action].empty()) 00633 XkbSelectEvents(**otk::display, XkbUseCoreKbd, 00634 XkbBellNotifyMask, 0); 00635 #endif // XKB 00636 return true; 00637 } 00638 return false; 00639 } |
|
Definition at line 465 of file bindings.cc. References _curpos, _keytree, _timer, and grabKeys(). Referenced by fireKey().
00466 { 00467 if (self->_timer) { 00468 delete self->_timer; 00469 self->_timer = (otk::Timer *) 0; 00470 } 00471 // grab the server here to make sure no key pressed go missed 00472 otk::display->grab(); 00473 self->grabKeys(false); 00474 self->_curpos = &self->_keytree; 00475 self->grabKeys(true); 00476 otk::display->ungrab(); 00477 } |
|
Definition at line 299 of file bindings.cc. References _resetkey, grabKeys(), ob::Binding::key, ob::Binding::modifiers, and translate().
00300 { 00301 Binding b(0, 0); 00302 if (translate(key, b)) { 00303 // grab the server here to make sure no key pressed go missed 00304 otk::display->grab(); 00305 grabKeys(false); 00306 _resetkey.key = b.key; 00307 _resetkey.modifiers = b.modifiers; 00308 grabKeys(true); 00309 otk::display->ungrab(); 00310 } 00311 } |
|
Translates a binding string into the actual Binding.
Definition at line 73 of file bindings.cc. References _, ob::buttonvalue(), ob::Binding::key, ob::Binding::modifiers, and ob::modvalue(). Referenced by addButton(), buildtree(), and setResetKey().
00074 { 00075 // parse out the base key name 00076 std::string::size_type keybegin = str.find_last_of('-'); 00077 keybegin = (keybegin == std::string::npos) ? 0 : keybegin + 1; 00078 std::string key(str, keybegin); 00079 00080 // parse out the requested modifier keys 00081 unsigned int modval = 0; 00082 std::string::size_type begin = 0, end; 00083 while (begin != keybegin) { 00084 end = str.find_first_of('-', begin); 00085 00086 std::string mod(str, begin, end-begin); 00087 if (!modvalue(mod, &modval)) { 00088 printf(_("Invalid modifier element in key binding: %s\n"), mod.c_str()); 00089 return false; 00090 } 00091 00092 begin = end + 1; 00093 } 00094 00095 // set the binding 00096 b.modifiers = modval; 00097 if (askey) { 00098 KeySym sym = XStringToKeysym(const_cast<char *>(key.c_str())); 00099 if (sym == NoSymbol) { 00100 printf(_("Invalid Key name in key binding: %s\n"), key.c_str()); 00101 return false; 00102 } 00103 if (!(b.key = XKeysymToKeycode(**otk::display, sym))) 00104 printf(_("No valid keycode for Key in key binding: %s\n"), key.c_str()); 00105 return b.key != 0; 00106 } else { 00107 return buttonvalue(key, &b.key); 00108 } 00109 } |
|
Definition at line 392 of file bindings.cc. References _keybgrab_callback.
00393 { 00394 if (!_keybgrab_callback) return; // not grabbed 00395 00396 _keybgrab_callback = 0; 00397 XUngrabKeyboard(**otk::display, CurrentTime); 00398 XUngrabPointer(**otk::display, CurrentTime); 00399 } |
|
Definition at line 414 of file bindings.cc.
00415 { 00416 XUngrabPointer(**otk::display, CurrentTime); 00417 } |
|
Definition at line 80 of file bindings.hh. Referenced by addButton(), fireButton(), grabButtons(), and removeAllButtons(). |
|
Definition at line 66 of file bindings.hh. Referenced by fireKey(), grabKeys(), and resetChains(). |
|
Definition at line 85 of file bindings.hh. Referenced by addEvent(), fireEvent(), removeAllEvents(), and removeEvent(). |
|
Definition at line 87 of file bindings.hh. Referenced by grabKeyboard(), and ungrabKeyboard(). |
|
Definition at line 65 of file bindings.hh. Referenced by assimilate(), find(), removeAllKeys(), and resetChains(). |
|
Definition at line 68 of file bindings.hh. Referenced by fireKey(), grabKeys(), and setResetKey(). |
|
Definition at line 70 of file bindings.hh. Referenced by fireKey(), resetChains(), and ~Bindings(). |