From 1f1d43bdbf675ff24e80e3e6bac157171eba7ca1 Mon Sep 17 00:00:00 2001 From: Nephiel Date: Thu, 17 Sep 2015 17:25:40 +0200 Subject: Add Resize Snap Make windows snap to edges when resizing them, as well as when moving. From http://darkshed.net/files/patches/fluxbox/fluxbox-resize-snap-try2.diff --- src/Screen.hh | 2 + src/ScreenResource.cc | 1 + src/ScreenResource.hh | 1 + src/Window.cc | 126 +++++++++++++++++++++++++++++++++++++++++++------- src/Window.hh | 2 +- 5 files changed, 114 insertions(+), 18 deletions(-) diff --git a/src/Screen.hh b/src/Screen.hh index 983aa81..1aeac91 100644 --- a/src/Screen.hh +++ b/src/Screen.hh @@ -232,6 +232,8 @@ public: int getEdgeSnapThreshold() const { return *resource.edge_snap_threshold; } + int getEdgeResizeSnapThreshold() const { return *resource.edge_resize_snap_threshold; } + void setRootColormapInstalled(bool r) { root_colormap_installed = r; } void saveTabPlacement(FbWinFrame::TabPlacement place) { *resource.tab_placement = place; } diff --git a/src/ScreenResource.cc b/src/ScreenResource.cc index 0d8aaf7..dbf532b 100644 --- a/src/ScreenResource.cc +++ b/src/ScreenResource.cc @@ -97,6 +97,7 @@ ScreenResource::ScreenResource(FbTk::ResourceManager& rm, typing_delay(rm, 0, scrname+".noFocusWhileTypingDelay", altscrname+".NoFocusWhileTypingDelay"), workspaces(rm, 4, scrname+".workspaces", altscrname+".Workspaces"), edge_snap_threshold(rm, 10, 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"), diff --git a/src/ScreenResource.hh b/src/ScreenResource.hh index 3a6eaa1..7f1e621 100644 --- a/src/ScreenResource.hh +++ b/src/ScreenResource.hh @@ -47,6 +47,7 @@ struct ScreenResource { FbTk::Resource typing_delay; FbTk::Resource workspaces, edge_snap_threshold, + edge_resize_snap_threshold, focused_alpha, unfocused_alpha, menu_alpha, diff --git a/src/Window.cc b/src/Window.cc index 0f91a9e..9129e7d 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -2526,6 +2526,82 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) { 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, @@ -2816,7 +2892,8 @@ void FluxboxWindow::stopMoving(bool interrupted) { */ 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 @@ -2827,7 +2904,7 @@ inline void snapToWindow(int &xlimit, int &ylimit, // 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 @@ -2838,7 +2915,7 @@ inline void snapToWindow(int &xlimit, int &ylimit, // 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); } } @@ -2847,18 +2924,25 @@ inline void snapToWindow(int &xlimit, int &ylimit, * 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 (resize) { + threshold = screen().getEdgeResizeSnapThreshold(); + } else { + threshold = screen().getEdgeSnapThreshold(); + } - if (screen().getEdgeSnapThreshold() == 0) return; + 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; @@ -2897,28 +2981,32 @@ void FluxboxWindow::doSnapping(int &orig_left, int &orig_top) { 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); } ///////////////////////////////////// @@ -2942,14 +3030,16 @@ void FluxboxWindow::doSnapping(int &orig_left, int &orig_top) { (*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 @@ -2958,21 +3048,23 @@ void FluxboxWindow::doSnapping(int &orig_left, int &orig_top) { (*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; } diff --git a/src/Window.hh b/src/Window.hh index da126ec..c04676a 100644 --- a/src/Window.hh +++ b/src/Window.hh @@ -502,7 +502,7 @@ private: void attachWorkAreaSig(); // 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(); void moveResizeClient(WinClient &client); -- cgit v0.11.2