+void Client::maximize(bool max, int dir, bool savearea)
+{
+ assert(dir == 0 || dir == 1 || dir == 2);
+ if (!(_functions & Func_Maximize)) return; // can't
+
+ // check if already done
+ if (max) {
+ if (dir == 0 && _max_horz && _max_vert) return;
+ if (dir == 1 && _max_horz) return;
+ if (dir == 2 && _max_vert) return;
+ } else {
+ if (dir == 0 && !_max_horz && !_max_vert) return;
+ if (dir == 1 && !_max_horz) return;
+ if (dir == 2 && !_max_vert) return;
+ }
+
+ 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);
+}