X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fframe.cc;h=20e65932273af6c37166d9b2bf134f722739e568;hb=5face4c6f35172761367f63ac0b6eaf62d84e532;hp=1fed17684e92b7449bbbb8262b8056f17149cd80;hpb=24dd636f7318b0d21637aa7ffe253fe0ebf71f24;p=chaz%2Fopenbox diff --git a/src/frame.cc b/src/frame.cc index 1fed1768..20e65932 100644 --- a/src/frame.cc +++ b/src/frame.cc @@ -10,76 +10,68 @@ extern "C" { #endif // SHAPE } +#include "openbox.hh" #include "frame.hh" #include "client.hh" +#include "python.hh" +#include "bindings.hh" #include "otk/display.hh" #include namespace ob { -OBFrame::OBFrame(const OBClient *client, const otk::Style *style) - : _client(client), - _screen(otk::OBDisplay::screenInfo(client->screen())) +const long Frame::event_mask; + +Frame::Frame(Client *client, otk::RenderStyle *style) + : otk::Widget(openbox, style, Horizontal, 0, 1, true), + WidgetBase(WidgetBase::Type_Frame), + _client(client), + _screen(otk::display->screenInfo(client->screen())), + _plate(this, WidgetBase::Type_Plate), + _titlebar(this, WidgetBase::Type_Titlebar), + _button_close(&_titlebar, WidgetBase::Type_CloseButton, client), + _button_iconify(&_titlebar, WidgetBase::Type_IconifyButton, client), + _button_max(&_titlebar, WidgetBase::Type_MaximizeButton, client), + _button_alldesk(&_titlebar, WidgetBase::Type_AllDesktopsButton, client), + _label(&_titlebar, WidgetBase::Type_Label), + _handle(this, WidgetBase::Type_Handle), + _grip_left(&_handle, WidgetBase::Type_LeftGrip, client), + _grip_right(&_handle, WidgetBase::Type_RightGrip, client), + _decorations(client->decorations()) { assert(client); assert(style); - - _decorations = client->decorations(); - - // create the base frame parent window - _window = createFrame(); - assert(_window); - - // create all of the style element child windows - _titlebar = createChild(_window, 0); - assert(_titlebar); - _button_iconify = createChild(_titlebar, 0); - assert(_button_iconify); - _button_max = createChild(_titlebar, 0); - assert(_button_max); - _button_stick = createChild(_titlebar, 0); - assert(_button_stick); - _button_close = createChild(_titlebar, 0); - assert(_button_close); - _label = createChild(_titlebar, 0); - assert(_label); - XMapSubwindows(otk::OBDisplay::display, _titlebar); - - _handle = createChild(_window, 0); - assert(_handle); - _grip_left = createChild(_handle, 0); - assert(_grip_left); - _grip_right = createChild(_handle, 0); - assert(_grip_right); - XMapSubwindows(otk::OBDisplay::display, _handle); + + XSelectInput(**otk::display, _window, Frame::event_mask); + + _grip_left.setCursor(openbox->cursors().ll_angle); + _grip_right.setCursor(openbox->cursors().lr_angle); + _label.setText(_client->title()); + _style = 0; - loadStyle(style); + setStyle(style); + + otk::Widget::unfocus(); // stuff starts out appearing focused in otk + + _plate.show(); // the other stuff is shown based on decor settings +} + - grabClient(); +Frame::~Frame() +{ } -OBFrame::~OBFrame() +void Frame::setTitle(const otk::ustring &text) { - XDestroyWindow(otk::OBDisplay::display, _button_iconify); - XDestroyWindow(otk::OBDisplay::display, _button_max); - XDestroyWindow(otk::OBDisplay::display, _button_stick); - XDestroyWindow(otk::OBDisplay::display, _button_close); - XDestroyWindow(otk::OBDisplay::display, _label); - XDestroyWindow(otk::OBDisplay::display, _titlebar); - XDestroyWindow(otk::OBDisplay::display, _grip_left); - XDestroyWindow(otk::OBDisplay::display, _grip_right); - XDestroyWindow(otk::OBDisplay::display, _handle); - - releaseClient(false); - - XDestroyWindow(otk::OBDisplay::display, _window); + _label.setText(text); + _label.update(); } -void OBFrame::loadStyle(const otk::Style *style) +void Frame::setStyle(otk::RenderStyle *style) { assert(style); @@ -87,301 +79,315 @@ void OBFrame::loadStyle(const otk::Style *style) // replacing a style bool replace = (_style); + otk::Widget::setStyle(style); + if (replace) { // XXX: do shit here whatever } _style = style; - XSetWindowBorderWidth(otk::OBDisplay::display, _window, - _style->getBorderWidth()); - XSetWindowBorder(otk::OBDisplay::display, _window, - _style->getBorderColor().pixel()); - XSetWindowBorderWidth(otk::OBDisplay::display, _titlebar, - _style->getBorderWidth()); - XSetWindowBorder(otk::OBDisplay::display, _titlebar, - _style->getBorderColor().pixel()); - XSetWindowBorderWidth(otk::OBDisplay::display, _grip_left, - _style->getBorderWidth()); - XSetWindowBorder(otk::OBDisplay::display, _grip_left, - _style->getBorderColor().pixel()); - XSetWindowBorderWidth(otk::OBDisplay::display, _grip_right, - _style->getBorderWidth()); - XSetWindowBorder(otk::OBDisplay::display, _grip_right, - _style->getBorderColor().pixel()); - XSetWindowBorderWidth(otk::OBDisplay::display, _handle, - _style->getBorderWidth()); - XSetWindowBorder(otk::OBDisplay::display, _handle, - _style->getBorderColor().pixel()); - - // XXX: if (focused) - XSetWindowBackground(otk::OBDisplay::display, _window, - _style->getFrameFocus().color().pixel()); - // XXX: else - // XXX: XSetWindowBackground(otk::OBDisplay::display, _window, - // XXX: _style->getFrameUnfocus().color().pixel()); - - // if !replace, then update() will get called after the client is grabbed! + setBorderColor(_style->frameBorderColor()); + + // if !replace, then adjust() will get called after the client is grabbed! if (replace) { - update(); - - // XXX: make everything redraw + // size/position everything + adjustSize(); + adjustPosition(); } } -void OBFrame::update() +void Frame::focus() +{ + otk::Widget::focus(); + update(); +} + + +void Frame::unfocus() +{ + otk::Widget::unfocus(); + update(); +} + + +void Frame::adjust() +{ + // the party all happens in adjustSize +} + + +void Frame::adjustSize() { // XXX: only if not overridden or something!!! MORE LOGIC HERE!! _decorations = _client->decorations(); - int width; // the width of the client window and the border around it + // true/false for whether to show each element of the titlebar + bool tit_i = false, tit_m = false, tit_s = false, tit_c = false; + int width; // the width of the client and its border + int bwidth; // width to make borders + int cbwidth; // width of the inner client border + int butsize=0; // width and height of the titlebar buttons + const int bevel = _style->bevelWidth(); - if (_decorations & OBClient::Decor_Border) { - _size.left = _size.top = _size.bottom = _size.right = - _style->getFrameWidth(); - width = _client->area().width() + _style->getFrameWidth() * 2; - } else { - _size.left = _size.top = _size.bottom = _size.right = 0; - width = _client->area().width(); - } - - if (_decorations & OBClient::Decor_Titlebar) { + if (_decorations & Client::Decor_Border) { + bwidth = _style->frameBorderWidth(); + cbwidth = _style->clientBorderWidth(); + } else + bwidth = cbwidth = 0; + _innersize.left = _innersize.top = _innersize.bottom = _innersize.right = + cbwidth; + width = _client->area().width() + cbwidth * 2; + + _plate.setBorderWidth(cbwidth); + + setBorderWidth(bwidth); + _titlebar.setBorderWidth(bwidth); + _grip_left.setBorderWidth(bwidth); + _grip_right.setBorderWidth(bwidth); + _handle.setBorderWidth(bwidth); + + if (_decorations & Client::Decor_Titlebar) { // set the titlebar size - _titlebar_area.setRect(-_style->getBorderWidth(), - -_style->getBorderWidth(), - width, - (_style->getFont().height() + - _style->getBevelWidth() * 2)); - _size.top += _titlebar_area.height() + _style->getBorderWidth(); + _titlebar.setGeometry(-bwidth, + -bwidth, + width, + _style->labelFont()->height() + (bevel * 2)); + _innersize.top += _titlebar.height() + bwidth; // set the label size - _label_area.setRect(0, _style->getBevelWidth(), - width, _style->getFont().height()); + _label.setGeometry(0, bevel, width, _style->labelFont()->height()); // set the buttons sizes - if (_decorations & OBClient::Decor_Iconify) - _button_iconify_area.setRect(0, _style->getBevelWidth() + 1, - _label_area.height() - 2, - _label_area.height() - 2); - if (_decorations & OBClient::Decor_Maximize) - _button_max_area.setRect(0, _style->getBevelWidth() + 1, - _label_area.height() - 2, - _label_area.height() - 2); - if (_decorations & OBClient::Decor_Sticky) - _button_stick_area.setRect(0, _style->getBevelWidth() + 1, - _label_area.height() - 2, - _label_area.height() - 2); - if (_decorations & OBClient::Decor_Close) - _button_close_area.setRect(0, _style->getBevelWidth() + 1, - _label_area.height() - 2, - _label_area.height() - 2); + butsize = _label.height() - 2; + if (_decorations & Client::Decor_Iconify) + _button_iconify.setGeometry(0, bevel + 1, butsize, butsize); + if (_decorations & Client::Decor_Maximize) + _button_max.setGeometry(0, bevel + 1, butsize, butsize); + if (_decorations & Client::Decor_AllDesktops) + _button_alldesk.setGeometry(0, bevel + 1, butsize, butsize); + if (_decorations & Client::Decor_Close) + _button_close.setGeometry(0, bevel + 1, butsize, butsize); // separation between titlebar elements - const int sep = _style->getBevelWidth() + 1; + const int sep = bevel + 1; - std::string layout = "ILMC"; // XXX: get this from somewhere - // XXX: it is REQUIRED that by this point, the string only has one of each - // possible letter, all of the letters are valid, and L exists somewhere in - // the string! + otk::ustring layout; + if (!python_get_string("titlebar_layout", &layout)) + layout = "ILMC"; + // this code ensures that the string only has one of each possible + // letter, all of the letters are valid, and L exists somewhere in the + // string! + bool tit_l = false; + + for (std::string::size_type i = 0; i < layout.size(); ++i) { + switch (layout[i]) { + case 'i': + case 'I': + if (!tit_i && (_decorations & Client::Decor_Iconify)) { + tit_i = true; + continue; + } + break; + case 'l': + case 'L': + if (!tit_l) { + tit_l = true; + continue; + } + break; + case 'm': + case 'M': + if (!tit_m && (_decorations & Client::Decor_Maximize)) { + tit_m = true; + continue; + } + break; + case 'd': + case 'D': + if (!tit_s && (_decorations & Client::Decor_AllDesktops)) { + tit_s = true; + continue; + } + break; + case 'c': + case 'C': + if (!tit_c && (_decorations & Client::Decor_Close)) { + tit_c = true; + continue; + } + break; + } + // if we get here then we don't want the letter, kill it + layout.erase(i--, 1); + } + if (!tit_l) + layout += "L"; + // the size of the label. this ASSUMES the layout has only buttons other // that the ONE LABEL!! // adds an extra sep so that there's a space on either side of the // titlebar.. note: x = sep, below. - _label_area.setWidth(_label_area.width() - - ((_button_iconify_area.width() + sep) * - (layout.size() - 1) + sep)); + int lwidth = width - sep * 2 - + (butsize + sep) * (layout.size() - 1); + // quick sanity check for really small windows. if this is needed, its + // obviously not going to be displayed right... + // XXX: maybe we should make this look better somehow? constraints? + if (lwidth <= 0) lwidth = 1; + _label.setWidth(lwidth); int x = sep; - for (int i = 0, len = layout.size(); i < len; ++i) { - otk::Rect *area; + for (std::string::size_type i = 0, len = layout.size(); i < len; ++i) { switch (layout[i]) { + case 'i': case 'I': - if (!(_decorations & OBClient::Decor_Iconify)) - continue; // skip it - area = &_button_iconify_area; + _button_iconify.move(x, _button_iconify.rect().y()); + x += _button_iconify.width(); break; + case 'l': case 'L': - area = &_label_area; + _label.move(x, _label.rect().y()); + x += _label.width(); break; + case 'm': case 'M': - if (!(_decorations & OBClient::Decor_Maximize)) - continue; // skip it - area = &_button_max_area; + _button_max.move(x, _button_max.rect().y()); + x += _button_max.width(); break; - case 'S': - if (!(_decorations & OBClient::Decor_Sticky)) - continue; // skip it - area = &_button_stick_area; + case 'd': + case 'D': + _button_alldesk.move(x, _button_alldesk.rect().y()); + x += _button_alldesk.width(); break; + case 'c': case 'C': - if (!(_decorations & OBClient::Decor_Close)) - continue; // skip it - area = &_button_close_area; + _button_close.move(x, _button_close.rect().y()); + x += _button_close.width(); break; default: assert(false); // the layout string is invalid! - continue; // just to fuck with g++ } - area->setX(x); - x += sep + area->width(); + x += sep; } } - if (_decorations & OBClient::Decor_Handle) { - _handle_area.setRect(-_style->getBorderWidth(), - _size.top + _client->area().height() + - _style->getFrameWidth(), - width, _style->getHandleWidth()); - _grip_left_area.setRect(-_style->getBorderWidth(), - -_style->getBorderWidth(), - // XXX: get a Point class in otk and use that for - // the 'buttons size' since theyre all the same - _button_iconify_area.width() * 2, - _handle_area.height()); - _grip_right_area.setRect(((_handle_area.right() + 1) - - _button_iconify_area.width() * 2), - -_style->getBorderWidth(), - // XXX: get a Point class in otk and use that for - // the 'buttons size' since theyre all the same - _button_iconify_area.width() * 2, - _handle_area.height()); - _size.bottom += _handle_area.height() + _style->getBorderWidth(); + if (_decorations & Client::Decor_Handle) { + _handle.setGeometry(-bwidth, + _innersize.top + _client->area().height() + cbwidth, + width, _style->handleWidth()); + _grip_left.setGeometry(-bwidth, + -bwidth, + butsize * 2, + _handle.height()); + _grip_right.setGeometry(((_handle.rect().right() + 1) - + butsize * 2), + -bwidth, + butsize * 2, + _handle.height()); + _innersize.bottom += _handle.height() + bwidth; } // position/size all the windows - XResizeWindow(otk::OBDisplay::display, _window, - _size.left + _size.right + _client->area().width(), - _size.top + _size.bottom + _client->area().height()); - - XMoveWindow(otk::OBDisplay::display, _client->window(), - _size.left, _size.top); - - if (_decorations & OBClient::Decor_Titlebar) { - XMoveResizeWindow(otk::OBDisplay::display, _titlebar, - _titlebar_area.x(), _titlebar_area.y(), - _titlebar_area.width(), _titlebar_area.height()); - XMoveResizeWindow(otk::OBDisplay::display, _label, - _label_area.x(), _label_area.y(), - _label_area.width(), _label_area.height()); - if (_decorations & OBClient::Decor_Iconify) - XMoveResizeWindow(otk::OBDisplay::display, _button_iconify, - _button_iconify_area.x(), _button_iconify_area.y(), - _button_iconify_area.width(), - _button_iconify_area.height()); - if (_decorations & OBClient::Decor_Maximize) - XMoveResizeWindow(otk::OBDisplay::display, _button_max, - _button_max_area.x(), _button_max_area.y(), - _button_max_area.width(), - _button_max_area.height()); - if (_decorations & OBClient::Decor_Sticky) - XMoveResizeWindow(otk::OBDisplay::display, _button_stick, - _button_stick_area.x(), _button_stick_area.y(), - _button_stick_area.width(), - _button_stick_area.height()); - if (_decorations & OBClient::Decor_Close) - XMoveResizeWindow(otk::OBDisplay::display, _button_close, - _button_close_area.x(), _button_close_area.y(), - _button_close_area.width(), - _button_close_area.height()); - } + if (_client->shaded()) + resize(_innersize.left + _innersize.right + _client->area().width(), + _titlebar.height()); + else + resize(_innersize.left + _innersize.right + _client->area().width(), + _innersize.top + _innersize.bottom + _client->area().height()); - if (_decorations & OBClient::Decor_Handle) { - XMoveResizeWindow(otk::OBDisplay::display, _handle, - _handle_area.x(), _handle_area.y(), - _handle_area.width(), _handle_area.height()); - XMoveResizeWindow(otk::OBDisplay::display, _grip_left, - _grip_left_area.x(), _grip_left_area.y(), - _grip_left_area.width(), _grip_left_area.height()); - XMoveResizeWindow(otk::OBDisplay::display, _grip_right, - _grip_right_area.x(), _grip_right_area.y(), - _grip_right_area.width(), _grip_right_area.height()); - } + _plate.setGeometry(_innersize.left - cbwidth, _innersize.top - cbwidth, + _client->area().width(), _client->area().height()); // map/unmap all the windows - if (_decorations & OBClient::Decor_Titlebar) { - XMapWindow(otk::OBDisplay::display, _label); - if (_decorations & OBClient::Decor_Iconify) - XMapWindow(otk::OBDisplay::display, _button_iconify); + if (_decorations & Client::Decor_Titlebar) { + _label.show(); + if (tit_i) + _button_iconify.show(); else - XUnmapWindow(otk::OBDisplay::display, _button_iconify); - if (_decorations & OBClient::Decor_Maximize) - XMapWindow(otk::OBDisplay::display, _button_max); + _button_iconify.hide(); + if (tit_m) + _button_max.show(); else - XUnmapWindow(otk::OBDisplay::display, _button_max); - if (_decorations & OBClient::Decor_Sticky) - XMapWindow(otk::OBDisplay::display, _button_stick); + _button_max.hide(); + if (tit_s) + _button_alldesk.show(); else - XUnmapWindow(otk::OBDisplay::display, _button_stick); - if (_decorations & OBClient::Decor_Close) - XMapWindow(otk::OBDisplay::display, _button_close); + _button_alldesk.hide(); + if (tit_c) + _button_close.show(); else - XUnmapWindow(otk::OBDisplay::display, _button_close); - XMapWindow(otk::OBDisplay::display, _titlebar); + _button_close.hide(); + _titlebar.show(); } else { - XUnmapWindow(otk::OBDisplay::display, _titlebar); - XUnmapWindow(otk::OBDisplay::display, _label); - XUnmapWindow(otk::OBDisplay::display, _button_iconify); - XUnmapWindow(otk::OBDisplay::display, _button_max); - XUnmapWindow(otk::OBDisplay::display, _button_stick); - XUnmapWindow(otk::OBDisplay::display, _button_close); + _titlebar.hide(true); } - if (_decorations & OBClient::Decor_Handle) { - XMapWindow(otk::OBDisplay::display, _grip_left); - XMapWindow(otk::OBDisplay::display, _grip_right); - XMapWindow(otk::OBDisplay::display, _handle); - } else { - XUnmapWindow(otk::OBDisplay::display, _handle); - XUnmapWindow(otk::OBDisplay::display, _grip_left); - XUnmapWindow(otk::OBDisplay::display, _grip_right); - } + if (_decorations & Client::Decor_Handle) + _handle.show(true); + else + _handle.hide(true); - // XXX: more is gunna have to happen here + _size.left = _innersize.left + bwidth; + _size.right = _innersize.right + bwidth; + _size.top = _innersize.top + bwidth; + _size.bottom = _innersize.bottom + bwidth; + + adjustShape(); - updateShape(); + update(); +} + + +void Frame::adjustPosition() +{ + int x, y; + clientGravity(x, y); + move(x, y); } -void OBFrame::updateShape() +void Frame::adjustShape() { #ifdef SHAPE + int bwidth = (_decorations & Client::Decor_Border) ? + _style->frameBorderWidth() : 0; + if (!_client->shaped()) { // clear the shape on the frame window - XShapeCombineMask(otk::OBDisplay::display, _window, ShapeBounding, - _size.left, - _size.top, + XShapeCombineMask(**otk::display, _window, ShapeBounding, + _innersize.left, + _innersize.top, None, ShapeSet); } else { // make the frame's shape match the clients - XShapeCombineShape(otk::OBDisplay::display, _window, ShapeBounding, - _size.left, - _size.top, + XShapeCombineShape(**otk::display, _window, ShapeBounding, + _innersize.left, + _innersize.top, _client->window(), ShapeBounding, ShapeSet); - int num = 0; + int num = 0; XRectangle xrect[2]; - /* - if (decorations & Decor_Titlebar) { - xrect[0].x = xrect[0].y = -frame.border_w; - xrect[0].width = frame.rect.width(); - xrect[0].height = frame.title_h + (frame.border_w * 2); - ++num; + if (_decorations & Client::Decor_Titlebar) { + xrect[0].x = _titlebar.rect().x(); + xrect[0].y = _titlebar.rect().y(); + xrect[0].width = _titlebar.width() + bwidth * 2; // XXX: this is useless once the widget handles borders! + xrect[0].height = _titlebar.height() + bwidth * 2; + ++num; } - if (decorations & Decor_Handle) { - xrect[1].x = -frame.border_w; - xrect[1].y = frame.rect.height() - frame.margin.bottom + - frame.mwm_border_w - frame.border_w; - xrect[1].width = frame.rect.width(); - xrect[1].height = frame.handle_h + (frame.border_w * 2); - ++num; - }*/ + if (_decorations & Client::Decor_Handle) { + xrect[1].x = _handle.rect().x(); + xrect[1].y = _handle.rect().y(); + xrect[1].width = _handle.width() + bwidth * 2; // XXX: this is useless once the widget handles borders! + xrect[1].height = _handle.height() + bwidth * 2; + ++num; + } - XShapeCombineRectangles(otk::OBDisplay::display, _window, + XShapeCombineRectangles(**otk::display, window(), ShapeBounding, 0, 0, xrect, num, ShapeUnion, Unsorted); } @@ -389,97 +395,169 @@ void OBFrame::updateShape() } -void OBFrame::grabClient() +void Frame::adjustState() { - - XGrabServer(otk::OBDisplay::display); + _button_alldesk.update(); + _button_max.update(); +} - // select the event mask on the frame - XSelectInput(otk::OBDisplay::display, _window, SubstructureRedirectMask); +void Frame::grabClient() +{ // reparent the client to the frame - XSelectInput(otk::OBDisplay::display, _client->window(), - OBClient::event_mask & ~StructureNotifyMask); - XReparentWindow(otk::OBDisplay::display, _client->window(), _window, 0, 0); - XSelectInput(otk::OBDisplay::display, _client->window(), - OBClient::event_mask); - - // raise the client above the frame - //XRaiseWindow(otk::OBDisplay::display, _client->window()); - // map the client so it maps when the frame does - XMapWindow(otk::OBDisplay::display, _client->window()); - - XUngrabServer(otk::OBDisplay::display); + XReparentWindow(**otk::display, _client->window(), _plate.window(), 0, 0); + /* + When reparenting the client window, it is usually not mapped yet, since + this occurs from a MapRequest. However, in the case where Openbox is + starting up, the window is already mapped, so we'll see unmap events for + it. There are 2 unmap events generated that we see, one with the 'event' + member set the root window, and one set to the client, but both get handled + and need to be ignored. + */ + if (openbox->state() == Openbox::State_Starting) + _client->ignore_unmaps += 2; - update(); + // select the event mask on the client's parent (to receive config/map req's) + XSelectInput(**otk::display, _plate.window(), SubstructureRedirectMask); + + // map the client so it maps when the frame does + XMapWindow(**otk::display, _client->window()); - XMapWindow(otk::OBDisplay::display, _window); + adjustSize(); + adjustPosition(); } -void OBFrame::releaseClient(bool remap) +void Frame::releaseClient() { - // check if the app has already reparented its window to the root window XEvent ev; - if (XCheckTypedWindowEvent(otk::OBDisplay::display, _client->window(), + + // check if the app has already reparented its window away + if (XCheckTypedWindowEvent(**otk::display, _client->window(), ReparentNotify, &ev)) { - remap = true; // XXX: why do we remap the window if they already - // reparented to root? + XPutBackEvent(**otk::display, &ev); + // re-map the window since the unmanaging process unmaps it + XMapWindow(**otk::display, _client->window()); } else { - // according to the ICCCM - if the client doesn't reparent to - // root, then we have to do it for them - XReparentWindow(otk::OBDisplay::display, _client->window(), - _screen->getRootWindow(), + // according to the ICCCM - if the client doesn't reparent itself, then we + // will reparent the window to root for them + XReparentWindow(**otk::display, _client->window(), + _screen->rootWindow(), _client->area().x(), _client->area().y()); } - - // if we want to remap the window, do so now - if (remap) - XMapWindow(otk::OBDisplay::display, _client->window()); } -Window OBFrame::createChild(Window parent, Cursor cursor) +void Frame::clientGravity(int &x, int &y) { - XSetWindowAttributes attrib_create; - unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWEventMask; - - attrib_create.background_pixmap = None; - attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask | - ButtonMotionMask | ExposureMask; - - if (cursor) { - create_mask |= CWCursor; - attrib_create.cursor = cursor; + x = _client->area().x(); + y = _client->area().y(); + + // horizontal + switch (_client->gravity()) { + default: + case NorthWestGravity: + case SouthWestGravity: + case WestGravity: + break; + + case NorthGravity: + case SouthGravity: + case CenterGravity: + x -= (_size.left + _size.right) / 2; + break; + + case NorthEastGravity: + case SouthEastGravity: + case EastGravity: + x -= _size.left + _size.right; + break; + + case ForgetGravity: + case StaticGravity: + x -= _size.left; + break; } - Window w = XCreateWindow(otk::OBDisplay::display, parent, 0, 0, 1, 1, 0, - _screen->getDepth(), InputOutput, - _screen->getVisual(), create_mask, &attrib_create); - return w; + // vertical + switch (_client->gravity()) { + default: + case NorthWestGravity: + case NorthEastGravity: + case NorthGravity: + break; + + case CenterGravity: + case EastGravity: + case WestGravity: + y -= (_size.top + _size.bottom) / 2; + break; + + case SouthWestGravity: + case SouthEastGravity: + case SouthGravity: + y -= _size.top + _size.bottom; + break; + + case ForgetGravity: + case StaticGravity: + y -= _size.top; + break; + } } -Window OBFrame::createFrame() +void Frame::frameGravity(int &x, int &y) { - XSetWindowAttributes attrib_create; - unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWColormap | - CWOverrideRedirect | CWEventMask; - - attrib_create.background_pixmap = None; - attrib_create.colormap = _screen->getColormap(); - attrib_create.override_redirect = True; - attrib_create.event_mask = EnterWindowMask | LeaveWindowMask | ButtonPress; - /* - We catch button presses because other wise they get passed down to the - root window, which will then cause root menus to show when you click the - window's frame. - */ + x = rect().x(); + y = rect().y(); + + // horizontal + switch (_client->gravity()) { + default: + case NorthWestGravity: + case WestGravity: + case SouthWestGravity: + break; + case NorthGravity: + case CenterGravity: + case SouthGravity: + x += (_size.left + _size.right) / 2; + break; + case NorthEastGravity: + case EastGravity: + case SouthEastGravity: + x += _size.left + _size.right; + break; + case StaticGravity: + case ForgetGravity: + x += _size.left; + break; + } - return XCreateWindow(otk::OBDisplay::display, _screen->getRootWindow(), - 0, 0, 1, 1, 0, - _screen->getDepth(), InputOutput, _screen->getVisual(), - create_mask, &attrib_create); + // vertical + switch (_client->gravity()) { + default: + case NorthWestGravity: + case WestGravity: + case SouthWestGravity: + break; + case NorthGravity: + case CenterGravity: + case SouthGravity: + y += (_size.top + _size.bottom) / 2; + break; + case NorthEastGravity: + case EastGravity: + case SouthEastGravity: + y += _size.top + _size.bottom; + break; + case StaticGravity: + case ForgetGravity: + y += _size.top; + break; + } } + }