aboutsummaryrefslogtreecommitdiff
path: root/src/FocusControl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FocusControl.cc')
-rw-r--r--src/FocusControl.cc127
1 files changed, 48 insertions, 79 deletions
diff --git a/src/FocusControl.cc b/src/FocusControl.cc
index 7bc1db4..ae5b5e3 100644
--- a/src/FocusControl.cc
+++ b/src/FocusControl.cc
@@ -78,15 +78,17 @@ FocusControl::FocusControl(BScreen &screen):
78 m_focus_new(screen.resourceManager(), true, 78 m_focus_new(screen.resourceManager(), true,
79 screen.name()+".focusNewWindows", 79 screen.name()+".focusNewWindows",
80 screen.altName()+".FocusNewWindows"), 80 screen.altName()+".FocusNewWindows"),
81 m_focused_list(screen), m_creation_order_list(screen),
82 m_focused_win_list(screen), m_creation_order_win_list(screen),
81 m_cycling_list(0), 83 m_cycling_list(0),
82 m_was_iconic(false), 84 m_was_iconic(false),
83 m_cycling_last(0) { 85 m_cycling_last(0) {
84 86
85 m_cycling_window = m_focused_win_list.end(); 87 m_cycling_window = m_focused_list.clientList().end();
86 88
87} 89}
88 90
89void FocusControl::cycleFocus(const Focusables &window_list, 91void FocusControl::cycleFocus(const FocusableList &window_list,
90 const ClientPattern *pat, bool cycle_reverse) { 92 const ClientPattern *pat, bool cycle_reverse) {
91 93
92 if (!m_cycling_list) { 94 if (!m_cycling_list) {
@@ -98,8 +100,8 @@ void FocusControl::cycleFocus(const Focusables &window_list,
98 } else if (m_cycling_list != &window_list) 100 } else if (m_cycling_list != &window_list)
99 m_cycling_list = &window_list; 101 m_cycling_list = &window_list;
100 102
101 Focusables::const_iterator it_begin = window_list.begin(); 103 Focusables::const_iterator it_begin = window_list.clientList().begin();
102 Focusables::const_iterator it_end = window_list.end(); 104 Focusables::const_iterator it_end = window_list.clientList().end();
103 105
104 // too many things can go wrong with remembering this 106 // too many things can go wrong with remembering this
105 m_cycling_window = find(it_begin, it_end, s_focused_window); 107 m_cycling_window = find(it_begin, it_end, s_focused_window);
@@ -165,10 +167,10 @@ void FocusControl::cycleFocus(const Focusables &window_list,
165 167
166} 168}
167 169
168void FocusControl::goToWindowNumber(const Focusables &winlist, int num, 170void FocusControl::goToWindowNumber(const FocusableList &winlist, int num,
169 const ClientPattern *pat) { 171 const ClientPattern *pat) {
170 Focusables::const_iterator it = winlist.begin(); 172 Focusables::const_iterator it = winlist.clientList().begin();
171 Focusables::const_iterator it_end = winlist.end(); 173 Focusables::const_iterator it_end = winlist.clientList().end();
172 for (; it != it_end && num; ++it) { 174 for (; it != it_end && num; ++it) {
173 if (!doSkipWindow(**it, pat) && (*it)->acceptsFocus()) { 175 if (!doSkipWindow(**it, pat) && (*it)->acceptsFocus()) {
174 num > 0 ? --num : ++num; 176 num > 0 ? --num : ++num;
@@ -182,61 +184,43 @@ void FocusControl::goToWindowNumber(const Focusables &winlist, int num,
182} 184}
183 185
184void FocusControl::addFocusBack(WinClient &client) { 186void FocusControl::addFocusBack(WinClient &client) {
185 m_focused_list.push_back(&client); 187 m_focused_list.pushBack(client);
186 m_creation_order_list.push_back(&client); 188 m_creation_order_list.pushBack(client);
187} 189}
188 190
189void FocusControl::addFocusFront(WinClient &client) { 191void FocusControl::addFocusFront(WinClient &client) {
190 m_focused_list.push_front(&client); 192 m_focused_list.pushFront(client);
191 m_creation_order_list.push_back(&client); 193 m_creation_order_list.pushBack(client);
192} 194}
193 195
194void FocusControl::addFocusWinBack(Focusable &win) { 196void FocusControl::addFocusWinBack(Focusable &win) {
195 m_focused_win_list.push_back(&win); 197 m_focused_win_list.pushBack(win);
196 m_creation_order_win_list.push_back(&win); 198 m_creation_order_win_list.pushBack(win);
197} 199}
198 200
199void FocusControl::addFocusWinFront(Focusable &win) { 201void FocusControl::addFocusWinFront(Focusable &win) {
200 m_focused_win_list.push_front(&win); 202 m_focused_win_list.pushFront(win);
201 m_creation_order_win_list.push_back(&win); 203 m_creation_order_win_list.pushBack(win);
202} 204}
203 205
204// move all clients in given window to back of focused list 206// move all clients in given window to back of focused list
205void FocusControl::setFocusBack(FluxboxWindow *fbwin) { 207void FocusControl::setFocusBack(FluxboxWindow &fbwin) {
206 // do nothing if there are no windows open 208 // do nothing if there are no windows open
207 // don't change focus order while cycling 209 // don't change focus order while cycling
208 if (m_focused_list.empty() || s_reverting) 210 if (m_focused_list.empty() || s_reverting)
209 return; 211 return;
210 212
211 // if the window isn't already in this list, we could accidentally add it 213 m_focused_win_list.moveToBack(fbwin);
212 Focusables::iterator win_begin = m_focused_win_list.begin(),
213 win_end = m_focused_win_list.end();
214 Focusables::iterator win_it = find(win_begin, win_end, fbwin);
215 if (win_it == win_end)
216 return;
217
218 m_focused_win_list.erase(win_it);
219 m_focused_win_list.push_back(fbwin);
220 214
221 Focusables::iterator it = m_focused_list.begin(); 215 // we need to move its clients to the back while preserving their order
222 // use back to avoid an infinite loop 216 Focusables list = m_focused_list.clientList();
223 Focusables::iterator it_back = --m_focused_list.end(); 217 Focusables::iterator it = list.begin(), it_end = list.end();
224 218 for (; it != it_end; ++it) {
225 while (it != it_back) { 219 if ((*it)->fbwindow() == &fbwin)
226 if ((*it)->fbwindow() == fbwin) { 220 m_focused_list.moveToBack(**it);
227 m_focused_list.push_back(*it);
228 it = m_focused_list.erase(it);
229 } else
230 ++it;
231 }
232 // move the last one, if necessary, in order to preserve focus order
233 if ((*it)->fbwindow() == fbwin) {
234 m_focused_list.push_back(*it);
235 m_focused_list.erase(it);
236 } 221 }
237
238} 222}
239 223
240void FocusControl::stopCyclingFocus() { 224void FocusControl::stopCyclingFocus() {
241 // nothing to do 225 // nothing to do
242 if (m_cycling_list == 0) 226 if (m_cycling_list == 0)
@@ -262,10 +246,10 @@ void FocusControl::stopCyclingFocus() {
262Focusable *FocusControl::lastFocusedWindow(int workspace) { 246Focusable *FocusControl::lastFocusedWindow(int workspace) {
263 if (m_focused_list.empty() || m_screen.isShuttingdown()) return 0; 247 if (m_focused_list.empty() || m_screen.isShuttingdown()) return 0;
264 if (workspace < 0 || workspace >= (int) m_screen.numberOfWorkspaces()) 248 if (workspace < 0 || workspace >= (int) m_screen.numberOfWorkspaces())
265 return m_focused_list.front(); 249 return m_focused_list.clientList().front();
266 250
267 Focusables::iterator it = m_focused_list.begin(); 251 Focusables::iterator it = m_focused_list.clientList().begin();
268 Focusables::iterator it_end = m_focused_list.end(); 252 Focusables::iterator it_end = m_focused_list.clientList().end();
269 for (; it != it_end; ++it) { 253 for (; it != it_end; ++it) {
270 if ((*it)->fbwindow() && 254 if ((*it)->fbwindow() &&
271 ((((int)(*it)->fbwindow()->workspaceNumber()) == workspace || 255 ((((int)(*it)->fbwindow()->workspaceNumber()) == workspace ||
@@ -285,8 +269,8 @@ WinClient *FocusControl::lastFocusedWindow(FluxboxWindow &group, WinClient *igno
285 if (m_focused_list.empty() || m_screen.isShuttingdown()) 269 if (m_focused_list.empty() || m_screen.isShuttingdown())
286 return 0; 270 return 0;
287 271
288 Focusables::iterator it = m_focused_list.begin(); 272 Focusables::iterator it = m_focused_list.clientList().begin();
289 Focusables::iterator it_end = m_focused_list.end(); 273 Focusables::iterator it_end = m_focused_list.clientList().end();
290 for (; it != it_end; ++it) { 274 for (; it != it_end; ++it) {
291 if (((*it)->fbwindow() == &group) && 275 if (((*it)->fbwindow() == &group) &&
292 (*it) != ignore_client) 276 (*it) != ignore_client)
@@ -300,27 +284,9 @@ void FocusControl::setScreenFocusedWindow(WinClient &win_client) {
300 // raise newly focused window to the top of the focused list 284 // raise newly focused window to the top of the focused list
301 // don't change the order if we're cycling or shutting down 285 // don't change the order if we're cycling or shutting down
302 if (!isCycling() && !m_screen.isShuttingdown() && !s_reverting) { 286 if (!isCycling() && !m_screen.isShuttingdown() && !s_reverting) {
303 287 m_focused_list.moveToFront(win_client);
304 // make sure client is in our list, or else we could end up adding it 288 if (win_client.fbwindow())
305 Focusables::iterator it_begin = m_focused_list.begin(), 289 m_focused_win_list.moveToFront(*win_client.fbwindow());
306 it_end = m_focused_list.end();
307 Focusables::iterator it = find(it_begin, it_end, &win_client);
308 if (it == it_end)
309 return;
310
311 m_focused_list.erase(it);
312 m_focused_list.push_front(&win_client);
313
314 // also check the fbwindow
315 it_begin = m_focused_win_list.begin();
316 it_end = m_focused_win_list.end();
317 it = find(it_begin, it_end, win_client.fbwindow());
318
319 if (it != it_end) {
320 m_focused_win_list.erase(it);
321 m_focused_win_list.push_front(win_client.fbwindow());
322 }
323
324 } 290 }
325} 291}
326 292
@@ -435,15 +401,15 @@ void FocusControl::removeClient(WinClient &client) {
435 if (client.screen().isShuttingdown()) 401 if (client.screen().isShuttingdown())
436 return; 402 return;
437 403
438 if (m_cycling_list && m_cycling_window != m_cycling_list->end() && 404 if (isCycling() && m_cycling_window != m_cycling_list->clientList().end() &&
439 *m_cycling_window == &client) { 405 *m_cycling_window == &client) {
440 m_cycling_window = m_cycling_list->end(); 406 m_cycling_window = m_cycling_list->clientList().end();
441 stopCyclingFocus(); 407 stopCyclingFocus();
442 } else if (m_cycling_last == &client) 408 } else if (m_cycling_last == &client)
443 m_cycling_last = 0; 409 m_cycling_last = 0;
444 410
445 m_focused_list.remove(&client); 411 m_focused_list.remove(client);
446 m_creation_order_list.remove(&client); 412 m_creation_order_list.remove(client);
447 client.screen().clientListSig().notify(); 413 client.screen().clientListSig().notify();
448} 414}
449 415
@@ -451,21 +417,21 @@ void FocusControl::removeWindow(Focusable &win) {
451 if (win.screen().isShuttingdown()) 417 if (win.screen().isShuttingdown())
452 return; 418 return;
453 419
454 if (m_cycling_list && m_cycling_window != m_cycling_list->end() && 420 if (isCycling() && m_cycling_window != m_cycling_list->clientList().end() &&
455 *m_cycling_window == &win) { 421 *m_cycling_window == &win) {
456 m_cycling_window = m_cycling_list->end(); 422 m_cycling_window = m_cycling_list->clientList().end();
457 stopCyclingFocus(); 423 stopCyclingFocus();
458 } 424 }
459 425
460 m_focused_win_list.remove(&win); 426 m_focused_win_list.remove(win);
461 m_creation_order_win_list.remove(&win); 427 m_creation_order_win_list.remove(win);
462 win.screen().clientListSig().notify(); 428 win.screen().clientListSig().notify();
463} 429}
464 430
465void FocusControl::shutdown() { 431void FocusControl::shutdown() {
466 // restore windows backwards so they get put back correctly on restart 432 // restore windows backwards so they get put back correctly on restart
467 Focusables::reverse_iterator it = m_focused_list.rbegin(); 433 Focusables::reverse_iterator it = m_focused_list.clientList().rbegin();
468 for (; it != m_focused_list.rend(); ++it) { 434 for (; it != m_focused_list.clientList().rend(); ++it) {
469 WinClient *client = dynamic_cast<WinClient *>(*it); 435 WinClient *client = dynamic_cast<WinClient *>(*it);
470 if (client && client->fbwindow()) 436 if (client && client->fbwindow())
471 client->fbwindow()->restore(client, true); 437 client->fbwindow()->restore(client, true);
@@ -582,7 +548,10 @@ void FocusControl::setFocusedWindow(WinClient *client) {
582 } 548 }
583 549
584 // update AtomHandlers and/or other stuff... 550 // update AtomHandlers and/or other stuff...
585 Fluxbox::instance()->updateFocusedWindow(screen, old_screen); 551 if (screen)
552 screen->focusedWindowSig().notify();
553 if (old_screen && screen != old_screen)
554 old_screen->focusedWindowSig().notify();
586} 555}
587 556
588////////////////////// FocusControl RESOURCES 557////////////////////// FocusControl RESOURCES