X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fframe.cc;h=ab21daffd823ee296e5fa2bb45441a2e5045fb57;hb=1da8531a7b4eea22592b6d0760352d2a34e9b6b0;hp=ee770b25375b54eba9d1ebb25629424dfd4ff1f6;hpb=d9e7a7b8cd667cc6e11add9062d3c12ef21b6fda;p=chaz%2Fopenbox diff --git a/src/frame.cc b/src/frame.cc index ee770b25..ab21daff 100644 --- a/src/frame.cc +++ b/src/frame.cc @@ -21,76 +21,73 @@ extern "C" { namespace ob { -const long OBFrame::event_mask; +const long Frame::event_mask; -OBFrame::OBFrame(OBClient *client, otk::Style *style) - : otk::OtkWidget(Openbox::instance, style), - OBWidget(Type_Frame), +Frame::Frame(Client *client, otk::RenderStyle *style) + : otk::Widget(openbox, style, Horizontal, 0, 1, true), + WidgetBase(WidgetBase::Type_Frame), _client(client), - _screen(otk::OBDisplay::screenInfo(client->screen())), - _plate(this, OBWidget::Type_Plate), - _titlebar(this, OBWidget::Type_Titlebar), - _button_close(&_titlebar, OBWidget::Type_CloseButton), - _button_iconify(&_titlebar, OBWidget::Type_IconifyButton), - _button_max(&_titlebar, OBWidget::Type_MaximizeButton), - _button_stick(&_titlebar, OBWidget::Type_StickyButton), - _label(&_titlebar, OBWidget::Type_Label), - _handle(this, OBWidget::Type_Handle), - _grip_left(&_handle, OBWidget::Type_LeftGrip), - _grip_right(&_handle, OBWidget::Type_RightGrip), + _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); - XSelectInput(otk::OBDisplay::display, window(), OBFrame::event_mask); - - _grip_left.setCursor(Openbox::instance->cursors().ll_angle); - _grip_right.setCursor(Openbox::instance->cursors().lr_angle); + 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; setStyle(style); - otk::OtkWidget::unfocus(); // stuff starts out appearing focused in otk + otk::Widget::unfocus(); // stuff starts out appearing focused in otk _plate.show(); // the other stuff is shown based on decor settings - - grabClient(); } -OBFrame::~OBFrame() +Frame::~Frame() { - releaseClient(false); } -void OBFrame::setTitle(const std::string &text) +void Frame::setTitle(const otk::ustring &text) { _label.setText(text); _label.update(); } -void OBFrame::setStyle(otk::Style *style) +void Frame::setStyle(otk::RenderStyle *style) { assert(style); - otk::OtkWidget::setStyle(style); - // if a style was previously set, then 'replace' is true, cause we're // replacing a style bool replace = (_style); + otk::Widget::setStyle(style); + if (replace) { // XXX: do shit here whatever } _style = style; - setBorderColor(_style->getBorderColor()); + setBorderColor(_style->frameBorderColor()); // if !replace, then adjust() will get called after the client is grabbed! if (replace) { @@ -101,28 +98,27 @@ void OBFrame::setStyle(otk::Style *style) } -void OBFrame::focus() +void Frame::focus() { - otk::OtkWidget::focus(); + otk::Widget::focus(); update(); - _handle.update(); } -void OBFrame::unfocus() +void Frame::unfocus() { - otk::OtkWidget::unfocus(); + otk::Widget::unfocus(); update(); } -void OBFrame::adjust() +void Frame::adjust() { // the party all happens in adjustSize } -void OBFrame::adjustSize() +void Frame::adjustSize() { // XXX: only if not overridden or something!!! MORE LOGIC HERE!! _decorations = _client->decorations(); @@ -132,11 +128,13 @@ void OBFrame::adjustSize() int width; // the width of the client and its border int bwidth; // width to make borders int cbwidth; // width of the inner client border - const int bevel = _style->getBevelWidth(); + int fontheight = _style->labelFont()->height(); // height of the font + int butsize = fontheight - 2; // width and height of the titlebar buttons + const int bevel = _style->bevelWidth(); - if (_decorations & OBClient::Decor_Border) { - bwidth = _style->getBorderWidth(); - cbwidth = _style->getFrameWidth(); + if (_decorations & Client::Decor_Border) { + bwidth = _style->frameBorderWidth(); + cbwidth = _style->clientBorderWidth(); } else bwidth = cbwidth = 0; _innersize.left = _innersize.top = _innersize.bottom = _innersize.right = @@ -151,38 +149,30 @@ void OBFrame::adjustSize() _grip_right.setBorderWidth(bwidth); _handle.setBorderWidth(bwidth); - if (_decorations & OBClient::Decor_Titlebar) { + if (_decorations & Client::Decor_Titlebar) { // set the titlebar size _titlebar.setGeometry(-bwidth, -bwidth, width, - _style->getFont()->height() + bevel * 2); + _style->labelFont()->height() + (bevel * 2)); _innersize.top += _titlebar.height() + bwidth; // set the label size - _label.setGeometry(0, bevel, width, _style->getFont()->height()); + _label.setGeometry(0, bevel, width, fontheight); // set the buttons sizes - if (_decorations & OBClient::Decor_Iconify) - _button_iconify.setGeometry(0, bevel + 1, - _label.height() - 2, - _label.height() - 2); - if (_decorations & OBClient::Decor_Maximize) - _button_max.setGeometry(0, bevel + 1, - _label.height() - 2, - _label.height() - 2); - if (_decorations & OBClient::Decor_Sticky) - _button_stick.setGeometry(0, bevel + 1, - _label.height() - 2, - _label.height() - 2); - if (_decorations & OBClient::Decor_Close) - _button_close.setGeometry(0, bevel + 1, - _label.height() - 2, - _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 = bevel + 1; - std::string layout; + otk::ustring layout; if (!python_get_string("titlebar_layout", &layout)) layout = "ILMC"; @@ -192,50 +182,55 @@ void OBFrame::adjustSize() bool tit_l = false; for (std::string::size_type i = 0; i < layout.size(); ++i) { - switch(layout[i]) { + switch (layout[i]) { case 'i': case 'I': - if (!tit_i && (_decorations & OBClient::Decor_Iconify)) { + 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 & OBClient::Decor_Maximize)) { + if (!tit_m && (_decorations & Client::Decor_Maximize)) { tit_m = true; continue; } - case 's': - case 'S': - if (!tit_s && (_decorations & OBClient::Decor_Sticky)) { + 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 & OBClient::Decor_Close)) { + 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'; + 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. int lwidth = width - sep * 2 - - (_button_iconify.width() + sep) * (layout.size() - 1); + (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? @@ -243,24 +238,29 @@ void OBFrame::adjustSize() _label.setWidth(lwidth); int x = sep; - for (int i = 0, len = layout.size(); i < len; ++i) { + for (std::string::size_type i = 0, len = layout.size(); i < len; ++i) { switch (layout[i]) { + case 'i': case 'I': _button_iconify.move(x, _button_iconify.rect().y()); x += _button_iconify.width(); break; + case 'l': case 'L': _label.move(x, _label.rect().y()); x += _label.width(); break; + case 'm': case 'M': _button_max.move(x, _button_max.rect().y()); x += _button_max.width(); break; - case 'S': - _button_stick.move(x, _button_stick.rect().y()); - x += _button_stick.width(); + case 'd': + case 'D': + _button_alldesk.move(x, _button_alldesk.rect().y()); + x += _button_alldesk.width(); break; + case 'c': case 'C': _button_close.move(x, _button_close.rect().y()); x += _button_close.width(); @@ -272,22 +272,18 @@ void OBFrame::adjustSize() } } - if (_decorations & OBClient::Decor_Handle) { + if (_decorations & Client::Decor_Handle) { _handle.setGeometry(-bwidth, _innersize.top + _client->area().height() + cbwidth, - width, _style->getHandleWidth()); + width, _style->handleWidth()); _grip_left.setGeometry(-bwidth, -bwidth, - // XXX: get a Point class in otk and use that for - // the 'buttons size' since theyre all the same - _button_iconify.width() * 2, + butsize * 2, _handle.height()); _grip_right.setGeometry(((_handle.rect().right() + 1) - - _button_iconify.width() * 2), + butsize * 2), -bwidth, - // XXX: get a Point class in otk and use that for - // the 'buttons size' since theyre all the same - _button_iconify.width() * 2, + butsize * 2, _handle.height()); _innersize.bottom += _handle.height() + bwidth; } @@ -306,7 +302,7 @@ void OBFrame::adjustSize() _client->area().width(), _client->area().height()); // map/unmap all the windows - if (_decorations & OBClient::Decor_Titlebar) { + if (_decorations & Client::Decor_Titlebar) { _label.show(); if (tit_i) _button_iconify.show(); @@ -317,9 +313,9 @@ void OBFrame::adjustSize() else _button_max.hide(); if (tit_s) - _button_stick.show(); + _button_alldesk.show(); else - _button_stick.hide(); + _button_alldesk.hide(); if (tit_c) _button_close.show(); else @@ -329,7 +325,7 @@ void OBFrame::adjustSize() _titlebar.hide(true); } - if (_decorations & OBClient::Decor_Handle) + if (_decorations & Client::Decor_Handle) _handle.show(true); else _handle.hide(true); @@ -345,29 +341,31 @@ void OBFrame::adjustSize() } -void OBFrame::adjustPosition() +void Frame::adjustPosition() { int x, y; + x = _client->area().x(); + y = _client->area().y(); clientGravity(x, y); move(x, y); } -void OBFrame::adjustShape() +void Frame::adjustShape() { #ifdef SHAPE - int bwidth = (_decorations & OBClient::Decor_Border) ? - _style->getBorderWidth() : 0; + 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, + 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, + XShapeCombineShape(**otk::display, _window, ShapeBounding, _innersize.left, _innersize.top, _client->window(), ShapeBounding, ShapeSet); @@ -375,7 +373,7 @@ void OBFrame::adjustShape() int num = 0; XRectangle xrect[2]; - if (_decorations & OBClient::Decor_Titlebar) { + 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! @@ -383,7 +381,7 @@ void OBFrame::adjustShape() ++num; } - if (_decorations & OBClient::Decor_Handle) { + 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! @@ -391,7 +389,7 @@ void OBFrame::adjustShape() ++num; } - XShapeCombineRectangles(otk::OBDisplay::display, window(), + XShapeCombineRectangles(**otk::display, window(), ShapeBounding, 0, 0, xrect, num, ShapeUnion, Unsorted); } @@ -399,53 +397,61 @@ void OBFrame::adjustShape() } -void OBFrame::grabClient() +void Frame::adjustState() { - - // reparent the client to the frame - XReparentWindow(otk::OBDisplay::display, _client->window(), - _plate.window(), 0, 0); - _client->ignore_unmaps++; + _button_alldesk.update(); + _button_max.update(); +} + - // select the event mask on the client's parent (to receive config req's) - XSelectInput(otk::OBDisplay::display, _plate.window(), - SubstructureRedirectMask); +void Frame::grabClient() +{ + // reparent the client to the frame + 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; + + // 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::OBDisplay::display, _client->window()); + XMapWindow(**otk::display, _client->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(), + // 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()); } -void OBFrame::clientGravity(int &x, int &y) +void Frame::clientGravity(int &x, int &y) { - x = _client->area().x(); - y = _client->area().y(); - // horizontal switch (_client->gravity()) { default: @@ -500,11 +506,8 @@ void OBFrame::clientGravity(int &x, int &y) } -void OBFrame::frameGravity(int &x, int &y) +void Frame::frameGravity(int &x, int &y) { - x = rect().x(); - y = rect().y(); - // horizontal switch (_client->gravity()) { default: