all repos — fluxbox @ 391712b9805eda9d56a100f49d69b38863910565

custom fork of the fluxbox windowmanager

Add support for nearest corner or edge resizing
Michael Abbott michael@araneidae.co.uk
commit

391712b9805eda9d56a100f49d69b38863910565

parent

7b6ab828c7e5453a2720462156d165707935c9ef

M doc/asciidoc/fluxbox-keys.txtdoc/asciidoc/fluxbox-keys.txt

@@ -178,8 +178,16 @@ Start dragging to resize the window as if you had grabbed the window

at the specified 'corner'. + By default 'corner' is *BottomRight*, but may be overridden with one of:;; -*NearestCorner NearestEdge Center TopLeft Top TopRight Left Right BottomLeft -Bottom BottomRight* +*NearestCorner NearestEdge NearestCornerOrEdge Center TopLeft Top TopRight +Left Right BottomLeft Bottom BottomRight* + ++ +If *NearestCornerOrEdge* is specified the size of the corner can also be +specified to be the larger of one or two following numbers: ['pixel-size' +['percent-size']] or 'percent-size'%, where 'percent-size' is the +percentage of half the window width or height. If no size is given, it +defaults to 50 pixels and 30%. + *StartTabbing*:: Start dragging to add this window to another's tabgroup.
M src/CurrentWindowCmd.ccsrc/CurrentWindowCmd.cc

@@ -20,6 +20,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING

// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. +#include <string.h> #include "CurrentWindowCmd.hh" #include "fluxbox.hh"

@@ -369,15 +370,13 @@

FbTk::Command<void> *StartResizingCmd::parse(const string &cmd, const string &args, bool trusted) { FluxboxWindow::ResizeModel mode = FluxboxWindow::DEFAULTRESIZE; + int corner_size_px = 0; + int corner_size_pc = 0; std::vector<string> tokens; FbTk::StringUtil::stringtok<std::vector<string> >(tokens, args); if (!tokens.empty()) { string arg = FbTk::StringUtil::toLower(tokens[0]); - if (arg == "nearestcorner") - mode = FluxboxWindow::QUADRANTRESIZE; - else if (arg == "nearestedge") - mode = FluxboxWindow::NEARESTEDGERESIZE; - else if (arg == "center") + if (arg == "center") mode = FluxboxWindow::CENTERRESIZE; else if (arg == "topleft") mode = FluxboxWindow::TOPLEFTRESIZE;

@@ -395,8 +394,35 @@ else if (arg == "bottom")

mode = FluxboxWindow::BOTTOMRESIZE; else if (arg == "bottomright") mode = FluxboxWindow::BOTTOMRIGHTRESIZE; + else if (arg == "nearestcorner") { + mode = FluxboxWindow::EDGEORCORNERRESIZE; + corner_size_pc = 100; + } else if (arg == "nearestedge") { + mode = FluxboxWindow::EDGEORCORNERRESIZE; + } else if (arg == "nearestcorneroredge") { + mode = FluxboxWindow::EDGEORCORNERRESIZE; + /* The NearestCornerOrEdge can be followed by a corner size in + * one of three forms: + * <size in pixels> + * <size in pixels> <size in percent> + * <size in percent>% + * If no corner size is given then it defaults to 50 pixels, 30%. */ + if (tokens.size() > 1) { + const char * size1 = tokens[1].c_str(); + if (size1[strlen(size1)-1] == '%') + corner_size_pc = atoi(size1); + else { + corner_size_px = atoi(size1); + if (tokens.size() > 2) + corner_size_pc = atoi(tokens[2].c_str()); + } + } else { + corner_size_px = 50; + corner_size_pc = 30; + } + } } - return new StartResizingCmd(mode); + return new StartResizingCmd(mode, corner_size_px, corner_size_pc); } REGISTER_COMMAND_PARSER(startresizing, StartResizingCmd::parse, void);

@@ -422,7 +448,8 @@

x -= fbwindow().x() - fbwindow().frame().window().borderWidth(); y -= fbwindow().y() - fbwindow().frame().window().borderWidth(); - fbwindow().startResizing(x, y, fbwindow().getResizeDirection(x, y, m_mode)); + fbwindow().startResizing(x, y, fbwindow().getResizeDirection( + x, y, m_mode, m_corner_size_px, m_corner_size_pc)); } REGISTER_COMMAND(starttabbing, StartTabbingCmd, void);
M src/CurrentWindowCmd.hhsrc/CurrentWindowCmd.hh

@@ -124,13 +124,16 @@

