From ec6df5c3d19ed760f343d6755ad396b00ac8f4ea Mon Sep 17 00:00:00 2001 From: Mathias Gumz <akira at fluxbox dot org> Date: Fri, 26 Aug 2011 09:21:50 +0200 Subject: 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 --- src/Keys.cc | 36 +++++++++++++++++++++++++----------- 1 file 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: typedef std::list<t_key*> keylist_t; // constructor / destructor - t_key(int type, unsigned int mod, unsigned int key, int context, + t_key(int type, unsigned int mod, unsigned int key, const char* key_str, int context, bool isdouble); t_key(t_key *k); ~t_key(); @@ -162,6 +162,7 @@ public: int type; // KeyPress or ButtonPress unsigned int mod; unsigned int key; // key code or button number + std::string key_str; // key-symbol, needed for regrab() int context; // ON_TITLEBAR, etc.: bitwise-or of all desired contexts bool isdouble; FbTk::RefCount<FbTk::Command<void> > m_command; @@ -170,6 +171,7 @@ public: }; Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_, + const char* key_str_, int context_, bool isdouble_) : type(type_), mod(mod_), @@ -177,6 +179,10 @@ Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_, context(context_), isdouble(isdouble_), m_command(0) { + + if (key_str_) { + key_str.assign(key_str_); + } context = context_ ? context_ : GLOBAL; } @@ -319,7 +325,7 @@ void Keys::reload() { // free memory of previous grabs deleteTree(); - m_map["default:"] = new t_key(0,0,0,0,false); + m_map["default:"] = new t_key(0,0,0,0,0,false); unsigned int current_line = 0; //so we can tell the user where the fault is @@ -349,7 +355,7 @@ void Keys::loadDefaults() { fbdbg<<"Loading default key bindings"<<endl; deleteTree(); - m_map["default:"] = new t_key(0,0,0,0,false); + m_map["default:"] = new t_key(0,0,0,0,0,false); addBinding("OnDesktop Mouse1 :HideMenus"); addBinding("OnDesktop Mouse2 :WorkspaceMenu"); addBinding("OnDesktop Mouse3 :RootMenu"); @@ -389,7 +395,7 @@ bool Keys::addBinding(const string &linebuffer) { argc++; keyspace_t::iterator it = m_map.find(val[0]); if (it == m_map.end()) - m_map[val[0]] = new t_key(0,0,0,0,false); + m_map[val[0]] = new t_key(0,0,0,0,0,false); current_key = m_map[val[0]]; } // for each argument @@ -399,6 +405,8 @@ bool Keys::addBinding(const string &linebuffer) { if (arg[0] != ':') { // parse key(s) + const char* key_str = 0; + int tmpmod = FbTk::KeyUtil::getModifier(arg.c_str()); if(tmpmod) mod |= tmpmod; //If it's a modifier @@ -462,6 +470,7 @@ bool Keys::addBinding(const string &linebuffer) { } else if ((key = FbTk::KeyUtil::getKey(val[argc].c_str()))) { // convert from string symbol type = KeyPress; + key_str = val[argc].c_str(); // keycode covers the following three two-byte cases: // 0x - hex @@ -484,13 +493,13 @@ bool Keys::addBinding(const string &linebuffer) { current_key = current_key->find(type, mod, key, context, isdouble); if (!current_key) { - first_new_key = new t_key(type, mod, key, context, + first_new_key = new t_key(type, mod, key, key_str, context, isdouble); current_key = first_new_key; } else if (current_key->m_command) // already being used return false; } else { - t_key *temp_key = new t_key(type, mod, key, context, + t_key *temp_key = new t_key(type, mod, key, key_str, context, isdouble); current_key->keylist.push_back(temp_key); current_key = temp_key; @@ -654,12 +663,17 @@ void Keys::setKeyMode(t_key *keyMode) { t_key::keylist_t::iterator it = keyMode->keylist.begin(); t_key::keylist_t::iterator it_end = keyMode->keylist.end(); for (; it != it_end; ++it) { - if ((*it)->type == KeyPress) - grabKey((*it)->key, (*it)->mod); - else - grabButton((*it)->key, (*it)->mod, (*it)->context); + t_key* t = *it; + if (t->type == KeyPress) { + if (!t->key_str.empty()) { + int key = FbTk::KeyUtil::getKey(t->key_str.c_str()); + t->key = key; + } + grabKey(t->key, t->mod); + } else { + grabButton(t->key, t->mod, t->context); + } } m_keylist = keyMode; } - -- cgit v0.11.2