summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2002-07-24 08:33:35 +0000
committerDana Jansens <danakj@orodu.net>2002-07-24 08:33:35 +0000
commit28594da6de001f1d8b6b975286032302db3a6491 (patch)
treedfbd92e585fbe52456061b79065814b9405b51b3
parent3792d283331087b1ae92419f847efaa7f879e440 (diff)
epist + multihead == <drool>
added next/prevWindowOnAllScreens added next/prevScreen
-rw-r--r--util/epist/actions.hh18
-rw-r--r--util/epist/epist.cc18
-rw-r--r--util/epist/epist.hh20
-rw-r--r--util/epist/screen.cc130
-rw-r--r--util/epist/screen.hh12
-rw-r--r--util/epist/window.hh1
6 files changed, 144 insertions, 55 deletions
diff --git a/util/epist/actions.hh b/util/epist/actions.hh
index 30ea0e68..25f1e968 100644
--- a/util/epist/actions.hh
+++ b/util/epist/actions.hh
@@ -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,
diff --git a/util/epist/epist.cc b/util/epist/epist.cc
index 30b2f47d..f3084e8c 100644
--- a/util/epist/epist.cc
+++ b/util/epist/epist.cc
@@ -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(),
diff --git a/util/epist/epist.hh b/util/epist/epist.hh
index 6da38181..1932902d 100644
--- a/util/epist/epist.hh
+++ b/util/epist/epist.hh
@@ -31,27 +31,30 @@ 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:
- std::string _rc_file;
- XAtom *_xatom;
- char **_argv;
+ std::string _rc_file;
+ XAtom *_xatom;
+ char **_argv;
typedef std::vector<screen *> ScreenList;
- ScreenList _screens;
+ ScreenList _screens;
typedef std::map<Window, XWindow*> WindowLookup;
typedef WindowLookup::value_type WindowLookupPair;
WindowLookup _windows;
+
+ WindowList _clients;
+ WindowList::iterator _active;
- ActionList _actions;
+ ActionList _actions;
virtual void process_event(XEvent *e);
virtual bool handleSignal(int sig);
@@ -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
diff --git a/util/epist/screen.cc b/util/epist/screen.cc
index d711fcb3..56f64f0c 100644
--- a/util/epist/screen.cc
+++ b/util/epist/screen.cc
@@ -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 {
+ ++target;
+ if (target == end)
+ target = begin;
+ }
} else {
- if (target == _clients.begin())
- target = _clients.end();
+ 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));
diff --git a/util/epist/screen.hh b/util/epist/screen.hh
index be30baa5..6d0c87ba 100644
--- a/util/epist/screen.hh
+++ b/util/epist/screen.hh
@@ -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;
@@ -68,12 +69,15 @@ public:
inline Window rootWindow() const { return _root; }
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;
diff --git a/util/epist/window.hh b/util/epist/window.hh
index 18742194..fdf2223e 100644
--- a/util/epist/window.hh
+++ b/util/epist/window.hh
@@ -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; }