diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Keys.cc | 122 |
1 files changed, 84 insertions, 38 deletions
diff --git a/src/Keys.cc b/src/Keys.cc index 5c0be86..d8d65fd 100644 --- a/src/Keys.cc +++ b/src/Keys.cc | |||
@@ -147,6 +147,8 @@ public: | |||
147 | static void initKeys(FbTk::Lua &l); | 147 | static void initKeys(FbTk::Lua &l); |
148 | static int addBinding(lua::state *l); | 148 | static int addBinding(lua::state *l); |
149 | static int newKeyMode(lua::state *l); | 149 | static int newKeyMode(lua::state *l); |
150 | static int index(lua::state *l); | ||
151 | static int newindex(lua::state *l); | ||
150 | 152 | ||
151 | bool equalExact(const RefKey &x) { | 153 | bool equalExact(const RefKey &x) { |
152 | return type == x->type && key == x->key && context == x->context | 154 | return type == x->type && key == x->key && context == x->context |
@@ -194,7 +196,7 @@ public: | |||
194 | static FbTk::Lua::RegisterInitFunction registerInitKeys; | 196 | static FbTk::Lua::RegisterInitFunction registerInitKeys; |
195 | }; | 197 | }; |
196 | 198 | ||
197 | int Keys::t_key::addBinding(lua::state *l) | 199 | int Keys::t_key::newindex(lua::state *l) |
198 | { | 200 | { |
199 | l->checkstack(2); | 201 | l->checkstack(2); |
200 | 202 | ||
@@ -203,33 +205,43 @@ int Keys::t_key::addBinding(lua::state *l) | |||
203 | 205 | ||
204 | RefKey k = *l->checkudata<RefKey>(1, keymode_metatable); | 206 | RefKey k = *l->checkudata<RefKey>(1, keymode_metatable); |
205 | 207 | ||
206 | if(! l->isstring(2)) { | ||
207 | throw KeyError(_FB_CONSOLETEXT(Keys, Bad2ndArg, "2nd argument is not a string.", | ||
208 | "2nd argument is not a string.")); | ||
209 | } | ||
210 | vector<string> val; | 208 | vector<string> val; |
211 | FbTk::StringUtil::stringtok(val, l->tostring(-2).c_str()); | 209 | FbTk::StringUtil::stringtok(val, l->checkstring(2).c_str()); |
212 | 210 | ||
213 | if(! (l->isstring(3) || l->isfunction(3)) ) { | 211 | RefKey k2; |
214 | throw KeyError(_FB_CONSOLETEXT(Keys, Bad3rdArg, "3rd argument is not a command.", | 212 | try { |
215 | "3rd argument is not a command.")); | 213 | k2 = *l->checkudata<RefKey>(3, keymode_metatable); |
216 | } | 214 | } |
217 | FbTk::RefCount<FbTk::Command<void> > cmd; | 215 | catch(lua::check_error &) { |
218 | if(l->isstring(3)) | 216 | k2.reset(new t_key); |
219 | cmd.reset(FbTk::CommandParser<void>::instance().parse(l->tostring(-1))); | 217 | |
220 | else { | 218 | if(l->isstring(3)) |
221 | l->pushvalue(3); | 219 | k2->m_command.reset(FbTk::CommandParser<void>::instance().parse(l->tostring(-1))); |
222 | cmd.reset(new FbCommands::LuaCmd(*l)); | 220 | else if(l->isfunction(3)) { |
221 | l->pushvalue(3); | ||
222 | k2->m_command.reset(new FbCommands::LuaCmd(*l)); | ||
223 | } else if(l->isnil(3)) | ||
224 | k2.reset(); | ||
225 | else { | ||
226 | throw KeyError(_FB_CONSOLETEXT(Keys, Bad3rdArg, "3rd argument is not a command.", | ||
227 | "3rd argument is not a command.")); | ||
228 | } | ||
223 | } | 229 | } |
224 | 230 | ||
225 | FindPair p = k->findBinding(val, true); | 231 | FindPair p = k->findBinding(val, true); |
226 | 232 | if(k2) { | |
227 | k = *p.first; | 233 | RefKey t = *p.first; |
228 | k->m_command = cmd; | 234 | k2->type = t->type; |
229 | k->keylist.clear(); | 235 | k2->mod = t->mod; |
236 | k2->key = t->key; | ||
237 | k2->context = t->context; | ||
238 | k2->isdouble = t->isdouble; | ||
239 | *p.first = k2; | ||
240 | } else | ||
241 | p.second.keylist.erase(p.first); | ||
230 | } | 242 | } |
231 | catch(std::runtime_error &e) { | 243 | catch(std::runtime_error &e) { |
232 | cerr << "addBinding: " << e.what() << endl; | 244 | cerr << "keymode newindex: " << e.what() << endl; |
233 | } | 245 | } |
234 | 246 | ||
235 | return 0; | 247 | return 0; |
@@ -244,6 +256,42 @@ int Keys::t_key::newKeyMode(lua::state *l) { | |||
244 | } return 1; | 256 | } return 1; |
245 | } | 257 | } |
246 | 258 | ||
259 | int Keys::t_key::index(lua::state *l) { | ||
260 | l->checkstack(2); | ||
261 | |||
262 | try { | ||
263 | l->checkargno(2); | ||
264 | |||
265 | RefKey k = *l->checkudata<RefKey>(1, keymode_metatable); | ||
266 | |||
267 | string str = l->checkstring(2); | ||
268 | |||
269 | if(str == "activate") | ||
270 | l->pushfunction(&setKeyModeWrapper); | ||
271 | else { | ||
272 | vector<string> val; | ||
273 | FbTk::StringUtil::stringtok(val, str.c_str()); | ||
274 | |||
275 | FindPair p = k->findBinding(val, false); | ||
276 | if(p.first == p.second.keylist.end()) | ||
277 | l->pushnil(); | ||
278 | else { | ||
279 | l->createuserdata<RefKey>(*p.first); { | ||
280 | l->rawgetfield(lua::REGISTRYINDEX, keymode_metatable); | ||
281 | l->setmetatable(-2); | ||
282 | } | ||
283 | } | ||
284 | |||
285 | } | ||
286 | } | ||
287 | catch(std::runtime_error &e) { | ||
288 | cerr << "keymode index: " << e.what() << endl; | ||
289 | l->pushnil(); | ||
290 | } | ||
291 | |||
292 | return 1; | ||
293 | } | ||
294 | |||
247 | void Keys::t_key::initKeys(FbTk::Lua &l) { | 295 | void Keys::t_key::initKeys(FbTk::Lua &l) { |
248 | l.checkstack(3); | 296 | l.checkstack(3); |
249 | lua::stack_sentry s(l); | 297 | lua::stack_sentry s(l); |
@@ -252,13 +300,11 @@ void Keys::t_key::initKeys(FbTk::Lua &l) { | |||
252 | l.pushdestructor<RefKey>(); | 300 | l.pushdestructor<RefKey>(); |
253 | l.rawsetfield(-2, "__gc"); | 301 | l.rawsetfield(-2, "__gc"); |
254 | 302 | ||
255 | l.newtable(); { | 303 | l.pushfunction(&index); |
256 | l.pushfunction(&addBinding); | 304 | l.rawsetfield(-2, "__index"); |
257 | l.rawsetfield(-2, "addBinding"); | ||
258 | 305 | ||
259 | l.pushfunction(&setKeyModeWrapper); | 306 | l.pushfunction(&newindex); |
260 | l.rawsetfield(-2, "activate"); | 307 | l.rawsetfield(-2, "__newindex"); |
261 | } l.rawsetfield(-2, "__index"); | ||
262 | } l.pop(); | 308 | } l.pop(); |
263 | 309 | ||
264 | newKeyMode(&l); | 310 | newKeyMode(&l); |
@@ -547,18 +593,18 @@ void Keys::loadDefaults(FbTk::Lua &l) { | |||
547 | fbdbg<<"Loading default key bindings"<<endl; | 593 | fbdbg<<"Loading default key bindings"<<endl; |
548 | 594 | ||
549 | l.loadstring( | 595 | l.loadstring( |
550 | "default_keymode:addBinding('OnDesktop Mouse1', 'HideMenus')\n" | 596 | "default_keymode['OnDesktop Mouse1'] = 'HideMenus'\n" |
551 | "default_keymode:addBinding('OnDesktop Mouse2', 'WorkspaceMenu')\n" | 597 | "default_keymode['OnDesktop Mouse2'] = 'WorkspaceMenu'\n" |
552 | "default_keymode:addBinding('OnDesktop Mouse3', 'RootMenu')\n" | 598 | "default_keymode['OnDesktop Mouse3'] = 'RootMenu'\n" |
553 | "default_keymode:addBinding('OnTitlebar Mouse3', 'WindowMenu')\n" | 599 | "default_keymode['OnTitlebar Mouse3'] = 'WindowMenu'\n" |
554 | "default_keymode:addBinding('Mod1 OnWindow Mouse1', 'MacroCmd {Focus} {Raise} {StartMoving}')\n" | 600 | "default_keymode['Mod1 OnWindow Mouse1'] = 'MacroCmd {Focus} {Raise} {StartMoving}'\n" |
555 | "default_keymode:addBinding('OnTitlebar Mouse1', 'MacroCmd {Focus} {Raise} {ActivateTab}')\n" | 601 | "default_keymode['OnTitlebar Mouse1'] = 'MacroCmd {Focus} {Raise} {ActivateTab}'\n" |
556 | "default_keymode:addBinding('OnTitlebar Move1', 'StartMoving')\n" | 602 | "default_keymode['OnTitlebar Move1'] = 'StartMoving'\n" |
557 | "default_keymode:addBinding('OnLeftGrip Move1', 'StartResizing bottomleft')\n" | 603 | "default_keymode['OnLeftGrip Move1'] = 'StartResizing bottomleft'\n" |
558 | "default_keymode:addBinding('OnRightGrip Move1', 'StartResizing bottomright')\n" | 604 | "default_keymode['OnRightGrip Move1'] = 'StartResizing bottomright'\n" |
559 | "default_keymode:addBinding('OnWindowBorder Move1', 'StartMoving')\n" | 605 | "default_keymode['OnWindowBorder Move1'] = 'StartMoving'\n" |
560 | "default_keymode:addBinding('Mod1 Tab', 'NextWindow (workspace=[current])')\n" | 606 | "default_keymode['Mod1 Tab'] = 'NextWindow (workspace=[current])'\n" |
561 | "default_keymode:addBinding('Mod1 Shift Tab', 'PrevWindow (workspace=[current])')\n" | 607 | "default_keymode['Mod1 Shift Tab'] = 'PrevWindow (workspace=[current])'\n" |
562 | ); | 608 | ); |
563 | l.call(0, 0); | 609 | l.call(0, 0); |
564 | } | 610 | } |