summaryrefslogtreecommitdiff
path: root/src/FocusControl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FocusControl.cc')
-rw-r--r--src/FocusControl.cc69
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
82void FocusControl::cycleFocus(int opts, bool cycle_reverse) { 82void 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) {
158void FocusControl::setFocusBack(FluxboxWindow *fbwin) { 163void 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
182void FocusControl::stopCyclingFocus() { 187void 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 */
404void FocusControl::revertFocus(BScreen &screen) { 404void 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;