handle configure requests
This commit is contained in:
parent
bbdfd8f1d6
commit
1fa445c880
8 changed files with 213 additions and 105 deletions
|
@ -33,7 +33,7 @@ void OtkEventDispatcher::clearHandler(Window id)
|
|||
{
|
||||
_map.erase(id);
|
||||
}
|
||||
#include <stdio.h>
|
||||
|
||||
void OtkEventDispatcher::dispatchEvents(void)
|
||||
{
|
||||
XEvent e;
|
||||
|
|
145
src/client.cc
145
src/client.cc
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
129
src/client.hh
129
src/client.hh
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
15
src/frame.cc
15
src/frame.cc
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -280,6 +280,5 @@ OBClient *Openbox::findClient(Window window)
|
|||
return (OBClient*) 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue