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
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,

View file

@ -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(),

View file

@ -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;
ActionList _actions;
WindowList _clients;
WindowList::iterator _active;
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

View file

@ -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));

View file

@ -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;

View file

@ -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; }