summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog22
-rw-r--r--src/FbCommandFactory.cc7
-rw-r--r--src/FbCommands.cc15
-rw-r--r--src/FbCommands.hh9
-rw-r--r--src/FbTk/KeyUtil.cc16
-rw-r--r--src/Keys.cc193
-rw-r--r--src/Keys.hh12
-rw-r--r--src/fluxbox.cc8
8 files changed, 182 insertions, 100 deletions
diff --git a/ChangeLog b/ChangeLog
index c921dde..f6a32df 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,27 @@
1(Format: Year/Month/Day) 1(Format: Year/Month/Day)
2Changes for 0.9.16: 2Changes for 0.9.16:
3*06/04/13:
4 * Provide "Key Modes" (Thanks Mark Tiefenbruck, mark at tiefenbruck dot org)
5 - New action in keys file:
6 Modifier Key :Keymode <Name> <End Modifier> <End Key>
7 Will define a keybinding namespace activated by the given mod/key
8 combination. The End Modifier and key are optional. They define
9 the key combination that quits the given key mode. They default
10 to just 'Escape'.
11 - New keys file optional prefix:
12 <Name>: Modifier Key :Command
13 will only work when the <Name> keymode is activated.
14 - <Name> is "default" if not specified - so:
15 **default commands will not be activated inside another keymode**
16 - Handy Example:
17 Mod1 X :KeyMode XNest
18 XNest: Mod1 X :KeyMode default
19 Will switch to XNest keymode when you press Alt-X. Then the
20 default bindings will not be caught by normal fluxbox, and will
21 pass through to an Xnested one! Groovy... Alt-X will switch back
22 to normal.
23 Keys.hh/cc FbCommands.hh/cc fluxbox.cc FbCommandFactory.cc
24 FbTk/KeyUtil.cc
3*06/04/11: 25*06/04/11:
4 * Ensure applying of size hints while maximizing (Mathias) 26 * Ensure applying of size hints while maximizing (Mathias)
5 Window.cc 27 Window.cc
diff --git a/src/FbCommandFactory.cc b/src/FbCommandFactory.cc
index aa091bb..4bf1dd5 100644
--- a/src/FbCommandFactory.cc
+++ b/src/FbCommandFactory.cc
@@ -65,6 +65,7 @@ FbCommandFactory::FbCommandFactory() {
65 "focusright", 65 "focusright",
66 "fullscreen", 66 "fullscreen",
67 "iconify", 67 "iconify",
68 "keymode",
68 "killwindow", 69 "killwindow",
69 "leftworkspace", 70 "leftworkspace",
70 "lower", 71 "lower",
@@ -106,11 +107,11 @@ FbCommandFactory::FbCommandFactory() {
106 "rightworkspace", 107 "rightworkspace",
107 "rootmenu", 108 "rootmenu",
108 "saverc", 109 "saverc",
109 "setenv",
110 "sethead",
111 "sendtoworkspace", 110 "sendtoworkspace",
112 "sendtonextworkspace", 111 "sendtonextworkspace",
113 "sendtoprevworkspace", 112 "sendtoprevworkspace",
113 "setenv",
114 "sethead",
114 "setstyle", 115 "setstyle",
115 "setworkspacename", 116 "setworkspacename",
116 "setworkspacenamedialog", 117 "setworkspacenamedialog",
@@ -168,6 +169,8 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
168 return new SetStyleCmd(arguments); 169 return new SetStyleCmd(arguments);
169 else if (command == "reloadstyle") 170 else if (command == "reloadstyle")
170 return new ReloadStyleCmd(); 171 return new ReloadStyleCmd();
172 else if (command == "keymode")
173 return new KeyModeCmd(arguments);
171 else if (command == "saverc") 174 else if (command == "saverc")
172 return new SaveResources(); 175 return new SaveResources();
173 else if (command == "execcommand" || command == "execute" || command == "exec") 176 else if (command == "execcommand" || command == "execute" || command == "exec")
diff --git a/src/FbCommands.cc b/src/FbCommands.cc
index eb4e040..fc2426d 100644
--- a/src/FbCommands.cc
+++ b/src/FbCommands.cc
@@ -225,6 +225,21 @@ void SetStyleCmd::execute() {
225 Fluxbox::instance()->getStyleOverlayFilename()); 225 Fluxbox::instance()->getStyleOverlayFilename());
226} 226}
227 227
228KeyModeCmd::KeyModeCmd(const std::string &arguments):m_keymode(arguments),m_end_args("None Escape") {
229 string::size_type second_pos = m_keymode.find_first_of(" \t", 0);
230 if (second_pos != string::npos) {
231 // ok we have arguments, parsing them here
232 m_end_args = m_keymode.substr(second_pos);
233 m_keymode.erase(second_pos); // remove argument from command
234 }
235 if (m_keymode != "default")
236 Fluxbox::instance()->keys()->addBinding(m_keymode + ": " + m_end_args + " :keymode default");
237}
238
239void KeyModeCmd::execute() {
240 Fluxbox::instance()->keys()->keyMode(m_keymode);
241}
242
228void ShowRootMenuCmd::execute() { 243void ShowRootMenuCmd::execute() {
229 BScreen *screen = Fluxbox::instance()->mouseScreen(); 244 BScreen *screen = Fluxbox::instance()->mouseScreen();
230 if (screen == 0) 245 if (screen == 0)
diff --git a/src/FbCommands.hh b/src/FbCommands.hh
index 1783c3a..023ff02 100644
--- a/src/FbCommands.hh
+++ b/src/FbCommands.hh
@@ -96,6 +96,15 @@ private:
96 std::string m_filename; 96 std::string m_filename;
97}; 97};
98 98
99class KeyModeCmd: public FbTk::Command {
100public:
101 explicit KeyModeCmd(const std::string &arguments);
102 void execute();
103private:
104 std::string m_keymode;
105 std::string m_end_args;
106};
107
99class ShowRootMenuCmd: public FbTk::Command { 108class ShowRootMenuCmd: public FbTk::Command {
100public: 109public:
101 void execute(); 110 void execute();
diff --git a/src/FbTk/KeyUtil.cc b/src/FbTk/KeyUtil.cc
index 1837873..cb0db93 100644
--- a/src/FbTk/KeyUtil.cc
+++ b/src/FbTk/KeyUtil.cc
@@ -124,42 +124,42 @@ void KeyUtil::grabKey(unsigned int key, unsigned int mod) {
124 124
125 XGrabKey(display, key, mod, 125 XGrabKey(display, key, mod,
126 root, True, 126 root, True,
127 GrabModeAsync, GrabModeAsync); 127 GrabModeAsync, GrabModeSync);
128 128
129 // Grab with numlock, capslock and scrlock 129 // Grab with numlock, capslock and scrlock
130 130
131 //numlock 131 //numlock
132 XGrabKey(display, key, mod|nummod, 132 XGrabKey(display, key, mod|nummod,
133 root, True, 133 root, True,
134 GrabModeAsync, GrabModeAsync); 134 GrabModeAsync, GrabModeSync);
135 //scrolllock 135 //scrolllock
136 XGrabKey(display, key, mod|scrollmod, 136 XGrabKey(display, key, mod|scrollmod,
137 root, True, 137 root, True,
138 GrabModeAsync, GrabModeAsync); 138 GrabModeAsync, GrabModeSync);
139 //capslock 139 //capslock
140 XGrabKey(display, key, mod|capsmod, 140 XGrabKey(display, key, mod|capsmod,
141 root, True, 141 root, True,
142 GrabModeAsync, GrabModeAsync); 142 GrabModeAsync, GrabModeSync);
143 143
144 //capslock+numlock 144 //capslock+numlock
145 XGrabKey(display, key, mod|capsmod|nummod, 145 XGrabKey(display, key, mod|capsmod|nummod,
146 root, True, 146 root, True,
147 GrabModeAsync, GrabModeAsync); 147 GrabModeAsync, GrabModeSync);
148 148
149 //capslock+scrolllock 149 //capslock+scrolllock
150 XGrabKey(display, key, mod|capsmod|scrollmod, 150 XGrabKey(display, key, mod|capsmod|scrollmod,
151 root, True, 151 root, True,
152 GrabModeAsync, GrabModeAsync); 152 GrabModeAsync, GrabModeSync);
153 153
154 //capslock+numlock+scrolllock 154 //capslock+numlock+scrolllock
155 XGrabKey(display, key, mod|capsmod|scrollmod|nummod, 155 XGrabKey(display, key, mod|capsmod|scrollmod|nummod,
156 root, True, 156 root, True,
157 GrabModeAsync, GrabModeAsync); 157 GrabModeAsync, GrabModeSync);
158 158
159 //numlock+scrollLock 159 //numlock+scrollLock
160 XGrabKey(display, key, mod|nummod|scrollmod, 160 XGrabKey(display, key, mod|nummod|scrollmod,
161 root, True, 161 root, True,
162 GrabModeAsync, GrabModeAsync); 162 GrabModeAsync, GrabModeSync);
163 163
164 } 164 }
165 165
diff --git a/src/Keys.cc b/src/Keys.cc
index 5e30726..c4099f6 100644
--- a/src/Keys.cc
+++ b/src/Keys.cc
@@ -86,6 +86,7 @@
86#include <iostream> 86#include <iostream>
87#include <fstream> 87#include <fstream>
88#include <vector> 88#include <vector>
89#include <map>
89#ifdef HAVE_CASSERT 90#ifdef HAVE_CASSERT
90 #include <cassert> 91 #include <cassert>
91#else 92#else
@@ -95,12 +96,10 @@
95 96
96using namespace std; 97using namespace std;
97 98
98Keys::Keys(const char *filename): 99Keys::Keys():
99 m_display(FbTk::App::instance()->display()) 100 m_display(FbTk::App::instance()->display())
100{ 101{
101 102
102 if (filename != 0)
103 load(filename);
104} 103}
105 104
106Keys::~Keys() { 105Keys::~Keys() {
@@ -111,11 +110,15 @@ Keys::~Keys() {
111 110
112/// Destroys the keytree 111/// Destroys the keytree
113void Keys::deleteTree() { 112void Keys::deleteTree() {
114 keylist_t::iterator it = m_keylist.begin(); 113 for (keyspace_t::iterator map_it = m_map.begin(); map_it != m_map.end(); ++map_it) {
115 const keylist_t::iterator end = m_keylist.end(); 114 keylist_t::iterator it = map_it->second->begin();
116 for ( ; it != end; it++) 115 const keylist_t::iterator it_end = map_it->second->end();
117 delete *it; 116 for ( ; it != it_end; it++)
118 m_keylist.clear(); 117 delete *it;
118 map_it->second->clear();
119 delete map_it->second;
120 m_map.erase(map_it->first);
121 }
119} 122}
120 123
121/** 124/**
@@ -133,6 +136,8 @@ bool Keys::load(const char *filename) {
133 //free memory of previous grabs 136 //free memory of previous grabs
134 deleteTree(); 137 deleteTree();
135 138
139 m_map["default:"] = new keylist_t;
140
136 FbTk::App::instance()->sync(false); 141 FbTk::App::instance()->sync(false);
137 142
138 //open the file 143 //open the file
@@ -154,6 +159,7 @@ bool Keys::load(const char *filename) {
154 159
155 m_current_line = 0; 160 m_current_line = 0;
156 m_filename = filename; 161 m_filename = filename;
162 m_keylist = m_map["default:"];
157 return true; 163 return true;
158} 164}
159 165
@@ -184,55 +190,60 @@ bool Keys::addBinding(const std::string &linebuffer) {
184 return true; // still a valid line. 190 return true; // still a valid line.
185 191
186 unsigned int key = 0, mod = 0; 192 unsigned int key = 0, mod = 0;
187 char keyarg = 0;
188 t_key *current_key=0, *last_key=0; 193 t_key *current_key=0, *last_key=0;
189 194 size_t argc = 0;
195 std::string keyMode = "default:";
196
197 if (val[0][val[0].length()-1] == ':') {
198 argc++;
199 keyspace_t::iterator it = m_map.find(val[0]);
200 if (it == m_map.end())
201 m_map[val[0]] = new keylist_t;
202 keyMode = val[0];
203 }
190 _FB_USES_NLS; 204 _FB_USES_NLS;
191 // for each argument 205 // for each argument
192 for (size_t argc = 0; argc < val.size(); argc++) { 206 for (; argc < val.size(); argc++) {
193 207
194 if (val[argc][0] != ':') { // parse key(s) 208 if (val[argc][0] != ':') { // parse key(s)
195 keyarg++; 209
196 if (keyarg==1) //first arg is modifier 210 int tmpmod = FbTk::KeyUtil::getModifier(val[argc].c_str());
197 mod = FbTk::KeyUtil::getModifier(val[argc].c_str()); 211 if(tmpmod)
198 else if (keyarg > 1) { 212 mod |= tmpmod; //If it's a modifier
199 213 else if (strcasecmp("NONE",val[argc].c_str()) == 0)
200 int tmpmod = FbTk::KeyUtil::getModifier(val[argc].c_str()); 214 mod = 0;
201 if(tmpmod) 215 else {
202 mod |= tmpmod; //If it's a modifier 216 // keycode covers the following three two-byte cases:
203 else { 217 // 0x - hex
204 // keycode covers the following three two-byte cases: 218 // +[1-9] - number between +1 and +9
205 // 0x - hex 219 // numbers 10 and above
206 // +[1-9] - number between +1 and +9 220 //
207 // numbers 10 and above 221 if (val[argc].size() > 1 && (isdigit(val[argc][0]) &&
208 // 222 (isdigit(val[argc][1]) || val[argc][1] == 'x') ||
209 if (val[argc].size() > 1 && (isdigit(val[argc][0]) && 223 val[argc][0] == '+' && isdigit(val[argc][1])) ) {
210 (isdigit(val[argc][1]) || val[argc][1] == 'x') ||
211 val[argc][0] == '+' && isdigit(val[argc][1])) ) {
212 224
213 key = strtoul(val[argc].c_str(), NULL, 0); 225 key = strtoul(val[argc].c_str(), NULL, 0);
214 226
215 if (errno == EINVAL || errno == ERANGE) 227 if (errno == EINVAL || errno == ERANGE)
216 key = 0; 228 key = 0;
217 229
218 } else // convert from string symbol 230 } else // convert from string symbol
219 key = FbTk::KeyUtil::getKey(val[argc].c_str()); 231 key = FbTk::KeyUtil::getKey(val[argc].c_str());
220 232
221 if (key == 0) { 233 if (key == 0) {
222 cerr<<_FBTEXT(Keys, InvalidKeyMod, 234 cerr<<_FBTEXT(Keys, InvalidKeyMod,
223 "Keys: Invalid key/modifier on line", 235 "Keys: Invalid key/modifier on line",
224 "A bad key/modifier string was found on line (number following)")<<" "<< 236 "A bad key/modifier string was found on line (number following)")<<" "<<
225 m_current_line<<"): "<<linebuffer<<endl; 237 m_current_line<<"): "<<linebuffer<<endl;
226 return false; 238 return false;
227 } 239 }
228 if (!current_key) { 240 if (!current_key) {
229 current_key = new t_key(key, mod); 241 current_key = new t_key(key, mod);
230 last_key = current_key; 242 last_key = current_key;
231 } else { 243 } else {
232 t_key *temp_key = new t_key(key, mod); 244 t_key *temp_key = new t_key(key, mod);
233 last_key->keylist.push_back(temp_key); 245 last_key->keylist.push_back(temp_key);
234 last_key = temp_key; 246 last_key = temp_key;
235 }
236 } 247 }
237 } 248 }
238 249
@@ -258,6 +269,8 @@ bool Keys::addBinding(const std::string &linebuffer) {
258 cerr<<_FBTEXT(Keys, BadLine, "Keys: Error on line", "Error on line (number following)")<<": "<<m_current_line<<endl; 269 cerr<<_FBTEXT(Keys, BadLine, "Keys: Error on line", "Error on line (number following)")<<": "<<m_current_line<<endl;
259 cerr<<"> "<<linebuffer<<endl; 270 cerr<<"> "<<linebuffer<<endl;
260 } else { 271 } else {
272 // need to change keymode here so it doesn't get changed by CommandParser
273 m_keylist = m_map[keyMode];
261 // Add the keychain to list 274 // Add the keychain to list
262 if (!mergeTree(current_key)) { 275 if (!mergeTree(current_key)) {
263 cerr<<_FBTEXT(Keys, BadMerge, "Keys: Failed to merge keytree!", "relatively technical error message. Key bindings are stored in a tree structure")<<endl; 276 cerr<<_FBTEXT(Keys, BadMerge, "Keys: Failed to merge keytree!", "relatively technical error message. Key bindings are stored in a tree structure")<<endl;
@@ -279,46 +292,50 @@ bool Keys::addBinding(const std::string &linebuffer) {
279 292
280 293
281/** 294/**
282 @return the KeyAction of the XKeyEvent 295 @return the KeyAction of the XKeyEvent; return false if not bound
283*/ 296*/
284void Keys::doAction(XKeyEvent &ke) { 297bool Keys::doAction(XKeyEvent &ke) {
285 298
286 ke.state = FbTk::KeyUtil::instance().cleanMods(ke.state); 299 ke.state = FbTk::KeyUtil::instance().cleanMods(ke.state);
287 300
288 static struct t_key* next_key = 0; 301 static struct t_key* next_key = 0;
289 302
290 if (!next_key) { 303 if (!next_key) {
291 304 bool retval = false;
292 for (size_t i = 0; i < m_keylist.size(); i++) { 305 // need a local keylist, in case m_command->execute() changes it
293 if (*m_keylist[i] == ke) { 306 keylist_t *keylist = m_keylist;
294 if (m_keylist[i]->keylist.size()) { 307 for (size_t i = 0; i < keylist->size(); i++) {
295 next_key = m_keylist[i]; 308 if (*(*keylist)[i] == ke) {
296 break; //end for-loop 309 if ((*keylist)[i]->keylist.size()) {
297 } else { 310 next_key = (*keylist)[i];
298 if (*m_keylist[i]->m_command != 0) 311 return true; //still counts as being grabbed
299 m_keylist[i]->m_command->execute(); 312 }
313 if (*(*keylist)[i]->m_command != 0) {
314 (*keylist)[i]->m_command->execute();
315 retval = true;
300 } 316 }
301 } 317 }
302 } 318 }
303 319 return retval;
304 } else { //check the nextkey 320 }
305 t_key *temp_key = next_key->find(ke); 321 t_key *temp_key = next_key->find(ke);
306 if (temp_key) { 322 if (temp_key) {
307 if (temp_key->keylist.size()) { 323 if (temp_key->keylist.size()) {
308 next_key = temp_key; 324 next_key = temp_key;
309 } else { 325 return true;
310 next_key = 0;
311 if (*temp_key->m_command != 0)
312 temp_key->m_command->execute();
313 }
314 } else {
315 temp_key = next_key;
316 next_key = 0;
317 if (*temp_key->m_command != 0)
318 temp_key->m_command->execute();
319
320 } 326 }
327 next_key = 0;
328 if (*temp_key->m_command == 0)
329 return false;
330 temp_key->m_command->execute();
331 return true;
321 } 332 }
333 temp_key = next_key;
334 next_key = 0;
335 if (*temp_key->m_command == 0)
336 return false;
337 temp_key->m_command->execute();
338 return true;
322} 339}
323 340
324/** 341/**
@@ -337,22 +354,22 @@ bool Keys::reconfigure(const char *filename) {
337bool Keys::mergeTree(t_key *newtree, t_key *basetree) { 354bool Keys::mergeTree(t_key *newtree, t_key *basetree) {
338 size_t baselist_i = 0; 355 size_t baselist_i = 0;
339 if (basetree==0) { 356 if (basetree==0) {
340 for (; baselist_i<m_keylist.size(); baselist_i++) { 357 for (; baselist_i<m_keylist->size(); baselist_i++) {
341 if (m_keylist[baselist_i]->mod == newtree->mod && 358 if ((*m_keylist)[baselist_i]->mod == newtree->mod &&
342 m_keylist[baselist_i]->key == newtree->key) { 359 (*m_keylist)[baselist_i]->key == newtree->key) {
343 if (newtree->keylist.size() && *m_keylist[baselist_i]->m_command == 0) { 360 if (newtree->keylist.size() && *(*m_keylist)[baselist_i]->m_command == 0) {
344 //assumes the newtree only have one branch 361 //assumes the newtree only have one branch
345 return mergeTree(newtree->keylist[0], m_keylist[baselist_i]); 362 return mergeTree(newtree->keylist[0], (*m_keylist)[baselist_i]);
346 } else 363 } else
347 break; 364 break;
348 } 365 }
349 } 366 }
350 367
351 if (baselist_i == m_keylist.size()) { 368 if (baselist_i == m_keylist->size()) {
352 FbTk::KeyUtil::grabKey(newtree->key, newtree->mod); 369 FbTk::KeyUtil::grabKey(newtree->key, newtree->mod);
353 m_keylist.push_back(new t_key(newtree)); 370 m_keylist->push_back(new t_key(newtree));
354 if (newtree->keylist.size()) 371 if (newtree->keylist.size())
355 return mergeTree(newtree->keylist[0], m_keylist.back()); 372 return mergeTree(newtree->keylist[0], m_keylist->back());
356 return true; 373 return true;
357 } 374 }
358 375
@@ -380,6 +397,14 @@ bool Keys::mergeTree(t_key *newtree, t_key *basetree) {
380 return false; 397 return false;
381} 398}
382 399
400void Keys::keyMode(std::string keyMode = "default") {
401 keyspace_t::iterator it = m_map.find(keyMode + ":");
402 if (it == m_map.end())
403 m_keylist = m_map["default:"];
404 else
405 m_keylist = it->second;
406}
407
383Keys::t_key::t_key(unsigned int key_, unsigned int mod_, FbTk::RefCount<FbTk::Command> command) { 408Keys::t_key::t_key(unsigned int key_, unsigned int mod_, FbTk::RefCount<FbTk::Command> command) {
384 key = key_; 409 key = key_;
385 mod = mod_; 410 mod = mod_;
diff --git a/src/Keys.hh b/src/Keys.hh
index 75a8a68..6b393e7 100644
--- a/src/Keys.hh
+++ b/src/Keys.hh
@@ -26,6 +26,7 @@
26 26
27#include <string> 27#include <string>
28#include <vector> 28#include <vector>
29#include <map>
29#include <X11/Xlib.h> 30#include <X11/Xlib.h>
30 31
31#include "FbTk/NotCopyable.hh" 32#include "FbTk/NotCopyable.hh"
@@ -41,7 +42,7 @@ public:
41 @param display display connection 42 @param display display connection
42 @param filename file to load, default none 43 @param filename file to load, default none
43 */ 44 */
44 explicit Keys(const char *filename=0); 45 explicit Keys();
45 /// destructor 46 /// destructor
46 ~Keys(); 47 ~Keys();
47 48
@@ -61,9 +62,9 @@ public:
61 bool addBinding(const std::string &binding); 62 bool addBinding(const std::string &binding);
62 63
63 /** 64 /**
64 do action from XKeyEvent 65 do action from XKeyEvent; return false if not bound to anything
65 */ 66 */
66 void doAction(XKeyEvent &ke); 67 bool doAction(XKeyEvent &ke);
67 68
68 /** 69 /**
69 Reload configuration from filename 70 Reload configuration from filename
@@ -71,6 +72,7 @@ public:
71 */ 72 */
72 bool reconfigure(const char *filename); 73 bool reconfigure(const char *filename);
73 const std::string filename() const { return m_filename; } 74 const std::string filename() const { return m_filename; }
75 void keyMode(std::string keyMode);
74private: 76private:
75 void deleteTree(); 77 void deleteTree();
76 78
@@ -120,7 +122,9 @@ private:
120 */ 122 */
121 bool mergeTree(t_key *newtree, t_key *basetree=0); 123 bool mergeTree(t_key *newtree, t_key *basetree=0);
122 124
123 keylist_t m_keylist; 125 typedef std::map<std::string, keylist_t *> keyspace_t;
126 keylist_t *m_keylist;
127 keyspace_t m_map;
124 128
125 Display *m_display; ///< display connection 129 Display *m_display; ///< display connection
126 unsigned int m_current_line; 130 unsigned int m_current_line;
diff --git a/src/fluxbox.cc b/src/fluxbox.cc
index fbb4203..5fcd4fe 100644
--- a/src/fluxbox.cc
+++ b/src/fluxbox.cc
@@ -383,7 +383,8 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile
383 m_reconfigure_wait = m_reread_menu_wait = false; 383 m_reconfigure_wait = m_reread_menu_wait = false;
384 384
385 // Create keybindings handler and load keys file 385 // Create keybindings handler and load keys file
386 m_key.reset(new Keys(StringUtil::expandFilename(*m_rc_keyfile).c_str())); 386 m_key.reset(new Keys);
387 m_key->load(StringUtil::expandFilename(*m_rc_keyfile).c_str());
387 388
388 m_resourcemanager.unlock(); 389 m_resourcemanager.unlock();
389 ungrab(); 390 ungrab();
@@ -1083,7 +1084,10 @@ void Fluxbox::handleKeyEvent(XKeyEvent &ke) {
1083 1084
1084 switch (ke.type) { 1085 switch (ke.type) {
1085 case KeyPress: 1086 case KeyPress:
1086 m_key->doAction(ke); 1087 if (m_key->doAction(ke))
1088 XAllowEvents(FbTk::App::instance()->display(), AsyncKeyboard, CurrentTime);
1089 else
1090 XAllowEvents(FbTk::App::instance()->display(), ReplayKeyboard, CurrentTime);
1087 break; 1091 break;
1088 case KeyRelease: { 1092 case KeyRelease: {
1089 // we ignore most key releases unless we need to use 1093 // we ignore most key releases unless we need to use