diff options
Diffstat (limited to 'src/FocusControl.cc')
-rw-r--r-- | src/FocusControl.cc | 69 |
1 files changed, 34 insertions, 35 deletions
diff --git a/src/FocusControl.cc b/src/FocusControl.cc index 5cbf645..f4c8cdf 100644 --- a/src/FocusControl.cc +++ b/src/FocusControl.cc | |||
@@ -54,7 +54,7 @@ FocusControl::FocusControl(BScreen &screen): | |||
54 | m_focus_new(screen.resourceManager(), true, | 54 | m_focus_new(screen.resourceManager(), true, |
55 | screen.name()+".focusNewWindows", | 55 | screen.name()+".focusNewWindows", |
56 | screen.altName()+".FocusNewWindows"), | 56 | screen.altName()+".FocusNewWindows"), |
57 | m_cycling_focus(false), | 57 | m_cycling_list(0), |
58 | m_was_iconic(false), | 58 | m_was_iconic(false), |
59 | m_cycling_last(0) { | 59 | m_cycling_last(0) { |
60 | 60 | ||
@@ -79,26 +79,25 @@ bool doSkipWindow(const WinClient &winclient, int opts) { | |||
79 | ); | 79 | ); |
80 | } | 80 | } |
81 | 81 | ||
82 | void FocusControl::cycleFocus(int opts, bool cycle_reverse) { | 82 | void FocusControl::cycleFocus(FocusedWindows *window_list, int opts, bool cycle_reverse) { |
83 | 83 | ||
84 | FocusedWindows *window_list = (opts & CYCLELINEAR) ? &m_creation_order_list : &m_focused_list; | 84 | if (!m_cycling_list) { |
85 | if (!m_cycling_focus) { | ||
86 | if (&m_screen == Fluxbox::instance()->watchingScreen()) | 85 | if (&m_screen == Fluxbox::instance()->watchingScreen()) |
87 | m_cycling_focus = true; | 86 | // only set this when we're waiting for modifiers |
88 | m_cycling_window = find(window_list->begin(),window_list->end(),s_focused_window); | 87 | m_cycling_list = window_list; |
89 | m_cycling_creation_order = (opts & CYCLELINEAR); | 88 | m_was_iconic = 0; |
90 | m_was_iconic = false; | ||
91 | m_cycling_last = 0; | 89 | m_cycling_last = 0; |
92 | } else if (m_cycling_creation_order ^ (bool)(opts & CYCLELINEAR)) { | 90 | } else if (m_cycling_list != window_list) |
93 | m_cycling_creation_order ^= true; | 91 | m_cycling_list = window_list; |
94 | m_cycling_window = find(window_list->begin(),window_list->end(),*m_cycling_window); | 92 | |
95 | } | 93 | // too many things can go wrong with remembering this |
96 | // if it is stacked, we want the highest window in the focused list | 94 | m_cycling_window = find(window_list->begin(),window_list->end(),s_focused_window); |
97 | // that is on the same workspace | 95 | |
98 | FocusedWindows::iterator it = m_cycling_window; | 96 | FocusedWindows::iterator it = m_cycling_window; |
99 | FocusedWindows::iterator it_begin = window_list->begin(); | 97 | FocusedWindows::iterator it_begin = window_list->begin(); |
100 | FocusedWindows::iterator it_end = window_list->end(); | 98 | FocusedWindows::iterator it_end = window_list->end(); |
101 | 99 | ||
100 | // find the next window in the list that works | ||
102 | while (true) { | 101 | while (true) { |
103 | if (cycle_reverse && it == it_begin) | 102 | if (cycle_reverse && it == it_begin) |
104 | it = it_end; | 103 | it = it_end; |
@@ -130,12 +129,18 @@ void FocusControl::cycleFocus(int opts, bool cycle_reverse) { | |||
130 | 129 | ||
131 | // set back to orig current Client in that fbwin | 130 | // set back to orig current Client in that fbwin |
132 | m_cycling_last->fbwindow()->setCurrentClient(*m_cycling_last, false); | 131 | m_cycling_last->fbwindow()->setCurrentClient(*m_cycling_last, false); |
132 | if (m_was_iconic == m_cycling_last) { | ||
133 | s_reverting = true; // little hack | ||
134 | m_cycling_last->fbwindow()->iconify(); | ||
135 | s_reverting = false; | ||
136 | } | ||
133 | } | 137 | } |
134 | m_cycling_last = &last_client; | 138 | m_cycling_last = &last_client; |
135 | if (m_was_iconic) | 139 | if (fbwin->isIconic()) |
136 | (*m_cycling_window)->fbwindow()->iconify(); | 140 | m_was_iconic = m_cycling_last; |
137 | m_was_iconic = fbwin->isIconic(); | 141 | if (m_cycling_list) |
138 | fbwin->tempRaise(); | 142 | // else window will raise itself (if desired) on FocusIn |
143 | fbwin->tempRaise(); | ||
139 | } | 144 | } |
140 | break; | 145 | break; |
141 | } | 146 | } |
@@ -158,7 +163,7 @@ void FocusControl::addFocusFront(WinClient &client) { | |||
158 | void FocusControl::setFocusBack(FluxboxWindow *fbwin) { | 163 | void FocusControl::setFocusBack(FluxboxWindow *fbwin) { |
159 | // do nothing if there are no windows open | 164 | // do nothing if there are no windows open |
160 | // don't change focus order while cycling | 165 | // don't change focus order while cycling |
161 | if (m_focused_list.empty() || isCycling()) | 166 | if (m_focused_list.empty() || s_reverting) |
162 | return; | 167 | return; |
163 | 168 | ||
164 | FocusedWindows::iterator it = m_focused_list.begin(); | 169 | FocusedWindows::iterator it = m_focused_list.begin(); |
@@ -181,28 +186,24 @@ void FocusControl::setFocusBack(FluxboxWindow *fbwin) { | |||
181 | 186 | ||
182 | void FocusControl::stopCyclingFocus() { | 187 | void FocusControl::stopCyclingFocus() { |
183 | // nothing to do | 188 | // nothing to do |
184 | if (!m_cycling_focus) | 189 | if (m_cycling_list == 0) |
185 | return; | 190 | return; |
186 | 191 | ||
187 | m_cycling_focus = false; | 192 | FocusedWindows::iterator it_end = m_cycling_list->end(); |
188 | m_cycling_last = 0; | 193 | m_cycling_last = 0; |
194 | m_cycling_list = 0; | ||
195 | |||
189 | // put currently focused window to top | 196 | // put currently focused window to top |
190 | // the iterator may be invalid if the window died | 197 | // the iterator may be invalid if the window died |
191 | // in which case we'll do a proper revert focus | 198 | // in which case we'll do a proper revert focus |
192 | if (m_cycling_creation_order && m_cycling_window != m_creation_order_list.end()) | 199 | if (m_cycling_window != it_end && (*m_cycling_window)->fbwindow() && |
193 | m_cycling_window = find(m_focused_list.begin(),m_focused_list.end(),*m_cycling_window); | ||
194 | if (m_cycling_window != m_focused_list.end() && | ||
195 | m_cycling_window != m_creation_order_list.end() && | ||
196 | (*m_cycling_window)->fbwindow() && | ||
197 | (*m_cycling_window)->fbwindow()->isVisible()) { | 200 | (*m_cycling_window)->fbwindow()->isVisible()) { |
198 | WinClient *client = *m_cycling_window; | 201 | WinClient *client = *m_cycling_window; |
199 | m_focused_list.erase(m_cycling_window); | 202 | m_focused_list.remove(client); |
200 | m_focused_list.push_front(client); | 203 | m_focused_list.push_front(client); |
201 | client->fbwindow()->raise(); | 204 | client->fbwindow()->raise(); |
202 | } else { | 205 | } else |
203 | revertFocus(m_screen); | 206 | revertFocus(m_screen); |
204 | } | ||
205 | |||
206 | } | 207 | } |
207 | 208 | ||
208 | /** | 209 | /** |
@@ -254,7 +255,6 @@ void FocusControl::setScreenFocusedWindow(WinClient &win_client) { | |||
254 | !Fluxbox::instance()->isStartup()) { | 255 | !Fluxbox::instance()->isStartup()) { |
255 | m_focused_list.remove(&win_client); | 256 | m_focused_list.remove(&win_client); |
256 | m_focused_list.push_front(&win_client); | 257 | m_focused_list.push_front(&win_client); |
257 | m_cycling_window = m_focused_list.begin(); | ||
258 | } | 258 | } |
259 | } | 259 | } |
260 | 260 | ||
@@ -370,14 +370,14 @@ void FocusControl::removeClient(WinClient &client) { | |||
370 | return; | 370 | return; |
371 | 371 | ||
372 | WinClient *cyc = 0; | 372 | WinClient *cyc = 0; |
373 | if (m_cycling_window != m_focused_list.end() && m_cycling_window != m_creation_order_list.end()) | 373 | if (m_cycling_list && m_cycling_window != m_cycling_list->end()) |
374 | cyc = *m_cycling_window; | 374 | cyc = *m_cycling_window; |
375 | 375 | ||
376 | m_focused_list.remove(&client); | 376 | m_focused_list.remove(&client); |
377 | m_creation_order_list.remove(&client); | 377 | m_creation_order_list.remove(&client); |
378 | 378 | ||
379 | if (cyc == &client) { | 379 | if (cyc == &client) { |
380 | m_cycling_window = m_creation_order_list.end(); | 380 | m_cycling_window = m_cycling_list->end(); |
381 | stopCyclingFocus(); | 381 | stopCyclingFocus(); |
382 | } | 382 | } |
383 | } | 383 | } |
@@ -402,8 +402,7 @@ void FocusControl::shutdown() { | |||
402 | * it gets a focusIn | 402 | * it gets a focusIn |
403 | */ | 403 | */ |
404 | void FocusControl::revertFocus(BScreen &screen) { | 404 | void FocusControl::revertFocus(BScreen &screen) { |
405 | 405 | if (s_reverting) | |
406 | if (screen.focusControl().isCycling()) | ||
407 | return; | 406 | return; |
408 | 407 | ||
409 | FocusControl::s_reverting = true; | 408 | FocusControl::s_reverting = true; |