aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/FbCommandFactory.cc3
-rw-r--r--src/Screen.cc53
-rw-r--r--src/Screen.hh6
-rw-r--r--src/WinClient.hh5
-rw-r--r--src/WorkspaceCmd.cc14
-rw-r--r--src/WorkspaceCmd.hh8
6 files changed, 84 insertions, 5 deletions
diff --git a/src/FbCommandFactory.cc b/src/FbCommandFactory.cc
index c02365a..bd20c39 100644
--- a/src/FbCommandFactory.cc
+++ b/src/FbCommandFactory.cc
@@ -145,6 +145,7 @@ FbCommandFactory::FbCommandFactory() {
145 "taketoprevworkspace", 145 "taketoprevworkspace",
146 "togglecmd", 146 "togglecmd",
147 "toggledecor", 147 "toggledecor",
148 "typeaheadfocus",
148 "windowmenu", 149 "windowmenu",
149 "workspace", 150 "workspace",
150 /* NOTE: The following are DEPRECATED and subject to removal */ 151 /* NOTE: The following are DEPRECATED and subject to removal */
@@ -419,6 +420,8 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
419 return new NextWindowCmd(atoi(arguments.c_str())); 420 return new NextWindowCmd(atoi(arguments.c_str()));
420 else if (command == "prevwindow") 421 else if (command == "prevwindow")
421 return new PrevWindowCmd(atoi(arguments.c_str())); 422 return new PrevWindowCmd(atoi(arguments.c_str()));
423 else if (command == "typeaheadfocus")
424 return new TypeAheadFocusCmd(atoi(arguments.c_str()));
422 else if (command == "focusup") 425 else if (command == "focusup")
423 return new DirFocusCmd(FocusControl::FOCUSUP); 426 return new DirFocusCmd(FocusControl::FOCUSUP);
424 else if (command == "focusdown") 427 else if (command == "focusdown")
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 }
diff --git a/src/Screen.hh b/src/Screen.hh
index bf03ac6..c2e493b 100644
--- a/src/Screen.hh
+++ b/src/Screen.hh
@@ -217,6 +217,7 @@ public:
217 void buttonPressEvent(XButtonEvent &be); 217 void buttonPressEvent(XButtonEvent &be);
218 void notifyUngrabKeyboard(); 218 void notifyUngrabKeyboard();
219 219
220 void startTypeAheadFocus(std::list<WinClient *> &winlist, int opts);
220 void cycleFocus(int opts, bool reverse); 221 void cycleFocus(int opts, bool reverse);
221 222
222 FbTk::Menu *createMenu(const std::string &label); 223 FbTk::Menu *createMenu(const std::string &label);
@@ -485,7 +486,10 @@ private:
485 typedef std::map<Window, WinClient *> Groupables; 486 typedef std::map<Window, WinClient *> Groupables;
486 Groupables m_expecting_groups; 487 Groupables m_expecting_groups;
487 488
488 bool m_cycling; 489 bool m_cycling, m_typing_ahead;
490 int m_cycle_opts;
491 FbTk::TypeAhead<std::list<WinClient *>, WinClient *> m_type_ahead;
492 std::list<WinClient *> m_matches;
489 493
490 // Xinerama related private data 494 // Xinerama related private data
491 bool m_xinerama_avail; 495 bool m_xinerama_avail;
diff --git a/src/WinClient.hh b/src/WinClient.hh
index 0082bb0..7d2c734 100644
--- a/src/WinClient.hh
+++ b/src/WinClient.hh
@@ -29,6 +29,7 @@
29#include "Subject.hh" 29#include "Subject.hh"
30#include "FbWindow.hh" 30#include "FbWindow.hh"
31#include "FbTk/FbString.hh" 31#include "FbTk/FbString.hh"
32#include "FbTk/ITypeAheadable.hh"
32 33
33#include <X11/Xutil.h> 34#include <X11/Xutil.h>
34 35
@@ -36,7 +37,8 @@ class BScreen;
36class Strut; 37class Strut;
37 38
38/// Holds client window info 39/// Holds client window info
39class WinClient: public Focusable, public FbTk::FbWindow { 40class WinClient: public Focusable, public FbTk::ITypeAheadable,
41 public FbTk::FbWindow {
40public: 42public:
41 typedef std::list<WinClient *> TransientList; 43 typedef std::list<WinClient *> TransientList;
42 // this structure only contains 3 elements... the Motif 2.0 structure contains 44 // this structure only contains 3 elements... the Motif 2.0 structure contains
@@ -143,6 +145,7 @@ public:
143 inline unsigned int maxWidth() const { return max_width; } 145 inline unsigned int maxWidth() const { return max_width; }
144 inline unsigned int maxHeight() const { return max_height; } 146 inline unsigned int maxHeight() const { return max_height; }
145 147
148 const std::string &iTypeString() const { return m_title; }
146 149
147 static const int PropBlackboxHintsElements = 5; 150 static const int PropBlackboxHintsElements = 5;
148 static const int PropMwmHintsElements = 3; 151 static const int PropMwmHintsElements = 3;
diff --git a/src/WorkspaceCmd.cc b/src/WorkspaceCmd.cc
index 0cbf5b9..f92418f 100644
--- a/src/WorkspaceCmd.cc
+++ b/src/WorkspaceCmd.cc
@@ -53,6 +53,20 @@ void PrevWindowCmd::execute() {
53 screen->cycleFocus(m_option, true); 53 screen->cycleFocus(m_option, true);
54} 54}
55 55
56void TypeAheadFocusCmd::execute() {
57 Fluxbox *fb = Fluxbox::instance();
58 BScreen *screen = fb->keyScreen();
59 if (screen != 0) {
60 int options = m_option;
61 FocusControl::FocusedWindows *win_list =
62 (options & FocusControl::CYCLELINEAR) ?
63 &screen->focusControl().creationOrderList() :
64 &screen->focusControl().focusedOrderList();
65
66 screen->startTypeAheadFocus(*win_list, m_option);
67 }
68}
69
56void DirFocusCmd::execute() { 70void DirFocusCmd::execute() {
57 BScreen *screen = Fluxbox::instance()->keyScreen(); 71 BScreen *screen = Fluxbox::instance()->keyScreen();
58 if (screen == 0) 72 if (screen == 0)
diff --git a/src/WorkspaceCmd.hh b/src/WorkspaceCmd.hh
index 7d8d9e6..d0a6713 100644
--- a/src/WorkspaceCmd.hh
+++ b/src/WorkspaceCmd.hh
@@ -45,6 +45,14 @@ private:
45 const int m_option; 45 const int m_option;
46}; 46};
47 47
48class TypeAheadFocusCmd: public FbTk::Command {
49public:
50 explicit TypeAheadFocusCmd(int option): m_option(option) { }
51 void execute();
52private:
53 const int m_option;
54};
55
48class DirFocusCmd: public FbTk::Command { 56class DirFocusCmd: public FbTk::Command {
49public: 57public:
50 explicit DirFocusCmd(const FocusControl::FocusDir dir): m_dir(dir) { } 58 explicit DirFocusCmd(const FocusControl::FocusDir dir): m_dir(dir) { }