diff options
Diffstat (limited to 'src/FocusControl.cc')
-rw-r--r-- | src/FocusControl.cc | 127 |
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 | ||
89 | void FocusControl::cycleFocus(const Focusables &window_list, | 91 | void 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 | ||
168 | void FocusControl::goToWindowNumber(const Focusables &winlist, int num, | 170 | void 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 | ||
184 | void FocusControl::addFocusBack(WinClient &client) { | 186 | void 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 | ||
189 | void FocusControl::addFocusFront(WinClient &client) { | 191 | void 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 | ||
194 | void FocusControl::addFocusWinBack(Focusable &win) { | 196 | void 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 | ||
199 | void FocusControl::addFocusWinFront(Focusable &win) { | 201 | void 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 |
205 | void FocusControl::setFocusBack(FluxboxWindow *fbwin) { | 207 | void 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 | ||
240 | void FocusControl::stopCyclingFocus() { | 224 | void 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() { | |||
262 | Focusable *FocusControl::lastFocusedWindow(int workspace) { | 246 | Focusable *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 | ||
465 | void FocusControl::shutdown() { | 431 | void 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 |