namespace ob {
OBClient::OBClient(int screen, Window window)
- : _screen(screen), _window(window)
+ : otk::OtkEventHandler(),
+ _screen(screen), _window(window)
{
+ assert(screen >= 0);
assert(window);
+ Openbox::instance->registerHandler(_window, this);
+
+ ignore_unmaps = 0;
+
// update EVERYTHING the first time!!
// the state is kinda assumed to be normal. is this right? XXX
void OBClient::getArea()
{
XWindowAttributes wattrib;
- assert(XGetWindowAttributes(otk::OBDisplay::display, _window, &wattrib));
+ Status ret;
+
+ ret = XGetWindowAttributes(otk::OBDisplay::display, _window, &wattrib);
+ assert(ret != BadWindow);
_area.setRect(wattrib.x, wattrib.y, wattrib.width, wattrib.height);
_border_width = wattrib.border_width;
}
-void OBClient::update(const XPropertyEvent &e)
+void OBClient::propertyHandler(const XPropertyEvent &e)
{
+ otk::OtkEventHandler::propertyHandler(e);
+
const otk::OBProperty *property = Openbox::instance->property();
+ // compress changes to a single property into a single change
+ XEvent ce;
+ while (XCheckTypedEvent(otk::OBDisplay::display, e.type, &ce)) {
+ // XXX: it would be nice to compress ALL changes to a property, not just
+ // changes in a row without other props between.
+ if (ce.xproperty.atom != e.atom) {
+ XPutBackEvent(otk::OBDisplay::display, &ce);
+ break;
+ }
+ }
+
if (e.atom == XA_WM_NORMAL_HINTS)
updateNormalHints();
else if (e.atom == XA_WM_HINTS)
}
-void OBClient::update(const XClientMessageEvent &e)
+void OBClient::clientMessageHandler(const XClientMessageEvent &e)
{
+ otk::OtkEventHandler::clientMessageHandler(e);
+
if (e.format != 32) return;
const otk::OBProperty *property = Openbox::instance->property();
- if (e.message_type == property->atom(otk::OBProperty::wm_change_state))
- setWMState(e.data.l[0]);
- else if (e.message_type ==
- property->atom(otk::OBProperty::net_wm_desktop))
- setDesktop(e.data.l[0]);
+ if (e.message_type == property->atom(otk::OBProperty::wm_change_state)) {
+ // compress changes into a single change
+ bool compress = false;
+ XEvent ce;
+ while (XCheckTypedEvent(otk::OBDisplay::display, e.type, &ce)) {
+ // XXX: it would be nice to compress ALL messages of a type, not just
+ // messages in a row without other message types between.
+ if (ce.xclient.message_type != e.message_type) {
+ XPutBackEvent(otk::OBDisplay::display, &ce);
+ break;
+ }
+ compress = true;
+ }
+ if (compress)
+ setWMState(ce.xclient.data.l[0]); // use the found event
+ else
+ setWMState(e.data.l[0]); // use the original event
+ } else if (e.message_type ==
+ property->atom(otk::OBProperty::net_wm_desktop)) {
+ // compress changes into a single change
+ bool compress = false;
+ XEvent ce;
+ while (XCheckTypedEvent(otk::OBDisplay::display, e.type, &ce)) {
+ // XXX: it would be nice to compress ALL messages of a type, not just
+ // messages in a row without other message types between.
+ if (ce.xclient.message_type != e.message_type) {
+ XPutBackEvent(otk::OBDisplay::display, &ce);
+ break;
+ }
+ compress = true;
+ }
+ if (compress)
+ setDesktop(e.data.l[0]); // use the found event
+ else
+ setDesktop(e.data.l[0]); // use the original event
+ }
else if (e.message_type == property->atom(otk::OBProperty::net_wm_state))
+ // can't compress these
setState((StateAction)e.data.l[0], e.data.l[1], e.data.l[2]);
}
#if defined(SHAPE) || defined(DOXYGEN_IGNORE)
-void OBClient::update(const XShapeEvent &e)
+void OBClient::shapeHandler(const XShapeEvent &e)
{
+ otk::OtkEventHandler::shapeHandler(e);
+
_shaped = e.shaped;
}
#endif