+void BlackboxWindow::constrain(Corner anchor, int *pw, int *ph) {
+ // frame.changing represents the requested frame size, we need to
+ // strip the frame margin off and constrain the client size
+ frame.changing.setCoords(frame.changing.left() + frame.margin.left,
+ frame.changing.top() + frame.margin.top,
+ frame.changing.right() - frame.margin.right,
+ frame.changing.bottom() - frame.margin.bottom);
+
+ int dw = frame.changing.width(), dh = frame.changing.height(),
+ base_width = (client.base_width) ? client.base_width : client.min_width,
+ base_height = (client.base_height) ? client.base_height :
+ client.min_height;
+
+ // constrain
+ if (dw < static_cast<signed>(client.min_width)) dw = client.min_width;
+ if (dh < static_cast<signed>(client.min_height)) dh = client.min_height;
+ if (dw > static_cast<signed>(client.max_width)) dw = client.max_width;
+ if (dh > static_cast<signed>(client.max_height)) dh = client.max_height;
+
+ dw -= base_width;
+ dw /= client.width_inc;
+ dh -= base_height;
+ dh /= client.height_inc;
+
+ if (pw) {
+ if (client.width_inc == 1)
+ *pw = dw + base_width;
+ else
+ *pw = dw;
+ }
+ if (ph) {
+ if (client.height_inc == 1)
+ *ph = dh + base_height;
+ else
+ *ph = dh;
+ }
+
+ dw *= client.width_inc;
+ dw += base_width;
+ dh *= client.height_inc;
+ dh += base_height;
+
+ frame.changing.setSize(dw, dh);
+
+ // add the frame margin back onto frame.changing
+ frame.changing.setCoords(frame.changing.left() - frame.margin.left,
+ frame.changing.top() - frame.margin.top,
+ frame.changing.right() + frame.margin.right,
+ frame.changing.bottom() + frame.margin.bottom);
+
+ // move frame.changing to the specified anchor
+ int dx = 0,
+ dy = 0;
+ switch (anchor) {
+ case TopLeft:
+ break;
+
+ case TopRight:
+ dx = frame.rect.right() - frame.changing.right();
+ break;
+
+ case BottomLeft:
+ dy = frame.rect.bottom() - frame.changing.bottom();
+ break;
+
+ case BottomRight:
+ dx = frame.rect.right() - frame.changing.right();
+ dy = frame.rect.bottom() - frame.changing.bottom();
+ break;
+
+ default:
+ assert(false); // unhandled corner
+ }
+ frame.changing.setPos(frame.changing.x() + dx, frame.changing.y() + dy);
+}
+
+
+int WindowStyle::doJustify(const char *text, int &start_pos,
+ unsigned int max_length, unsigned int modifier,
+ bool multibyte) const {
+ size_t text_len = strlen(text);
+ unsigned int length;
+
+ do {
+ if (multibyte) {
+ XRectangle ink, logical;
+ XmbTextExtents(fontset, text, text_len, &ink, &logical);
+ length = logical.width;
+ } else {
+ length = XTextWidth(font, text, text_len);
+ }
+ length += modifier;
+ } while (length > max_length && text_len-- > 0);
+
+ switch (justify) {
+ case RightJustify:
+ start_pos += max_length - length;
+ break;