}
XSelectInput(_epist->getXDisplay(), _root, PropertyChangeMask);
-
+
+ updateNumDesktops();
+ updateActiveDesktop();
updateClientList();
updateActiveWindow();
}
switch (e.type) {
case PropertyNotify:
// root window
+ if (e.xproperty.atom == _xatom->getAtom(XAtom::net_number_of_desktops))
+ updateNumDesktops();
+ if (e.xproperty.atom == _xatom->getAtom(XAtom::net_current_desktop))
+ updateActiveDesktop();
if (e.xproperty.atom == _xatom->getAtom(XAtom::net_active_window))
updateActiveWindow();
if (e.xproperty.atom == _xatom->getAtom(XAtom::net_client_list)) {
return;
case Action::nextWindow:
- cycleWindow(true);
+ cycleWindow(true, false);
return;
case Action::prevWindow:
- cycleWindow(false);
+ cycleWindow(false, false);
+ return;
+
+ case Action::nextWindowOnAllWorkspaces:
+ cycleWindow(true, true);
+ return;
+
+ case Action::prevWindowOnAllWorkspaces:
+ cycleWindow(false, true);
return;
case Action::changeWorkspace:
}
+void screen::updateNumDesktops() {
+ assert(_managed);
+
+ if (! _xatom->getValue(_root, XAtom::net_number_of_desktops, XAtom::cardinal,
+ (unsigned long)_num_desktops))
+ _num_desktops = 1; // assume that there is at least 1 desktop!
+}
+
+
+void screen::updateActiveDesktop() {
+ assert(_managed);
+
+ if (! _xatom->getValue(_root, XAtom::net_current_desktop, XAtom::cardinal,
+ (unsigned long)_active_desktop))
+ _active_desktop = 0; // there must be at least one desktop, and it must
+ // be the current one
+}
+
+
void screen::updateClientList() {
assert(_managed);
*/
-void screen::cycleWindow(const bool forward) const {
+void screen::cycleWindow(const bool forward, const bool alldesktops) const {
+ assert(_managed);
+
if (_clients.empty()) return;
WindowList::const_iterator target = _active;
target = _clients.end();
--target;
}
- } while (target == _clients.end() || (*target)->iconic());
+ } while (target == _clients.end() ||
+ (*target)->iconic() ||
+ (! alldesktops && (*target)->desktop() != _active_desktop));
if (target != _clients.end()) {
+ if ((*target)->desktop() != _active_desktop)
+ changeWorkspace((*target)->desktop());
+
// we dont send an ACTIVE_WINDOW client message because that would also
// unshade the window if it was shaded
XSetInputFocus(_epist->getXDisplay(), (*target)->window(), RevertToNone,
}
-void screen::cycleWorkspace(const bool forward) const {
- unsigned long currentDesktop = 0;
- unsigned long numDesktops = 0;
-
- if (_xatom->getValue(_root, XAtom::net_current_desktop, XAtom::cardinal,
- currentDesktop)) {
- if (forward)
- ++currentDesktop;
- else
- --currentDesktop;
-
- _xatom->getValue(_root, XAtom::net_number_of_desktops, XAtom::cardinal,
- numDesktops);
-
- if ( ( (signed)currentDesktop) == -1)
- currentDesktop = numDesktops - 1;
- else if (currentDesktop >= numDesktops)
- currentDesktop = 0;
+void screen::cycleWorkspace(const bool forward, const bool loop) const {
+ assert(_managed);
- changeWorkspace(currentDesktop);
+ unsigned int destination = _active_desktop;
+
+ if (forward) {
+ if (destination < _num_desktops - 1)
+ ++destination;
+ else if (loop)
+ destination = 0;
+ } else {
+ if (destination > 0)
+ --destination;
+ else if (loop)
+ destination = _num_desktops - 1;
}
+
+ if (destination != _active_desktop)
+ changeWorkspace(destination);
}
void screen::changeWorkspace(const int num) const {
+ assert(_managed);
+
_xatom->sendClientMessage(_root, XAtom::net_current_desktop, _root, num);
}
WindowList _clients;
WindowList::iterator _active;
+ unsigned int _active_desktop;
+ unsigned int _num_desktops;
bool _managed;
XWindow *findWindow(const XEvent &e) const;
+ void updateNumDesktops();
+ void updateActiveDesktop();
void updateClientList();
void updateActiveWindow();
bool doAddWindow(Window window) const;
void handleKeypress(const XEvent &e);
- void cycleWindow(const bool forward) const;
- void cycleWorkspace(const bool forward) const;
+ void cycleWindow(const bool forward, const bool alldesktops) const;
+ void cycleWorkspace(const bool forward, const bool loop = true) const;
void changeWorkspace(const int num) const;
void toggleShaded(const Window win) const;
};