From 22f3df9aa81efc071cb13d43a372ead97548eebc Mon Sep 17 00:00:00 2001 From: Mark Tiefenbruck Date: Fri, 3 Oct 2008 22:59:14 -0700 Subject: break keychains after an invalid key is pressed (which unfortunately will be swallowed) --- ChangeLog | 2 ++ src/Keys.cc | 15 ++++++--------- src/Keys.hh | 5 ++++- src/Screen.cc | 5 +++-- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index c4f3ab0..0214d31 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,8 @@ (Format: Year/Month/Day) Changes for 1.1.2 *08/10/04: + * Break emacs-style keychains after one invalid key has been pressed (Mark) + Screen.cc Keys.cc/hh * Fix flickering of shaped windows, #2131548 and #2001027 (Mark) FbTk/Shape.cc *08/10/01: diff --git a/src/Keys.cc b/src/Keys.cc index 05f1747..658820e 100644 --- a/src/Keys.cc +++ b/src/Keys.cc @@ -170,7 +170,9 @@ Keys::t_key::~t_key() { -Keys::Keys(): m_reloader(new FbTk::AutoReloadHelper()), next_key(0) { +Keys::Keys(): + m_reloader(new FbTk::AutoReloadHelper()), + next_key(0), saved_keymode(0) { m_reloader->setReloadCmd(FbTk::RefCount >(new FbTk::SimpleCommand(*this, &Keys::reload))); } @@ -187,6 +189,7 @@ void Keys::deleteTree() { delete map_it->second; m_map.clear(); next_key = 0; + saved_keymode = 0; } // keys are only grabbed in global context @@ -504,22 +507,16 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key, if (!temp_key && isdouble) temp_key = next_key->find(type, mods, key, context, false); - // need to save this for emacs-style keybindings - static t_key *saved_keymode = 0; - - // grab "None Escape" to exit keychain in the middle - unsigned int esc = FbTk::KeyUtil::getKey("Escape"); - if (temp_key && !temp_key->keylist.empty()) { // emacs-style if (!saved_keymode) saved_keymode = m_keylist; next_key = temp_key; setKeyMode(next_key); - grabKey(esc,0); return true; } if (!temp_key || *temp_key->m_command == 0) { - if (type == KeyPress && key == esc && mods == 0) { + if (type == KeyPress && + !FbTk::KeyUtil::instance().keycodeToModmask(key)) { // if we're in the middle of an emacs-style keychain, exit it next_key = 0; if (saved_keymode) { diff --git a/src/Keys.hh b/src/Keys.hh index 03a15dd..9502643 100644 --- a/src/Keys.hh +++ b/src/Keys.hh @@ -83,6 +83,9 @@ public: */ void reconfigure(); void keyMode(const std::string& keyMode); + + bool inKeychain() const { return saved_keymode != 0; } + private: class t_key; // helper class to build a 'keytree' typedef std::map keyspace_t; @@ -109,7 +112,7 @@ private: keyspace_t m_map; // former doAction static var, we need to access it from deleteTree - t_key *next_key; + t_key *next_key, *saved_keymode; WindowMap m_window_map; HandlerMap m_handler_map; diff --git a/src/Screen.cc b/src/Screen.cc index 892afda..49b631d 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -856,6 +856,7 @@ void BScreen::keyPressEvent(XKeyEvent &ke) { if (Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode, Keys::GLOBAL|Keys::ON_DESKTOP)) // re-grab keyboard, so we don't pass KeyRelease to clients + // also for catching invalid keys in the middle of keychains FbTk::EventManager::instance()->grabKeyboard(rootWindow().window()); } @@ -871,8 +872,8 @@ void BScreen::keyReleaseEvent(XKeyEvent &ke) { m_cycling = false; focusControl().stopCyclingFocus(); } - - FbTk::EventManager::instance()->ungrabKeyboard(); + if (!Fluxbox::instance()->keys()->inKeychain()) + FbTk::EventManager::instance()->ungrabKeyboard(); } void BScreen::buttonPressEvent(XButtonEvent &be) { -- cgit v0.11.2