fix handling of base_Width/height hints in wm_normal_hints

- fixes abiword resize issues
This commit is contained in:
rathnor 2003-09-29 14:58:15 +00:00
parent 15dfe81112
commit 81378f9494
5 changed files with 94 additions and 55 deletions

View file

@ -1,6 +1,9 @@
(Format: Year/Month/Day)
Changes for 0.9.6:
*03/09/29:
* Fix resize calculations, particularly wrt base_width/height (Simon)
- fixes abiword resize issues
Window.hh/cc WinClient.hh/cc
* Nearest-quadrant resizing (Thanks Mathias Gumz)
Window.hh/cc Screen.hh/cc FbWinFrameTheme.hh/cc
* Update from Han

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: WinClient.cc,v 1.27 2003/09/24 14:02:25 rathnor Exp $
// $Id: WinClient.cc,v 1.28 2003/09/29 14:58:15 rathnor Exp $
#include "WinClient.hh"
@ -43,7 +43,7 @@ WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin):FbTk::Fb
window_group(0),
x(0), y(0), old_bw(0),
min_width(1), min_height(1),
max_width(1), max_height(1),
max_width(0), max_height(0),
width_inc(1), height_inc(1),
min_aspect_x(1), min_aspect_y(1),
max_aspect_x(1), max_aspect_y(1),
@ -434,8 +434,23 @@ void WinClient::updateWMNormalHints() {
if (sizehint.flags & PMinSize) {
min_width = sizehint.min_width;
min_height = sizehint.min_height;
} else
if (!(sizehint.flags & PBaseSize)) {
base_width = min_width;
base_height = min_height;
}
} else {
min_width = min_height = 1;
base_width = base_height = 0;
}
if (sizehint.flags & PBaseSize) {
base_width = sizehint.base_width;
base_height = sizehint.base_height;
if (!(sizehint.flags & PMinSize)) {
min_width = base_width;
min_height = base_height;
}
} // default set in PMinSize
if (sizehint.flags & PMaxSize) {
max_width = sizehint.max_width;
@ -460,12 +475,6 @@ void WinClient::updateWMNormalHints() {
min_aspect_x = min_aspect_y =
max_aspect_x = max_aspect_y = 1;
if (sizehint.flags & PBaseSize) {
base_width = sizehint.base_width;
base_height = sizehint.base_height;
} else
base_width = base_height = 0;
if (sizehint.flags & PWinGravity)
m_win_gravity = sizehint.win_gravity;
else
@ -605,3 +614,48 @@ void WinClient::updateWMProtocols() {
}
}
/**
* Changes width and height to the nearest (lower) value
* that conforms to it's size hints.
*
* display_* give the values that would be displayed
* to the user when resizing.
* We use pointers for display_* since they are optional.
*
* See ICCCM section 4.1.2.3
*/
void WinClient::applySizeHints(int &width, int &height,
int *display_width, int *display_height) {
int i = width, j = height;
// Check minimum size
if (width < 0 || width < min_width)
width = min_width;
if (height < 0 || height < min_height)
height = min_height;
// Check maximum size
if (max_width > 0 && width > max_width)
width = max_width;
if (max_height > 0 && height > max_height)
height = max_height;
// enforce incremental size limits, wrt base size
// only calculate this if we really need to
i = (width - base_width) / width_inc;
width = i*width_inc + base_width;
j = (height - base_height) / height_inc;
height = j*height_inc + base_height;
if (display_width)
*display_width = i;
if (display_height)
*display_height = j;
}

View file

@ -19,7 +19,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: WinClient.hh,v 1.14 2003/09/21 12:49:48 rathnor Exp $
// $Id: WinClient.hh,v 1.15 2003/09/29 14:58:15 rathnor Exp $
#ifndef WINCLIENT_HH
#define WINCLIENT_HH
@ -102,6 +102,16 @@ public:
void updateWMHints();
void updateWMNormalHints();
/**
* Changes width and height to the nearest (lower) value
* that conforms to it's size hints.
*
* display_* give the values that would be displayed
* to the user when resizing.
* We use pointers for display_* since they are optional.
*/
void applySizeHints(int &width, int &height, int *display_width = 0, int *display_height = 0);
// grouping is tracked by remembering the window to the left in the group
Window getGroupLeftWindow() const;
void setGroupLeftWindow(Window win);

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Window.cc,v 1.235 2003/09/29 12:53:58 rathnor Exp $
// $Id: Window.cc,v 1.236 2003/09/29 14:58:15 rathnor Exp $
#include "Window.hh"
@ -2437,11 +2437,11 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
fixsize(&gx, &gy);
// draw resize rectangle
parent().drawRectangle(screen().rootTheme().opGC(),
m_last_resize_x, m_last_resize_y,
m_last_resize_w - 1 + 2 * frame().window().borderWidth(),
m_last_resize_h - 1 + 2 * frame().window().borderWidth());
// draw resize rectangle
parent().drawRectangle(screen().rootTheme().opGC(),
m_last_resize_x, m_last_resize_y,
m_last_resize_w - 1 + 2 * frame().window().borderWidth(),
m_last_resize_h - 1 + 2 * frame().window().borderWidth());
if (screen().doShowWindowPos())
screen().showGeometry(gx, gy);
@ -3166,7 +3166,7 @@ void FluxboxWindow::downsize() {
}
void FluxboxWindow::fixsize(int *gx, int *gy) {
void FluxboxWindow::fixsize(int *user_w, int *user_h) {
int titlebar_height = (decorations.titlebar ?
frame().titlebar().height() +
frame().titlebar().borderWidth() : 0);
@ -3177,49 +3177,20 @@ void FluxboxWindow::fixsize(int *gx, int *gy) {
// dx is new width = current width + difference between new and old x values
//int dx = frame().width() + frame().x() - m_last_resize_x;
int dx = m_last_resize_w - m_client->base_width;
int dw = m_last_resize_w;
// dy = new height (w/o decorations), similarly
int dy = m_last_resize_h - m_client->base_height - decoration_height;
int dh = m_last_resize_h - decoration_height;
// check minimum size
if (dx < static_cast<signed int>(m_client->min_width))
dx = m_client->min_width;
if (dy < static_cast<signed int>(m_client->min_height))
dy = m_client->min_height;
// check maximum size
if (m_client->max_width > 0 && dx > static_cast<signed int>(m_client->max_width))
dx = m_client->max_width;
if (m_client->max_height > 0 && dy > static_cast<signed int>(m_client->max_height))
dy = m_client->max_height;
// make sure we have valid increment
if (m_client->width_inc == 0)
m_client->width_inc = 1;
if (m_client->height_inc == 0)
m_client->height_inc = 1;
// set snapping
dx /= m_client->width_inc;
dy /= m_client->height_inc;
// set return values
if (gx != 0)
*gx = dx;
if (gy != 0)
*gy = dy;
// snapping
dx = dx * m_client->width_inc + m_client->base_width;
dy = dy * m_client->height_inc + m_client->base_height + decoration_height;
m_client->applySizeHints(dw, dh, user_w, user_h);
// update last resize
m_last_resize_w = dx;
m_last_resize_h = dy;
m_last_resize_w = dw;
m_last_resize_h = dh + decoration_height;
// move X if necessary
if (m_resize_corner == LEFTTOP || m_resize_corner == LEFTBOTTOM) {
m_last_resize_x = frame().x() + frame().width() - m_last_resize_w;
m_last_resize_x = frame().x() + frame().width() - m_last_resize_w;
}
if (m_resize_corner == LEFTTOP || m_resize_corner == RIGHTTOP) {

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Window.hh,v 1.96 2003/09/29 12:53:58 rathnor Exp $
// $Id: Window.hh,v 1.97 2003/09/29 14:58:15 rathnor Exp $
#ifndef WINDOW_HH
#define WINDOW_HH
@ -398,7 +398,8 @@ private:
// modifies left and top if snap is necessary
void doSnapping(int &left, int &top);
void fixsize(int *x = 0, int *y = 0);
// user_w/h return the values that should be shown to the user
void fixsize(int *user_w = 0, int *user_h = 0);
void resizeClient(WinClient &client, unsigned int width, unsigned int height);
/// sends configurenotify to all clients
void sendConfigureNotify(bool send_to_netizens = true);