all repos — openbox @ 5fed16de70c0fbe40c9e62667f80f612d027c717

openbox fork - make it a bit more like ryudo

we now know for every window its state and its desktop
Dana Jansens danakj@orodu.net
commit

5fed16de70c0fbe40c9e62667f80f612d027c717

parent

b10d59dabb5dfd5f3beb2fe71c39b4ee0a3dc5fc

3 files changed, 89 insertions(+), 19 deletions(-)

jump to
M util/epist/process.ccutil/epist/process.cc

@@ -32,12 +32,26 @@ #include <iostream>

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 @@ if (e.xany.window == _root) {

// 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 @@ Window *rootclients = 0;

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

// 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 @@ // remove clients that no longer exist

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 @@ _xatom->getValue(_root, XAtom::net_active_window, XAtom::window, a);

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; }
M util/epist/window.ccutil/epist/window.cc

@@ -28,15 +28,26 @@ #include "window.hh"

#include "epist.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) { - 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 @@ }

delete [] state; } + + +void XWindow::updateDesktop() { + if (! _xatom->getValue(_window, XAtom::net_wm_desktop, XAtom::cardinal, + static_cast<unsigned long>(_desktop))) + _desktop = 0; +}
M util/epist/window.hhutil/epist/window.hh

@@ -31,7 +31,7 @@ #include <list>

class XWindow; -typedef std::list<XWindow> WindowList; +typedef std::list<XWindow *> WindowList; class XWindow { private:

@@ -41,6 +41,8 @@ bool _shaded;

bool _iconic; bool _max_vert; bool _max_horz; + + bool _unmapped; public: XWindow(Window window);

@@ -53,7 +55,10 @@ inline bool iconic() const { return _iconic; }

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