+ const otk::OBProperty *property = Openbox::instance->property();
+
+ // these values should not be persisted across a window unmapping/mapping
+ property->erase(_window, otk::OBProperty::net_wm_desktop);
+ property->erase(_window, otk::OBProperty::net_wm_state);
+}
+
+
+void OBClient::getDesktop()
+{
+ const otk::OBProperty *property = Openbox::instance->property();
+
+ // defaults to the current desktop
+ _desktop = 0; // XXX: change this to the current desktop!
+
+ property->get(_window, otk::OBProperty::net_wm_desktop,
+ otk::OBProperty::Atom_Cardinal,
+ &_desktop);
+}
+
+
+void OBClient::getType()
+{
+ const otk::OBProperty *property = Openbox::instance->property();
+
+ _type = (WindowType) -1;
+
+ unsigned long *val;
+ unsigned long num = (unsigned) -1;
+ if (property->get(_window, otk::OBProperty::net_wm_window_type,
+ otk::OBProperty::Atom_Atom,
+ &num, &val)) {
+ // use the first value that we know about in the array
+ for (unsigned long i = 0; i < num; ++i) {
+ if (val[i] ==
+ property->atom(otk::OBProperty::net_wm_window_type_desktop))
+ _type = Type_Desktop;
+ else if (val[i] ==
+ property->atom(otk::OBProperty::net_wm_window_type_dock))
+ _type = Type_Dock;
+ else if (val[i] ==
+ property->atom(otk::OBProperty::net_wm_window_type_toolbar))
+ _type = Type_Toolbar;
+ else if (val[i] ==
+ property->atom(otk::OBProperty::net_wm_window_type_menu))
+ _type = Type_Menu;
+ else if (val[i] ==
+ property->atom(otk::OBProperty::net_wm_window_type_utility))
+ _type = Type_Utility;
+ else if (val[i] ==
+ property->atom(otk::OBProperty::net_wm_window_type_splash))
+ _type = Type_Splash;
+ else if (val[i] ==
+ property->atom(otk::OBProperty::net_wm_window_type_dialog))
+ _type = Type_Dialog;
+ else if (val[i] ==
+ property->atom(otk::OBProperty::net_wm_window_type_normal))
+ _type = Type_Normal;
+// else if (val[i] ==
+// property->atom(otk::OBProperty::kde_net_wm_window_type_override))
+// mwm_decorations = 0; // prevent this window from getting any decor
+ // XXX: make this work again
+ }
+ delete val;
+ }
+
+ if (_type == (WindowType) -1) {
+ /*
+ * the window type hint was not set, which means we either classify ourself
+ * as a normal window or a dialog, depending on if we are a transient.
+ */
+ // XXX: make this code work!
+ //if (isTransient())
+ // _type = Type_Dialog;
+ //else
+ _type = Type_Normal;
+ }
+}
+
+
+void OBClient::getMwmHints()
+{
+ const otk::OBProperty *property = Openbox::instance->property();
+
+ unsigned long num;
+ MwmHints *hints;
+
+ num = MwmHints::elements;
+ if (!property->get(_window, otk::OBProperty::motif_wm_hints,
+ otk::OBProperty::motif_wm_hints, &num,
+ (unsigned long **)&hints))
+ return;
+
+ if (num < MwmHints::elements) {
+ delete [] hints;
+ return;
+ }
+
+ // retrieved the hints
+ // Mwm Hints are applied subtractively to what has already been chosen for
+ // decor and functionality
+
+ if (hints->flags & MwmFlag_Decorations) {
+ if (! (hints->decorations & MwmDecor_All)) {
+ if (! (hints->decorations & MwmDecor_Border))
+ _decorations &= ~Decor_Border;
+ if (! (hints->decorations & MwmDecor_Handle))
+ _decorations &= ~Decor_Handle;
+ if (! (hints->decorations & MwmDecor_Title))
+ _decorations &= ~Decor_Titlebar;
+ if (! (hints->decorations & MwmDecor_Iconify))
+ _decorations &= ~Decor_Iconify;
+ if (! (hints->decorations & MwmDecor_Maximize))
+ _decorations &= ~Decor_Maximize;
+ }
+ }
+
+ if (hints->flags & MwmFlag_Functions) {
+ if (! (hints->functions & MwmFunc_All)) {
+ if (! (hints->functions & MwmFunc_Resize))
+ _functions &= ~Func_Resize;
+ if (! (hints->functions & MwmFunc_Move))
+ _functions &= ~Func_Move;
+ if (! (hints->functions & MwmFunc_Iconify))
+ _functions &= ~Func_Iconify;
+ if (! (hints->functions & MwmFunc_Maximize))
+ _functions &= ~Func_Maximize;
+ //if (! (hints->functions & MwmFunc_Close))
+ // _functions &= ~Func_Close;
+ }
+ }
+ delete [] hints;
+}
+
+
+void OBClient::getArea()
+{
+ XWindowAttributes 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::getState()
+{
+ const otk::OBProperty *property = Openbox::instance->property();
+
+ _modal = _shaded = _max_horz = _max_vert = _fullscreen = _above = _below =
+ false;
+
+ unsigned long *state;
+ unsigned long num = (unsigned) -1;
+
+ if (property->get(_window, otk::OBProperty::net_wm_state,
+ otk::OBProperty::Atom_Atom, &num, &state)) {
+ for (unsigned long i = 0; i < num; ++i) {
+ if (state[i] == property->atom(otk::OBProperty::net_wm_state_modal))
+ _modal = true;
+ else if (state[i] ==
+ property->atom(otk::OBProperty::net_wm_state_shaded))
+ _shaded = true;
+ else if (state[i] ==
+ property->atom(otk::OBProperty::net_wm_state_fullscreen))
+ _fullscreen = true;
+ else if (state[i] ==
+ property->atom(otk::OBProperty::net_wm_state_maximized_vert))
+ _max_vert = true;
+ else if (state[i] ==
+ property->atom(otk::OBProperty::net_wm_state_maximized_horz))
+ _max_horz = true;
+ else if (state[i] ==
+ property->atom(otk::OBProperty::net_wm_state_above))
+ _above = true;
+ else if (state[i] ==
+ property->atom(otk::OBProperty::net_wm_state_below))
+ _below = true;
+ }
+
+ delete [] state;
+ }
+}
+
+
+void OBClient::getShaped()
+{
+ _shaped = false;
+#ifdef SHAPE
+ if (otk::OBDisplay::shape()) {
+ int foo;
+ unsigned int ufoo;
+ int s;
+
+ XShapeSelectInput(otk::OBDisplay::display, _window, ShapeNotifyMask);
+
+ XShapeQueryExtents(otk::OBDisplay::display, _window, &s, &foo,
+ &foo, &ufoo, &ufoo, &foo, &foo, &foo, &ufoo, &ufoo);
+ _shaped = (s != 0);
+ }
+#endif // SHAPE
+}
+
+
+void OBClient::calcLayer() {
+ if (_iconic) _layer = OBScreen::Layer_Icon;
+ else if (_type == Type_Desktop) _layer = OBScreen::Layer_Desktop;
+ else if (_type == Type_Dock) _layer = OBScreen::Layer_Top;
+ else if (_fullscreen) _layer = OBScreen::Layer_Fullscreen;
+ else if (_above) _layer = OBScreen::Layer_Above;
+ else if (_below) _layer = OBScreen::Layer_Below;
+ else _layer = OBScreen::Layer_Normal;
+}
+
+
+void OBClient::updateProtocols()
+{
+ const otk::OBProperty *property = Openbox::instance->property();
+
+ Atom *proto;
+ int num_return = 0;
+
+ _focus_notify = false;
+ _decorations &= ~Decor_Close;
+ _functions &= ~Func_Close;
+
+ if (XGetWMProtocols(otk::OBDisplay::display, _window, &proto, &num_return)) {
+ for (int i = 0; i < num_return; ++i) {
+ if (proto[i] == property->atom(otk::OBProperty::wm_delete_window)) {
+ _decorations |= Decor_Close;
+ _functions |= Func_Close;
+ // XXX: update the decor?
+ } else if (proto[i] == property->atom(otk::OBProperty::wm_take_focus))
+ // if this protocol is requested, then the window will be notified
+ // by the window manager whenever it receives focus
+ _focus_notify = true;
+ }
+ XFree(proto);
+ }