we now know for every window its state and its desktop
This commit is contained in:
parent
b10d59dabb
commit
5fed16de70
3 changed files with 89 additions and 19 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
Loading…
Reference in a new issue