aboutsummaryrefslogtreecommitdiff
path: root/src/Keys.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/Keys.cc')
-rw-r--r--src/Keys.cc122
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
195int Keys::t_key::addBinding(lua::state *l) 197int 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
257int 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
245void Keys::t_key::initKeys(FbTk::Lua &l) { 293void 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}