aboutsummaryrefslogtreecommitdiff
path: root/src/Keys.cc
diff options
context:
space:
mode:
authormathias <mathias>2005-05-06 09:22:53 (GMT)
committermathias <mathias>2005-05-06 09:22:53 (GMT)
commit6c057c6903151aab92309310087d5af455ecefce (patch)
tree1d4c98ad1637df09b89593b3e6a4a70245db4602 /src/Keys.cc
parent7d4f711204ab0b51d45eaff332708f529c11c9f5 (diff)
downloadfluxbox-6c057c6903151aab92309310087d5af455ecefce.zip
fluxbox-6c057c6903151aab92309310087d5af455ecefce.tar.bz2
Fix for #1160244, #1099704, #1094107:
if the xkb-extension is enabled and the user switches between his/her keyboardlayouts fluxbox's keybhandling doesn't work well anymore because xkeyevent.state contains also xkb-related flags and thus we have to handle that with caution. KeyUtils now contain 'isolateModifierMask()' to really work only on the modifiers. why not as part of cleanMods() ? because the XLookupString return false results, eg TextBox's would only print chars from the first keyboardlayout.
Diffstat (limited to 'src/Keys.cc')
-rw-r--r--src/Keys.cc76
1 files changed, 39 insertions, 37 deletions
diff --git a/src/Keys.cc b/src/Keys.cc
index 96f57cb..0d3eecd 100644
--- a/src/Keys.cc
+++ b/src/Keys.cc
@@ -27,7 +27,6 @@
27#include "FbTk/StringUtil.hh" 27#include "FbTk/StringUtil.hh"
28#include "FbTk/App.hh" 28#include "FbTk/App.hh"
29#include "FbTk/Command.hh" 29#include "FbTk/Command.hh"
30#include "FbTk/KeyUtil.hh"
31 30
32#include "CommandParser.hh" 31#include "CommandParser.hh"
33#include "FbTk/I18n.hh" 32#include "FbTk/I18n.hh"
@@ -81,6 +80,8 @@
81#include <X11/Xlib.h> 80#include <X11/Xlib.h>
82#include <X11/Xproto.h> 81#include <X11/Xproto.h>
83#include <X11/keysym.h> 82#include <X11/keysym.h>
83#include <X11/Xutil.h>
84#include <X11/XKBlib.h>
84 85
85#include <iostream> 86#include <iostream>
86#include <fstream> 87#include <fstream>
@@ -102,7 +103,7 @@ Keys::Keys(const char *filename):
102 load(filename); 103 load(filename);
103} 104}
104 105
105Keys::~Keys() { 106Keys::~Keys() {
106 107
107 FbTk::KeyUtil::ungrabKeys(); 108 FbTk::KeyUtil::ungrabKeys();
108 deleteTree(); 109 deleteTree();
@@ -112,12 +113,12 @@ Keys::~Keys() {
112void Keys::deleteTree() { 113void Keys::deleteTree() {
113 while (!m_keylist.empty()) { 114 while (!m_keylist.empty()) {
114 if (m_keylist.back()) 115 if (m_keylist.back())
115 delete m_keylist.back(); 116 delete m_keylist.back();
116 m_keylist.pop_back(); 117 m_keylist.pop_back();
117 } 118 }
118} 119}
119 120
120/** 121/**
121 Load and grab keys 122 Load and grab keys
122 TODO: error checking 123 TODO: error checking
123 @return true on success else false 124 @return true on success else false
@@ -125,7 +126,7 @@ void Keys::deleteTree() {
125bool Keys::load(const char *filename) { 126bool Keys::load(const char *filename) {
126 if (!filename) 127 if (!filename)
127 return false; 128 return false;
128 129
129 //ungrab all keys 130 //ungrab all keys
130 FbTk::KeyUtil::ungrabKeys(); 131 FbTk::KeyUtil::ungrabKeys();
131 132
@@ -133,7 +134,7 @@ bool Keys::load(const char *filename) {
133 deleteTree(); 134 deleteTree();
134 135
135 FbTk::App::instance()->sync(false); 136 FbTk::App::instance()->sync(false);
136 137
137 //open the file 138 //open the file
138 ifstream infile(filename); 139 ifstream infile(filename);
139 if (!infile) 140 if (!infile)
@@ -158,8 +159,8 @@ bool Keys::load(const char *filename) {
158 159
159bool Keys::save(const char *filename) const { 160bool Keys::save(const char *filename) const {
160 //!! 161 //!!
161 //!! TODO: fix keybinding saving 162 //!! TODO: fix keybinding saving
162 //!! (we probably need to save key actions 163 //!! (we probably need to save key actions
163 //!! as strings instead of creating new Commands) 164 //!! as strings instead of creating new Commands)
164 165
165 // open file for writing 166 // open file for writing
@@ -178,16 +179,16 @@ bool Keys::addBinding(const std::string &linebuffer) {
178 // must have at least 1 argument 179 // must have at least 1 argument
179 if (val.size() <= 0) 180 if (val.size() <= 0)
180 return true; // empty lines are valid. 181 return true; // empty lines are valid.
181 182
182 if (val[0][0] == '#' || val[0][0] == '!' ) //the line is commented 183 if (val[0][0] == '#' || val[0][0] == '!' ) //the line is commented
183 return true; // still a valid line. 184 return true; // still a valid line.
184 185
185 unsigned int key = 0, mod = 0; 186 unsigned int key = 0, mod = 0;
186 char keyarg = 0; 187 char keyarg = 0;
187 t_key *current_key=0, *last_key=0; 188 t_key *current_key=0, *last_key=0;
188 189
189 _FB_USES_NLS; 190 _FB_USES_NLS;
190 // for each argument 191 // for each argument
191 for (unsigned int argc=0; argc<val.size(); argc++) { 192 for (unsigned int argc=0; argc<val.size(); argc++) {
192 193
193 if (val[argc][0] != ':') { // parse key(s) 194 if (val[argc][0] != ':') { // parse key(s)
@@ -199,7 +200,7 @@ bool Keys::addBinding(const std::string &linebuffer) {
199 int tmpmod = FbTk::KeyUtil::getModifier(val[argc].c_str()); 200 int tmpmod = FbTk::KeyUtil::getModifier(val[argc].c_str());
200 if(tmpmod) 201 if(tmpmod)
201 mod |= tmpmod; //If it's a modifier 202 mod |= tmpmod; //If it's a modifier
202 else { 203 else {
203 key = FbTk::KeyUtil::getKey(val[argc].c_str()); // else get the key 204 key = FbTk::KeyUtil::getKey(val[argc].c_str()); // else get the key
204 if (key == 0) { 205 if (key == 0) {
205 cerr<<_FBTEXT(Keys, InvalidKeyMod, "Keys: Invalid key/modifier on line", "A bad key/modifier string was found on line (number following)")<<" "<< 206 cerr<<_FBTEXT(Keys, InvalidKeyMod, "Keys: Invalid key/modifier on line", "A bad key/modifier string was found on line (number following)")<<" "<<
@@ -209,13 +210,13 @@ bool Keys::addBinding(const std::string &linebuffer) {
209 if (!current_key) { 210 if (!current_key) {
210 current_key = new t_key(key, mod); 211 current_key = new t_key(key, mod);
211 last_key = current_key; 212 last_key = current_key;
212 } else { 213 } else {
213 t_key *temp_key = new t_key(key, mod); 214 t_key *temp_key = new t_key(key, mod);
214 last_key->keylist.push_back(temp_key); 215 last_key->keylist.push_back(temp_key);
215 last_key = temp_key; 216 last_key = temp_key;
216 } 217 }
217 } 218 }
218 } 219 }
219 220
220 } else { // parse command line 221 } else { // parse command line
221 if (last_key == 0) { 222 if (last_key == 0) {
@@ -224,7 +225,7 @@ bool Keys::addBinding(const std::string &linebuffer) {
224 return false; 225 return false;
225 } 226 }
226 bool ret_val = true; 227 bool ret_val = true;
227 const char *str = 228 const char *str =
228 FbTk::StringUtil::strcasestr(linebuffer.c_str(), 229 FbTk::StringUtil::strcasestr(linebuffer.c_str(),
229 val[argc].c_str() + 1); // +1 to skip ':' 230 val[argc].c_str() + 1); // +1 to skip ':'
230 if (str == 0) { 231 if (str == 0) {
@@ -263,41 +264,42 @@ bool Keys::addBinding(const std::string &linebuffer) {
263 @return the KeyAction of the XKeyEvent 264 @return the KeyAction of the XKeyEvent
264*/ 265*/
265void Keys::doAction(XKeyEvent &ke) { 266void Keys::doAction(XKeyEvent &ke) {
266 static t_key *next_key = 0; 267
267 // Remove numlock, capslock and scrolllock
268 ke.state = FbTk::KeyUtil::instance().cleanMods(ke.state); 268 ke.state = FbTk::KeyUtil::instance().cleanMods(ke.state);
269 269
270 static struct t_key* next_key = 0;
271
270 if (!next_key) { 272 if (!next_key) {
271 273
272 for (unsigned int i=0; i<m_keylist.size(); i++) { 274 for (unsigned int i=0; i<m_keylist.size(); i++) {
273 if (*m_keylist[i] == ke) { 275 if (*m_keylist[i] == ke) {
274 if (m_keylist[i]->keylist.size()) { 276 if (m_keylist[i]->keylist.size()) {
275 next_key = m_keylist[i]; 277 next_key = m_keylist[i];
276 break; //end for-loop 278 break; //end for-loop
277 } else { 279 } else {
278 if (*m_keylist[i]->m_command != 0) 280 if (*m_keylist[i]->m_command != 0)
279 m_keylist[i]->m_command->execute(); 281 m_keylist[i]->m_command->execute();
280 } 282 }
281 } 283 }
282 } 284 }
283 285
284 } else { //check the nextkey 286 } else { //check the nextkey
285 t_key *temp_key = next_key->find(ke); 287 t_key *temp_key = next_key->find(ke);
286 if (temp_key) { 288 if (temp_key) {
287 if (temp_key->keylist.size()) { 289 if (temp_key->keylist.size()) {
288 next_key = temp_key; 290 next_key = temp_key;
289 } else { 291 } else {
290 next_key = 0; 292 next_key = 0;
291 if (*temp_key->m_command != 0) 293 if (*temp_key->m_command != 0)
292 temp_key->m_command->execute(); 294 temp_key->m_command->execute();
293 } 295 }
294 } else { 296 } else {
295 temp_key = next_key; 297 temp_key = next_key;
296 next_key = 0; 298 next_key = 0;
297 if (*temp_key->m_command != 0) 299 if (*temp_key->m_command != 0)
298 temp_key->m_command->execute(); 300 temp_key->m_command->execute();
299 301
300 } 302 }
301 } 303 }
302} 304}
303 305
@@ -318,7 +320,7 @@ bool Keys::mergeTree(t_key *newtree, t_key *basetree) {
318 if (basetree==0) { 320 if (basetree==0) {
319 unsigned int baselist_i=0; 321 unsigned int baselist_i=0;
320 for (; baselist_i<m_keylist.size(); baselist_i++) { 322 for (; baselist_i<m_keylist.size(); baselist_i++) {
321 if (m_keylist[baselist_i]->mod == newtree->mod && 323 if (m_keylist[baselist_i]->mod == newtree->mod &&
322 m_keylist[baselist_i]->key == newtree->key) { 324 m_keylist[baselist_i]->key == newtree->key) {
323 if (newtree->keylist.size() && *m_keylist[baselist_i]->m_command == 0) { 325 if (newtree->keylist.size() && *m_keylist[baselist_i]->m_command == 0) {
324 //assumes the newtree only have one branch 326 //assumes the newtree only have one branch
@@ -330,12 +332,12 @@ bool Keys::mergeTree(t_key *newtree, t_key *basetree) {
330 332
331 if (baselist_i == m_keylist.size()) { 333 if (baselist_i == m_keylist.size()) {
332 FbTk::KeyUtil::grabKey(newtree->key, newtree->mod); 334 FbTk::KeyUtil::grabKey(newtree->key, newtree->mod);
333 m_keylist.push_back(new t_key(newtree)); 335 m_keylist.push_back(new t_key(newtree));
334 if (newtree->keylist.size()) 336 if (newtree->keylist.size())
335 return mergeTree(newtree->keylist[0], m_keylist.back()); 337 return mergeTree(newtree->keylist[0], m_keylist.back());
336 return true; 338 return true;
337 } 339 }
338 340
339 } else { 341 } else {
340 unsigned int baselist_i = 0; 342 unsigned int baselist_i = 0;
341 for (; baselist_i<basetree->keylist.size(); baselist_i++) { 343 for (; baselist_i<basetree->keylist.size(); baselist_i++) {
@@ -346,24 +348,24 @@ bool Keys::mergeTree(t_key *newtree, t_key *basetree) {
346 return mergeTree(newtree->keylist[0], basetree->keylist[baselist_i]); 348 return mergeTree(newtree->keylist[0], basetree->keylist[baselist_i]);
347 } else 349 } else
348 return false; 350 return false;
349 } 351 }
350 } 352 }
351 //if it wasn't in the list grab the key and add it to the list 353 //if it wasn't in the list grab the key and add it to the list
352 if (baselist_i==basetree->keylist.size()) { 354 if (baselist_i==basetree->keylist.size()) {
353 FbTk::KeyUtil::grabKey(newtree->key, newtree->mod); 355 FbTk::KeyUtil::grabKey(newtree->key, newtree->mod);
354 basetree->keylist.push_back(new t_key(newtree)); 356 basetree->keylist.push_back(new t_key(newtree));
355 if (newtree->keylist.size()) 357 if (newtree->keylist.size())
356 return mergeTree(newtree->keylist[0], basetree->keylist.back()); 358 return mergeTree(newtree->keylist[0], basetree->keylist.back());
357 return true; 359 return true;
358 } 360 }
359 } 361 }
360 362
361 return false; 363 return false;
362} 364}
363 365
364Keys::t_key::t_key(unsigned int key_, unsigned int mod_, FbTk::RefCount<FbTk::Command> command) { 366Keys::t_key::t_key(unsigned int key_, unsigned int mod_, FbTk::RefCount<FbTk::Command> command) {
365 key = key_; 367 key = key_;
366 mod = mod_; 368 mod = mod_;
367 m_command = command; 369 m_command = command;
368} 370}
369 371
@@ -373,8 +375,8 @@ Keys::t_key::t_key(t_key *k) {
373 m_command = k->m_command; 375 m_command = k->m_command;
374} 376}
375 377
376Keys::t_key::~t_key() { 378Keys::t_key::~t_key() {
377 while (!keylist.empty()) { 379 while (!keylist.empty()) {
378 t_key *k = keylist.back(); 380 t_key *k = keylist.back();
379 if (k != 0) { // make sure we don't have a bad key pointer 381 if (k != 0) { // make sure we don't have a bad key pointer
380 delete k; 382 delete k;