#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(). |
1.3-rc2