aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Gumz <akira at fluxbox dot org>2011-08-26 07:21:50 (GMT)
committerMathias Gumz <akira at fluxbox dot org>2011-08-26 07:21:50 (GMT)
commitec6df5c3d19ed760f343d6755ad396b00ac8f4ea (patch)
treee07b0b28097d33667b5ee82ce997779c9cb2f96f
parent7b10649e281187980e84fdb81fa27e2bae0b8842 (diff)
downloadfluxbox_paul-ec6df5c3d19ed760f343d6755ad396b00ac8f4ea.zip
fluxbox_paul-ec6df5c3d19ed760f343d6755ad396b00ac8f4ea.tar.bz2
bugfix: remap keysyms to keycodes after 'MappingNotify', fix #3386257
setxkbmap and xmodmap both might change the keycodes. thus fluxbox needs to remap the keysyms from the currently loaded keytree to new keycodes after it received a 'MappingNotify' event. we do not reload() the keys file because: * the user might work on it right now * remap only needed symbols is cheaper than parsing the keysfile anyway
-rw-r--r--src/Keys.cc36
1 files changed, 25 insertions, 11 deletions
diff --git a/src/Keys.cc b/src/Keys.cc
index 79c273b..5d59701 100644
--- a/src/Keys.cc
+++ b/src/Keys.cc
@@ -137,7 +137,7 @@ public:
137 typedef std::list<t_key*> keylist_t; 137 typedef std::list<t_key*> keylist_t;
138 138
139 // constructor / destructor 139 // constructor / destructor
140 t_key(int type, unsigned int mod, unsigned int key, int context, 140 t_key(int type, unsigned int mod, unsigned int key, const char* key_str, int context,
141 bool isdouble); 141 bool isdouble);
142 t_key(t_key *k); 142 t_key(t_key *k);
143 ~t_key(); 143 ~t_key();
@@ -162,6 +162,7 @@ public:
162 int type; // KeyPress or ButtonPress 162 int type; // KeyPress or ButtonPress
163 unsigned int mod; 163 unsigned int mod;
164 unsigned int key; // key code or button number 164 unsigned int key; // key code or button number
165 std::string key_str; // key-symbol, needed for regrab()
165 int context; // ON_TITLEBAR, etc.: bitwise-or of all desired contexts 166 int context; // ON_TITLEBAR, etc.: bitwise-or of all desired contexts
166 bool isdouble; 167 bool isdouble;
167 FbTk::RefCount<FbTk::Command<void> > m_command; 168 FbTk::RefCount<FbTk::Command<void> > m_command;
@@ -170,6 +171,7 @@ public:
170}; 171};
171 172
172Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_, 173Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_,
174 const char* key_str_,
173 int context_, bool isdouble_) : 175 int context_, bool isdouble_) :
174 type(type_), 176 type(type_),
175 mod(mod_), 177 mod(mod_),
@@ -177,6 +179,10 @@ Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_,
177 context(context_), 179 context(context_),
178 isdouble(isdouble_), 180 isdouble(isdouble_),
179 m_command(0) { 181 m_command(0) {
182
183 if (key_str_) {
184 key_str.assign(key_str_);
185 }
180 context = context_ ? context_ : GLOBAL; 186 context = context_ ? context_ : GLOBAL;
181} 187}
182 188
@@ -319,7 +325,7 @@ void Keys::reload() {
319 // free memory of previous grabs 325 // free memory of previous grabs
320 deleteTree(); 326 deleteTree();
321 327
322 m_map["default:"] = new t_key(0,0,0,0,false); 328 m_map["default:"] = new t_key(0,0,0,0,0,false);
323 329
324 unsigned int current_line = 0; //so we can tell the user where the fault is 330 unsigned int current_line = 0; //so we can tell the user where the fault is
325 331
@@ -349,7 +355,7 @@ void Keys::loadDefaults() {
349 fbdbg<<"Loading default key bindings"<<endl; 355 fbdbg<<"Loading default key bindings"<<endl;
350 356
351 deleteTree(); 357 deleteTree();
352 m_map["default:"] = new t_key(0,0,0,0,false); 358 m_map["default:"] = new t_key(0,0,0,0,0,false);
353 addBinding("OnDesktop Mouse1 :HideMenus"); 359 addBinding("OnDesktop Mouse1 :HideMenus");
354 addBinding("OnDesktop Mouse2 :WorkspaceMenu"); 360 addBinding("OnDesktop Mouse2 :WorkspaceMenu");
355 addBinding("OnDesktop Mouse3 :RootMenu"); 361 addBinding("OnDesktop Mouse3 :RootMenu");
@@ -389,7 +395,7 @@ bool Keys::addBinding(const string &linebuffer) {
389 argc++; 395 argc++;
390 keyspace_t::iterator it = m_map.find(val[0]); 396 keyspace_t::iterator it = m_map.find(val[0]);
391 if (it == m_map.end()) 397 if (it == m_map.end())
392 m_map[val[0]] = new t_key(0,0,0,0,false); 398 m_map[val[0]] = new t_key(0,0,0,0,0,false);
393 current_key = m_map[val[0]]; 399 current_key = m_map[val[0]];
394 } 400 }
395 // for each argument 401 // for each argument
@@ -399,6 +405,8 @@ bool Keys::addBinding(const string &linebuffer) {
399 405
400 if (arg[0] != ':') { // parse key(s) 406 if (arg[0] != ':') { // parse key(s)
401 407
408 const char* key_str = 0;
409
402 int tmpmod = FbTk::KeyUtil::getModifier(arg.c_str()); 410 int tmpmod = FbTk::KeyUtil::getModifier(arg.c_str());
403 if(tmpmod) 411 if(tmpmod)
404 mod |= tmpmod; //If it's a modifier 412 mod |= tmpmod; //If it's a modifier
@@ -462,6 +470,7 @@ bool Keys::addBinding(const string &linebuffer) {
462 470
463 } else if ((key = FbTk::KeyUtil::getKey(val[argc].c_str()))) { // convert from string symbol 471 } else if ((key = FbTk::KeyUtil::getKey(val[argc].c_str()))) { // convert from string symbol
464 type = KeyPress; 472 type = KeyPress;
473 key_str = val[argc].c_str();
465 474
466 // keycode covers the following three two-byte cases: 475 // keycode covers the following three two-byte cases:
467 // 0x - hex 476 // 0x - hex
@@ -484,13 +493,13 @@ bool Keys::addBinding(const string &linebuffer) {
484 current_key = current_key->find(type, mod, key, context, 493 current_key = current_key->find(type, mod, key, context,
485 isdouble); 494 isdouble);
486 if (!current_key) { 495 if (!current_key) {
487 first_new_key = new t_key(type, mod, key, context, 496 first_new_key = new t_key(type, mod, key, key_str, context,
488 isdouble); 497 isdouble);
489 current_key = first_new_key; 498 current_key = first_new_key;
490 } else if (current_key->m_command) // already being used 499 } else if (current_key->m_command) // already being used
491 return false; 500 return false;
492 } else { 501 } else {
493 t_key *temp_key = new t_key(type, mod, key, context, 502 t_key *temp_key = new t_key(type, mod, key, key_str, context,
494 isdouble); 503 isdouble);
495 current_key->keylist.push_back(temp_key); 504 current_key->keylist.push_back(temp_key);
496 current_key = temp_key; 505 current_key = temp_key;
@@ -654,12 +663,17 @@ void Keys::setKeyMode(t_key *keyMode) {
654 t_key::keylist_t::iterator it = keyMode->keylist.begin(); 663 t_key::keylist_t::iterator it = keyMode->keylist.begin();
655 t_key::keylist_t::iterator it_end = keyMode->keylist.end(); 664 t_key::keylist_t::iterator it_end = keyMode->keylist.end();
656 for (; it != it_end; ++it) { 665 for (; it != it_end; ++it) {
657 if ((*it)->type == KeyPress) 666 t_key* t = *it;
658 grabKey((*it)->key, (*it)->mod); 667 if (t->type == KeyPress) {
659 else 668 if (!t->key_str.empty()) {
660 grabButton((*it)->key, (*it)->mod, (*it)->context); 669 int key = FbTk::KeyUtil::getKey(t->key_str.c_str());
670 t->key = key;
671 }
672 grabKey(t->key, t->mod);
673 } else {
674 grabButton(t->key, t->mod, t->context);
675 }
661 } 676 }
662 m_keylist = keyMode; 677 m_keylist = keyMode;
663} 678}
664 679
665