epist + multihead == <drool>

added next/prevWindowOnAllScreens
added next/prevScreen
This commit is contained in:
Dana Jansens 2002-07-24 08:33:35 +00:00
parent 3792d28333
commit 28594da6de
6 changed files with 144 additions and 55 deletions

View file

@ -57,18 +57,24 @@ public:
nextWindow, //done for now nextWindow, //done for now
prevWindow, //done for now prevWindow, //done for now
nextWindowOnAllWorkspaces, //done nextWindowOnAllWorkspaces, //done for now
prevWindowOnAllWorkspaces, //done prevWindowOnAllWorkspaces, //done for now
nextWindowOfClass, //done nextWindowOnAllScreens, //done for now
prevWindowOfClass, //done prevWindowOnAllScreens, //done for now
nextWindowOfClassOnAllWorkspaces, //done
prevWindowOfClassOnAllWorkspaces, //done nextWindowOfClass, //done for now
prevWindowOfClass, //done for now
nextWindowOfClassOnAllWorkspaces, //done for now
prevWindowOfClassOnAllWorkspaces, //done for now
changeWorkspace, //done changeWorkspace, //done
nextWorkspace, //done nextWorkspace, //done
prevWorkspace, //done prevWorkspace, //done
nextScreen, //done for now
prevScreen, //done for now
// these are openbox extensions // these are openbox extensions
showRootMenu, showRootMenu,
showWorkspaceMenu, showWorkspaceMenu,

View file

