From 81378f9494db4ab1d033947532d7fac968095ecd Mon Sep 17 00:00:00 2001 From: rathnor <rathnor> Date: Mon, 29 Sep 2003 14:58:15 +0000 Subject: fix handling of base_Width/height hints in wm_normal_hints - fixes abiword resize issues --- ChangeLog | 3 +++ src/WinClient.cc | 72 +++++++++++++++++++++++++++++++++++++++++++++++++------- src/WinClient.hh | 12 +++++++++- src/Window.cc | 59 ++++++++++++---------------------------------- src/Window.hh | 5 ++-- 5 files changed, 95 insertions(+), 56 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5576fc1..48106b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/src/WinClient.cc b/src/WinClient.cc index 614b7a4..e032304 100644 --- a/src/WinClient.cc +++ b/src/WinClient.cc @@ -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; +} diff --git a/src/WinClient.hh b/src/WinClient.hh index 6bdfe3f..c93a76d 100644 --- a/src/WinClient.hh +++ b/src/WinClient.hh @@ -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); diff --git a/src/Window.cc b/src/Window.cc index 193f689..e6ff0c6 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -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; - - // 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; + int dh = m_last_resize_h - 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) { diff --git a/src/Window.hh b/src/Window.hh index e023253..9d94166 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -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); -- cgit v0.11.2