From 6ca6422344f0046ef1794c5fbaea90d28692fd5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Wed, 31 Aug 2016 01:24:31 +0200 Subject: introduce a 5s timeout for emacs shortcuts The user needs to enter his chain within 5 seconds Otherwise the chain is reset. REQUEST: 291 --- src/Keys.cc | 23 +++++++++++++++++------ src/Screen.cc | 2 +- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/Keys.cc b/src/Keys.cc index 1e66463..072cba9 100644 --- a/src/Keys.cc +++ b/src/Keys.cc @@ -522,6 +522,8 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key, if (!m_keylist) return false; + static Time first_key_time = 0; + static Time last_button_time = 0; static unsigned int last_button = 0; @@ -544,6 +546,17 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key, isdouble = double_click; } + auto resetKeyChain = [&]() { + first_key_time = 0; + next_key.reset(); + if (saved_keymode) { + setKeyMode(saved_keymode); + saved_keymode.reset(); + } + }; + if (type == KeyPress && first_key_time && time - first_key_time > 5000) + resetKeyChain(); + if (!next_key) next_key = m_keylist; @@ -560,8 +573,10 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key, return true; // if there's a motion action, prevent replay to the client (but do nothing) if (temp_key && !temp_key->keylist.empty()) { // emacs-style - if (!saved_keymode) + if (!saved_keymode) { + first_key_time = time; saved_keymode = m_keylist; + } next_key = temp_key; setKeyMode(next_key); return true; @@ -570,11 +585,7 @@ bool Keys::doAction(int type, unsigned int mods, unsigned int key, if (type == KeyPress && !FbTk::KeyUtil::instance().keycodeToModmask(key)) { // if we're in the middle of an emacs-style keychain, exit it - next_key.reset(); - if (saved_keymode) { - setKeyMode(saved_keymode); - saved_keymode.reset(); - } + resetKeyChain(); } return false; } diff --git a/src/Screen.cc b/src/Screen.cc index 53b772e..c24250a 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -656,7 +656,7 @@ void BScreen::propertyNotify(Atom atom) { void BScreen::keyPressEvent(XKeyEvent &ke) { if (Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode, - Keys::GLOBAL|(ke.subwindow ? 0 : Keys::ON_DESKTOP))) { + Keys::GLOBAL|(ke.subwindow ? 0 : Keys::ON_DESKTOP), 0, ke.time)) { // re-grab keyboard, so we don't pass KeyRelease to clients // also for catching invalid keys in the middle of keychains -- cgit v0.11.2