aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Labath <pavelo@centrum.sk>2011-07-22 15:55:55 (GMT)
committerPavel Labath <pavelo@centrum.sk>2011-09-14 17:39:11 (GMT)
commit536a16e6e2d9080aec9df9d488d41296888e5cd9 (patch)
tree604a680e32caed8e9760fee2d23cb3995fd29ad9
parentd21ceb4a235d8f8994390d7bc7611b990e6c0c31 (diff)
downloadfluxbox-536a16e6e2d9080aec9df9d488d41296888e5cd9.zip
fluxbox-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.cc85
-rw-r--r--src/Keys.hh12
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'
133class Keys::t_key { 133class Keys::t_key {
134public: 134public:
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
173Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_, 172Keys::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
189Keys::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
198Keys::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
206Keys::Keys(): 187Keys::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
221void Keys::deleteTree() { 202void 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
653void Keys::setKeyMode(t_key *keyMode) { 632void 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
95private: 96private:
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;