#include "client.hh"
#include "frame.hh"
+#include "screen.hh"
#include "bbscreen.hh"
#include "openbox.hh"
#include "otk/display.hh"
OBClient::OBClient(int screen, Window window)
: otk::OtkEventHandler(),
- _screen(screen), _window(window)
+ OBWidget(OBWidget::Type_Client),
+ frame(0), _screen(screen), _window(window)
{
assert(screen >= 0);
assert(window);
- Openbox::instance->registerHandler(_window, this);
-
ignore_unmaps = 0;
// update EVERYTHING the first time!!
{
XSizeHints size;
long ret;
+ int oldgravity = _gravity;
// defaults
_gravity = NorthWestGravity;
if (size.flags & PWinGravity)
_gravity = size.win_gravity;
-
+
if (size.flags & PMinSize)
_min_size.setPoint(size.min_width, size.min_height);
if (size.flags & PResizeInc)
_size_inc.setPoint(size.width_inc, size.height_inc);
}
+
+ // if the client has a frame, i.e. has already been mapped and is
+ // changing its gravity
+ if (frame && _gravity != oldgravity) {
+ // move our idea of the client's position based on its new gravity
+ int x, y;
+ frame->frameGravity(x, y);
+ _area.setPos(x, y);
+ }
}
}
+void OBClient::toggleClientBorder(bool addborder)
+{
+ // adjust our idea of where the client is, based on its border. When the
+ // border is removed, the client should now be considered to be in a
+ // different position.
+ // when re-adding the border to the client, the same operation needs to be
+ // reversed.
+ int x = _area.x(), y = _area.y();
+ switch(_gravity) {
+ case NorthWestGravity:
+ case WestGravity:
+ case SouthWestGravity:
+ if (addborder) x += _border_width;
+ else x -= _border_width;
+ break;
+ case NorthEastGravity:
+ case EastGravity:
+ case SouthEastGravity:
+ if (addborder) x -= _border_width * 2;
+ else x += _border_width * 2;
+ break;
+ }
+ switch(_gravity) {
+ case NorthWestGravity:
+ case NorthGravity:
+ case NorthEastGravity:
+ if (addborder) y += _border_width;
+ else y -= _border_width;
+ break;
+ case SouthWestGravity:
+ case SouthGravity:
+ case SouthEastGravity:
+ if (addborder) y -= _border_width * 2;
+ else y += _border_width * 2;
+ break;
+ default:
+ // no change for StaticGravity etc.
+ break;
+ }
+ _area.setPos(x, y);
+
+ if (addborder) {
+ XSetWindowBorderWidth(otk::OBDisplay::display, _window, _border_width);
+
+ // move the client so it is back it the right spot _with_ its border!
+ XMoveWindow(otk::OBDisplay::display, _window, x, y);
+ } else
+ XSetWindowBorderWidth(otk::OBDisplay::display, _window, 0);
+}
+
+
void OBClient::clientMessageHandler(const XClientMessageEvent &e)
{
otk::OtkEventHandler::clientMessageHandler(e);
w -= _base_size.x();
h -= _base_size.y();
+ // for interactive resizing. have to move half an increment in each
+ // direction.
+ 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()) {
w += _base_size.x();
h += _base_size.y();
-
+
+ int x = _area.x(), y = _area.y();
switch (anchor) {
case TopLeft:
break;
case TopRight:
- _area.setX(_area.x() - _area.width() - w);
+ x -= w - _area.width();
break;
case BottomLeft:
- _area.setY(_area.y() - _area.height() - h);
+ y -= h - _area.height();
break;
case BottomRight:
- _area.setX(_area.x() - _area.width() - w);
- _area.setY(_area.y() - _area.height() - h);
+ x -= w - _area.width();
+ y -= h - _area.height();
break;
}
_area.setSize(w, h);
+ XResizeWindow(otk::OBDisplay::display, _window, w, h);
- // resize the frame to match
- frame->adjust();
+ // resize the frame to match the request
+ frame->adjustSize();
+ move(x, y);
}
{
_area.setPos(x, y);
// move the frame to be in the requested position
- frame->applyGravity();
+ frame->adjustPosition();
}
void OBClient::configureRequestHandler(const XConfigureRequestEvent &e)
{
+ OtkEventHandler::configureRequestHandler(e);
+
// XXX: if we are iconic (or shaded? (fvwm does that)) ignore the event
if (e.value_mask & CWBorderWidth)
}
+void OBClient::unmapHandler(const XUnmapEvent &e)
+{
+#ifdef DEBUG
+ printf("UnmapNotify for 0x%lx\n", e.window);
+#endif // DEBUG
+
+ if (ignore_unmaps) {
+ ignore_unmaps--;
+ return;
+ }
+
+ OtkEventHandler::unmapHandler(e);
+
+ // this deletes us etc
+ Openbox::instance->screen(_screen)->unmanageWindow(this);
+}
+
+
+void OBClient::destroyHandler(const XDestroyWindowEvent &e)
+{
+#ifdef DEBUG
+ printf("DestroyNotify for 0x%lx\n", e.window);
+#endif // DEBUG
+
+ OtkEventHandler::destroyHandler(e);
+
+ // this deletes us etc
+ Openbox::instance->screen(_screen)->unmanageWindow(this);
+}
+
+
}