+ const otk::Rect &a = openbox->screen(_screen)->area(_desktop);
+ int x = frame->area().x(), y = frame->area().y(),
+ w = _area.width(), h = _area.height();
+
+ if (max) {
+ if (savearea) {
+ long dimensions[4];
+ long *readdim;
+ unsigned long n = 4;
+
+ dimensions[0] = x;
+ dimensions[1] = y;
+ dimensions[2] = w;
+ dimensions[3] = h;
+
+ // get the property off the window and use it for the dimentions we are
+ // already maxed on
+ if (otk::Property::get(_window, otk::Property::atoms.openbox_premax,
+ otk::Property::atoms.cardinal, &n,
+ (long unsigned**) &readdim)) {
+ if (n >= 4) {
+ if (_max_horz) {
+ dimensions[0] = readdim[0];
+ dimensions[2] = readdim[2];
+ }
+ if (_max_vert) {
+ dimensions[1] = readdim[1];
+ dimensions[3] = readdim[3];
+ }
+ }
+ delete readdim;
+ }
+
+ otk::Property::set(_window, otk::Property::atoms.openbox_premax,
+ otk::Property::atoms.cardinal,
+ (long unsigned*)dimensions, 4);
+ }
+ if (dir == 0 || dir == 1) { // horz
+ x = a.x();
+ w = a.width();
+ }
+ if (dir == 0 || dir == 2) { // vert
+ y = a.y();
+ h = a.height() - frame->size().top - frame->size().bottom;
+ }
+ } else {
+ long *dimensions;
+ long unsigned n = 4;
+
+ if (otk::Property::get(_window, otk::Property::atoms.openbox_premax,
+ otk::Property::atoms.cardinal, &n,
+ (long unsigned**) &dimensions)) {
+ if (n >= 4) {
+ if (dir == 0 || dir == 1) { // horz
+ x = (signed int)dimensions[0];
+ w = (signed int)dimensions[2];
+ }
+ if (dir == 0 || dir == 2) { // vert
+ y = (signed int)dimensions[1];
+ h = (signed int)dimensions[3];
+ }
+ }
+ delete dimensions;
+ } else {
+ // pick some fallbacks...
+ if (dir == 0 || dir == 1) { // horz
+ x = a.x() + a.width() / 4;
+ w = a.width() / 2;
+ }
+ if (dir == 0 || dir == 2) { // vert
+ y = a.y() + a.height() / 4;
+ h = a.height() / 2;
+ }
+ }
+ }
+
+ if (dir == 0 || dir == 1) // horz
+ _max_horz = max;
+ if (dir == 0 || dir == 2) // vert
+ _max_vert = max;
+
+ if (!_max_horz && !_max_vert)
+ otk::Property::erase(_window, otk::Property::atoms.openbox_premax);
+
+ changeState(); // change the state hints on the client
+
+ frame->frameGravity(x, y); // figure out where the client should be going
+ internal_resize(TopLeft, w, h, true, x, y);
+}
+
+void Client::fullscreen(bool fs, bool savearea)
+{
+ static FunctionFlags saved_func;
+ static DecorationFlags saved_decor;
+
+ if (!(_functions & Func_Fullscreen) || // can't
+ _fullscreen == fs) return; // already done
+
+ _fullscreen = fs;
+ changeState(); // change the state hints on the client
+
+ int x = _area.x(), y = _area.y(), w = _area.width(), h = _area.height();
+
+ if (fs) {
+ // save the functions and remove them
+ saved_func = _functions;
+ _functions = _functions & (Func_Close | Func_Fullscreen | Func_Iconify);
+ // save the decorations and remove them
+ saved_decor = _decorations;
+ _decorations = 0;
+ if (savearea) {
+ long dimensions[4];
+ dimensions[0] = _area.x();
+ dimensions[1] = _area.y();
+ dimensions[2] = _area.width();
+ dimensions[3] = _area.height();
+ otk::Property::set(_window, otk::Property::atoms.openbox_premax,
+ otk::Property::atoms.cardinal,
+ (long unsigned*)dimensions, 4);
+ }
+ const otk::ScreenInfo *info = otk::display->screenInfo(_screen);
+ x = 0;
+ y = 0;
+ w = info->size().width();
+ h = info->size().height();
+ } else {
+ _functions = saved_func;
+ _decorations = saved_decor;
+
+ long *dimensions;
+ long unsigned n = 4;
+
+ if (otk::Property::get(_window, otk::Property::atoms.openbox_premax,
+ otk::Property::atoms.cardinal, &n,
+ (long unsigned**) &dimensions)) {
+ if (n >= 4) {
+ x = dimensions[0];
+ y = dimensions[1];
+ w = dimensions[2];
+ h = dimensions[3];
+ }
+ delete dimensions;
+ } else {
+ // pick some fallbacks...
+ const otk::Rect &a = openbox->screen(_screen)->area(_desktop);
+ x = a.x() + a.width() / 4;
+ y = a.y() + a.height() / 4;
+ w = a.width() / 2;
+ h = a.height() / 2;
+ }
+ }
+
+ changeAllowedActions(); // based on the new _functions
+
+ // when fullscreening, don't obey things like increments, fill the screen
+ internal_resize(TopLeft, w, h, !fs, x, y);
+
+ // raise (back) into our stacking layer
+ openbox->screen(_screen)->raiseWindow(this);
+
+ // try focus us when we go into fullscreen mode
+ if (fs) focus();
+}
+
+void Client::iconify(bool iconic, bool curdesk)
+{
+ if (_iconic == iconic) return; // nothing to do
+
+#ifdef DEBUG
+ printf("%sconifying window: 0x%lx\n", (iconic ? "I" : "Uni"), _window);
+#endif
+
+ _iconic = iconic;
+
+ if (_iconic) {
+ _wmstate = IconicState;
+ ignore_unmaps++;
+ // we unmap the client itself so that we can get MapRequest events, and
+ // because the ICCCM tells us to!
+ XUnmapWindow(**otk::display, _window);
+ } else {
+ if (curdesk)
+ setDesktop(openbox->screen(_screen)->desktop());
+ _wmstate = NormalState;
+ XMapWindow(**otk::display, _window);
+ }
+ changeState();
+ showhide();
+ openbox->screen(_screen)->updateStruts();
+}
+
+void Client::disableDecorations(DecorationFlags flags)
+{
+ _disabled_decorations = flags;
+ setupDecorAndFunctions();
+}
+
+void Client::installColormap(bool install) const
+{
+ XWindowAttributes wa;
+ if (XGetWindowAttributes(**otk::display, _window, &wa)) {
+ if (install)
+ XInstallColormap(**otk::display, wa.colormap);
+ else
+ XUninstallColormap(**otk::display, wa.colormap);
+ }
+}
+
+Client *Client::searchModalTree(Client *node, Client *skip)
+{
+ List::const_iterator it, end = node->_transients.end();
+ Client *ret;
+
+ for (it = node->_transients.begin(); it != end; ++it) {
+ if (*it == skip) continue; // circular?
+ if ((ret = searchModalTree(*it, skip))) return ret; // got one
+ if ((*it)->_modal) return *it; // got one
+ }
+ return 0;
+}
+
+Client *Client::findModalChild()
+{
+ return searchModalTree(this, this);
+}
+
+
+bool Client::focus()