support the aspect ratio hints in the WMNormalHints
This commit is contained in:
parent
25b8526603
commit
3f784100ab
2 changed files with 46 additions and 10 deletions
|
@ -23,6 +23,8 @@ extern "C" {
|
||||||
#define _(str) gettext(str)
|
#define _(str) gettext(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace ob {
|
namespace ob {
|
||||||
|
|
||||||
Client::Client(int screen, Window window)
|
Client::Client(int screen, Window window)
|
||||||
|
@ -198,6 +200,11 @@ void Client::setupDecorAndFunctions()
|
||||||
_decorations |= Decor_Close;
|
_decorations |= Decor_Close;
|
||||||
_functions |= Func_Close;
|
_functions |= Func_Close;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_min_size.x() > _max_size.x() || _min_size.y() > _max_size.y()) {
|
||||||
|
_decorations &= ~Decor_Maximize;
|
||||||
|
_functions &= ~(Func_Resize | Func_Maximize);
|
||||||
|
}
|
||||||
|
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case Type_Normal:
|
case Type_Normal:
|
||||||
|
@ -418,6 +425,8 @@ void Client::updateNormalHints()
|
||||||
int oldgravity = _gravity;
|
int oldgravity = _gravity;
|
||||||
|
|
||||||
// defaults
|
// defaults
|
||||||
|
_min_ratio = 0.0;
|
||||||
|
_max_ratio = 0.0;
|
||||||
_size_inc.setPoint(1, 1);
|
_size_inc.setPoint(1, 1);
|
||||||
_base_size.setPoint(0, 0);
|
_base_size.setPoint(0, 0);
|
||||||
_min_size.setPoint(0, 0);
|
_min_size.setPoint(0, 0);
|
||||||
|
@ -443,6 +452,11 @@ void Client::updateNormalHints()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (size.flags & PAspect) {
|
||||||
|
if (size.min_aspect.y) _min_ratio = size.min_aspect.x/size.min_aspect.y;
|
||||||
|
if (size.max_aspect.y) _max_ratio = size.max_aspect.x/size.max_aspect.y;
|
||||||
|
}
|
||||||
|
|
||||||
if (size.flags & PMinSize)
|
if (size.flags & PMinSize)
|
||||||
_min_size.setPoint(size.min_width, size.min_height);
|
_min_size.setPoint(size.min_width, size.min_height);
|
||||||
|
|
||||||
|
@ -497,7 +511,7 @@ void Client::updateWMHints(bool initstate)
|
||||||
#endif
|
#endif
|
||||||
// fire the urgent callback if we're mapped, otherwise, wait until after
|
// fire the urgent callback if we're mapped, otherwise, wait until after
|
||||||
// we're mapped
|
// we're mapped
|
||||||
if (_urgent && frame)
|
if (frame)
|
||||||
fireUrgent();
|
fireUrgent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -634,9 +648,10 @@ void Client::propertyHandler(const XPropertyEvent &e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.atom == XA_WM_NORMAL_HINTS)
|
if (e.atom == XA_WM_NORMAL_HINTS) {
|
||||||
updateNormalHints();
|
updateNormalHints();
|
||||||
else if (e.atom == XA_WM_HINTS)
|
setupDecorAndFunctions(); // normal hints can make a window non-resizable
|
||||||
|
} else if (e.atom == XA_WM_HINTS)
|
||||||
updateWMHints();
|
updateWMHints();
|
||||||
else if (e.atom == XA_WM_TRANSIENT_FOR) {
|
else if (e.atom == XA_WM_TRANSIENT_FOR) {
|
||||||
updateTransientFor();
|
updateTransientFor();
|
||||||
|
@ -980,7 +995,8 @@ void Client::resize(Corner anchor, int w, int h)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Client::internal_resize(Corner anchor, int w, int h, int x, int y)
|
void Client::internal_resize(Corner anchor, int w, int h, bool user,
|
||||||
|
int x, int y)
|
||||||
{
|
{
|
||||||
w -= _base_size.x();
|
w -= _base_size.x();
|
||||||
h -= _base_size.y();
|
h -= _base_size.y();
|
||||||
|
@ -990,14 +1006,21 @@ void Client::internal_resize(Corner anchor, int w, int h, int x, int y)
|
||||||
w += _size_inc.x() / 2;
|
w += _size_inc.x() / 2;
|
||||||
h += _size_inc.y() / 2;
|
h += _size_inc.y() / 2;
|
||||||
|
|
||||||
// is the window resizable? if it is not, then don't check its sizes, the
|
if (user) {
|
||||||
// client can do what it wants and the user can't change it anyhow
|
// if this is a user-requested resize, then check against min/max sizes
|
||||||
if (_min_size.x() <= _max_size.x() && _min_size.y() <= _max_size.y()) {
|
// and aspect ratios
|
||||||
|
|
||||||
// smaller than min size or bigger than max size?
|
// smaller than min size or bigger than max size?
|
||||||
if (w < _min_size.x()) w = _min_size.x();
|
if (w < _min_size.x()) w = _min_size.x();
|
||||||
else if (w > _max_size.x()) w = _max_size.x();
|
else if (w > _max_size.x()) w = _max_size.x();
|
||||||
if (h < _min_size.y()) h = _min_size.y();
|
if (h < _min_size.y()) h = _min_size.y();
|
||||||
else if (h > _max_size.y()) h = _max_size.y();
|
else if (h > _max_size.y()) h = _max_size.y();
|
||||||
|
|
||||||
|
// adjust the height ot match the width for the aspect ratios
|
||||||
|
if (_min_ratio)
|
||||||
|
if (h * _min_ratio > w) h = static_cast<int>(w / _min_ratio);
|
||||||
|
if (_max_ratio)
|
||||||
|
if (h * _max_ratio < w) h = static_cast<int>(w / _max_ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
// keep to the increments
|
// keep to the increments
|
||||||
|
@ -1404,9 +1427,9 @@ void Client::configureRequestHandler(const XConfigureRequestEvent &e)
|
||||||
if (e.value_mask & (CWX | CWY)) {
|
if (e.value_mask & (CWX | CWY)) {
|
||||||
int x = (e.value_mask & CWX) ? e.x : _area.x();
|
int x = (e.value_mask & CWX) ? e.x : _area.x();
|
||||||
int y = (e.value_mask & CWY) ? e.y : _area.y();
|
int y = (e.value_mask & CWY) ? e.y : _area.y();
|
||||||
internal_resize(corner, w, h, x, y);
|
internal_resize(corner, w, h, false, x, y);
|
||||||
} else // if JUST resizing...
|
} else // if JUST resizing...
|
||||||
internal_resize(corner, w, h);
|
internal_resize(corner, w, h, false);
|
||||||
} else if (e.value_mask & (CWX | CWY)) { // if JUST moving...
|
} else if (e.value_mask & (CWX | CWY)) { // if JUST moving...
|
||||||
int x = (e.value_mask & CWX) ? e.x : _area.x();
|
int x = (e.value_mask & CWX) ? e.x : _area.x();
|
||||||
int y = (e.value_mask & CWY) ? e.y : _area.y();
|
int y = (e.value_mask & CWY) ? e.y : _area.y();
|
||||||
|
|
|
@ -236,6 +236,17 @@ private:
|
||||||
*/
|
*/
|
||||||
int _border_width;
|
int _border_width;
|
||||||
|
|
||||||
|
//! The minimum aspect ratio the client window can be sized to.
|
||||||
|
/*!
|
||||||
|
A value of 0 means this is ignored.
|
||||||
|
*/
|
||||||
|
float _min_ratio;
|
||||||
|
//! The maximum aspect ratio the client window can be sized to.
|
||||||
|
/*!
|
||||||
|
A value of 0 means this is ignored.
|
||||||
|
*/
|
||||||
|
float _max_ratio;
|
||||||
|
|
||||||
//! The minimum size 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
|
||||||
|
@ -429,6 +440,8 @@ private:
|
||||||
@param anchor The corner to keep in the same position when resizing.
|
@param anchor The corner to keep in the same position when resizing.
|
||||||
@param w The width component of the new size for the client.
|
@param w The width component of the new size for the client.
|
||||||
@param h The height component of the new size for the client.
|
@param h The height component of the new size for the client.
|
||||||
|
@param user Specifies whether this is a user-requested change or a
|
||||||
|
program requested change.
|
||||||
@param x An optional X coordinate to which the window will be moved
|
@param x An optional X coordinate to which the window will be moved
|
||||||
after resizing.
|
after resizing.
|
||||||
@param y An optional Y coordinate to which the window will be moved
|
@param y An optional Y coordinate to which the window will be moved
|
||||||
|
@ -436,7 +449,7 @@ private:
|
||||||
The x and y coordinates must both be sepcified together, or they will have
|
The x and y coordinates must both be sepcified together, or they will have
|
||||||
no effect. When they are specified, the anchor is ignored.
|
no effect. When they are specified, the anchor is ignored.
|
||||||
*/
|
*/
|
||||||
void internal_resize(Corner anchor, int w, int h,
|
void internal_resize(Corner anchor, int w, int h, bool user = true,
|
||||||
int x = INT_MIN, int y = INT_MIN);
|
int x = INT_MIN, int y = INT_MIN);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in a new issue