handle configure requests

This commit is contained in:
Dana Jansens 2002-12-04 00:26:45 +00:00
parent bbdfd8f1d6
commit 1fa445c880
8 changed files with 213 additions and 105 deletions

View file

@ -33,7 +33,7 @@ void OtkEventDispatcher::clearHandler(Window id)
{
_map.erase(id);
}
#include <stdio.h>
void OtkEventDispatcher::dispatchEvents(void)
{
XEvent e;

View file

@ -5,6 +5,7 @@
#endif
#include "client.hh"
#include "frame.hh"
#include "bbscreen.hh"
#include "openbox.hh"
#include "otk/display.hh"
@ -374,10 +375,10 @@ void OBClient::updateNormalHints()
// defaults
_gravity = NorthWestGravity;
_inc_x = _inc_y = 1;
_base_x = _base_y = 0;
_min_x = _min_y = 0;
_max_x = _max_y = INT_MAX;
_size_inc.setPoint(1, 1);
_base_size.setPoint(0, 0);
_min_size.setPoint(0, 0);
_max_size.setPoint(INT_MAX, INT_MAX);
// XXX: might want to cancel any interactive resizing of the window at this
// point..
@ -389,25 +390,17 @@ void OBClient::updateNormalHints()
if (size.flags & PWinGravity)
_gravity = size.win_gravity;
if (size.flags & PMinSize) {
_min_x = size.min_width;
_min_y = size.min_height;
}
if (size.flags & PMinSize)
_min_size.setPoint(size.min_width, size.min_height);
if (size.flags & PMaxSize) {
_max_x = size.max_width;
_max_y = size.max_height;
}
if (size.flags & PMaxSize)
_max_size.setPoint(size.max_width, size.max_height);
if (size.flags & PBaseSize) {
_base_x = size.base_width;
_base_y = size.base_height;
}
if (size.flags & PBaseSize)
_base_size.setPoint(size.base_width, size.base_height);
if (size.flags & PResizeInc) {
_inc_x = size.width_inc;
_inc_y = size.height_inc;
}
if (size.flags & PResizeInc)
_size_inc.setPoint(size.width_inc, size.height_inc);
}
}
@ -719,9 +712,117 @@ void OBClient::shapeHandler(const XShapeEvent &e)
#endif
void OBClient::setArea(const otk::Rect &area)
void OBClient::resize(Corner anchor, int w, int h)
{
_area = area;
w -= _base_size.x();
h -= _base_size.y();
// 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()) {
// 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();
}
// keep to the increments
w /= _size_inc.x();
h /= _size_inc.y();
// store the logical size
_logical_size.setPoint(w, h);
w *= _size_inc.x();
h *= _size_inc.y();
w += _base_size.x();
h += _base_size.y();
switch (anchor) {
case TopLeft:
break;
case TopRight:
_area.setX(_area.x() - _area.width() - w);
break;
case BottomLeft:
_area.setY(_area.y() - _area.height() - h);
break;
case BottomRight:
_area.setX(_area.x() - _area.width() - w);
_area.setY(_area.y() - _area.height() - h);
break;
}
_area.setSize(w, h);
// resize the frame to match
frame->adjust();
}
void OBClient::move(int x, int y)
{
_area.setPos(x, y);
// move the frame to be in the requested position
frame->applyGravity();
}
void OBClient::configureRequestHandler(const XConfigureRequestEvent &e)
{
// XXX: if we are iconic (or shaded? (fvwm does that)) ignore the event
if (e.value_mask & CWBorderWidth)
_border_width = e.border_width;
// resize, then move, as specified in the EWMH section 7.7
if (e.value_mask & (CWWidth | CWHeight)) {
int w = (e.value_mask & CWWidth) ? e.width : _area.width();
int h = (e.value_mask & CWHeight) ? e.height : _area.height();
Corner corner;
switch (_gravity) {
case NorthEastGravity:
case EastGravity:
corner = TopRight;
break;
case SouthWestGravity:
case SouthGravity:
corner = BottomLeft;
break;
case SouthEastGravity:
corner = BottomRight;
break;
default: // NorthWest, Static, etc
corner = TopLeft;
}
resize(corner, w, h);
}
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();
move(x, y);
}
if (e.value_mask & CWStackMode) {
switch (e.detail) {
case Below:
case BottomIf:
// XXX: lower the window
break;
case Above:
case TopIf:
default:
// XXX: raise the window
break;
}
}
}
}

View file

