From 5fed16de70c0fbe40c9e62667f80f612d027c717 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 12 Jul 2002 01:50:56 +0000 Subject: [PATCH] we now know for every window its state and its desktop --- util/epist/process.cc | 79 ++++++++++++++++++++++++++++++++++--------- util/epist/window.cc | 22 ++++++++++-- util/epist/window.hh | 7 +++- 3 files changed, 89 insertions(+), 19 deletions(-) diff --git a/util/epist/process.cc b/util/epist/process.cc index 95588963..893670c4 100644 --- a/util/epist/process.cc +++ b/util/epist/process.cc @@ -32,12 +32,26 @@ using std::cout; using std::endl; +using std::hex; +using std::dec; #include "../../src/XAtom.hh" WindowList _clients; 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) { switch (e.type) { case PropertyNotify: @@ -45,23 +59,50 @@ void processEvent(const XEvent &e) { // root window if (e.xproperty.atom == _xatom->getAtom(XAtom::net_active_window)) 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(); + } } else { // a client window - WindowList::iterator it, end = _clients.end(); - for (it = _clients.begin(); it != end; ++it) - if (*it == e.xproperty.window) - break; - assert(it != end); // this means a client somehow got removed from the - // list! - it->updateState(); + if (e.xproperty.atom == _xatom->getAtom(XAtom::net_wm_state)) + findWindow(e).updateState(); + if (e.xproperty.atom == _xatom->getAtom(XAtom::net_wm_desktop)) + findWindow(e).updateDesktop(); } 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() { WindowList::iterator insert_point = _active; if (insert_point != _clients.end()) @@ -72,7 +113,10 @@ void updateClientList() { unsigned long num = (unsigned) -1; if (! _xatom->getValue(_root, XAtom::net_client_list, XAtom::window, num, &rootclients)) { - _clients.clear(); // no clients left + while (! _clients.empty()) { + delete _clients.front(); + _clients.erase(_clients.begin()); + } if (rootclients) delete [] rootclients; return; } @@ -83,11 +127,13 @@ void updateClientList() { // insert new clients after the active window for (i = 0; i < num; ++i) { for (it = _clients.begin(); it != end; ++it) - if (*it == rootclients[i]) + if (**it == rootclients[i]) break; if (it == end) { // didn't already exist - _clients.insert(insert_point, rootclients[i]); - cout << "Added window: " << rootclients[i] << endl; + if (doAddWindow(rootclients[i])) { + 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;) { WindowList::iterator it2 = it++; for (i = 0; i < num; ++i) - if (*it2 == rootclients[i]) + if (**it2 == rootclients[i]) break; if (i == num) { // no longer exists + cout << "Removed window: 0x" << hex << (*it2)->window() << dec << endl; + delete *it2; _clients.erase(it2); - cout << "Removed window: " << it2->window() << endl; } } @@ -113,12 +160,12 @@ void updateActiveWindow() { WindowList::iterator it, end = _clients.end(); for (it = _clients.begin(); it != end; ++it) { - if (*it == a) + if (**it == a) break; } _active = it; cout << "Active window is now: "; if (_active == _clients.end()) cout << "None\n"; - else cout << _active->window() << endl; + else cout << "0x" << hex << (*_active)->window() << dec << endl; } diff --git a/util/epist/window.cc b/util/epist/window.cc index a366fc49..15f8b11c 100644 --- a/util/epist/window.cc +++ b/util/epist/window.cc @@ -28,15 +28,26 @@ #include "epist.hh" #include "../../src/XAtom.hh" +#include + +using std::cout; +using std::endl; +using std::hex; +using std::dec; + XWindow::XWindow(Window window) : _window(window) { - XSelectInput(_display, _window, PropertyChangeMask); + _unmapped = false; + + XSelectInput(_display, _window, PropertyChangeMask | StructureNotifyMask); updateState(); + updateDesktop(); } XWindow::~XWindow() { - XSelectInput(_display, _window, None); + if (! _unmapped) + XSelectInput(_display, _window, None); } @@ -62,3 +73,10 @@ void XWindow::updateState() { delete [] state; } + + +void XWindow::updateDesktop() { + if (! _xatom->getValue(_window, XAtom::net_wm_desktop, XAtom::cardinal, + static_cast(_desktop))) + _desktop = 0; +} diff --git a/util/epist/window.hh b/util/epist/window.hh index 140d63bc..c544091a 100644 --- a/util/epist/window.hh +++ b/util/epist/window.hh @@ -31,7 +31,7 @@ extern "C" { class XWindow; -typedef std::list WindowList; +typedef std::list WindowList; class XWindow { private: @@ -42,6 +42,8 @@ private: bool _max_vert; bool _max_horz; + bool _unmapped; + public: XWindow(Window window); virtual ~XWindow(); @@ -53,7 +55,10 @@ public: inline bool maxVert() const { return _max_vert; } inline bool maxHorz() const { return _max_horz; } + inline void setUnmapped(bool u) { _unmapped = u; } + void updateState(); + void updateDesktop(); bool operator == (const XWindow &w) const { return w._window == _window; } bool operator == (const Window &w) const { return w == _window; } -- 2.39.2