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);
|
_map.erase(id);
|
||||||
}
|
}
|
||||||
#include <stdio.h>
|
|
||||||
void OtkEventDispatcher::dispatchEvents(void)
|
void OtkEventDispatcher::dispatchEvents(void)
|
||||||
{
|
{
|
||||||
XEvent e;
|
XEvent e;
|
||||||
|
|
145
src/client.cc
145
src/client.cc
|
@ -5,6 +5,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "client.hh"
|
#include "client.hh"
|
||||||
|
#include "frame.hh"
|
||||||
#include "bbscreen.hh"
|
#include "bbscreen.hh"
|
||||||
#include "openbox.hh"
|
#include "openbox.hh"
|
||||||
#include "otk/display.hh"
|
#include "otk/display.hh"
|
||||||
|
@ -374,10 +375,10 @@ void OBClient::updateNormalHints()
|
||||||
|
|
||||||
// defaults
|
// defaults
|
||||||
_gravity = NorthWestGravity;
|
_gravity = NorthWestGravity;
|
||||||
_inc_x = _inc_y = 1;
|
_size_inc.setPoint(1, 1);
|
||||||
_base_x = _base_y = 0;
|
_base_size.setPoint(0, 0);
|
||||||
_min_x = _min_y = 0;
|
_min_size.setPoint(0, 0);
|
||||||
_max_x = _max_y = INT_MAX;
|
_max_size.setPoint(INT_MAX, INT_MAX);
|
||||||
|
|
||||||
// XXX: might want to cancel any interactive resizing of the window at this
|
// XXX: might want to cancel any interactive resizing of the window at this
|
||||||
// point..
|
// point..
|
||||||
|
@ -389,25 +390,17 @@ void OBClient::updateNormalHints()
|
||||||
if (size.flags & PWinGravity)
|
if (size.flags & PWinGravity)
|
||||||
_gravity = size.win_gravity;
|
_gravity = size.win_gravity;
|
||||||
|
|
||||||
if (size.flags & PMinSize) {
|
if (size.flags & PMinSize)
|
||||||
_min_x = size.min_width;
|
_min_size.setPoint(size.min_width, size.min_height);
|
||||||
_min_y = size.min_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size.flags & PMaxSize) {
|
if (size.flags & PMaxSize)
|
||||||
_max_x = size.max_width;
|
_max_size.setPoint(size.max_width, size.max_height);
|
||||||
_max_y = size.max_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size.flags & PBaseSize) {
|
if (size.flags & PBaseSize)
|
||||||
_base_x = size.base_width;
|
_base_size.setPoint(size.base_width, size.base_height);
|
||||||
_base_y = size.base_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size.flags & PResizeInc) {
|
if (size.flags & PResizeInc)
|
||||||
_inc_x = size.width_inc;
|
_size_inc.setPoint(size.width_inc, size.height_inc);
|
||||||
_inc_y = size.height_inc;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -719,9 +712,117 @@ void OBClient::shapeHandler(const XShapeEvent &e)
|
||||||
#endif
|
#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 <string>
|
||||||
|
|
||||||
|
#include "otk/point.hh"
|
||||||
#include "otk/strut.hh"
|
#include "otk/strut.hh"
|
||||||
#include "otk/rect.hh"
|
#include "otk/rect.hh"
|
||||||
#include "otk/eventhandler.hh"
|
#include "otk/eventhandler.hh"
|
||||||
|
@ -41,8 +42,17 @@ class OBClient : public otk::OtkEventHandler {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! The frame window which decorates around the client window
|
//! The frame window which decorates around the client window
|
||||||
|
/*!
|
||||||
|
NOTE: This should NEVER be used inside the client class's constructor!
|
||||||
|
*/
|
||||||
OBFrame *frame;
|
OBFrame *frame;
|
||||||
|
|
||||||
|
//! Corners of the client window, used for anchor positions
|
||||||
|
enum Corner { TopLeft,
|
||||||
|
TopRight,
|
||||||
|
BottomLeft,
|
||||||
|
BottomRight };
|
||||||
|
|
||||||
//! Possible window types
|
//! Possible window types
|
||||||
enum WindowType { Type_Desktop, //!< A desktop (bottom-most window)
|
enum WindowType { Type_Desktop, //!< A desktop (bottom-most window)
|
||||||
Type_Dock, //!< A dock bar/panel window
|
Type_Dock, //!< A dock bar/panel window
|
||||||
|
@ -153,9 +163,23 @@ private:
|
||||||
//! The type of window (what its function is)
|
//! The type of window (what its function is)
|
||||||
WindowType _type;
|
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;
|
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.
|
//! Width of the border on the window.
|
||||||
/*!
|
/*!
|
||||||
The window manager will set this to 0 while the window is being managed,
|
The window manager will set this to 0 while the window is being managed,
|
||||||
|
@ -163,42 +187,24 @@ private:
|
||||||
*/
|
*/
|
||||||
int _border_width;
|
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
|
If the min is > the max, then the window is not resizable
|
||||||
*/
|
*/
|
||||||
int _min_x;
|
otk::Point _min_size;
|
||||||
//! The minimum height of the client window
|
//! The maximum size of the client window
|
||||||
/*!
|
/*!
|
||||||
If the min is > the max, then the window is not resizable
|
If the min is > the max, then the window is not resizable
|
||||||
*/
|
*/
|
||||||
int _min_y;
|
otk::Point _max_size;
|
||||||
//! The maximum width of the client window
|
//! 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;
|
otk::Point _base_size;
|
||||||
//! 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;
|
|
||||||
|
|
||||||
//! Where to place the decorated window in relation to the undecorated window
|
//! Where to place the decorated window in relation to the undecorated window
|
||||||
int _gravity;
|
int _gravity;
|
||||||
|
@ -289,6 +295,21 @@ private:
|
||||||
void updateClass();
|
void updateClass();
|
||||||
// XXX: updateTransientFor();
|
// 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:
|
public:
|
||||||
//! Constructs a new OBClient object around a specified window id
|
//! Constructs a new OBClient object around a specified window id
|
||||||
/*!
|
/*!
|
||||||
|
@ -387,49 +408,8 @@ public:
|
||||||
*/
|
*/
|
||||||
inline bool floating() const { return _floating; }
|
inline bool floating() const { return _floating; }
|
||||||
|
|
||||||
//! Returns the window's border width
|
//! Returns the client's requested border width (not used by the wm)
|
||||||
/*!
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
inline int borderWidth() const { return _border_width; }
|
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
|
//! Returns the position and size of the client relative to the root window
|
||||||
inline const otk::Rect &area() const { return _area; }
|
inline const otk::Rect &area() const { return _area; }
|
||||||
|
@ -440,12 +420,7 @@ public:
|
||||||
|
|
||||||
virtual void shapeHandler(const XShapeEvent &e);
|
virtual void shapeHandler(const XShapeEvent &e);
|
||||||
|
|
||||||
//! Changes the stored positions and size of the OBClient window
|
virtual void configureRequestHandler(const XConfigureRequestEvent &e);
|
||||||
/*!
|
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
15
src/frame.cc
15
src/frame.cc
|
@ -196,8 +196,13 @@ void OBFrame::adjust()
|
||||||
// that the ONE LABEL!!
|
// that the ONE LABEL!!
|
||||||
// adds an extra sep so that there's a space on either side of the
|
// adds an extra sep so that there's a space on either side of the
|
||||||
// titlebar.. note: x = sep, below.
|
// titlebar.. note: x = sep, below.
|
||||||
_label.setWidth(width - sep * 2 -
|
int lwidth = width - sep * 2 -
|
||||||
(_button_iconify.width() + sep) * (layout.size() - 1));
|
(_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;
|
int x = sep;
|
||||||
for (int i = 0, len = layout.size(); i < len; ++i) {
|
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
|
//! Reversely applies gravity for the client's gravity, moving the frame so
|
||||||
//! that the client is in its pre-gravity position
|
//! 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;
|
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 mapRequestHandler(const XMapRequestEvent &);
|
||||||
|
|
||||||
|
virtual void configureRequestHandler(const XConfigureRequestEvent &e);
|
||||||
|
|
||||||
//! Sets the name of a desktop
|
//! Sets the name of a desktop
|
||||||
/*!
|
/*!
|
||||||
@param i The index of the desktop to set the name for (base 0)
|
@param i The index of the desktop to set the name for (base 0)
|
||||||
|
|
Loading…
Reference in a new issue