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
This commit is contained in:
Nephiel 2015-09-17 17:25:40 +02:00 committed by Mathias Gumz
parent 3e4570becc
commit 1f1d43bdbf
5 changed files with 114 additions and 18 deletions

View file

@ -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; }

View file

@ -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"),

View file

@ -47,6 +47,7 @@ struct ScreenResource {
FbTk::Resource<unsigned int> typing_delay;
FbTk::Resource<int> workspaces,
edge_snap_threshold,
edge_resize_snap_threshold,
focused_alpha,
unfocused_alpha,
menu_alpha,

View file

@ -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 (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;
@ -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;
}

View file

@ -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);