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