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