diff options
Diffstat (limited to 'src/Keys.cc')
-rw-r--r-- | src/Keys.cc | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/src/Keys.cc b/src/Keys.cc index 774cd05..8659137 100644 --- a/src/Keys.cc +++ b/src/Keys.cc | |||
@@ -140,21 +140,35 @@ public: | |||
140 | // constructor / destructor | 140 | // constructor / destructor |
141 | t_key(int type = 0, unsigned int mod = 0, unsigned int key = 0, | 141 | t_key(int type = 0, unsigned int mod = 0, unsigned int key = 0, |
142 | const std::string &key_str = std::string(), int context = 0, | 142 | const std::string &key_str = std::string(), int context = 0, |
143 | bool isdouble = false); | 143 | bool isdouble = false, bool isPlaceHolderArg = false); |
144 | 144 | ||
145 | RefKey find(int type_, unsigned int mod_, unsigned int key_, | 145 | RefKey find(int type_, unsigned int mod_, unsigned int key_, |
146 | int context_, bool isdouble_) { | 146 | int context_, bool isdouble_) { |
147 | // t_key ctor sets context_ of 0 to GLOBAL, so we must here too | 147 | // t_key ctor sets context_ of 0 to GLOBAL, so we must here too |
148 | context_ = context_ ? context_ : GLOBAL; | 148 | context_ = context_ ? context_ : GLOBAL; |
149 | keylist_t::iterator itPlaceHolder = keylist.end(); | ||
149 | keylist_t::iterator it = keylist.begin(), it_end = keylist.end(); | 150 | keylist_t::iterator it = keylist.begin(), it_end = keylist.end(); |
150 | for (; it != it_end; ++it) { | 151 | for (; it != it_end; ++it) { |
152 | |||
153 | if ((*it)->isPlaceHolderArg) | ||
154 | itPlaceHolder = it; | ||
155 | |||
151 | if (*it && (*it)->type == type_ && (*it)->key == key_ && | 156 | if (*it && (*it)->type == type_ && (*it)->key == key_ && |
152 | ((*it)->context & context_) > 0 && | 157 | ((*it)->context & context_) > 0 && |
153 | isdouble_ == (*it)->isdouble && (*it)->mod == | 158 | isdouble_ == (*it)->isdouble && (*it)->mod == |
154 | FbTk::KeyUtil::instance().isolateModifierMask(mod_)) | 159 | FbTk::KeyUtil::instance().isolateModifierMask(mod_)) |
155 | return *it; | 160 | return *it; |
156 | } | 161 | } |
157 | return RefKey(); | 162 | |
163 | // Could not find any matching key. If a placeholder was located then user | ||
164 | // is trying to pass in a value for the placeholder. | ||
165 | if (itPlaceHolder == keylist.end()) { | ||
166 | return RefKey(); | ||
167 | } | ||
168 | else { | ||
169 | (*itPlaceHolder)->lastPlaceHolderArgValue = key_; | ||
170 | return *itPlaceHolder; | ||
171 | } | ||
158 | } | 172 | } |
159 | 173 | ||
160 | // member variables | 174 | // member variables |
@@ -165,6 +179,8 @@ public: | |||
165 | std::string key_str; // key-symbol, needed for regrab() | 179 | std::string key_str; // key-symbol, needed for regrab() |
166 | int context; // ON_TITLEBAR, etc.: bitwise-or of all desired contexts | 180 | int context; // ON_TITLEBAR, etc.: bitwise-or of all desired contexts |
167 | bool isdouble; | 181 | bool isdouble; |
182 | bool isPlaceHolderArg; | ||
183 | unsigned int lastPlaceHolderArgValue; | ||
168 | FbTk::RefCount<FbTk::Command<void> > m_command; | 184 | FbTk::RefCount<FbTk::Command<void> > m_command; |
169 | 185 | ||
170 | keylist_t keylist; | 186 | keylist_t keylist; |
@@ -172,13 +188,15 @@ public: | |||
172 | 188 | ||
173 | Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_, | 189 | Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_, |
174 | const std::string &key_str_, | 190 | const std::string &key_str_, |
175 | int context_, bool isdouble_) : | 191 | int context_, bool isdouble_, bool isPlaceHolderArg_) : |
176 | type(type_), | 192 | type(type_), |
177 | mod(mod_), | 193 | mod(mod_), |
178 | key(key_), | 194 | key(key_), |
179 | key_str(key_str_), | 195 | key_str(key_str_), |
180 | context(context_), | 196 | context(context_), |
181 | isdouble(isdouble_), | 197 | isdouble(isdouble_), |
198 | isPlaceHolderArg(isPlaceHolderArg_), | ||
199 | lastPlaceHolderArgValue(0), | ||
182 | m_command(0) { | 200 | m_command(0) { |
183 | 201 | ||
184 | context = context_ ? context_ : GLOBAL; | 202 | context = context_ ? context_ : GLOBAL; |
@@ -385,6 +403,8 @@ bool Keys::addBinding(const string &linebuffer) { | |||
385 | 403 | ||
386 | std::string arg = FbTk::StringUtil::toLower(val[argc]); | 404 | std::string arg = FbTk::StringUtil::toLower(val[argc]); |
387 | 405 | ||
406 | bool isPlaceHolderArg = false; | ||
407 | |||
388 | if (arg[0] != ':') { // parse key(s) | 408 | if (arg[0] != ':') { // parse key(s) |
389 | 409 | ||
390 | std::string key_str; | 410 | std::string key_str; |
@@ -461,7 +481,11 @@ bool Keys::addBinding(const string &linebuffer) { | |||
461 | type = ButtonRelease; | 481 | type = ButtonRelease; |
462 | } else if (extractKeyFromString(arg, "move", key)) { | 482 | } else if (extractKeyFromString(arg, "move", key)) { |
463 | type = MotionNotify; | 483 | type = MotionNotify; |
464 | 484 | } else if (arg == "arg") { | |
485 | isPlaceHolderArg = true; | ||
486 | key = 0; | ||
487 | mod = 0; | ||
488 | type = 0; | ||
465 | } else if ((key = FbTk::KeyUtil::getKey(val[argc].c_str()))) { // convert from string symbol | 489 | } else if ((key = FbTk::KeyUtil::getKey(val[argc].c_str()))) { // convert from string symbol |
466 | type = KeyPress; | 490 | type = KeyPress; |
467 | key_str = val[argc]; | 491 | key_str = val[argc]; |
@@ -476,25 +500,31 @@ bool Keys::addBinding(const string &linebuffer) { | |||
476 | type = KeyPress; | 500 | type = KeyPress; |
477 | } | 501 | } |
478 | 502 | ||
479 | if (key == 0 && (type == KeyPress || type == ButtonPress || type == ButtonRelease)) | 503 | if (key == 0 && (type == KeyPress || type == ButtonPress || type == ButtonRelease) && !isPlaceHolderArg) |
480 | return false; | 504 | return false; |
481 | 505 | ||
482 | if (type != ButtonPress) | 506 | if (type != ButtonPress) |
483 | isdouble = false; | 507 | isdouble = false; |
484 | 508 | ||
509 | // Placeholder argument cannot be the first key | ||
510 | if (!first_new_key && isPlaceHolderArg) { | ||
511 | return false; | ||
512 | } | ||
513 | |||
485 | if (!first_new_key) { | 514 | if (!first_new_key) { |
486 | first_new_keylist = current_key; | 515 | first_new_keylist = current_key; |
487 | current_key = current_key->find(type, mod, key, context, | 516 | current_key = current_key->find(type, mod, key, context, |
488 | isdouble); | 517 | isdouble); |
489 | if (!current_key) { | 518 | if (!current_key) { |
490 | first_new_key.reset( new t_key(type, mod, key, key_str, context, | 519 | first_new_key.reset( new t_key(type, mod, key, key_str, context, |
491 | isdouble) ); | 520 | isdouble, isPlaceHolderArg) ); |
492 | current_key = first_new_key; | 521 | current_key = first_new_key; |
493 | } else if (current_key->m_command) // already being used | 522 | } else if (current_key->m_command) // already being used |
494 | return false; | 523 | return false; |
495 | } else { | 524 | } else { |
525 | |||
496 | RefKey temp_key( new t_key(type, mod, key, key_str, context, | 526 | RefKey temp_key( new t_key(type, mod, key, key_str, context, |
497 | isdouble) ); | 527 | isdouble, isPlaceHolderArg) ); |
498 | current_key->keylist.push_back(temp_key); | 528 | current_key->keylist.push_back(temp_key); |
499 | current_key = temp_key; | 529 | current_key = temp_key; |
500 | } | 530 | } |
@@ -608,6 +638,15 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key, | |||
608 | 638 | ||
609 | WinClient *old = WindowCmd<void>::client(); | 639 | WinClient *old = WindowCmd<void>::client(); |
610 | WindowCmd<void>::setClient(current); | 640 | WindowCmd<void>::setClient(current); |
641 | |||
642 | // The key is a placeholder, store the value of the entered key in the shortcut manager | ||
643 | // before executing the action | ||
644 | if (temp_key->isPlaceHolderArg) { | ||
645 | fbdbg << "Encountered placeholder key. Assign value[" << temp_key->lastPlaceHolderArgValue | ||
646 | << "] to the placeholder" << std::endl; | ||
647 | Fluxbox::instance()->shortcutManager().setLastPlaceHolderKey(temp_key->lastPlaceHolderArgValue); | ||
648 | } | ||
649 | |||
611 | temp_key->m_command->execute(); | 650 | temp_key->m_command->execute(); |
612 | WindowCmd<void>::setClient(old); | 651 | WindowCmd<void>::setClient(old); |
613 | 652 | ||