// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
+/* A few comments about stacked cycling:
+ * When stacked cycling is turned on, the focused window is always at the top
+ * (front) of the list (_clients), EXCEPT for when we are in cycling mode.
+ * (_cycling is true) If we were to add the focused window to the top of the
+ * stack while we were cycling, we would end in a deadlock between 2 windows.
+ * When the modifiers are released, the window that has focus (but it's not
+ * at the top of the stack, since we are cycling) is placed at the top of the
+ * stack and raised.
+ * Hooray and Bummy. - Marius
+ */
+
#ifdef HAVE_CONFIG_H
# include "../../config.h"
#endif // HAVE_CONFIG_H
DestroyNotify, &ev) ||
XCheckTypedWindowEvent(_epist->getXDisplay(), e.xany.window,
UnmapNotify, &ev)) {
- processEvent(ev);
+
+ XWindow *win = _epist->findWindow(e.xany.window);
+ if (win) win->processEvent(ev);
}
updateClientList();
// the only keyrelease event we care about (for now) is when we do stacked
// cycling and the modifier is released
if (_stacked_cycling && _cycling && nothingIsPressed()) {
- XWindow *w = *_active;
-
// all modifiers have been released. ungrab the keyboard, move the
// focused window to the top of the Z-order and raise it
ungrabModifiers();
- _clients.remove(w);
- _clients.push_front(w);
- w->raise();
+ if (_active != _clients.end()) {
+ XWindow *w = *_active;
+ bool e = _last_active == _active;
+ _clients.remove(w);
+ _clients.push_front(w);
+ _active = _clients.begin();
+ if (e) _last_active = _active;
+ w->raise();
+ }
_cycling = false;
}
const WindowList::iterator end = _clients.end();
unsigned long i;
- // insert new clients after the active window
for (i = 0; i < num; ++i) {
for (it = _clients.begin(); it != end; ++it)
if (**it == rootclients[i])
break;
if (it == end) { // didn't already exist
if (doAddWindow(rootclients[i])) {
- // cout << "Added window: 0x" << hex << rootclients[i] << dec << endl;
+// cout << "Added window: 0x" << hex << rootclients[i] << dec << endl;
+ // insert new clients after the active window
_clients.insert(insert_point, new XWindow(_epist, this,
rootclients[i]));
}
WindowList::const_iterator it, end = _clients.end();
for (it = _clients.begin(); it != end; ++it)
if ((*it)->getScreen() == this && ! (*it)->iconic() &&
- ((*it)->desktop() == 0xffffffff || (*it)->desktop() == _active_desktop))
+ (*it)->canFocus() &&
+ ((*it)->desktop() == 0xffffffff ||
+ (*it)->desktop() == _active_desktop))
return *it;
// no windows on this screen
break;
}
}
+
_active = it;
- if (it != end)
- _last_active = it;
+
+ if (_active != end) {
+ /* if we're not cycling and a window gets focus, add it to the top of the
+ * cycle stack.
+ */
+ if (_stacked_cycling && !_cycling) {
+ XWindow *win = *_active;
+ _clients.remove(win);
+ _clients.push_front(win);
+ _active = _clients.begin();
+
+ _last_active = _active;
+ }
+ }
/* cout << "Active window is now: ";
if (_active == _clients.end()) cout << "None\n";
}
// if the window is on another desktop, we can't use XSetInputFocus, since
- // it doesn't imply a woskpace change.
- if (t->desktop() == _active_desktop)
+ // it doesn't imply a workspace change.
+ if (t->desktop() == _active_desktop || t->desktop() == 0xffffffff)
t->focus(false); // focus, but don't raise
else
t->focus(); // change workspace and focus