patch written by Michael Hanselmann http://hansmi.ch Index: fluxbox/src/Screen.cc =================================================================== --- fluxbox/src/Screen.cc (revision 4603) +++ fluxbox/src/Screen.cc (working copy) @@ -278,6 +278,8 @@ user_follow_model(rm, FOLLOW_ACTIVE_WINDOW, scrname+".userFollowModel", altscrname+".UserFollowModel"), workspaces(rm, 1, scrname+".workspaces", altscrname+".Workspaces"), edge_snap_threshold(rm, 0, scrname+".edgeSnapThreshold", altscrname+".EdgeSnapThreshold"), + edge_resize_snap_threshold(rm, 0, scrname+".edgeResizeSnapThreshold", + altscrname+".EdgeResizeSnapThreshold"), focused_alpha(rm, 255, scrname+".window.focus.alpha", altscrname+".Window.Focus.Alpha"), unfocused_alpha(rm, 255, scrname+".window.unfocus.alpha", altscrname+".Window.Unfocus.Alpha"), menu_alpha(rm, 255, scrname+".menu.alpha", altscrname+".Menu.Alpha"), Index: fluxbox/src/Window.cc =================================================================== --- fluxbox/src/Window.cc (revision 4603) +++ fluxbox/src/Window.cc (working copy) @@ -2946,6 +2946,7 @@ int dx = me.x - m_button_grab_x; int dy = me.y - m_button_grab_y; + switch (m_resize_corner) { case LEFTTOP: m_last_resize_w = frame().width() - dx; @@ -2994,6 +2995,82 @@ old_resize_w != m_last_resize_w || old_resize_h != m_last_resize_h ) { + if (screen().getEdgeResizeSnapThreshold() != 0) { + int tx, ty; + int botright_x = m_last_resize_x + m_last_resize_w; + int botright_y = m_last_resize_y + m_last_resize_h; + + switch (m_resize_corner) { + case LEFTTOP: + tx = m_last_resize_x; + ty = m_last_resize_y; + + doSnapping(tx, ty, true); + + m_last_resize_x = tx; + m_last_resize_y = ty; + + m_last_resize_w = botright_x - m_last_resize_x; + m_last_resize_h = botright_y - m_last_resize_y; + + break; + + case LEFTBOTTOM: + tx = m_last_resize_x; + ty = m_last_resize_y + m_last_resize_h; + + ty += frame().window().borderWidth() * 2; + + doSnapping(tx, ty, true); + + ty -= frame().window().borderWidth() * 2; + + m_last_resize_x = tx; + m_last_resize_h = ty - m_last_resize_y; + + m_last_resize_w = botright_x - m_last_resize_x; + + break; + + case RIGHTTOP: + tx = m_last_resize_x + m_last_resize_w; + ty = m_last_resize_y; + + tx += frame().window().borderWidth() * 2; + + doSnapping(tx, ty, true); + + tx -= frame().window().borderWidth() * 2; + + m_last_resize_w = tx - m_last_resize_x; + m_last_resize_y = ty; + + m_last_resize_h = botright_y - m_last_resize_y; + + break; + + case RIGHTBOTTOM: + tx = m_last_resize_x + m_last_resize_w; + ty = m_last_resize_y + m_last_resize_h; + + tx += frame().window().borderWidth() * 2; + ty += frame().window().borderWidth() * 2; + + doSnapping(tx, ty, true); + + tx -= frame().window().borderWidth() * 2; + ty -= frame().window().borderWidth() * 2; + + m_last_resize_w = tx - m_last_resize_x; + m_last_resize_h = ty - m_last_resize_y; + + break; + + default: + break; + } + } + // draw over old rect parent().drawRectangle(screen().rootTheme().opGC(), old_resize_x, old_resize_y, @@ -3408,7 +3485,8 @@ */ inline void snapToWindow(int &xlimit, int &ylimit, int left, int right, int top, int bottom, - int oleft, int oright, int otop, int obottom) { + int oleft, int oright, int otop, int obottom, + bool resize) { // Only snap if we're adjacent to the edge we're looking at // for left + right, need to be in the right y range @@ -3419,7 +3497,7 @@ // right if (abs(left-oright) < abs(xlimit)) xlimit = -(left-oright); - if (abs(right-oright) < abs(xlimit)) xlimit = -(right-oright); + if (!resize && abs(right-oright) < abs(xlimit)) xlimit = -(right-oright); } // for top + bottom, need to be in the right x range @@ -3430,7 +3508,7 @@ // bottom if (abs(top-obottom) < abs(ylimit)) ylimit = -(top-obottom); - if (abs(bottom-obottom) < abs(ylimit)) ylimit = -(bottom-obottom); + if (!resize && abs(bottom-obottom) < abs(ylimit)) ylimit = -(bottom-obottom); } } @@ -3439,18 +3517,25 @@ * Do Whatever snapping magic is necessary, and return using the orig_left * and orig_top variables to indicate the new x,y position */ -void FluxboxWindow::doSnapping(int &orig_left, int &orig_top) { +void FluxboxWindow::doSnapping(int &orig_left, int &orig_top, bool resize) { /* * Snap to screen/head edges * Snap to windows */ + int threshold; - if (screen().getEdgeSnapThreshold() == 0) return; + if (resize) { + threshold = screen().getEdgeResizeSnapThreshold(); + } else { + threshold = screen().getEdgeSnapThreshold(); + } + if (0 == threshold) return; + // Keep track of our best offsets so far // We need to find things less than or equal to the threshold - int dx = screen().getEdgeSnapThreshold() + 1; - int dy = screen().getEdgeSnapThreshold() + 1; + int dx = threshold + 1; + int dy = threshold + 1; // we only care about the left/top etc that includes borders int borderW = 0; @@ -3489,28 +3574,33 @@ screen().maxLeft(h), screen().maxRight(h), screen().maxTop(h), - screen().maxBottom(h)); + screen().maxBottom(h), + resize); if (i_have_tabs) snapToWindow(dx, dy, left - xoff, right - xoff + woff, top - yoff, bottom - yoff + hoff, screen().maxLeft(h), screen().maxRight(h), screen().maxTop(h), - screen().maxBottom(h)); + screen().maxBottom(h), + resize); } + for (int h=starth; h <= screen().numHeads(); h++) { snapToWindow(dx, dy, left, right, top, bottom, screen().getHeadX(h), screen().getHeadX(h) + screen().getHeadWidth(h), screen().getHeadY(h), - screen().getHeadY(h) + screen().getHeadHeight(h)); + screen().getHeadY(h) + screen().getHeadHeight(h), + resize); if (i_have_tabs) snapToWindow(dx, dy, left - xoff, right - xoff + woff, top - yoff, bottom - yoff + hoff, screen().getHeadX(h), screen().getHeadX(h) + screen().getHeadWidth(h), screen().getHeadY(h), - screen().getHeadY(h) + screen().getHeadHeight(h)); + screen().getHeadY(h) + screen().getHeadHeight(h), + resize); } ///////////////////////////////////// @@ -3534,14 +3624,16 @@ (*it)->x(), (*it)->x() + (*it)->width() + 2 * bw, (*it)->y(), - (*it)->y() + (*it)->height() + 2 * bw); + (*it)->y() + (*it)->height() + 2 * bw, + resize); if (i_have_tabs) snapToWindow(dx, dy, left - xoff, right - xoff + woff, top - yoff, bottom - yoff + hoff, (*it)->x(), (*it)->x() + (*it)->width() + 2 * bw, (*it)->y(), - (*it)->y() + (*it)->height() + 2 * bw); + (*it)->y() + (*it)->height() + 2 * bw, + resize); // also snap to the box containing the tabs (don't bother with actual // tab edges, since they're dynamic @@ -3550,23 +3642,23 @@ (*it)->x() - (*it)->xOffset(), (*it)->x() - (*it)->xOffset() + (*it)->width() + 2 * bw + (*it)->widthOffset(), (*it)->y() - (*it)->yOffset(), - (*it)->y() - (*it)->yOffset() + (*it)->height() + 2 * bw + (*it)->heightOffset()); + (*it)->y() - (*it)->yOffset() + (*it)->height() + 2 * bw + (*it)->heightOffset(), + resize); if (i_have_tabs) snapToWindow(dx, dy, left - xoff, right - xoff + woff, top - yoff, bottom - yoff + hoff, (*it)->x() - (*it)->xOffset(), (*it)->x() - (*it)->xOffset() + (*it)->width() + 2 * bw + (*it)->widthOffset(), (*it)->y() - (*it)->yOffset(), - (*it)->y() - (*it)->yOffset() + (*it)->height() + 2 * bw + (*it)->heightOffset()); - + (*it)->y() - (*it)->yOffset() + (*it)->height() + 2 * bw + (*it)->heightOffset(), + resize); } // commit - if (dx <= screen().getEdgeSnapThreshold()) + if (dx <= threshold) orig_left += dx; - if (dy <= screen().getEdgeSnapThreshold()) + if (dy <= threshold) orig_top += dy; - } Index: fluxbox/src/Screen.hh =================================================================== --- fluxbox/src/Screen.hh (revision 4603) +++ fluxbox/src/Screen.hh (working copy) @@ -220,6 +220,7 @@ void hideWindowMenus(const FluxboxWindow* except= 0); inline int getEdgeSnapThreshold() const { return *resource.edge_snap_threshold; } + inline int getEdgeResizeSnapThreshold() const { return *resource.edge_resize_snap_threshold; } void setRootColormapInstalled(bool r) { root_colormap_installed = r; } @@ -447,7 +448,8 @@ FbTk::Resource follow_model, user_follow_model; bool ordered_dither; FbTk::Resource workspaces, edge_snap_threshold, focused_alpha, - unfocused_alpha, menu_alpha, menu_delay, menu_delay_close, tab_width; + unfocused_alpha, menu_alpha, menu_delay, menu_delay_close, tab_width, + edge_resize_snap_threshold; FbTk::Resource menu_mode; FbTk::Resource gc_line_width; Index: fluxbox/src/Window.hh =================================================================== --- fluxbox/src/Window.hh (revision 4603) +++ fluxbox/src/Window.hh (working copy) @@ -452,7 +452,7 @@ void setState(unsigned long stateval, bool setting_up); // modifies left and top if snap is necessary - void doSnapping(int &left, int &top); + void doSnapping(int &left, int &top, bool resize = false); // user_w/h return the values that should be shown to the user void fixsize(int *user_w = 0, int *user_h = 0); void moveResizeClient(WinClient &client, int x, int y, unsigned int width, unsigned int height);