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
This commit is contained in:
Mathias Gumz 2011-08-26 09:21:50 +02:00
parent 7b10649e28
commit ec6df5c3d1

View file

@ -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;
}