X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fframe.cc;h=c5b144c5f3cbd4f8104389cb7529c008a77c8fef;hb=c8e246f8de5af9963b22cc104d22ca10772028dd;hp=a1c40306e252898c9f8066a4aa395811c2c6b573;hpb=7417e2b54e3a213cb47cf9454f5d4456bd03dedb;p=chaz%2Fopenbox diff --git a/src/frame.cc b/src/frame.cc index a1c40306..c5b144c5 100644 --- a/src/frame.cc +++ b/src/frame.cc @@ -24,7 +24,7 @@ namespace ob { const long OBFrame::event_mask; OBFrame::OBFrame(OBClient *client, otk::Style *style) - : otk::OtkWidget(Openbox::instance, style), + : otk::OtkWidget(Openbox::instance, style, Horizontal, 0, 1, true), OBWidget(Type_Frame), _client(client), _screen(otk::OBDisplay::screenInfo(client->screen())), @@ -43,8 +43,8 @@ OBFrame::OBFrame(OBClient *client, otk::Style *style) assert(client); assert(style); - XSelectInput(otk::OBDisplay::display, window(), OBFrame::event_mask); - + XSelectInput(otk::OBDisplay::display, _window, OBFrame::event_mask); + _grip_left.setCursor(Openbox::instance->cursors().ll_angle); _grip_right.setCursor(Openbox::instance->cursors().lr_angle); @@ -56,14 +56,11 @@ OBFrame::OBFrame(OBClient *client, otk::Style *style) otk::OtkWidget::unfocus(); // stuff starts out appearing focused in otk _plate.show(); // the other stuff is shown based on decor settings - - grabClient(); } OBFrame::~OBFrame() { - releaseClient(false); } @@ -105,7 +102,6 @@ void OBFrame::focus() { otk::OtkWidget::focus(); update(); - _handle.update(); } @@ -126,13 +122,13 @@ void OBFrame::adjustSize() { // XXX: only if not overridden or something!!! MORE LOGIC HERE!! _decorations = _client->decorations(); - _decorations = 0xffffffff; // 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->getBevelWidth(); if (_decorations & OBClient::Decor_Border) { @@ -163,22 +159,15 @@ void OBFrame::adjustSize() // set the label size _label.setGeometry(0, bevel, width, _style->getFont()->height()); // set the buttons sizes + butsize = _label.height() - 2; if (_decorations & OBClient::Decor_Iconify) - _button_iconify.setGeometry(0, bevel + 1, - _label.height() - 2, - _label.height() - 2); + _button_iconify.setGeometry(0, bevel + 1, butsize, butsize); if (_decorations & OBClient::Decor_Maximize) - _button_max.setGeometry(0, bevel + 1, - _label.height() - 2, - _label.height() - 2); + _button_max.setGeometry(0, bevel + 1, butsize, butsize); if (_decorations & OBClient::Decor_Sticky) - _button_stick.setGeometry(0, bevel + 1, - _label.height() - 2, - _label.height() - 2); + _button_stick.setGeometry(0, bevel + 1, butsize, butsize); if (_decorations & OBClient::Decor_Close) - _button_close.setGeometry(0, bevel + 1, - _label.height() - 2, - _label.height() - 2); + _button_close.setGeometry(0, bevel + 1, butsize, butsize); // separation between titlebar elements const int sep = bevel + 1; @@ -193,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)) { 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)) { tit_m = true; continue; } + break; case 's': case 'S': if (!tit_s && (_decorations & OBClient::Decor_Sticky)) { tit_s = true; continue; } + break; case 'c': case 'C': if (!tit_c && (_decorations & OBClient::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.append(1, '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? @@ -244,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': case 'S': _button_stick.move(x, _button_stick.rect().y()); x += _button_stick.width(); break; + case 'c': case 'C': _button_close.move(x, _button_close.rect().y()); x += _button_close.width(); @@ -281,14 +280,14 @@ void OBFrame::adjustSize() -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; } @@ -362,13 +361,13 @@ void OBFrame::adjustShape() if (!_client->shaped()) { // clear the shape on the frame window - XShapeCombineMask(otk::OBDisplay::display, window(), ShapeBounding, + XShapeCombineMask(otk::OBDisplay::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::OBDisplay::display, _window, ShapeBounding, _innersize.left, _innersize.top, _client->window(), ShapeBounding, ShapeSet); @@ -402,11 +401,19 @@ void OBFrame::adjustShape() void OBFrame::grabClient() { - // reparent the client to the frame XReparentWindow(otk::OBDisplay::display, _client->window(), _plate.window(), 0, 0); - _client->ignore_unmaps++; + /* + 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::instance->state() == Openbox::State_Starting) + _client->ignore_unmaps += 2; // select the event mask on the client's parent (to receive config req's) XSelectInput(otk::OBDisplay::display, _plate.window(), @@ -420,25 +427,23 @@ void OBFrame::grabClient() } -void OBFrame::releaseClient(bool remap) +void OBFrame::releaseClient() { - // check if the app has already reparented its window to the root window XEvent ev; + + // check if the app has already reparented its window away if (XCheckTypedWindowEvent(otk::OBDisplay::display, _client->window(), ReparentNotify, &ev)) { - remap = true; // XXX: why do we remap the window if they already - // reparented to root? + XPutBackEvent(otk::OBDisplay::display, &ev); + // re-map the window since the unmanaging process unmaps it + XMapWindow(otk::OBDisplay::display, _client->window()); } else { - // according to the ICCCM - if the client doesn't reparent to - // root, then we have to do it for them + // according to the ICCCM - if the client doesn't reparent itself, then we + // will reparent the window to root for them XReparentWindow(otk::OBDisplay::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()); }