epist + multihead == <drool>
added next/prevWindowOnAllScreens added next/prevScreen
This commit is contained in:
parent
3792d28333
commit
28594da6de
6 changed files with 144 additions and 55 deletions
|
@ -57,18 +57,24 @@ public:
|
|||
|
||||
nextWindow, //done for now
|
||||
prevWindow, //done for now
|
||||
nextWindowOnAllWorkspaces, //done
|
||||
prevWindowOnAllWorkspaces, //done
|
||||
nextWindowOnAllWorkspaces, //done for now
|
||||
prevWindowOnAllWorkspaces, //done for now
|
||||
|
||||
nextWindowOfClass, //done
|
||||
prevWindowOfClass, //done
|
||||
nextWindowOfClassOnAllWorkspaces, //done
|
||||
prevWindowOfClassOnAllWorkspaces, //done
|
||||
nextWindowOnAllScreens, //done for now
|
||||
prevWindowOnAllScreens, //done for now
|
||||
|
||||
nextWindowOfClass, //done for now
|
||||
prevWindowOfClass, //done for now
|
||||
nextWindowOfClassOnAllWorkspaces, //done for now
|
||||
prevWindowOfClassOnAllWorkspaces, //done for now
|
||||
|
||||
changeWorkspace, //done
|
||||
nextWorkspace, //done
|
||||
prevWorkspace, //done
|
||||
|
||||
nextScreen, //done for now
|
||||
prevScreen, //done for now
|
||||
|
||||
// these are openbox extensions
|
||||
showRootMenu,
|
||||
showWorkspaceMenu,
|
||||
|
|
|
@ -69,10 +69,14 @@ epist::epist(char **argv, char *dpy_name, char *rc_file)
|
|||
|
||||
_xatom = new XAtom(getXDisplay());
|
||||
|
||||
_active = _clients.end();
|
||||
|
||||
for (unsigned int i = 0; i < getNumberOfScreens(); ++i) {
|
||||
screen *s = new screen(this, i);
|
||||
if (s->managed())
|
||||
if (s->managed()) {
|
||||
_screens.push_back(s);
|
||||
s->updateEverything();
|
||||
}
|
||||
}
|
||||
if (_screens.empty()) {
|
||||
cout << "No compatible window manager found on any screens. Aborting.\n";
|
||||
|
@ -198,6 +202,18 @@ XWindow *epist::findWindow(Window window) const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void epist::cycleScreen(int current, bool forward) const {
|
||||
int dest = current + (forward ? 1 : -1);
|
||||
|
||||
if (dest < 0) dest = (signed)_screens.size() - 1;
|
||||
else if (dest >= (signed)_screens.size()) dest = 0;
|
||||
|
||||
const XWindow *target = _screens[dest]->lastActiveWindow();
|
||||
if (target) target->focus();
|
||||
}
|
||||
|
||||
|
||||
void epist::addAction(Action::ActionType act, unsigned int modifiers,
|
||||
string key, int number) {
|
||||
_actions.push_back(Action(act, XKeysymToKeycode(getXDisplay(),
|
||||
|
|
|
@ -31,12 +31,12 @@ extern "C" {
|
|||
#include <map>
|
||||
|
||||
#include "actions.hh"
|
||||
#include "window.hh"
|
||||
|
||||
#include "../../src/BaseDisplay.hh"
|
||||
|
||||
class XAtom;
|
||||
class screen;
|
||||
class XWindow;
|
||||
|
||||
class epist : public BaseDisplay {
|
||||
private:
|
||||
|
@ -51,6 +51,9 @@ private:
|
|||
typedef WindowLookup::value_type WindowLookupPair;
|
||||
WindowLookup _windows;
|
||||
|
||||
WindowList _clients;
|
||||
WindowList::iterator _active;
|
||||
|
||||
ActionList _actions;
|
||||
|
||||
virtual void process_event(XEvent *e);
|
||||
|
@ -72,12 +75,17 @@ public:
|
|||
void removeWindow(XWindow *window);
|
||||
XWindow *findWindow(Window window) const;
|
||||
|
||||
void cycleScreen(int current, bool forward) const;
|
||||
|
||||
void getLockModifiers(int &numlockMask, int &scrolllockMask) const {
|
||||
numlockMask = NumLockMask;
|
||||
scrolllockMask = ScrollLockMask;
|
||||
}
|
||||
|
||||
const ActionList &actions(void) { return _actions; }
|
||||
|
||||
WindowList& clientsList() { return _clients; }
|
||||
WindowList::iterator& activeWindow() { return _active; }
|
||||
};
|
||||
|
||||
#endif // __epist_hh
|
||||
|
|
|
@ -50,14 +50,19 @@ using std::string;
|
|||
#include "epist.hh"
|
||||
|
||||
|
||||
screen::screen(epist *epist, int number) {
|
||||
screen::screen(epist *epist, int number)
|
||||
: _clients(epist->clientsList()),
|
||||
_active(epist->activeWindow()) {
|
||||
_epist = epist;
|
||||
_xatom = _epist->xatom();
|
||||
_last_active = _clients.end();
|
||||
_number = number;
|
||||
_active = _clients.end();
|
||||
_info = _epist->getScreenInfo(_number);
|
||||
_root = _info->getRootWindow();
|
||||
|
||||
cout << "root window on screen " << _number << ": 0x" << hex << _root <<
|
||||
dec << endl;
|
||||
|
||||
// find a window manager supporting NETWM, waiting for it to load if we must
|
||||
int count = 20; // try for 20 seconds
|
||||
_managed = false;
|
||||
|
@ -76,14 +81,8 @@ screen::screen(epist *epist, int number) {
|
|||
}
|
||||
|
||||
XSelectInput(_epist->getXDisplay(), _root, PropertyChangeMask);
|
||||
|
||||
updateNumDesktops();
|
||||
updateActiveDesktop();
|
||||
updateClientList();
|
||||
updateActiveWindow();
|
||||
}
|
||||
|
||||
|
||||
screen::~screen() {
|
||||
if (_managed)
|
||||
XSelectInput(_epist->getXDisplay(), _root, None);
|
||||
|
@ -162,6 +161,14 @@ void screen::handleKeypress(const XEvent &e) {
|
|||
if (e.xkey.keycode == it->keycode() &&
|
||||
state == it->modifierMask()) {
|
||||
switch (it->type()) {
|
||||
case Action::nextScreen:
|
||||
_epist->cycleScreen(_number, true);
|
||||
return;
|
||||
|
||||
case Action::prevScreen:
|
||||
_epist->cycleScreen(_number, false);
|
||||
return;
|
||||
|
||||
case Action::nextWorkspace:
|
||||
cycleWorkspace(true);
|
||||
return;
|
||||
|
@ -179,27 +186,35 @@ void screen::handleKeypress(const XEvent &e) {
|
|||
return;
|
||||
|
||||
case Action::nextWindowOnAllWorkspaces:
|
||||
cycleWindow(true, true);
|
||||
cycleWindow(true, false, true);
|
||||
return;
|
||||
|
||||
case Action::prevWindowOnAllWorkspaces:
|
||||
cycleWindow(false, false, true);
|
||||
return;
|
||||
|
||||
case Action::nextWindowOnAllScreens:
|
||||
cycleWindow(true, true);
|
||||
return;
|
||||
|
||||
case Action::prevWindowOnAllScreens:
|
||||
cycleWindow(false, true);
|
||||
return;
|
||||
|
||||
case Action::nextWindowOfClass:
|
||||
cycleWindow(true, false, true, it->string());
|
||||
cycleWindow(true, false, false, true, it->string());
|
||||
return;
|
||||
|
||||
case Action::prevWindowOfClass:
|
||||
cycleWindow(false, false, true, it->string());
|
||||
cycleWindow(false, false, false, true, it->string());
|
||||
return;
|
||||
|
||||
case Action::nextWindowOfClassOnAllWorkspaces:
|
||||
cycleWindow(true, true, true, it->string());
|
||||
cycleWindow(true, false, true, true, it->string());
|
||||
return;
|
||||
|
||||
case Action::prevWindowOfClassOnAllWorkspaces:
|
||||
cycleWindow(false, true, true, it->string());
|
||||
cycleWindow(false, false, true, true, it->string());
|
||||
return;
|
||||
|
||||
case Action::changeWorkspace:
|
||||
|
@ -312,6 +327,14 @@ bool screen::doAddWindow(Window window) const {
|
|||
}
|
||||
|
||||
|
||||
void screen::updateEverything() {
|
||||
updateNumDesktops();
|
||||
updateActiveDesktop();
|
||||
updateClientList();
|
||||
updateActiveWindow();
|
||||
}
|
||||
|
||||
|
||||
void screen::updateNumDesktops() {
|
||||
assert(_managed);
|
||||
|
||||
|
@ -356,26 +379,32 @@ void screen::updateClientList() {
|
|||
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;
|
||||
_clients.insert(insert_point, new XWindow(_epist, this,
|
||||
rootclients[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove clients that no longer exist
|
||||
// remove clients that no longer exist (that belong to this screen)
|
||||
for (it = _clients.begin(); it != end;) {
|
||||
WindowList::iterator it2 = it;
|
||||
++it;
|
||||
|
||||
// is on another screen?
|
||||
if ((*it2)->getScreen() != this)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < num; ++i)
|
||||
if (**it2 == rootclients[i])
|
||||
break;
|
||||
if (i == num) { // no longer exists
|
||||
//cout << "Removed window: 0x" << hex << (*it2)->window() << dec << endl;
|
||||
// watch for the active window
|
||||
// cout << "Removed window: 0x" << hex << (*it2)->window() << dec << endl;
|
||||
// watch for the active and last-active window
|
||||
if (it2 == _active)
|
||||
_active = _clients.end();
|
||||
if (it2 == _last_active)
|
||||
_last_active = _clients.end();
|
||||
delete *it2;
|
||||
_clients.erase(it2);
|
||||
}
|
||||
|
@ -385,6 +414,21 @@ void screen::updateClientList() {
|
|||
}
|
||||
|
||||
|
||||
const XWindow *screen::lastActiveWindow() const {
|
||||
if (_last_active != _clients.end())
|
||||
return *_last_active;
|
||||
|
||||
// find a window if one exists
|
||||
WindowList::const_iterator it, end = _clients.end();
|
||||
for (it = _clients.begin(); it != end; ++it)
|
||||
if ((*it)->getScreen() == this)
|
||||
return *it;
|
||||
|
||||
// no windows on this screen
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void screen::updateActiveWindow() {
|
||||
assert(_managed);
|
||||
|
||||
|
@ -393,14 +437,19 @@ void screen::updateActiveWindow() {
|
|||
|
||||
WindowList::iterator it, end = _clients.end();
|
||||
for (it = _clients.begin(); it != end; ++it) {
|
||||
if (**it == a)
|
||||
if (**it == a) {
|
||||
if ((*it)->getScreen() != this)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_active = it;
|
||||
_last_active = it;
|
||||
|
||||
//cout << "Active window is now: ";
|
||||
//if (_active == _clients.end()) cout << "None\n";
|
||||
//else cout << "0x" << hex << (*_active)->window() << dec << endl;
|
||||
/* cout << "Active window is now: ";
|
||||
if (_active == _clients.end()) cout << "None\n";
|
||||
else cout << "0x" << hex << (*_active)->window() << dec << endl;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -429,37 +478,42 @@ void screen::execCommand(const std::string &cmd) const {
|
|||
}
|
||||
|
||||
|
||||
void screen::cycleWindow(const bool forward, const bool alldesktops,
|
||||
const bool sameclass, const string &cn) const {
|
||||
void screen::cycleWindow(const bool forward, const bool allscreens,
|
||||
const bool alldesktops, const bool sameclass,
|
||||
const string &cn) const {
|
||||
assert(_managed);
|
||||
|
||||
if (_clients.empty()) return;
|
||||
|
||||
string classname(cn);
|
||||
if (sameclass && classname.empty() && _active != _clients.end())
|
||||
classname = (*_active)->appClass();
|
||||
|
||||
WindowList::const_iterator target = _active;
|
||||
|
||||
if (target == _clients.end())
|
||||
target = _clients.begin();
|
||||
|
||||
WindowList::const_iterator begin = target;
|
||||
WindowList::const_iterator target = _active,
|
||||
first = _active,
|
||||
begin = _clients.begin(),
|
||||
end = _clients.end();
|
||||
|
||||
do {
|
||||
if (forward) {
|
||||
++target;
|
||||
if (target == _clients.end())
|
||||
target = _clients.begin();
|
||||
if (target == end) {
|
||||
target = begin;
|
||||
} else {
|
||||
if (target == _clients.begin())
|
||||
target = _clients.end();
|
||||
++target;
|
||||
if (target == end)
|
||||
target = begin;
|
||||
}
|
||||
} else {
|
||||
if (target == begin)
|
||||
target = end;
|
||||
--target;
|
||||
}
|
||||
|
||||
// no window to focus
|
||||
if (target == begin)
|
||||
// must be no window to focus
|
||||
if (target == first)
|
||||
return;
|
||||
} while (target == _clients.end() ||
|
||||
(*target)->iconic() ||
|
||||
} while ((*target)->iconic() ||
|
||||
(! allscreens && (*target)->getScreen() != this) ||
|
||||
(! alldesktops && (*target)->desktop() != _active_desktop) ||
|
||||
(sameclass && ! classname.empty() &&
|
||||
(*target)->appClass() != classname));
|
||||
|
|
|
@ -46,8 +46,9 @@ class screen {
|
|||
|
||||
std::string _wm_name;
|
||||
|
||||
WindowList _clients;
|
||||
WindowList::iterator _active;
|
||||
WindowList &_clients;
|
||||
WindowList::iterator &_active;
|
||||
WindowList::iterator _last_active;
|
||||
unsigned int _active_desktop;
|
||||
unsigned int _num_desktops;
|
||||
|
||||
|
@ -69,11 +70,14 @@ public:
|
|||
inline bool managed() const { return _managed; }
|
||||
inline int number() const { return _number; }
|
||||
|
||||
const XWindow *lastActiveWindow() const;
|
||||
|
||||
void processEvent(const XEvent &e);
|
||||
|
||||
void handleKeypress(const XEvent &e);
|
||||
void updateEverything();
|
||||
|
||||
void cycleWindow(const bool forward, const bool alldesktops = false,
|
||||
void cycleWindow(const bool forward, const bool allscreens = false,
|
||||
const bool alldesktops = false,
|
||||
const bool sameclass = false,
|
||||
const std::string &classname = "") const;
|
||||
void cycleWorkspace(const bool forward, const bool loop = true) const;
|
||||
|
|
|
@ -80,6 +80,7 @@ public:
|
|||
XWindow(epist *epist, screen *screen, Window window);
|
||||
virtual ~XWindow();
|
||||
|
||||
inline screen *getScreen() const { return _screen; }
|
||||
inline Window window() const { return _window; }
|
||||
|
||||
inline unsigned int desktop() const { return _desktop; }
|
||||
|
|
Loading…
Reference in a new issue