@ -17,6 +17,7 @@ extern "C" {
#include <string>
#include "otk/point.hh"
#include "otk/strut.hh"
#include "otk/rect.hh"
#include "otk/eventhandler.hh"
@ -41,8 +42,17 @@ class OBClient : public otk::OtkEventHandler {
public:
//! The frame window which decorates around the client window
/*!
NOTE: This should NEVER be used inside the client class's constructor!
*/
OBFrame *frame;
//! Corners of the client window, used for anchor positions
enum Corner { TopLeft,
TopRight,
BottomLeft,
BottomRight };
//! Possible window types
enum WindowType { Type_Desktop, //!< A desktop (bottom-most window)
Type_Dock, //!< A dock bar/panel window
@ -153,9 +163,23 @@ private:
//! The type of window (what its function is)
WindowType _type;
//! Position and size of the window (relative to the root window)
//! Position and size of the window
/*!
This will not always be the actual position of the window on screen, it is
rather, the position requested by the client, to which the window's gravity
is applied.
*/
otk::Rect _area;
//! The logical size of the window
/*!
The "logical" size of the window is refers to the user's perception of the
size of the window, and is the value that should be displayed to the user.
For example, with xterms, this value it the number of characters being
displayed in the terminal, instead of the number of pixels.
*/
otk::Point _logical_size;
//! Width of the border on the window.
/*!
The window manager will set this to 0 while the window is being managed,
@ -163,42 +187,24 @@ private:
*/
int _border_width;
//! The minimum width of the client window
//! The minimum size of the client window
/*!
If the min is > the max, then the window is not resizable
*/
int _min_x;
//! The minimum height of the client window
otk::Point _min_size;
//! The maximum size of the client window
/*!
If the min is > the max, then the window is not resizable
*/
int _min_y;
//! The maximum width of the client window
otk::Point _max_size;
//! The size of increments to resize the client window by
otk::Point _size_inc;
//! The base size of the client window
/*!
If the min is > the max, then the window is not resizable
This value should be subtracted from the window's actual size when
displaying its size to the user, or working with its min/max size
*/
int _max_x;
//! The maximum height of the client window
/*!
If the min is > the max, then the window is not resizable
*/
int _max_y;
//! The size of increments to resize the client window by (for the width)
int _inc_x;
//! The size of increments to resize the client window by (for the height)
int _inc_y;
//! The base width of the client window
/*!
This value should be subtracted from the window's actual width when
displaying its size to the user, or working with its min/max width
*/
int _base_x;
//! The base height of the client window
/*!
This value should be subtracted from the window's actual height when
displaying its size to the user, or working with its min/max height
*/
int _base_y;
otk::Point _base_size;
//! Where to place the decorated window in relation to the undecorated window
int _gravity;
@ -289,6 +295,21 @@ private:
void updateClass();
// 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
/*!
This also maintains things like the client's minsize, and size increments.
@param anchor The corner to keep in the same position when resizing
@param size The new size for the client
*/
void resize(Corner anchor, int x, int y);
public:
//! Constructs a new OBClient object around a specified window id
/*!
@ -387,49 +408,8 @@ public:
*/
inline bool floating() const { return _floating; }
//! Returns the window's border width
/*!
The border width is set to 0 when the client becomes managed, but the
border width is stored here so that it can be restored to the client window
when it is unmanaged later.
*/
//! Returns the client's requested border width (not used by the wm)
inline int borderWidth() const { return _border_width; }
//! Returns the minimum width of the client window
/*!
If the min is > the max, then the window is not resizable
*/
inline int minX() const { return _min_x; }
//! Returns the minimum height of the client window
/*!
If the min is > the max, then the window is not resizable
*/
inline int minY() const { return _min_y; }
//! Returns the maximum width of the client window
/*!
If the min is > the max, then the window is not resizable
*/
inline int maxX() const { return _max_x; }
//! Returns the maximum height of the client window
/*!
If the min is > the max, then the window is not resizable
*/
inline int maxY() const { return _max_y; }
//! Returns the increment size for resizing the window (for the width)
inline int incrementX() const { return _inc_x; }
//! Returns the increment size for resizing the window (for the height)
inline int incrementY() const { return _inc_y; }
//! Returns the base width of the window
/*!
This value should be subtracted from the window's actual width when
displaying its size to the user, or working with its min/max width
*/
inline int baseX() const { return _base_x; }
//! Returns the base height of the window
/*!
This value should be subtracted from the window's actual height when
displaying its size to the user, or working with its min/max height
*/
inline int baseY() const { return _base_y; }
//! Returns the position and size of the client relative to the root window
inline const otk::Rect &area() const { return _area; }
@ -440,12 +420,7 @@ public:
virtual void shapeHandler(const XShapeEvent &e);
//! Changes the stored positions and size of the OBClient window
/*!
This does not actually change the physical geometry, that needs to be done
before/after setting this value to keep it in sync
*/
void setArea(const otk::Rect &area);
virtual void configureRequestHandler(const XConfigureRequestEvent &e);
};
}

View file

@ -196,8 +196,13 @@ void OBFrame::adjust()
// that the ONE LABEL!!
// adds an extra sep so that there's a space on either side of the
// titlebar.. note: x = sep, below.
_label.setWidth(width - sep * 2 -
(_button_iconify.width() + sep) * (layout.size() - 1));
int lwidth = width - sep * 2 -
(_button_iconify.width() + sep) * (layout.size() - 1);
// quick sanity check for really small windows. if this is needed, its
// obviously not going to be displayed right...
// XXX: maybe we should make this look better somehow? constraints?
if (lwidth <= 0) lwidth = 1;
_label.setWidth(lwidth);
int x = sep;
for (int i = 0, len = layout.size(); i < len; ++i) {
@ -449,4 +454,10 @@ void OBFrame::applyGravity()
}
void OBFrame::reverseGravity()
{
move(_client->area().x() - _size.left, _client->area().y() - _size.top);
}
}

View file

@ -91,7 +91,7 @@ public:
//! Reversely applies gravity for the client's gravity, moving the frame so
//! that the client is in its pre-gravity position
void restoreGravity();
void reverseGravity();
};
}

View file

@ -280,6 +280,5 @@ OBClient *Openbox::findClient(Window window)
return (OBClient*) 0;
}
}

View file

@ -108,4 +108,24 @@ void OBRootWindow::mapRequestHandler(const XMapRequestEvent &e)
}
}
#include <stdio.h>
void OBRootWindow::configureRequestHandler(const XConfigureRequestEvent &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);
}
}

View file

@ -58,6 +58,8 @@ public:
virtual void mapRequestHandler(const XMapRequestEvent &);
virtual void configureRequestHandler(const XConfigureRequestEvent &e);
//! Sets the name of a desktop
/*!
@param i The index of the desktop to set the name for (base 0)