summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client.cc86
-rw-r--r--src/client.hh13
-rw-r--r--src/frame.cc104
-rw-r--r--src/frame.hh30
-rw-r--r--src/rootwindow.cc21
-rw-r--r--src/rootwindow.hh1
-rw-r--r--src/screen.cc9
7 files changed, 186 insertions, 78 deletions
diff --git a/src/client.cc b/src/client.cc
index aef3dcba..07d75462 100644
--- a/src/client.cc
+++ b/src/client.cc
@@ -26,7 +26,7 @@ namespace ob {
OBClient::OBClient(int screen, Window window)
: otk::OtkEventHandler(),
- _screen(screen), _window(window)
+ frame(0), _screen(screen), _window(window)
{
assert(screen >= 0);
assert(window);
@@ -371,6 +371,7 @@ void OBClient::updateNormalHints()
{
XSizeHints size;
long ret;
+ int oldgravity = _gravity;
// defaults
_gravity = NorthWestGravity;
@@ -388,7 +389,7 @@ void OBClient::updateNormalHints()
if (size.flags & PWinGravity)
_gravity = size.win_gravity;
-
+
if (size.flags & PMinSize)
_min_size.setPoint(size.min_width, size.min_height);
@@ -401,6 +402,15 @@ void OBClient::updateNormalHints()
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);
+ }
}
@@ -651,6 +661,57 @@ void OBClient::setState(StateAction action, long data1, long data2)
}
+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);
@@ -738,26 +799,29 @@ void OBClient::resize(Corner anchor, int w, int h)
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);
}
@@ -765,14 +829,14 @@ void OBClient::move(int x, int 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)
diff --git a/src/client.hh b/src/client.hh
index e07ce12d..37e26cb2 100644
--- a/src/client.hh
+++ b/src/client.hh
@@ -297,10 +297,6 @@ private:
// XXX: updateTransientFor();
//! Move the client window
- /*!
- This shouldnt be used to move the window internally! It will apply
- window gravity after moving the window.
- */
void move(int x, int y);
//! Resizes the client window, anchoring it in a given corner
@@ -409,8 +405,13 @@ public:
*/
inline bool floating() const { return _floating; }
- //! Returns the client's requested border width (not used by the wm)
- inline int borderWidth() const { return _border_width; }
+ //! Removes or reapplies the client's border to its window
+ /*!
+ Used when managing and unmanaging a window.
+ @param addborder true if adding the border to the client; false if removing
+ from the client
+ */
+ void toggleClientBorder(bool addborder);
//! Returns the position and size of the client relative to the root window
inline const otk::Rect &area() const { return _area; }
diff --git a/src/frame.cc b/src/frame.cc
index aa1e868f..15404f93 100644
--- a/src/frame.cc
+++ b/src/frame.cc
@@ -104,7 +104,6 @@ void OBFrame::setStyle(otk::Style *style)
if (replace) {
// XXX: do shit here whatever
- // XXX: save the position based on gravity
}
_style = style;
@@ -125,12 +124,15 @@ void OBFrame::setStyle(otk::Style *style)
_style->getBorderColor()->pixel());
// if !replace, then adjust() will get called after the client is grabbed!
- if (replace)
- adjust(); // size/position everything
+ if (replace) {
+ // size/position everything
+ adjustSize();
+ adjustPosition();
+ }
}
-void OBFrame::adjust()
+void OBFrame::adjustSize()
{
// XXX: only if not overridden or something!!! MORE LOGIC HERE!!
_decorations = _client->decorations();
@@ -311,6 +313,14 @@ void OBFrame::adjust()
}
+void OBFrame::adjustPosition()
+{
+ int x, y;
+ clientGravity(x, y);
+ move(x, y);
+}
+
+
void OBFrame::adjustShape()
{
#ifdef SHAPE
@@ -365,15 +375,15 @@ void OBFrame::grabClient()
_plate.getWindow(), 0, 0);
_client->ignore_unmaps++;
- // select the event mask on the client's parent
- //XSelectInput(otk::OBDisplay::display, _plate.getWindow(),
- // SubstructureRedirectMask);
+ // select the event mask on the client's parent (to receive config req's)
+ XSelectInput(otk::OBDisplay::display, _plate.getWindow(),
+ SubstructureRedirectMask);
// map the client so it maps when the frame does
XMapWindow(otk::OBDisplay::display, _client->window());
- adjust();
- applyGravity();
+ adjustSize();
+ adjustPosition();
}
@@ -399,69 +409,115 @@ void OBFrame::releaseClient(bool remap)
}
-void OBFrame::applyGravity()
+void OBFrame::clientGravity(int &x, int &y)
{
- int x, y;
- // apply horizontal window gravity
+ x = _client->area().x();
+ y = _client->area().y();
+
+ // horizontal
switch (_client->gravity()) {
default:
case NorthWestGravity:
case SouthWestGravity:
case WestGravity:
- x = _client->area().x();
break;
case NorthGravity:
case SouthGravity:
case CenterGravity:
- x = _client->area().x() - (_size.left + _size.right) / 2;
+ x -= (_size.left + _size.right) / 2;
break;
case NorthEastGravity:
case SouthEastGravity:
case EastGravity:
- x = _client->area().x() - _size.left - _size.right + 2;
+ x -= _size.left + _size.right;
break;
case ForgetGravity:
case StaticGravity:
- x = _client->area().x() - _size.left;
+ x -= _size.left;
break;
}
- // apply vertical window gravity
+ // vertical
switch (_client->gravity()) {
default:
case NorthWestGravity:
case NorthEastGravity:
case NorthGravity:
- y = _client->area().y();
break;
case CenterGravity:
case EastGravity:
case WestGravity:
- y = _client->area().y() - (_size.top + _size.bottom) / 2;
+ y -= (_size.top + _size.bottom) / 2;
break;
case SouthWestGravity:
case SouthEastGravity:
case SouthGravity:
- y = _client->area().y() - _size.top - _size.bottom + 2;
+ y -= _size.top + _size.bottom;
break;
case ForgetGravity:
case StaticGravity:
- y = _client->area().y() - _size.top;
+ y -= _size.top;
break;
}
- move(x, y);
}
-void OBFrame::reverseGravity()
+void OBFrame::frameGravity(int &x, int &y)
{
- move(_client->area().x() - _size.left, _client->area().y() - _size.top);
+ x = getRect().x();
+ y = getRect().y();
+
+ // horizontal
+ switch (_client->gravity()) {
+ default:
+ case NorthWestGravity:
+ case WestGravity:
+ case SouthWestGravity:
+ break;
+ case NorthGravity:
+ case CenterGravity:
+ case SouthGravity:
+ x += (_size.left + _size.right) / 2;
+ break;
+ case NorthEastGravity:
+ case EastGravity:
+ case SouthEastGravity:
+ x += _size.left + _size.right;
+ break;
+ case StaticGravity:
+ case ForgetGravity:
+ x += _size.left;
+ break;
+ }
+
+ // vertical
+ switch (_client->gravity()) {
+ default:
+ case NorthWestGravity:
+ case WestGravity:
+ case SouthWestGravity:
+ break;
+ case NorthGravity:
+ case CenterGravity:
+ case SouthGravity:
+ y += (_size.top + _size.bottom) / 2;
+ break;
+ case NorthEastGravity:
+ case EastGravity:
+ case SouthEastGravity:
+ y += _size.top + _size.bottom;
+ break;
+ case StaticGravity:
+ case ForgetGravity:
+ y += _size.top;
+ break;
+ }
}
diff --git a/src/frame.hh b/src/frame.hh
index 1816ad01..7248c71f 100644
--- a/src/frame.hh
+++ b/src/frame.hh
@@ -75,6 +75,9 @@ private:
*/
void releaseClient(bool remap);
+ //! Shape the frame window to the client window
+ void adjustShape();
+
public:
//! Constructs an OBFrame object, and reparents the client to itself
/*!
@@ -88,18 +91,25 @@ public:
//! Set the style to decorate the frame with
virtual void setStyle(otk::Style *style);
- //! Update the frame to match the client
- void adjust();
- //! Shape the frame window to the client window
- void adjustShape();
+ //! Update the frame's size to match the client
+ void adjustSize();
+ //! Update the frame's position to match the client
+ void adjustPosition();
- //! Applies gravity for the client's gravity, moving the frame to the
- //! appropriate place
- void applyGravity();
+ //! Applies gravity to the client's position to find where the frame should
+ //! be positioned.
+ /*!
+ @return The proper coordinates for the frame, based on the client.
+ */
+ void clientGravity(int &x, int &y);
+
+ //! Reversly applies gravity to the frame's position to find where the client
+ //! should be positioned.
+ /*!
+ @return The proper coordinates for the client, based on the frame.
+ */
+ void frameGravity(int &x, int &y);
- //! Reversely applies gravity for the client's gravity, moving the frame so
- //! that the client is in its pre-gravity position
- void reverseGravity();
};
}
diff --git a/src/rootwindow.cc b/src/rootwindow.cc
index 23361761..3fccc44a 100644
--- a/src/rootwindow.cc
+++ b/src/rootwindow.cc
@@ -108,25 +108,4 @@ void OBRootWindow::mapRequestHandler(const XMapRequestEvent &e)
}
}
-
-void OBRootWindow::configureRequestHandler(const XConfigureRequestEvent &e)
-{
- OtkEventHandler::configureRequestHandler(e);
-
- // when configure requests come to the root window, just pass them on
- XWindowChanges xwc;
-
- xwc.x = e.x;
- xwc.y = e.y;
- xwc.width = e.width;
- xwc.height = e.height;
- xwc.border_width = e.border_width;
- xwc.sibling = e.above;
- xwc.stack_mode = e.detail;
-
- XConfigureWindow(otk::OBDisplay::display, e.window,
- e.value_mask, &xwc);
-}
-
-
}
diff --git a/src/rootwindow.hh b/src/rootwindow.hh
index 35cda699..d78f4ff7 100644
--- a/src/rootwindow.hh
+++ b/src/rootwindow.hh
@@ -62,7 +62,6 @@ public:
virtual void propertyHandler(const XPropertyEvent &e);
virtual void clientMessageHandler(const XClientMessageEvent &e);
virtual void mapRequestHandler(const XMapRequestEvent &);
- virtual void configureRequestHandler(const XConfigureRequestEvent &e);
};
}
diff --git a/src/screen.cc b/src/screen.cc
index 22d5d1be..d40a2a3a 100644
--- a/src/screen.cc
+++ b/src/screen.cc
@@ -354,7 +354,7 @@ void OBScreen::manageWindow(Window window)
Openbox::instance->registerHandler(window, client);
// we dont want a border on the client
- XSetWindowBorderWidth(otk::OBDisplay::display, window, 0);
+ client->toggleClientBorder(false);
// specify that if we exit, the window should not be destroyed and should be
// reparented back to root automatically
@@ -399,10 +399,9 @@ void OBScreen::unmanageWindow(OBClient *client)
XSelectInput(otk::OBDisplay::display, client->window(), NoEventMask);
frame->hide();
-
- // we dont want a border on the client
- XSetWindowBorderWidth(otk::OBDisplay::display, client->window(),
- client->borderWidth());
+
+ // give the client its border back
+ client->toggleClientBorder(true);
delete client->frame;
client->frame = 0;