diff options
Diffstat (limited to 'src/Keys.cc')
-rw-r--r-- | src/Keys.cc | 110 |
1 files changed, 72 insertions, 38 deletions
diff --git a/src/Keys.cc b/src/Keys.cc index 72d59cd..6d13cd4 100644 --- a/src/Keys.cc +++ b/src/Keys.cc | |||
@@ -101,18 +101,7 @@ using std::vector; | |||
101 | using std::ifstream; | 101 | using std::ifstream; |
102 | using std::pair; | 102 | using std::pair; |
103 | 103 | ||
104 | Keys::Keys(): | 104 | Keys::Keys(): m_display(FbTk::App::instance()->display()) { } |
105 | m_display(FbTk::App::instance()->display()) | ||
106 | { | ||
107 | typedef std::list<BScreen *> ScreenList; | ||
108 | ScreenList screen_list = Fluxbox::instance()->screenList(); | ||
109 | ScreenList::iterator it = screen_list.begin(); | ||
110 | ScreenList::iterator it_end = screen_list.end(); | ||
111 | |||
112 | for (; it != it_end; ++it) | ||
113 | m_window_list.push_back(RootWindow(m_display,(*it)->screenNumber())); | ||
114 | |||
115 | } | ||
116 | 105 | ||
117 | Keys::~Keys() { | 106 | Keys::~Keys() { |
118 | ungrabKeys(); | 107 | ungrabKeys(); |
@@ -127,37 +116,69 @@ void Keys::deleteTree() { | |||
127 | m_map.clear(); | 116 | m_map.clear(); |
128 | } | 117 | } |
129 | 118 | ||
119 | // keys are only grabbed in global context | ||
130 | void Keys::grabKey(unsigned int key, unsigned int mod) { | 120 | void Keys::grabKey(unsigned int key, unsigned int mod) { |
131 | std::list<Window>::iterator it = m_window_list.begin(); | 121 | WindowMap::iterator it = m_window_map.begin(); |
132 | std::list<Window>::iterator it_end = m_window_list.end(); | 122 | WindowMap::iterator it_end = m_window_map.end(); |
133 | 123 | ||
134 | for (; it != it_end; ++it) | 124 | for (; it != it_end; ++it) { |
135 | FbTk::KeyUtil::grabKey(key, mod, *it); | 125 | if ((it->second & Keys::GLOBAL) > 0) |
126 | FbTk::KeyUtil::grabKey(key, mod, it->first); | ||
127 | } | ||
136 | } | 128 | } |
137 | 129 | ||
130 | // keys are only grabbed in global context | ||
138 | void Keys::ungrabKeys() { | 131 | void Keys::ungrabKeys() { |
139 | std::list<Window>::iterator it = m_window_list.begin(); | 132 | WindowMap::iterator it = m_window_map.begin(); |
140 | std::list<Window>::iterator it_end = m_window_list.end(); | 133 | WindowMap::iterator it_end = m_window_map.end(); |
141 | 134 | ||
142 | for (; it != it_end; ++it) | 135 | for (; it != it_end; ++it) { |
143 | FbTk::KeyUtil::ungrabKeys(*it); | 136 | if ((it->second & Keys::GLOBAL) > 0) |
137 | FbTk::KeyUtil::ungrabKeys(it->first); | ||
138 | } | ||
144 | } | 139 | } |
145 | 140 | ||
146 | void Keys::grabButton(unsigned int button, unsigned int mod) { | 141 | // ON_DESKTOP context doesn't need to be grabbed |
147 | std::list<Window>::iterator it = m_window_list.begin(); | 142 | void Keys::grabButton(unsigned int button, unsigned int mod, int context) { |
148 | std::list<Window>::iterator it_end = m_window_list.end(); | 143 | WindowMap::iterator it = m_window_map.begin(); |
144 | WindowMap::iterator it_end = m_window_map.end(); | ||
149 | 145 | ||
150 | for (; it != it_end; ++it) | 146 | for (; it != it_end; ++it) { |
151 | FbTk::KeyUtil::grabButton(button, mod, *it, | 147 | if ((context & it->second & ~Keys::ON_DESKTOP) > 0) |
152 | ButtonPressMask|ButtonReleaseMask); | 148 | FbTk::KeyUtil::grabButton(button, mod, it->first, |
149 | ButtonPressMask|ButtonReleaseMask); | ||
150 | } | ||
153 | } | 151 | } |
154 | 152 | ||
155 | void Keys::ungrabButtons() { | 153 | void Keys::ungrabButtons() { |
156 | std::list<Window>::iterator it = m_window_list.begin(); | 154 | WindowMap::iterator it = m_window_map.begin(); |
157 | std::list<Window>::iterator it_end = m_window_list.end(); | 155 | WindowMap::iterator it_end = m_window_map.end(); |
158 | 156 | ||
159 | for (; it != it_end; ++it) | 157 | for (; it != it_end; ++it) |
160 | FbTk::KeyUtil::ungrabButtons(*it); | 158 | FbTk::KeyUtil::ungrabButtons(it->first); |
159 | } | ||
160 | |||
161 | void Keys::grabWindow(Window win) { | ||
162 | if (!m_keylist) | ||
163 | return; | ||
164 | |||
165 | // make sure the window is in our list | ||
166 | WindowMap::iterator win_it = m_window_map.find(win); | ||
167 | if (win_it == m_window_map.end()) | ||
168 | return; | ||
169 | |||
170 | keylist_t::iterator it = m_keylist->keylist.begin(); | ||
171 | keylist_t::iterator it_end = m_keylist->keylist.end(); | ||
172 | for (; it != it_end; ++it) { | ||
173 | // keys are only grabbed in global context | ||
174 | if ((win_it->second & Keys::GLOBAL) > 0 && (*it)->type == KeyPress) | ||
175 | FbTk::KeyUtil::grabKey((*it)->key, (*it)->mod, win); | ||
176 | // ON_DESKTOP buttons don't need to be grabbed | ||
177 | else if ((win_it->second & (*it)->context & ~Keys::ON_DESKTOP) > 0 && | ||
178 | (*it)->type == ButtonPress) | ||
179 | FbTk::KeyUtil::grabButton((*it)->key, (*it)->mod, win, | ||
180 | ButtonPressMask|ButtonReleaseMask); | ||
181 | } | ||
161 | } | 182 | } |
162 | 183 | ||
163 | /** | 184 | /** |
@@ -278,6 +299,8 @@ bool Keys::addBinding(const string &linebuffer) { | |||
278 | mod |= tmpmod; //If it's a modifier | 299 | mod |= tmpmod; //If it's a modifier |
279 | else if (strcasecmp("ondesktop", val[argc].c_str()) == 0) | 300 | else if (strcasecmp("ondesktop", val[argc].c_str()) == 0) |
280 | context |= ON_DESKTOP; | 301 | context |= ON_DESKTOP; |
302 | else if (strcasecmp("ontoolbar", val[argc].c_str()) == 0) | ||
303 | context |= ON_TOOLBAR; | ||
281 | else if (strcasecmp("NONE",val[argc].c_str())) { | 304 | else if (strcasecmp("NONE",val[argc].c_str())) { |
282 | // check if it's a mouse button | 305 | // check if it's a mouse button |
283 | if (!strcasecmp(val[argc].substr(0,5).c_str(), "mouse") && | 306 | if (!strcasecmp(val[argc].substr(0,5).c_str(), "mouse") && |
@@ -349,16 +372,15 @@ bool Keys::addBinding(const string &linebuffer) { | |||
349 | } | 372 | } |
350 | 373 | ||
351 | // return true if bound to a command, else false | 374 | // return true if bound to a command, else false |
352 | bool Keys::doAction(int type, unsigned int mods, unsigned int key) { | 375 | bool Keys::doAction(int type, unsigned int mods, unsigned int key, |
376 | int context) { | ||
353 | 377 | ||
354 | static t_key* next_key = m_keylist; | 378 | static t_key* next_key = m_keylist; |
355 | if (!next_key) | 379 | if (!next_key) |
356 | next_key = m_keylist; | 380 | next_key = m_keylist; |
357 | 381 | ||
358 | mods = FbTk::KeyUtil::instance().cleanMods(mods); | 382 | mods = FbTk::KeyUtil::instance().cleanMods(mods); |
359 | // at the moment, any key/button that gets here is on root window | 383 | t_key *temp_key = next_key->find(type, mods, key, context); |
360 | // context will need to be added as an argument to doAction, though | ||
361 | t_key *temp_key = next_key->find(type, mods, key, ON_DESKTOP|GLOBAL); | ||
362 | 384 | ||
363 | // need to save this for emacs-style keybindings | 385 | // need to save this for emacs-style keybindings |
364 | static t_key *saved_keymode = 0; | 386 | static t_key *saved_keymode = 0; |
@@ -396,6 +418,19 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key) { | |||
396 | return true; | 418 | return true; |
397 | } | 419 | } |
398 | 420 | ||
421 | /// adds the window to m_window_map, so we know to grab buttons on it | ||
422 | void Keys::registerWindow(Window win, int context) { | ||
423 | m_window_map[win] = context; | ||
424 | grabWindow(win); | ||
425 | } | ||
426 | |||
427 | /// remove the window from the window map, probably being deleted | ||
428 | void Keys::unregisterWindow(Window win) { | ||
429 | FbTk::KeyUtil::ungrabKeys(win); | ||
430 | FbTk::KeyUtil::ungrabButtons(win); | ||
431 | m_window_map.erase(win); | ||
432 | } | ||
433 | |||
399 | /** | 434 | /** |
400 | deletes the tree and load configuration | 435 | deletes the tree and load configuration |
401 | returns true on success else false | 436 | returns true on success else false |
@@ -419,14 +454,13 @@ void Keys::setKeyMode(t_key *keyMode) { | |||
419 | keylist_t::iterator it_end = keyMode->keylist.end(); | 454 | keylist_t::iterator it_end = keyMode->keylist.end(); |
420 | for (; it != it_end; ++it) { | 455 | for (; it != it_end; ++it) { |
421 | if ((*it)->type == KeyPress) | 456 | if ((*it)->type == KeyPress) |
422 | grabKey((*it)->key,(*it)->mod); | 457 | grabKey((*it)->key, (*it)->mod); |
423 | else if ((*it)->context == GLOBAL) | 458 | else |
424 | grabButton((*it)->key,(*it)->mod); | 459 | grabButton((*it)->key, (*it)->mod, (*it)->context); |
425 | // we must use root window's event mask to get ON_DESKTOP events | ||
426 | } | 460 | } |
427 | m_keylist = keyMode; | 461 | m_keylist = keyMode; |
428 | } | 462 | } |
429 | 463 | ||
430 | Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_, | 464 | Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_, |
431 | int context_, FbTk::RefCount<FbTk::Command> command) { | 465 | int context_, FbTk::RefCount<FbTk::Command> command) { |
432 | key = key_; | 466 | key = key_; |