X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fclient.cc;h=3939b0c61ada1b63278e7d0691ccf392da3cf722;hb=ee356f4265d09a542d77474ac2f4b5057e7d04fe;hp=533a9c321055f03b5affbd44fec6d4a9de72e5c9;hpb=3e21214a1d2f7e7c4f35ccc9f8f033d4d263e41a;p=chaz%2Fopenbox diff --git a/src/client.cc b/src/client.cc index 533a9c32..3939b0c6 100644 --- a/src/client.cc +++ b/src/client.cc @@ -23,6 +23,8 @@ extern "C" { #define _(str) gettext(str) } +#include + namespace ob { Client::Client(int screen, Window window) @@ -47,6 +49,8 @@ Client::Client(int screen, Window window) _layer = Layer_Normal; // default to not urgent _urgent = false; + // not positioned unless specified + _positioned = false; getArea(); getDesktop(); @@ -113,6 +117,21 @@ Client::~Client() } +bool Client::validate() const +{ + XSync(**otk::display, false); // get all events on the server + + XEvent e; + if (XCheckTypedWindowEvent(**otk::display, _window, DestroyNotify, &e) || + XCheckTypedWindowEvent(**otk::display, _window, UnmapNotify, &e)) { + XPutBackEvent(**otk::display, &e); + return false; + } + + return true; +} + + void Client::getGravity() { XWindowAttributes wattrib; @@ -133,7 +152,7 @@ void Client::getDesktop() otk::Property::atoms.cardinal, (long unsigned*)&_desktop)) { #ifdef DEBUG - printf("DEBUG: Window requested desktop: %ld\n", _desktop); +// printf("Window requested desktop: %ld\n", _desktop); #endif } } @@ -198,6 +217,11 @@ void Client::setupDecorAndFunctions() _decorations |= Decor_Close; _functions |= Func_Close; } + + if (_min_size.x() > _max_size.x() || _min_size.y() > _max_size.y()) { + _decorations &= ~Decor_Maximize; + _functions &= ~(Func_Resize | Func_Maximize); + } switch (_type) { case Type_Normal: @@ -418,6 +442,8 @@ void Client::updateNormalHints() int oldgravity = _gravity; // defaults + _min_ratio = 0.0; + _max_ratio = 0.0; _size_inc.setPoint(1, 1); _base_size.setPoint(0, 0); _min_size.setPoint(0, 0); @@ -443,6 +469,11 @@ void Client::updateNormalHints() } } + if (size.flags & PAspect) { + if (size.min_aspect.y) _min_ratio = size.min_aspect.x/size.min_aspect.y; + if (size.max_aspect.y) _max_ratio = size.max_aspect.x/size.max_aspect.y; + } + if (size.flags & PMinSize) _min_size.setPoint(size.min_width, size.min_height); @@ -497,7 +528,7 @@ void Client::updateWMHints(bool initstate) #endif // fire the urgent callback if we're mapped, otherwise, wait until after // we're mapped - if (_urgent && frame) + if (frame) fireUrgent(); } } @@ -575,8 +606,8 @@ void Client::updateStrut() _strut.left = data[0]; _strut.right = data[1]; _strut.top = data[2]; - _strut.bottom = data[3]; - + _strut.bottom = data[3]; + openbox->screen(_screen)->updateStrut(); } @@ -622,6 +653,9 @@ void Client::updateTransientFor() void Client::propertyHandler(const XPropertyEvent &e) { otk::EventHandler::propertyHandler(e); + + // validate cuz we query stuff off the client here + if (!validate()) return; // compress changes to a single property into a single change XEvent ce; @@ -634,9 +668,10 @@ void Client::propertyHandler(const XPropertyEvent &e) } } - if (e.atom == XA_WM_NORMAL_HINTS) + if (e.atom == XA_WM_NORMAL_HINTS) { updateNormalHints(); - else if (e.atom == XA_WM_HINTS) + setupDecorAndFunctions(); // normal hints can make a window non-resizable + } else if (e.atom == XA_WM_HINTS) updateWMHints(); else if (e.atom == XA_WM_TRANSIENT_FOR) { updateTransientFor(); @@ -895,6 +930,9 @@ void Client::clientMessageHandler(const XClientMessageEvent &e) { otk::EventHandler::clientMessageHandler(e); + // validate cuz we query stuff off the client here + if (!validate()) return; + if (e.format != 32) return; if (e.message_type == otk::Property::atoms.wm_change_state) { @@ -980,7 +1018,8 @@ void Client::resize(Corner anchor, int w, int h) } -void Client::internal_resize(Corner anchor, int w, int h, int x, int y) +void Client::internal_resize(Corner anchor, int w, int h, bool user, + int x, int y) { w -= _base_size.x(); h -= _base_size.y(); @@ -990,14 +1029,21 @@ void Client::internal_resize(Corner anchor, int w, int h, int x, int y) w += _size_inc.x() / 2; h += _size_inc.y() / 2; - // is the window resizable? if it is not, then don't check its sizes, the - // client can do what it wants and the user can't change it anyhow - if (_min_size.x() <= _max_size.x() && _min_size.y() <= _max_size.y()) { + if (user) { + // if this is a user-requested resize, then check against min/max sizes + // 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(); + + // adjust the height ot match the width for the aspect ratios + if (_min_ratio) + if (h * _min_ratio > w) h = static_cast(w / _min_ratio); + if (_max_ratio) + if (h * _max_ratio < w) h = static_cast(w / _max_ratio); } // keep to the increments @@ -1181,7 +1227,6 @@ void Client::applyStartupState() // these are in a carefully crafted order.. if (_iconic) { - printf("MAP ICONIC\n"); _iconic = false; setDesktop(ICONIC_DESKTOP); } @@ -1209,8 +1254,8 @@ void Client::applyStartupState() void Client::fireUrgent() { - // call the python UrgentNotify callbacks - EventData data(_screen, this, EventUrgentNotify, 0); + // call the python UrgentWindow callbacks + EventData data(_screen, this, EventAction::UrgentWindow, 0); openbox->bindings()->fireEvent(&data); } @@ -1321,6 +1366,7 @@ bool Client::focus() XSendEvent(**otk::display, _window, False, NoEventMask, &ce); } + XSync(**otk::display, False); return true; } @@ -1405,9 +1451,9 @@ void Client::configureRequestHandler(const XConfigureRequestEvent &e) if (e.value_mask & (CWX | CWY)) { int x = (e.value_mask & CWX) ? e.x : _area.x(); int y = (e.value_mask & CWY) ? e.y : _area.y(); - internal_resize(corner, w, h, x, y); + internal_resize(corner, w, h, false, x, y); } else // if JUST resizing... - internal_resize(corner, w, h); + internal_resize(corner, w, h, false); } else if (e.value_mask & (CWX | CWY)) { // if JUST moving... int x = (e.value_mask & CWX) ? e.x : _area.x(); int y = (e.value_mask & CWY) ? e.y : _area.y(); @@ -1435,7 +1481,7 @@ void Client::unmapHandler(const XUnmapEvent &e) { if (ignore_unmaps) { #ifdef DEBUG - printf("Ignored UnmapNotify for 0x%lx (event 0x%lx)\n", e.window, e.event); +// printf("Ignored UnmapNotify for 0x%lx (event 0x%lx)\n", e.window, e.event); #endif // DEBUG ignore_unmaps--; return;