diff options
Diffstat (limited to 'src/Screen.cc')
-rw-r--r-- | src/Screen.cc | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/src/Screen.cc b/src/Screen.cc index 987bbd0..4bcc988 100644 --- a/src/Screen.cc +++ b/src/Screen.cc | |||
@@ -365,7 +365,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm, | |||
365 | m_altname(altscreenname), | 365 | m_altname(altscreenname), |
366 | m_focus_control(new FocusControl(*this)), | 366 | m_focus_control(new FocusControl(*this)), |
367 | m_placement_strategy(new ScreenPlacement(*this)), | 367 | m_placement_strategy(new ScreenPlacement(*this)), |
368 | m_cycling(false), | 368 | m_cycling(false), m_typing_ahead(false), m_cycle_opts(0), |
369 | m_xinerama_headinfo(0), | 369 | m_xinerama_headinfo(0), |
370 | m_restart(false), | 370 | m_restart(false), |
371 | m_shutdown(false) { | 371 | m_shutdown(false) { |
@@ -788,7 +788,43 @@ void BScreen::update(FbTk::Subject *subj) { | |||
788 | } | 788 | } |
789 | 789 | ||
790 | void BScreen::keyPressEvent(XKeyEvent &ke) { | 790 | void BScreen::keyPressEvent(XKeyEvent &ke) { |
791 | Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode); | 791 | if (!m_typing_ahead) { |
792 | Fluxbox::instance()->keys()->doAction(ke.type, ke.state, ke.keycode); | ||
793 | return; | ||
794 | } | ||
795 | |||
796 | KeySym ks; | ||
797 | char keychar[1]; | ||
798 | XLookupString(&ke, keychar, 1, &ks, 0); | ||
799 | // a modifier key by itself doesn't do anything | ||
800 | if (IsModifierKey(ks)) | ||
801 | return; | ||
802 | |||
803 | switch (ks) { | ||
804 | case XK_Escape: | ||
805 | case XK_KP_Enter: | ||
806 | case XK_Return: | ||
807 | m_type_ahead.reset(); | ||
808 | FbTk::EventManager::instance()->ungrabKeyboard(); | ||
809 | break; | ||
810 | case XK_BackSpace: | ||
811 | m_type_ahead.putBackSpace(); | ||
812 | m_matches = m_type_ahead.matched(); | ||
813 | break; | ||
814 | case XK_Tab: | ||
815 | case XK_ISO_Left_Tab: | ||
816 | m_type_ahead.seek(); | ||
817 | focusControl().cycleFocus(&m_matches, m_cycle_opts, (bool)(ke.state & ShiftMask)); | ||
818 | break; | ||
819 | default: | ||
820 | m_matches = m_type_ahead.putCharacter(keychar[0]); | ||
821 | // if focused win doesn't match new search string, find the next one | ||
822 | if (!m_matches.empty() && | ||
823 | std::find(m_matches.begin(), m_matches.end(), | ||
824 | FocusControl::focusedWindow()) == m_matches.end()) | ||
825 | focusControl().cycleFocus(&m_matches, m_cycle_opts); | ||
826 | break; | ||
827 | } | ||
792 | } | 828 | } |
793 | 829 | ||
794 | void BScreen::keyReleaseEvent(XKeyEvent &ke) { | 830 | void BScreen::keyReleaseEvent(XKeyEvent &ke) { |
@@ -812,9 +848,20 @@ void BScreen::buttonPressEvent(XButtonEvent &be) { | |||
812 | 848 | ||
813 | void BScreen::notifyUngrabKeyboard() { | 849 | void BScreen::notifyUngrabKeyboard() { |
814 | m_cycling = false; | 850 | m_cycling = false; |
851 | m_typing_ahead = false; | ||
852 | m_type_ahead.reset(); | ||
815 | focusControl().stopCyclingFocus(); | 853 | focusControl().stopCyclingFocus(); |
816 | } | 854 | } |
817 | 855 | ||
856 | void BScreen::startTypeAheadFocus(std::list<WinClient *> &winlist, int opts) { | ||
857 | m_type_ahead.init(winlist); | ||
858 | FbTk::EventManager *evm = FbTk::EventManager::instance(); | ||
859 | if (!m_typing_ahead && !m_cycling) | ||
860 | evm->grabKeyboard(*this, rootWindow().window()); | ||
861 | m_cycle_opts = opts; | ||
862 | m_typing_ahead = true; | ||
863 | } | ||
864 | |||
818 | void BScreen::cycleFocus(int options, bool reverse) { | 865 | void BScreen::cycleFocus(int options, bool reverse) { |
819 | // get modifiers from event that causes this for focus order cycling | 866 | // get modifiers from event that causes this for focus order cycling |
820 | XEvent ev = Fluxbox::instance()->lastEvent(); | 867 | XEvent ev = Fluxbox::instance()->lastEvent(); |
@@ -824,7 +871,7 @@ void BScreen::cycleFocus(int options, bool reverse) { | |||
824 | else if (ev.type == ButtonPress) | 871 | else if (ev.type == ButtonPress) |
825 | mods = FbTk::KeyUtil::instance().cleanMods(ev.xbutton.state); | 872 | mods = FbTk::KeyUtil::instance().cleanMods(ev.xbutton.state); |
826 | 873 | ||
827 | if (!m_cycling && mods) { | 874 | if (!m_cycling && !m_typing_ahead && mods) { |
828 | m_cycling = true; | 875 | m_cycling = true; |
829 | FbTk::EventManager::instance()->grabKeyboard(*this, rootWindow().window()); | 876 | FbTk::EventManager::instance()->grabKeyboard(*this, rootWindow().window()); |
830 | } | 877 | } |