aboutsummaryrefslogtreecommitdiff
path: root/src/FocusControl.cc
diff options
context:
space:
mode:
authormarkt <markt>2007-03-30 20:29:46 (GMT)
committermarkt <markt>2007-03-30 20:29:46 (GMT)
commit3ab6b48974c32c742bda5dc6c3f217f9d58e3d99 (patch)
tree7a9852f2513e4677e636cd6261c87ba3002b3ab4 /src/FocusControl.cc
parentaef362350332d80febe1a4b72ee9b4b962ed527b (diff)
downloadfluxbox-3ab6b48974c32c742bda5dc6c3f217f9d58e3d99.zip
fluxbox-3ab6b48974c32c742bda5dc6c3f217f9d58e3d99.tar.bz2
pattern matching for window cycling
Diffstat (limited to 'src/FocusControl.cc')
-rw-r--r--src/FocusControl.cc146
1 files changed, 78 insertions, 68 deletions
diff --git a/src/FocusControl.cc b/src/FocusControl.cc
index c5ee939..c97b699 100644
--- a/src/FocusControl.cc
+++ b/src/FocusControl.cc
@@ -23,6 +23,7 @@
23 23
24#include "FocusControl.hh" 24#include "FocusControl.hh"
25 25
26#include "ClientPattern.hh"
26#include "Screen.hh" 27#include "Screen.hh"
27#include "Window.hh" 28#include "Window.hh"
28#include "WinClient.hh" 29#include "WinClient.hh"
@@ -43,6 +44,22 @@ WinClient *FocusControl::s_focused_window = 0;
43FluxboxWindow *FocusControl::s_focused_fbwindow = 0; 44FluxboxWindow *FocusControl::s_focused_fbwindow = 0;
44bool FocusControl::s_reverting = false; 45bool FocusControl::s_reverting = false;
45 46
47namespace {
48
49bool doSkipWindow(const Focusable &win, const ClientPattern *pat) {
50 const FluxboxWindow *fbwin = win.fbwindow();
51 if (!fbwin || fbwin->isFocusHidden())
52 return true; // skip if no fbwindow or if focushidden
53 if (pat && !pat->match(win))
54 return true; // skip if it doesn't match the pattern
55 if (fbwin->workspaceNumber() != win.screen().currentWorkspaceID() &&
56 !fbwin->isStuck())
57 return true; // for now, we only cycle through the current workspace
58 return false; // else don't skip
59}
60
61}; // end anonymous namespace
62
46FocusControl::FocusControl(BScreen &screen): 63FocusControl::FocusControl(BScreen &screen):
47 m_screen(screen), 64 m_screen(screen),
48 m_focus_model(screen.resourceManager(), 65 m_focus_model(screen.resourceManager(),
@@ -64,43 +81,30 @@ FocusControl::FocusControl(BScreen &screen):
64 81
65} 82}
66 83
67// true if the windows should be skiped else false 84void FocusControl::cycleFocus(FocusedWindows &window_list,
68bool doSkipWindow(const Focusable &winclient, int opts) { 85 const ClientPattern *pat, bool cycle_reverse) {
69 const FluxboxWindow *win = winclient.fbwindow();
70 return (!win ||
71 // skip if stuck
72 (opts & FocusControl::CYCLESKIPSTUCK) != 0 && win->isStuck() ||
73 // skip if shaded
74 (opts & FocusControl::CYCLESKIPSHADED) != 0 && win->isShaded() ||
75 // skip if iconic
76 (opts & FocusControl::CYCLESKIPICONIC) != 0 && win->isIconic() ||
77 // skip if hidden
78 win->isFocusHidden()
79 );
80}
81
82void FocusControl::cycleFocus(FocusedWindows *window_list, int opts, bool cycle_reverse) {
83 Focusables tmp_list; 86 Focusables tmp_list;
84 FocusedWindows::iterator it = window_list->begin(); 87 FocusedWindows::iterator it = window_list.begin();
85 FocusedWindows::iterator it_end = window_list->end(); 88 FocusedWindows::iterator it_end = window_list.end();
86 for (; it != it_end; ++it) 89 for (; it != it_end; ++it)
87 tmp_list.push_back(*it); 90 tmp_list.push_back(*it);
88 cycleFocus(&tmp_list, opts, cycle_reverse); 91 cycleFocus(tmp_list, pat, cycle_reverse);
89} 92}
90 93
91void FocusControl::cycleFocus(Focusables *window_list, int opts, bool cycle_reverse) { 94void FocusControl::cycleFocus(Focusables &window_list, const ClientPattern *pat,
95 bool cycle_reverse) {
92 96
93 if (!m_cycling_list) { 97 if (!m_cycling_list) {
94 if (&m_screen == FbTk::EventManager::instance()->grabbingKeyboard()) 98 if (&m_screen == FbTk::EventManager::instance()->grabbingKeyboard())
95 // only set this when we're waiting for modifiers 99 // only set this when we're waiting for modifiers
96 m_cycling_list = window_list; 100 m_cycling_list = &window_list;
97 m_was_iconic = 0; 101 m_was_iconic = 0;
98 m_cycling_last = 0; 102 m_cycling_last = 0;
99 } else if (m_cycling_list != window_list) 103 } else if (m_cycling_list != &window_list)
100 m_cycling_list = window_list; 104 m_cycling_list = &window_list;
101 105
102 Focusables::iterator it_begin = window_list->begin(); 106 Focusables::iterator it_begin = window_list.begin();
103 Focusables::iterator it_end = window_list->end(); 107 Focusables::iterator it_end = window_list.end();
104 108
105 // too many things can go wrong with remembering this 109 // too many things can go wrong with remembering this
106 m_cycling_window = find(it_begin, it_end, s_focused_window); 110 m_cycling_window = find(it_begin, it_end, s_focused_window);
@@ -108,6 +112,8 @@ void FocusControl::cycleFocus(Focusables *window_list, int opts, bool cycle_reve
108 m_cycling_window = find(it_begin, it_end, s_focused_fbwindow); 112 m_cycling_window = find(it_begin, it_end, s_focused_fbwindow);
109 113
110 Focusables::iterator it = m_cycling_window; 114 Focusables::iterator it = m_cycling_window;
115 FluxboxWindow *fbwin = 0;
116 WinClient *last_client = 0;
111 117
112 // find the next window in the list that works 118 // find the next window in the list that works
113 while (true) { 119 while (true) {
@@ -123,50 +129,54 @@ void FocusControl::cycleFocus(Focusables *window_list, int opts, bool cycle_reve
123 if (it == it_end) 129 if (it == it_end)
124 continue; 130 continue;
125 131
126 FluxboxWindow *fbwin = (*it)->fbwindow(); 132 fbwin = (*it)->fbwindow();
127 if (fbwin && (fbwin->isStuck() 133 if (!fbwin)
128 || fbwin->workspaceNumber() == m_screen.currentWorkspaceID())) { 134 continue;
129 // either on this workspace, or stuck 135
130 136 // keep track of the originally selected window in a group
131 // keep track of the originally selected window in a set 137 last_client = &fbwin->winClient();
132 WinClient &last_client = fbwin->winClient(); 138
133 139 // now we actually try to focus the window
134 if (! (doSkipWindow(**it, opts) || !(*it)->focus()) ) { 140 if (!doSkipWindow(**it, pat) && (*it)->focus())
135 // moved onto a new fbwin 141 break;
136 if (!m_cycling_last || m_cycling_last->fbwindow() != fbwin) {
137 if (m_cycling_last) {
138 // already cycling, so restack to put windows back in
139 // their proper order
140 m_screen.layerManager().restack();
141
142 // set back to orig current Client in that fbwin
143 m_cycling_last->fbwindow()->setCurrentClient(*m_cycling_last, false);
144 if (m_was_iconic == m_cycling_last) {
145 s_reverting = true; // little hack
146 m_cycling_last->fbwindow()->iconify();
147 s_reverting = false;
148 }
149 }
150 m_cycling_last = &last_client;
151 if (fbwin->isIconic())
152 m_was_iconic = m_cycling_last;
153 if (m_cycling_list)
154 // else window will raise itself (if desired) on FocusIn
155 fbwin->tempRaise();
156 }
157 break;
158 }
159 }
160 } 142 }
143
161 m_cycling_window = it; 144 m_cycling_window = it;
145
146 // if we're still in the same fbwin, there's nothing else to do
147 if (m_cycling_last && m_cycling_last->fbwindow() == fbwin)
148 return;
149
150 // if we were already cycling, then restore the old state
151 if (m_cycling_last) {
152 m_screen.layerManager().restack();
153
154 // set back to originally selected window in that group
155 m_cycling_last->fbwindow()->setCurrentClient(*m_cycling_last, false);
156
157 if (m_was_iconic == m_cycling_last) {
158 s_reverting = true; // little hack
159 m_cycling_last->fbwindow()->iconify();
160 s_reverting = false;
161 }
162 }
163
164 m_cycling_last = last_client;
165 if (fbwin->isIconic())
166 m_was_iconic = m_cycling_last;
167 if (m_cycling_list)
168 // else window will raise itself (if desired) on FocusIn
169 fbwin->tempRaise();
170
162} 171}
163 172
164void FocusControl::goToWindowNumber(Focusables *winlist, int num, int options) { 173void FocusControl::goToWindowNumber(Focusables &winlist, int num,
165 if (num > 0 && winlist) { 174 const ClientPattern *pat) {
166 Focusables::iterator it = winlist->begin(); 175 if (num > 0) {
167 Focusables::iterator it_end = winlist->end(); 176 Focusables::iterator it = winlist.begin();
177 Focusables::iterator it_end = winlist.end();
168 for (; it != it_end; ++it) { 178 for (; it != it_end; ++it) {
169 if (!doSkipWindow(**it, options) && (*it)->acceptsFocus()) { 179 if (!doSkipWindow(**it, pat) && (*it)->acceptsFocus()) {
170 --num; 180 --num;
171 if (!num) { 181 if (!num) {
172 if ((*it)->fbwindow() && (*it)->fbwindow()->isIconic()) 182 if ((*it)->fbwindow() && (*it)->fbwindow()->isIconic())
@@ -176,11 +186,11 @@ void FocusControl::goToWindowNumber(Focusables *winlist, int num, int options) {
176 } 186 }
177 } 187 }
178 } 188 }
179 } else if (num < 0 && winlist) { 189 } else if (num < 0) {
180 Focusables::reverse_iterator it = winlist->rbegin(); 190 Focusables::reverse_iterator it = winlist.rbegin();
181 Focusables::reverse_iterator it_end = winlist->rend(); 191 Focusables::reverse_iterator it_end = winlist.rend();
182 for (; it != it_end; ++it) { 192 for (; it != it_end; ++it) {
183 if (!doSkipWindow(**it, options) && (*it)->acceptsFocus()) { 193 if (!doSkipWindow(**it, pat) && (*it)->acceptsFocus()) {
184 ++num; 194 ++num;
185 if (!num) { 195 if (!num) {
186 if ((*it)->fbwindow() && (*it)->fbwindow()->isIconic()) 196 if ((*it)->fbwindow() && (*it)->fbwindow()->isIconic())