X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fclient.cc;h=d5be00d01822b8b64f7796180eeea9f0035dfda0;hb=c54d92b784036a4d9e829592aab938e661287fca;hp=d42a962a8f9bcca3f05a212a4633f9b557c08394;hpb=51a41b9b765dbcf76ec09324f533d8c8edd46e37;p=chaz%2Fopenbox diff --git a/src/client.cc b/src/client.cc index d42a962a..d5be00d0 100644 --- a/src/client.cc +++ b/src/client.cc @@ -17,19 +17,18 @@ extern "C" { #include #include -#include - #include "gettext.h" #define _(str) gettext(str) } +#include +#include #include namespace ob { Client::Client(int screen, Window window) : otk::EventHandler(), - WidgetBase(WidgetBase::Type_Client), frame(0), _screen(screen), _window(window) { assert(screen >= 0); @@ -221,7 +220,8 @@ void Client::setupDecorAndFunctions() _functions |= Func_Close; } - if (!(_min_size.x() < _max_size.x() || _min_size.y() < _max_size.y())) { + if (!(_min_size.width() < _max_size.width() || + _min_size.height() < _max_size.height())) { _decorations &= ~(Decor_Maximize | Decor_Handle); _functions &= ~(Func_Resize | Func_Maximize); } @@ -264,11 +264,8 @@ void Client::setupDecorAndFunctions() _decorations &= ~Decor_Border; if (! (_mwmhints.decorations & MwmDecor_Handle)) _decorations &= ~Decor_Handle; - if (! (_mwmhints.decorations & MwmDecor_Title)) { + if (! (_mwmhints.decorations & MwmDecor_Title)) _decorations &= ~Decor_Titlebar; - // if we don't have a titlebar, then we cannot shade! - _functions &= ~Func_Shade; - } if (! (_mwmhints.decorations & MwmDecor_Iconify)) _decorations &= ~Decor_Iconify; if (! (_mwmhints.decorations & MwmDecor_Maximize)) @@ -313,16 +310,17 @@ void Client::setupDecorAndFunctions() if (_disabled_decorations & Decor_Close) _decorations &= ~Decor_Close; - // You can't shade without a titlebar + // if we don't have a titlebar, then we cannot shade! if (!(_decorations & Decor_Titlebar)) _functions &= ~Func_Shade; - + changeAllowedActions(); if (frame) { frame->adjustSize(); // change the decors on the frame frame->adjustPosition(); // with more/less decorations, we may need to be // moved + remaximize(); // with new decor, the window's maximized size may change } } @@ -358,7 +356,7 @@ void Client::getArea() ret = XGetWindowAttributes(**otk::display, _window, &wattrib); assert(ret != BadWindow); - _area.setRect(wattrib.x, wattrib.y, wattrib.width, wattrib.height); + _area = otk::Rect(wattrib.x, wattrib.y, wattrib.width, wattrib.height); _border_width = wattrib.border_width; } @@ -479,10 +477,10 @@ void Client::updateNormalHints() // defaults _min_ratio = 0.0; _max_ratio = 0.0; - _size_inc.setPoint(1, 1); - _base_size.setPoint(0, 0); - _min_size.setPoint(0, 0); - _max_size.setPoint(INT_MAX, INT_MAX); + _size_inc = otk::Size(1, 1); + _base_size = otk::Size(0, 0); + _min_size = otk::Size(0, 0); + _max_size = otk::Size(UINT_MAX, UINT_MAX); // get the hints from the window if (XGetWMNormalHints(**otk::display, _window, &size, &ret)) { @@ -495,9 +493,9 @@ void Client::updateNormalHints() // changing its gravity if (frame && _gravity != oldgravity) { // move our idea of the client's position based on its new gravity - int x = frame->rect().x(), y = frame->rect().y(); + int x = frame->area().x(), y = frame->area().y(); frame->frameGravity(x, y); - _area.setPos(x, y); + _area = otk::Rect(otk::Point(x, y), _area.size()); } } @@ -507,16 +505,16 @@ void Client::updateNormalHints() } if (size.flags & PMinSize) - _min_size.setPoint(size.min_width, size.min_height); + _min_size = otk::Size(size.min_width, size.min_height); if (size.flags & PMaxSize) - _max_size.setPoint(size.max_width, size.max_height); + _max_size = otk::Size(size.max_width, size.max_height); if (size.flags & PBaseSize) - _base_size.setPoint(size.base_width, size.base_height); + _base_size = otk::Size(size.base_width, size.base_height); if (size.flags & PResizeInc) - _size_inc.setPoint(size.width_inc, size.height_inc); + _size_inc = otk::Size(size.width_inc, size.height_inc); } } @@ -582,7 +580,7 @@ void Client::updateTitle() _title = _("Unnamed Window"); if (frame) - frame->setTitle(_title); + frame->adjustTitle(); } @@ -1014,7 +1012,7 @@ void Client::toggleClientBorder(bool addborder) else y += _border_width; break; } - _area.setPos(x, y); + _area = otk::Rect(otk::Point(x, y), _area.size()); if (addborder) { XSetWindowBorderWidth(**otk::display, _window, _border_width); @@ -1119,29 +1117,36 @@ void Client::shapeHandler(const XShapeEvent &e) #endif -void Client::resize(Corner anchor, int w, int h) +void Client::resize(Corner anchor, unsigned int w, unsigned int h) { if (!(_functions & Func_Resize)) return; internal_resize(anchor, w, h); } -void Client::internal_resize(Corner anchor, int w, int h, bool user, - int x, int y) +void Client::internal_resize(Corner anchor, unsigned int w, unsigned int h, + bool user, int x, int y) { - w -= _base_size.x(); - h -= _base_size.y(); + if (_base_size.width() < w) + w -= _base_size.width(); + else + w = 0; + if (_base_size.height() < h) + h -= _base_size.height(); + else + h = 0; if (user) { // for interactive resizing. have to move half an increment in each // direction. - int mw = w % _size_inc.x(); // how far we are towards the next size inc - int mh = h % _size_inc.y(); - int aw = _size_inc.x() / 2; // amount to add - int ah = _size_inc.y() / 2; + unsigned int mw = w % _size_inc.width(); // how far we are towards the next + // size inc + unsigned int mh = h % _size_inc.height(); + unsigned int aw = _size_inc.width() / 2; // amount to add + unsigned int ah = _size_inc.height() / 2; // don't let us move into a new size increment - if (mw + aw >= _size_inc.x()) aw = _size_inc.x() - mw - 1; - if (mh + ah >= _size_inc.y()) ah = _size_inc.y() - mh - 1; + if (mw + aw >= _size_inc.width()) aw = _size_inc.width() - mw - 1; + if (mh + ah >= _size_inc.height()) ah = _size_inc.height() - mh - 1; w += aw; h += ah; @@ -1149,10 +1154,10 @@ void Client::internal_resize(Corner anchor, int w, int h, bool user, // and aspect ratios // smaller than min size or bigger than max size? - if (w < _min_size.x()) w = _min_size.x(); - else if (w > _max_size.x()) w = _max_size.x(); - if (h < _min_size.y()) h = _min_size.y(); - else if (h > _max_size.y()) h = _max_size.y(); + if (w < _min_size.width()) w = _min_size.width(); + else if (w > _max_size.width()) w = _max_size.width(); + if (h < _min_size.height()) h = _min_size.height(); + else if (h > _max_size.height()) h = _max_size.height(); // adjust the height ot match the width for the aspect ratios if (_min_ratio) @@ -1162,21 +1167,21 @@ void Client::internal_resize(Corner anchor, int w, int h, bool user, } // keep to the increments - w /= _size_inc.x(); - h /= _size_inc.y(); + w /= _size_inc.width(); + h /= _size_inc.height(); // you cannot resize to nothing if (w < 1) w = 1; if (h < 1) h = 1; // store the logical size - _logical_size.setPoint(w, h); + _logical_size = otk::Size(w, h); - w *= _size_inc.x(); - h *= _size_inc.y(); + w *= _size_inc.width(); + h *= _size_inc.height(); - w += _base_size.x(); - h += _base_size.y(); + w += _base_size.width(); + h += _base_size.height(); if (x == INT_MIN || y == INT_MIN) { x = _area.x(); @@ -1197,7 +1202,7 @@ void Client::internal_resize(Corner anchor, int w, int h, bool user, } } - _area.setSize(w, h); + _area = otk::Rect(_area.position(), otk::Size(w, h)); XResizeWindow(**otk::display, _window, w, h); @@ -1218,7 +1223,7 @@ void Client::move(int x, int y) void Client::internal_move(int x, int y) { - _area.setPos(x, y); + _area = otk::Rect(otk::Point(x, y), _area.size()); // move the frame to be in the requested position if (frame) { // this can be called while mapping, before frame exists @@ -1344,6 +1349,21 @@ void Client::changeAllowedActions(void) otk::Property::set(_window, otk::Property::atoms.net_wm_allowed_actions, otk::Property::atoms.atom, actions, num); + + // make sure the window isn't breaking any rules now + + if (!(_functions & Func_Shade) && _shaded) + if (frame) shade(false); + else _shaded = false; + if (!(_functions & Func_Iconify) && _iconic) + if (frame) setDesktop(openbox->screen(_screen)->desktop()); + else _iconic = false; + if (!(_functions & Func_Fullscreen) && _fullscreen) + if (frame) fullscreen(false); + else _fullscreen = false; + if (!(_functions & Func_Maximize) && (_max_horz || _max_vert)) + if (frame) maximize(false, 0); + else _max_vert = _max_horz = false; } @@ -1445,7 +1465,7 @@ void Client::maximize(bool max, int dir, bool savearea) } const otk::Rect &a = openbox->screen(_screen)->area(); - int x = frame->rect().x(), y = frame->rect().y(), + int x = frame->area().x(), y = frame->area().y(), w = _area.width(), h = _area.height(); if (max) { @@ -1568,8 +1588,8 @@ void Client::fullscreen(bool fs, bool savearea) const otk::ScreenInfo *info = otk::display->screenInfo(_screen); x = 0; y = 0; - w = info->width(); - h = info->height(); + w = info->size().width(); + h = info->size().height(); } else { _functions = saved_func; _decorations = saved_decor; @@ -1637,7 +1657,7 @@ bool Client::focus() // won't try focus if the client doesn't want it, or if the window isn't // visible on the screen - if (!(frame->isVisible() && (_can_focus || _focus_notify))) return false; + if (!(frame->visible() && (_can_focus || _focus_notify))) return false; if (_focused) return true; @@ -1699,8 +1719,8 @@ void Client::focusHandler(const XFocusChangeEvent &e) otk::EventHandler::focusHandler(e); - frame->focus(); _focused = true; + frame->adjustFocus(); openbox->setFocusedClient(this); } @@ -1714,21 +1734,43 @@ void Client::unfocusHandler(const XFocusChangeEvent &e) otk::EventHandler::unfocusHandler(e); - frame->unfocus(); _focused = false; + frame->adjustFocus(); if (openbox->focusedClient() == this) openbox->setFocusedClient(0); } -void Client::configureRequestHandler(const XConfigureRequestEvent &e) +void Client::configureRequestHandler(const XConfigureRequestEvent &ec) { #ifdef DEBUG - printf("ConfigureRequest for 0x%lx\n", e.window); + printf("ConfigureRequest for 0x%lx\n", ec.window); #endif // DEBUG - otk::EventHandler::configureRequestHandler(e); + otk::EventHandler::configureRequestHandler(ec); + + // compress these + XConfigureRequestEvent e = ec; + XEvent ev; + while (XCheckTypedWindowEvent(**otk::display, window(), ConfigureRequest, + &ev)) { + // XXX if this causes bad things.. we can compress config req's with the + // same mask. + e.value_mask |= ev.xconfigurerequest.value_mask; + if (ev.xconfigurerequest.value_mask & CWX) + e.x = ev.xconfigurerequest.x; + if (ev.xconfigurerequest.value_mask & CWY) + e.y = ev.xconfigurerequest.y; + if (ev.xconfigurerequest.value_mask & CWWidth) + e.width = ev.xconfigurerequest.width; + if (ev.xconfigurerequest.value_mask & CWHeight) + e.height = ev.xconfigurerequest.height; + if (ev.xconfigurerequest.value_mask & CWBorderWidth) + e.border_width = ev.xconfigurerequest.border_width; + if (ev.xconfigurerequest.value_mask & CWStackMode) + e.detail = ev.xconfigurerequest.detail; + } // if we are iconic (or shaded (fvwm does this)) ignore the event if (_iconic || _shaded) return;