we now know for every window its state and its desktop

This commit is contained in:
Dana Jansens 2002-07-12 01:50:56 +00:00
parent b10d59dabb
commit 5fed16de70
3 changed files with 89 additions and 19 deletions

View file

@ -32,12 +32,26 @@
using std::cout; using std::cout;
using std::endl; using std::endl;
using std::hex;
using std::dec;
#include "../../src/XAtom.hh" #include "../../src/XAtom.hh"
WindowList _clients; WindowList _clients;
WindowList::iterator _active = _clients.end(); WindowList::iterator _active = _clients.end();
XWindow &findWindow(const XEvent &e) {
WindowList::iterator it, end = _clients.end();
for (it = _clients.begin(); it != end; ++it)
if (**it == e.xany.window)
break;
assert(it != end); // this means a client somehow got removed from the
// list!
return **it;
}
void processEvent(const XEvent &e) { void processEvent(const XEvent &e) {
switch (e.type) { switch (e.type) {
case PropertyNotify: case PropertyNotify:
@ -45,23 +59,50 @@ void processEvent(const XEvent &e) {
// root window // root window
if (e.xproperty.atom == _xatom->getAtom(XAtom::net_active_window)) if (e.xproperty.atom == _xatom->getAtom(XAtom::net_active_window))
updateActiveWindow(); updateActiveWindow();
if (e.xproperty.atom == _xatom->getAtom(XAtom::net_client_list)) if (e.xproperty.atom == _xatom->getAtom(XAtom::net_client_list)) {
// catch any window unmaps first
XEvent ev;
if (XCheckTypedWindowEvent(_display, e.xany.window,
DestroyNotify, &ev) ||
XCheckTypedWindowEvent(_display, e.xany.window,
UnmapNotify, &ev)) {
processEvent(ev);
}
updateClientList(); updateClientList();
}
} else { } else {
// a client window // a client window
WindowList::iterator it, end = _clients.end(); if (e.xproperty.atom == _xatom->getAtom(XAtom::net_wm_state))
for (it = _clients.begin(); it != end; ++it) findWindow(e).updateState();
if (*it == e.xproperty.window) if (e.xproperty.atom == _xatom->getAtom(XAtom::net_wm_desktop))
break; findWindow(e).updateDesktop();
assert(it != end); // this means a client somehow got removed from the
// list!
it->updateState();
} }
break; break;
case DestroyNotify:
case UnmapNotify:
cout << "unmap notify\n";
findWindow(e).setUnmapped(true);
break;
} }
} }
// do we want to add this window to our list?
bool doAddWindow(Window window) {
Atom type;
if (! _xatom->getValue(window, XAtom::net_wm_window_type, XAtom::atom,
type))
return True;
if (type == _xatom->getAtom(XAtom::net_wm_window_type_dock) ||
type == _xatom->getAtom(XAtom::net_wm_window_type_menu))
return False;
return True;
}
void updateClientList() { void updateClientList() {
WindowList::iterator insert_point = _active; WindowList::iterator insert_point = _active;
if (insert_point != _clients.end()) if (insert_point != _clients.end())
@ -72,7 +113,10 @@ void updateClientList() {
unsigned long num = (unsigned) -1; unsigned long num = (unsigned) -1;
if (! _xatom->getValue(_root, XAtom::net_client_list, XAtom::window, num, if (! _xatom->getValue(_root, XAtom::net_client_list, XAtom::window, num,
&rootclients)) { &rootclients)) {
_clients.clear(); // no clients left while (! _clients.empty()) {
delete _clients.front();
_clients.erase(_clients.begin());
}
if (rootclients) delete [] rootclients; if (rootclients) delete [] rootclients;
return; return;
} }
@ -83,11 +127,13 @@ void updateClientList() {
// insert new clients after the active window // insert new clients after the active window
for (i = 0; i < num; ++i) { for (i = 0; i < num; ++i) {
for (it = _clients.begin(); it != end; ++it) for (it = _clients.begin(); it != end; ++it)
if (*it == rootclients[i]) if (**it == rootclients[i])
break; break;
if (it == end) { // didn't already exist if (it == end) { // didn't already exist
_clients.insert(insert_point, rootclients[i]); if (doAddWindow(rootclients[i])) {
cout << "Added window: " << rootclients[i] << endl; cout << "Added window: 0x" << hex << rootclients[i] << dec << endl;
_clients.insert(insert_point, new XWindow(rootclients[i]));
}
} }
} }
@ -95,11 +141,12 @@ void updateClientList() {
for (it = _clients.begin(); it != end;) { for (it = _clients.begin(); it != end;) {
WindowList::iterator it2 = it++; WindowList::iterator it2 = it++;
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;
delete *it2;
_clients.erase(it2); _clients.erase(it2);
cout << "Removed window: " << it2->window() << endl;
} }
} }
@ -113,12 +160,12 @@ void 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)
break; break;
} }
_active = it; _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 << _active->window() << endl; else cout << "0x" << hex << (*_active)->window() << dec << endl;
} }

View file

@ -28,15 +28,26 @@
#include "epist.hh" #include "epist.hh"
#include "../../src/XAtom.hh" #include "../../src/XAtom.hh"
#include <iostream>
using std::cout;
using std::endl;
using std::hex;
using std::dec;
XWindow::XWindow(Window window) : _window(window) { XWindow::XWindow(Window window) : _window(window) {
XSelectInput(_display, _window, PropertyChangeMask); _unmapped = false;
XSelectInput(_display, _window, PropertyChangeMask | StructureNotifyMask);
updateState(); updateState();
updateDesktop();
} }
XWindow::~XWindow() { XWindow::~XWindow() {
XSelectInput(_display, _window, None); if (! _unmapped)
XSelectInput(_display, _window, None);
} }
@ -62,3 +73,10 @@ void XWindow::updateState() {
delete [] state; delete [] state;
} }
void XWindow::updateDesktop() {
if (! _xatom->getValue(_window, XAtom::net_wm_desktop, XAtom::cardinal,
static_cast<unsigned long>(_desktop)))
_desktop = 0;
}

View file

@ -31,7 +31,7 @@ extern "C" {
class XWindow; class XWindow;
typedef std::list<XWindow> WindowList; typedef std::list<XWindow *> WindowList;
class XWindow { class XWindow {
private: private:
@ -42,6 +42,8 @@ private:
bool _max_vert; bool _max_vert;
bool _max_horz; bool _max_horz;
bool _unmapped;
public: public:
XWindow(Window window); XWindow(Window window);
virtual ~XWindow(); virtual ~XWindow();
@ -53,7 +55,10 @@ public:
inline bool maxVert() const { return _max_vert; } inline bool maxVert() const { return _max_vert; }
inline bool maxHorz() const { return _max_horz; } inline bool maxHorz() const { return _max_horz; }
inline void setUnmapped(bool u) { _unmapped = u; }
void updateState(); void updateState();
void updateDesktop();
bool operator == (const XWindow &w) const { return w._window == _window; } bool operator == (const XWindow &w) const { return w._window == _window; }
bool operator == (const Window &w) const { return w == _window; } bool operator == (const Window &w) const { return w == _window; }