// begin resizing with mouse class StartResizingCmd: public WindowHelperCmd { public: - explicit StartResizingCmd(FluxboxWindow::ResizeModel mode):m_mode(mode) { } + explicit StartResizingCmd(FluxboxWindow::ResizeModel mode, int corner_size_px, int corner_size_pc): + m_mode(mode), m_corner_size_px(corner_size_px), m_corner_size_pc(corner_size_pc) { } static FbTk::Command<void> *parse(const std::string &command, const std::string &args, bool trusted); protected: void real_execute(); private: const FluxboxWindow::ResizeModel m_mode; + const int m_corner_size_px; // Corner size in pixels + const int m_corner_size_pc; // and in percent of half window width/height }; // begin tabbing with mouse
M src/Window.ccsrc/Window.cc

@@ -251,6 +251,18 @@ int m_num;

int m_mode; }; + +// Helper class for getResizeDirection below +// Tests whether a point is on an edge or the corner. +struct TestEdgeHelper { + int corner_size_px, corner_size_pc; + inline bool operator()(int xy, int wh) + { + /* The % checking must be right: 0% must fail, 100% must succeed. */ + return xy < corner_size_px || 100 * xy < corner_size_pc * wh; + } +}; + }

@@ -3004,30 +3016,44 @@ orig_top += dy;

} + FluxboxWindow::ReferenceCorner FluxboxWindow::getResizeDirection(int x, int y, - ResizeModel model) const { + ResizeModel model, int corner_size_px, int corner_size_pc) const +{ + if (model == TOPLEFTRESIZE) return LEFTTOP; + if (model == TOPRESIZE) return TOP; + if (model == TOPRIGHTRESIZE) return RIGHTTOP; + if (model == LEFTRESIZE) return LEFT; + if (model == RIGHTRESIZE) return RIGHT; + if (model == BOTTOMLEFTRESIZE) return LEFTBOTTOM; + if (model == BOTTOMRESIZE) return BOTTOM; + if (model == CENTERRESIZE) return CENTER; - int cx = frame().width() / 2; - int cy = frame().height() / 2; - if (model == CENTERRESIZE) - return CENTER; - if (model == NEARESTEDGERESIZE) { + if (model == EDGEORCORNERRESIZE) + { + int w = frame().width(); + int h = frame().height(); + int cx = w / 2; + int cy = h / 2; + TestEdgeHelper test_edge = { corner_size_px, corner_size_pc }; + if (x < cx && test_edge(x, cx)) { + if (y < cy && test_edge(y, cy)) + return LEFTTOP; + else if (test_edge(h - y - 1, h - cy)) + return LEFTBOTTOM; + } else if (test_edge(w - x - 1, w - cx)) { + if (y < cy && test_edge(y, cy)) + return RIGHTTOP; + else if (test_edge(h - y - 1, h - cy)) + return RIGHTBOTTOM; + } + + /* Nope, not a corner; find the nearest edge instead. */ if (cy - abs(y - cy) < cx - abs(x - cx)) // y is nearest return (y > cy) ? BOTTOM : TOP; - return (x > cx) ? RIGHT : LEFT; - } - if (model == QUADRANTRESIZE) { - if (x < cx) - return (y < cy) ? LEFTTOP : LEFTBOTTOM; - return (y < cy) ? RIGHTTOP : RIGHTBOTTOM; + else + return (x > cx) ? RIGHT : LEFT; } - if (model == TOPLEFTRESIZE) return LEFTTOP; - if (model == TOPRESIZE) return TOP; - if (model == TOPRIGHTRESIZE) return RIGHTTOP; - if (model == LEFTRESIZE) return LEFT; - if (model == RIGHTRESIZE) return RIGHT; - if (model == BOTTOMLEFTRESIZE) return LEFTBOTTOM; - if (model == BOTTOMRESIZE) return BOTTOM; return RIGHTBOTTOM; }
M src/Window.hhsrc/Window.hh

@@ -89,9 +89,7 @@ };

/// Different resize modes when resizing a window enum ResizeModel { - QUADRANTRESIZE, ///< resizes from one quadrant CENTERRESIZE, ///< resizes from center - NEARESTEDGERESIZE, ///< resizes the nearest edge TOPLEFTRESIZE, ///< resizes top left corner TOPRESIZE, ///< resizes top edge TOPRIGHTRESIZE, ///< resizes top right corner

@@ -100,6 +98,7 @@ RIGHTRESIZE, ///< resizes right edge

BOTTOMLEFTRESIZE, ///< resizes bottom left corner BOTTOMRESIZE, ///< resizes bottom edge BOTTOMRIGHTRESIZE, ///< resizes bottom right corner + EDGEORCORNERRESIZE, ///< resizes nearest edge or corner DEFAULTRESIZE = BOTTOMRIGHTRESIZE ///< default resize mode };

@@ -341,7 +340,7 @@ * @param dir the resize direction

*/ void startResizing(int x, int y, ReferenceCorner dir); /// determine which edge or corner to resize - ReferenceCorner getResizeDirection(int x, int y, ResizeModel model) const; + ReferenceCorner getResizeDirection(int x, int y, ResizeModel model, int corner_size_px, int corner_size_pc) const; /// stops the resizing void stopResizing(bool interrupted = false); /// starts tabbing