aboutsummaryrefslogtreecommitdiff
path: root/src/Screen.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/Screen.cc')
-rw-r--r--src/Screen.cc53
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
790void BScreen::keyPressEvent(XKeyEvent &ke) { 790void 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
794void BScreen::keyReleaseEvent(XKeyEvent &ke) { 830void BScreen::keyReleaseEvent(XKeyEvent &ke) {
@@ -812,9 +848,20 @@ void BScreen::buttonPressEvent(XButtonEvent &be) {
812 848
813void BScreen::notifyUngrabKeyboard() { 849void 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
856void 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
818void BScreen::cycleFocus(int options, bool reverse) { 865void 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 }