diff options
author | Pavel Labath <pavelo@centrum.sk> | 2011-07-22 15:55:55 (GMT) |
---|---|---|
committer | Pavel Labath <pavelo@centrum.sk> | 2011-09-14 17:39:11 (GMT) |
commit | 536a16e6e2d9080aec9df9d488d41296888e5cd9 (patch) | |
tree | 604a680e32caed8e9760fee2d23cb3995fd29ad9 | |
parent | d21ceb4a235d8f8994390d7bc7611b990e6c0c31 (diff) | |
download | fluxbox_pavel-536a16e6e2d9080aec9df9d488d41296888e5cd9.zip fluxbox_pavel-536a16e6e2d9080aec9df9d488d41296888e5cd9.tar.bz2 |
Use RefCount to store keybindings
I'm doing this because I want to have access to keybindings from lua and for that I need more
flexible ownership semantics.
-rw-r--r-- | src/Keys.cc | 85 | ||||
-rw-r--r-- | src/Keys.hh | 12 |
2 files changed, 39 insertions, 58 deletions
diff --git a/src/Keys.cc b/src/Keys.cc index 6bb0e42..fc53353 100644 --- a/src/Keys.cc +++ b/src/Keys.cc | |||
@@ -127,22 +127,21 @@ int extractKeyFromString(const std::string& in, const char* start_pattern, unsig | |||
127 | return ret; | 127 | return ret; |
128 | } | 128 | } |
129 | 129 | ||
130 | } // end of anonymouse namespace | 130 | } // end of anonymous namespace |
131 | 131 | ||
132 | // helper class 'keytree' | 132 | // helper class 'keytree' |
133 | class Keys::t_key { | 133 | class Keys::t_key { |
134 | public: | 134 | public: |
135 | 135 | ||
136 | // typedefs | 136 | // typedefs |
137 | typedef std::list<t_key*> keylist_t; | 137 | typedef std::list<RefKey> keylist_t; |
138 | 138 | ||
139 | // constructor / destructor | 139 | // constructor / destructor |
140 | t_key(int type, unsigned int mod, unsigned int key, const char* key_str, int context, | 140 | t_key(int type = 0, unsigned int mod = 0, unsigned int key = 0, |
141 | bool isdouble); | 141 | const std::string &key_str = std::string(), int context = 0, |
142 | t_key(t_key *k); | 142 | bool isdouble = false); |
143 | ~t_key(); | ||
144 | 143 | ||
145 | t_key *find(int type_, unsigned int mod_, unsigned int key_, | 144 | RefKey find(int type_, unsigned int mod_, unsigned int key_, |
146 | int context_, bool isdouble_) { | 145 | int context_, bool isdouble_) { |
147 | // t_key ctor sets context_ of 0 to GLOBAL, so we must here too | 146 | // t_key ctor sets context_ of 0 to GLOBAL, so we must here too |
148 | context_ = context_ ? context_ : GLOBAL; | 147 | context_ = context_ ? context_ : GLOBAL; |
@@ -154,7 +153,7 @@ public: | |||
154 | FbTk::KeyUtil::instance().isolateModifierMask(mod_)) | 153 | FbTk::KeyUtil::instance().isolateModifierMask(mod_)) |
155 | return *it; | 154 | return *it; |
156 | } | 155 | } |
157 | return 0; | 156 | return RefKey(); |
158 | } | 157 | } |
159 | 158 | ||
160 | // member variables | 159 | // member variables |
@@ -171,37 +170,19 @@ public: | |||
171 | }; | 170 | }; |
172 | 171 | ||
173 | Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_, | 172 | Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_, |
174 | const char* key_str_, | 173 | const std::string &key_str_, |
175 | int context_, bool isdouble_) : | 174 | int context_, bool isdouble_) : |
176 | type(type_), | 175 | type(type_), |
177 | mod(mod_), | 176 | mod(mod_), |
178 | key(key_), | 177 | key(key_), |
178 | key_str(key_str_), | ||
179 | context(context_), | 179 | context(context_), |
180 | isdouble(isdouble_), | 180 | isdouble(isdouble_), |
181 | m_command(0) { | 181 | m_command(0) { |
182 | 182 | ||
183 | if (key_str_) { | ||
184 | key_str.assign(key_str_); | ||
185 | } | ||
186 | context = context_ ? context_ : GLOBAL; | 183 | context = context_ ? context_ : GLOBAL; |
187 | } | 184 | } |
188 | 185 | ||
189 | Keys::t_key::t_key(t_key *k) { | ||
190 | key = k->key; | ||
191 | mod = k->mod; | ||
192 | type = k->type; | ||
193 | context = k->context; | ||
194 | isdouble = k->isdouble; | ||
195 | m_command = k->m_command; | ||
196 | } | ||
197 | |||
198 | Keys::t_key::~t_key() { | ||
199 | for (keylist_t::iterator list_it = keylist.begin(); list_it != keylist.end(); ++list_it) | ||
200 | delete *list_it; | ||
201 | keylist.clear(); | ||
202 | } | ||
203 | |||
204 | |||
205 | 186 | ||
206 | Keys::Keys(): | 187 | Keys::Keys(): |
207 | m_reloader(new FbTk::AutoReloadHelper()), | 188 | m_reloader(new FbTk::AutoReloadHelper()), |
@@ -220,10 +201,10 @@ Keys::~Keys() { | |||
220 | /// Destroys the keytree | 201 | /// Destroys the keytree |
221 | void Keys::deleteTree() { | 202 | void Keys::deleteTree() { |
222 | 203 | ||
223 | destroyAndClearSecond(m_map); | 204 | m_map.clear(); |
224 | m_keylist = 0; | 205 | m_keylist.reset(); |
225 | next_key = 0; | 206 | next_key.reset(); |
226 | saved_keymode = 0; | 207 | saved_keymode.reset(); |
227 | } | 208 | } |
228 | 209 | ||
229 | // keys are only grabbed in global context | 210 | // keys are only grabbed in global context |
@@ -325,7 +306,7 @@ void Keys::reload() { | |||
325 | // free memory of previous grabs | 306 | // free memory of previous grabs |
326 | deleteTree(); | 307 | deleteTree(); |
327 | 308 | ||
328 | m_map["default:"] = new t_key(0,0,0,0,0,false); | 309 | m_map["default:"] = FbTk::makeRef<t_key>(); |
329 | 310 | ||
330 | unsigned int current_line = 0; //so we can tell the user where the fault is | 311 | unsigned int current_line = 0; //so we can tell the user where the fault is |
331 | 312 | ||
@@ -355,7 +336,7 @@ void Keys::loadDefaults() { | |||
355 | fbdbg<<"Loading default key bindings"<<endl; | 336 | fbdbg<<"Loading default key bindings"<<endl; |
356 | 337 | ||
357 | deleteTree(); | 338 | deleteTree(); |
358 | m_map["default:"] = new t_key(0,0,0,0,0,false); | 339 | m_map["default:"] = FbTk::makeRef<t_key>(); |
359 | addBinding("OnDesktop Mouse1 :HideMenus"); | 340 | addBinding("OnDesktop Mouse1 :HideMenus"); |
360 | addBinding("OnDesktop Mouse2 :WorkspaceMenu"); | 341 | addBinding("OnDesktop Mouse2 :WorkspaceMenu"); |
361 | addBinding("OnDesktop Mouse3 :RootMenu"); | 342 | addBinding("OnDesktop Mouse3 :RootMenu"); |
@@ -388,14 +369,14 @@ bool Keys::addBinding(const string &linebuffer) { | |||
388 | int type = 0, context = 0; | 369 | int type = 0, context = 0; |
389 | bool isdouble = false; | 370 | bool isdouble = false; |
390 | size_t argc = 0; | 371 | size_t argc = 0; |
391 | t_key *current_key=m_map["default:"]; | 372 | RefKey current_key = m_map["default:"]; |
392 | t_key *first_new_keylist = current_key, *first_new_key=0; | 373 | RefKey first_new_keylist = current_key, first_new_key; |
393 | 374 | ||
394 | if (val[0][val[0].length()-1] == ':') { | 375 | if (val[0][val[0].length()-1] == ':') { |
395 | argc++; | 376 | argc++; |
396 | keyspace_t::iterator it = m_map.find(val[0]); | 377 | keyspace_t::iterator it = m_map.find(val[0]); |
397 | if (it == m_map.end()) | 378 | if (it == m_map.end()) |
398 | m_map[val[0]] = new t_key(0,0,0,0,0,false); | 379 | m_map[val[0]] = FbTk::makeRef<t_key>(); |
399 | current_key = m_map[val[0]]; | 380 | current_key = m_map[val[0]]; |
400 | } | 381 | } |
401 | // for each argument | 382 | // for each argument |
@@ -405,7 +386,7 @@ bool Keys::addBinding(const string &linebuffer) { | |||
405 | 386 | ||
406 | if (arg[0] != ':') { // parse key(s) | 387 | if (arg[0] != ':') { // parse key(s) |
407 | 388 | ||
408 | const char* key_str = 0; | 389 | std::string key_str; |
409 | 390 | ||
410 | int tmpmod = FbTk::KeyUtil::getModifier(arg.c_str()); | 391 | int tmpmod = FbTk::KeyUtil::getModifier(arg.c_str()); |
411 | if(tmpmod) | 392 | if(tmpmod) |
@@ -470,7 +451,7 @@ bool Keys::addBinding(const string &linebuffer) { | |||
470 | 451 | ||
471 | } else if ((key = FbTk::KeyUtil::getKey(val[argc].c_str()))) { // convert from string symbol | 452 | } else if ((key = FbTk::KeyUtil::getKey(val[argc].c_str()))) { // convert from string symbol |
472 | type = KeyPress; | 453 | type = KeyPress; |
473 | key_str = val[argc].c_str(); | 454 | key_str = val[argc]; |
474 | 455 | ||
475 | // keycode covers the following three two-byte cases: | 456 | // keycode covers the following three two-byte cases: |
476 | // 0x - hex | 457 | // 0x - hex |
@@ -493,14 +474,14 @@ bool Keys::addBinding(const string &linebuffer) { | |||
493 | current_key = current_key->find(type, mod, key, context, | 474 | current_key = current_key->find(type, mod, key, context, |
494 | isdouble); | 475 | isdouble); |
495 | if (!current_key) { | 476 | if (!current_key) { |
496 | first_new_key = new t_key(type, mod, key, key_str, context, | 477 | first_new_key.reset( new t_key(type, mod, key, key_str, context, |
497 | isdouble); | 478 | isdouble) ); |
498 | current_key = first_new_key; | 479 | current_key = first_new_key; |
499 | } else if (current_key->m_command) // already being used | 480 | } else if (current_key->m_command) // already being used |
500 | return false; | 481 | return false; |
501 | } else { | 482 | } else { |
502 | t_key *temp_key = new t_key(type, mod, key, key_str, context, | 483 | RefKey temp_key( new t_key(type, mod, key, key_str, context, |
503 | isdouble); | 484 | isdouble) ); |
504 | current_key->keylist.push_back(temp_key); | 485 | current_key->keylist.push_back(temp_key); |
505 | current_key = temp_key; | 486 | current_key = temp_key; |
506 | } | 487 | } |
@@ -520,10 +501,8 @@ bool Keys::addBinding(const string &linebuffer) { | |||
520 | if (str) // +1 to skip ':' | 501 | if (str) // +1 to skip ':' |
521 | current_key->m_command.reset(FbTk::CommandParser<void>::instance().parse(str + 1)); | 502 | current_key->m_command.reset(FbTk::CommandParser<void>::instance().parse(str + 1)); |
522 | 503 | ||
523 | if (!str || current_key->m_command == 0 || mod) { | 504 | if (!str || current_key->m_command == 0 || mod) |
524 | delete first_new_key; | ||
525 | return false; | 505 | return false; |
526 | } | ||
527 | 506 | ||
528 | // success | 507 | // success |
529 | first_new_keylist->keylist.push_back(first_new_key); | 508 | first_new_keylist->keylist.push_back(first_new_key); |
@@ -567,7 +546,7 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key, | |||
567 | next_key = m_keylist; | 546 | next_key = m_keylist; |
568 | 547 | ||
569 | mods = FbTk::KeyUtil::instance().cleanMods(mods); | 548 | mods = FbTk::KeyUtil::instance().cleanMods(mods); |
570 | t_key *temp_key = next_key->find(type, mods, key, context, isdouble); | 549 | RefKey temp_key = next_key->find(type, mods, key, context, isdouble); |
571 | 550 | ||
572 | // just because we double-clicked doesn't mean we shouldn't look for single | 551 | // just because we double-clicked doesn't mean we shouldn't look for single |
573 | // click commands | 552 | // click commands |
@@ -585,10 +564,10 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key, | |||
585 | if (type == KeyPress && | 564 | if (type == KeyPress && |
586 | !FbTk::KeyUtil::instance().keycodeToModmask(key)) { | 565 | !FbTk::KeyUtil::instance().keycodeToModmask(key)) { |
587 | // if we're in the middle of an emacs-style keychain, exit it | 566 | // if we're in the middle of an emacs-style keychain, exit it |
588 | next_key = 0; | 567 | next_key.reset(); |
589 | if (saved_keymode) { | 568 | if (saved_keymode) { |
590 | setKeyMode(saved_keymode); | 569 | setKeyMode(saved_keymode); |
591 | saved_keymode = 0; | 570 | saved_keymode.reset(); |
592 | } | 571 | } |
593 | } | 572 | } |
594 | return false; | 573 | return false; |
@@ -607,9 +586,9 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key, | |||
607 | if (saved_keymode) { | 586 | if (saved_keymode) { |
608 | if (next_key == m_keylist) // don't reset keymode if command changed it | 587 | if (next_key == m_keylist) // don't reset keymode if command changed it |
609 | setKeyMode(saved_keymode); | 588 | setKeyMode(saved_keymode); |
610 | saved_keymode = 0; | 589 | saved_keymode.reset(); |
611 | } | 590 | } |
612 | next_key = 0; | 591 | next_key.reset(); |
613 | return true; | 592 | return true; |
614 | } | 593 | } |
615 | 594 | ||
@@ -650,7 +629,7 @@ void Keys::keyMode(const string& keyMode) { | |||
650 | setKeyMode(it->second); | 629 | setKeyMode(it->second); |
651 | } | 630 | } |
652 | 631 | ||
653 | void Keys::setKeyMode(t_key *keyMode) { | 632 | void Keys::setKeyMode(const FbTk::RefCount<t_key> &keyMode) { |
654 | ungrabKeys(); | 633 | ungrabKeys(); |
655 | ungrabButtons(); | 634 | ungrabButtons(); |
656 | 635 | ||
@@ -663,7 +642,7 @@ void Keys::setKeyMode(t_key *keyMode) { | |||
663 | t_key::keylist_t::iterator it = keyMode->keylist.begin(); | 642 | t_key::keylist_t::iterator it = keyMode->keylist.begin(); |
664 | t_key::keylist_t::iterator it_end = keyMode->keylist.end(); | 643 | t_key::keylist_t::iterator it_end = keyMode->keylist.end(); |
665 | for (; it != it_end; ++it) { | 644 | for (; it != it_end; ++it) { |
666 | t_key* t = *it; | 645 | RefKey t = *it; |
667 | if (t->type == KeyPress) { | 646 | if (t->type == KeyPress) { |
668 | if (!t->key_str.empty()) { | 647 | if (!t->key_str.empty()) { |
669 | int key = FbTk::KeyUtil::getKey(t->key_str.c_str()); | 648 | int key = FbTk::KeyUtil::getKey(t->key_str.c_str()); |
diff --git a/src/Keys.hh b/src/Keys.hh index 43f4445..7a6b3b8 100644 --- a/src/Keys.hh +++ b/src/Keys.hh | |||
@@ -23,6 +23,7 @@ | |||
23 | #define KEYS_HH | 23 | #define KEYS_HH |
24 | 24 | ||
25 | #include "FbTk/NotCopyable.hh" | 25 | #include "FbTk/NotCopyable.hh" |
26 | #include "FbTk/RefCount.hh" | ||
26 | 27 | ||
27 | #include <X11/Xlib.h> | 28 | #include <X11/Xlib.h> |
28 | #include <string> | 29 | #include <string> |
@@ -94,7 +95,8 @@ public: | |||
94 | 95 | ||
95 | private: | 96 | private: |
96 | class t_key; // helper class to build a 'keytree' | 97 | class t_key; // helper class to build a 'keytree' |
97 | typedef std::map<std::string, t_key *> keyspace_t; | 98 | typedef FbTk::RefCount<t_key> RefKey; |
99 | typedef std::map<std::string, RefKey> keyspace_t; | ||
98 | typedef std::map<Window, int> WindowMap; | 100 | typedef std::map<Window, int> WindowMap; |
99 | typedef std::map<Window, FbTk::EventHandler*> HandlerMap; | 101 | typedef std::map<Window, FbTk::EventHandler*> HandlerMap; |
100 | 102 | ||
@@ -108,17 +110,17 @@ private: | |||
108 | 110 | ||
109 | // Load default keybindings for when there are errors loading the keys file | 111 | // Load default keybindings for when there are errors loading the keys file |
110 | void loadDefaults(); | 112 | void loadDefaults(); |
111 | void setKeyMode(t_key *keyMode); | 113 | void setKeyMode(const FbTk::RefCount<t_key> &keyMode); |
112 | 114 | ||
113 | 115 | ||
114 | // member variables | 116 | // member variables |
115 | std::string m_filename; | 117 | std::string m_filename; |
116 | FbTk::AutoReloadHelper* m_reloader; | 118 | FbTk::AutoReloadHelper* m_reloader; |
117 | t_key *m_keylist; | 119 | RefKey m_keylist; |
118 | keyspace_t m_map; | 120 | keyspace_t m_map; |
119 | 121 | ||
120 | // former doAction static var, we need to access it from deleteTree | 122 | RefKey next_key; |
121 | t_key *next_key, *saved_keymode; | 123 | RefKey saved_keymode; |
122 | 124 | ||
123 | WindowMap m_window_map; | 125 | WindowMap m_window_map; |
124 | HandlerMap m_handler_map; | 126 | HandlerMap m_handler_map; |