@ -69,10 +69,14 @@ epist::epist(char **argv, char *dpy_name, char *rc_file)
_xatom = new XAtom(getXDisplay()); _xatom = new XAtom(getXDisplay());
_active = _clients.end();
for (unsigned int i = 0; i < getNumberOfScreens(); ++i) { for (unsigned int i = 0; i < getNumberOfScreens(); ++i) {
screen *s = new screen(this, i); screen *s = new screen(this, i);
if (s->managed()) if (s->managed()) {
_screens.push_back(s); _screens.push_back(s);
s->updateEverything();
}
} }
if (_screens.empty()) { if (_screens.empty()) {
cout << "No compatible window manager found on any screens. Aborting.\n"; cout << "No compatible window manager found on any screens. Aborting.\n";
@ -198,6 +202,18 @@ XWindow *epist::findWindow(Window window) const {
return 0; 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, void epist::addAction(Action::ActionType act, unsigned int modifiers,
string key, int number) { string key, int number) {
_actions.push_back(Action(act, XKeysymToKeycode(getXDisplay(), _actions.push_back(Action(act, XKeysymToKeycode(getXDisplay(),

View file

@ -31,27 +31,30 @@ extern "C" {
#include <map> #include <map>
#include "actions.hh" #include "actions.hh"
#include "window.hh"
#include "../../src/BaseDisplay.hh" #include "../../src/BaseDisplay.hh"
class XAtom; class XAtom;
class screen; class screen;
class XWindow;
class epist : public BaseDisplay { class epist : public BaseDisplay {
private: private:
std::string _rc_file; std::string _rc_file;
XAtom *_xatom; XAtom *_xatom;
char **_argv; char **_argv;
typedef std::vector<screen *> ScreenList; typedef std::vector<screen *> ScreenList;
ScreenList _screens; ScreenList _screens;
typedef std::map<Window, XWindow*> WindowLookup; typedef std::map<Window, XWindow*> WindowLookup;
typedef WindowLookup::value_type WindowLookupPair; typedef WindowLookup::value_type WindowLookupPair;
WindowLookup _windows; WindowLookup _windows;
WindowList _clients;
WindowList::iterator _active;
ActionList _actions; ActionList _actions;
virtual void process_event(XEvent *e); virtual void process_event(XEvent *e);
virtual bool handleSignal(int sig); virtual bool handleSignal(int sig);
@ -72,12 +75,17 @@ public:
void removeWindow(XWindow *window); void removeWindow(XWindow *window);
XWindow *findWindow(Window window) const; XWindow *findWindow(Window window) const;
void cycleScreen(int current, bool forward) const;
void getLockModifiers(int &numlockMask, int &scrolllockMask) const { void getLockModifiers(int &numlockMask, int &scrolllockMask) const {
numlockMask = NumLockMask; numlockMask = NumLockMask;
scrolllockMask = ScrollLockMask; scrolllockMask = ScrollLockMask;
} }
const ActionList &actions(void) { return _actions; } const ActionList &actions(void) { return _actions; }
WindowList& clientsList() { return _clients; }
WindowList::iterator& activeWindow() { return _active; }
}; };
#endif // __epist_hh #endif // __epist_hh

View file

@ -50,14 +50,19 @@ using std::string;
#include "epist.hh" #include "epist.hh"
screen::screen(epist *epist, int number) { screen::screen(epist *epist, int number)
: _clients(epist->clientsList()),
_active(epist->activeWindow()) {
_epist = epist; _epist = epist;
_xatom = _epist->xatom(); _xatom = _epist->xatom();
_last_active = _clients.end();
_number = number; _number = number;
_active = _clients.end();
_info = _epist->getScreenInfo(_number); _info = _epist->getScreenInfo(_number);
_root = _info->getRootWindow(); _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 // find a window manager supporting NETWM, waiting for it to load if we must
int count = 20; // try for 20 seconds int count = 20; // try for 20 seconds
_managed = false; _managed = false;
@ -76,14 +81,8 @@ screen::screen(epist *epist, int number) {
} }
XSelectInput(_epist->getXDisplay(), _root, PropertyChangeMask); XSelectInput(_epist->getXDisplay(), _root, PropertyChangeMask);
updateNumDesktops();
updateActiveDesktop();
updateClientList();
updateActiveWindow();
} }
screen::~screen() { screen::~screen() {
if (_managed) if (_managed)
XSelectInput(_epist->getXDisplay(), _root, None); XSelectInput(_epist->getXDisplay(), _root, None);
@ -162,6 +161,14 @@ void screen::handleKeypress(const XEvent &e) {
if (e.xkey.keycode == it->keycode() && if (e.xkey.keycode == it->keycode() &&
state == it->modifierMask()) { state == it->modifierMask()) {
switch (it->type()) { switch (it->type()) {
case Action::nextScreen:
_epist->cycleScreen(_number, true);
return;
case Action::prevScreen:
_epist->cycleScreen(_number, false);
return;
case Action::nextWorkspace: case Action::nextWorkspace:
cycleWorkspace(true); cycleWorkspace(true);
return; return;
@ -179,27 +186,35 @@ void screen::handleKeypress(const XEvent &e) {
return; return;
case Action::nextWindowOnAllWorkspaces: case Action::nextWindowOnAllWorkspaces:
cycleWindow(true, true); cycleWindow(true, false, true);
return; return;
case Action::prevWindowOnAllWorkspaces: case Action::prevWindowOnAllWorkspaces:
cycleWindow(false, false, true);
return;
case Action::nextWindowOnAllScreens:
cycleWindow(true, true);
return;
case Action::prevWindowOnAllScreens:
cycleWindow(false, true); cycleWindow(false, true);
return; return;
case Action::nextWindowOfClass: case Action::nextWindowOfClass:
cycleWindow(true, false, true, it->string()); cycleWindow(true, false, false, true, it->string());
return; return;
case Action::prevWindowOfClass: case Action::prevWindowOfClass:
cycleWindow(false, false, true, it->string()); cycleWindow(false, false, false, true, it->string());
return; return;
case Action::nextWindowOfClassOnAllWorkspaces: case Action::nextWindowOfClassOnAllWorkspaces:
cycleWindow(true, true, true, it->string()); cycleWindow(true, false, true, true, it->string());
return; return;
case Action::prevWindowOfClassOnAllWorkspaces: case Action::prevWindowOfClassOnAllWorkspaces:
cycleWindow(false, true, true, it->string()); cycleWindow(false, false, true, true, it->string());
return; return;
case Action::changeWorkspace: case Action::changeWorkspace:
@ -312,6 +327,14 @@ bool screen::doAddWindow(Window window) const {
} }
void screen::updateEverything() {
updateNumDesktops();
updateActiveDesktop();
updateClientList();
updateActiveWindow();
}
void screen::updateNumDesktops() { void screen::updateNumDesktops() {
assert(_managed); assert(_managed);
@ -356,26 +379,32 @@ void screen::updateClientList() {
break; break;
if (it == end) { // didn't already exist if (it == end) { // didn't already exist
if (doAddWindow(rootclients[i])) { 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, _clients.insert(insert_point, new XWindow(_epist, this,
rootclients[i])); 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;) { for (it = _clients.begin(); it != end;) {
WindowList::iterator it2 = it; WindowList::iterator it2 = it;
++it; ++it;
// is on another screen?
if ((*it2)->getScreen() != this)
continue;
for (i = 0; i < num; ++i) for (i = 0; i < num; ++i)
if (**it2 == rootclients[i]) if (**it2 == rootclients[i])
break; break;
if (i == num) { // no longer exists if (i == num) { // no longer exists
//cout << "Removed window: 0x" << hex << (*it2)->window() << dec << endl; // cout << "Removed window: 0x" << hex << (*it2)->window() << dec << endl;
// watch for the active window // watch for the active and last-active window
if (it2 == _active) if (it2 == _active)
_active = _clients.end(); _active = _clients.end();
if (it2 == _last_active)
_last_active = _clients.end();
delete *it2; delete *it2;
_clients.erase(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() { void screen::updateActiveWindow() {
assert(_managed); assert(_managed);
@ -393,14 +437,19 @@ void screen::updateActiveWindow() {
WindowList::iterator it, end = _clients.end(); WindowList::iterator it, end = _clients.end();
for (it = _clients.begin(); it != end; ++it) { for (it = _clients.begin(); it != end; ++it) {
if (**it == a) if (**it == a) {
if ((*it)->getScreen() != this)
return;
break; break;
}
} }
_active = it; _active = it;
_last_active = it;
//cout << "Active window is now: "; /* cout << "Active window is now: ";
//if (_active == _clients.end()) cout << "None\n"; if (_active == _clients.end()) cout << "None\n";
//else cout << "0x" << hex << (*_active)->window() << dec << endl; 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, void screen::cycleWindow(const bool forward, const bool allscreens,
const bool sameclass, const string &cn) const { const bool alldesktops, const bool sameclass,
const string &cn) const {
assert(_managed); assert(_managed);
if (_clients.empty()) return;
string classname(cn); string classname(cn);
if (sameclass && classname.empty() && _active != _clients.end()) if (sameclass && classname.empty() && _active != _clients.end())
classname = (*_active)->appClass(); classname = (*_active)->appClass();
WindowList::const_iterator target = _active; WindowList::const_iterator target = _active,
first = _active,
if (target == _clients.end()) begin = _clients.begin(),
target = _clients.begin(); end = _clients.end();
WindowList::const_iterator begin = target;
do { do {
if (forward) { if (forward) {
++target; if (target == end) {
if (target == _clients.end()) target = begin;
target = _clients.begin(); } else {
++target;
if (target == end)
target = begin;
}
} else { } else {
if (target == _clients.begin()) if (target == begin)
target = _clients.end(); target = end;
--target; --target;
} }
// no window to focus // must be no window to focus
if (target == begin) if (target == first)
return; return;
} while (target == _clients.end() || } while ((*target)->iconic() ||
(*target)->iconic() || (! allscreens && (*target)->getScreen() != this) ||
(! alldesktops && (*target)->desktop() != _active_desktop) || (! alldesktops && (*target)->desktop() != _active_desktop) ||
(sameclass && ! classname.empty() && (sameclass && ! classname.empty() &&
(*target)->appClass() != classname)); (*target)->appClass() != classname));

View file

@ -46,8 +46,9 @@ class screen {
std::string _wm_name; std::string _wm_name;
WindowList _clients; WindowList &_clients;
WindowList::iterator _active; WindowList::iterator &_active;
WindowList::iterator _last_active;
unsigned int _active_desktop; unsigned int _active_desktop;
unsigned int _num_desktops; unsigned int _num_desktops;
@ -68,12 +69,15 @@ public:
inline Window rootWindow() const { return _root; } inline Window rootWindow() const { return _root; }
inline bool managed() const { return _managed; } inline bool managed() const { return _managed; }
inline int number() const { return _number; } inline int number() const { return _number; }
const XWindow *lastActiveWindow() const;
void processEvent(const XEvent &e); void processEvent(const XEvent &e);
void handleKeypress(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 bool sameclass = false,
const std::string &classname = "") const; const std::string &classname = "") const;
void cycleWorkspace(const bool forward, const bool loop = true) const; void cycleWorkspace(const bool forward, const bool loop = true) const;

View file

@ -80,6 +80,7 @@ public:
XWindow(epist *epist, screen *screen, Window window); XWindow(epist *epist, screen *screen, Window window);
virtual ~XWindow(); virtual ~XWindow();
inline screen *getScreen() const { return _screen; }
inline Window window() const { return _window; } inline Window window() const { return _window; }
inline unsigned int desktop() const { return _desktop; } inline unsigned int desktop() const { return _desktop; }