aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Abbott <michael@araneidae.co.uk>2012-09-29 07:10:48 (GMT)
committerMathias Gumz <akira at fluxbox dot org>2012-10-04 07:36:23 (GMT)
commit391712b9805eda9d56a100f49d69b38863910565 (patch)
tree05d5a6eea9fef53a371676f76ec4c1e1ef0893a1
parent7b6ab828c7e5453a2720462156d165707935c9ef (diff)
downloadfluxbox-391712b9805eda9d56a100f49d69b38863910565.zip
fluxbox-391712b9805eda9d56a100f49d69b38863910565.tar.bz2
Add support for nearest corner or edge resizing
-rw-r--r--doc/asciidoc/fluxbox-keys.txt12
-rw-r--r--src/CurrentWindowCmd.cc41
-rw-r--r--src/CurrentWindowCmd.hh5
-rw-r--r--src/Window.cc66
-rw-r--r--src/Window.hh5
5 files changed, 96 insertions, 33 deletions
diff --git a/doc/asciidoc/fluxbox-keys.txt b/doc/asciidoc/fluxbox-keys.txt
index 0d0b52e..96b1141 100644
--- a/doc/asciidoc/fluxbox-keys.txt
+++ b/doc/asciidoc/fluxbox-keys.txt
@@ -178,8 +178,16 @@ Start dragging to resize the window as if you had grabbed the window
178at the specified 'corner'. 178at the specified 'corner'.
179+ 179+
180By default 'corner' is *BottomRight*, but may be overridden with one of:;; 180By default 'corner' is *BottomRight*, but may be overridden with one of:;;
181*NearestCorner NearestEdge Center TopLeft Top TopRight Left Right BottomLeft 181*NearestCorner NearestEdge NearestCornerOrEdge Center TopLeft Top TopRight
182Bottom BottomRight* 182Left Right BottomLeft Bottom BottomRight*
183
184+
185If *NearestCornerOrEdge* is specified the size of the corner can also be
186specified to be the larger of one or two following numbers: ['pixel-size'
187['percent-size']] or 'percent-size'%, where 'percent-size' is the
188percentage of half the window width or height. If no size is given, it
189defaults to 50 pixels and 30%.
190
183 191
184*StartTabbing*:: 192*StartTabbing*::
185 Start dragging to add this window to another's tabgroup. 193 Start dragging to add this window to another's tabgroup.
diff --git a/src/CurrentWindowCmd.cc b/src/CurrentWindowCmd.cc
index 4363d0d..6138e64 100644
--- a/src/CurrentWindowCmd.cc
+++ b/src/CurrentWindowCmd.cc
@@ -20,6 +20,7 @@
20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21// DEALINGS IN THE SOFTWARE. 21// DEALINGS IN THE SOFTWARE.
22 22
23#include <string.h>
23#include "CurrentWindowCmd.hh" 24#include "CurrentWindowCmd.hh"
24 25
25#include "fluxbox.hh" 26#include "fluxbox.hh"
@@ -369,15 +370,13 @@ void StartMovingCmd::real_execute() {
369FbTk::Command<void> *StartResizingCmd::parse(const string &cmd, const string &args, 370FbTk::Command<void> *StartResizingCmd::parse(const string &cmd, const string &args,
370 bool trusted) { 371 bool trusted) {
371 FluxboxWindow::ResizeModel mode = FluxboxWindow::DEFAULTRESIZE; 372 FluxboxWindow::ResizeModel mode = FluxboxWindow::DEFAULTRESIZE;
373 int corner_size_px = 0;
374 int corner_size_pc = 0;
372 std::vector<string> tokens; 375 std::vector<string> tokens;
373 FbTk::StringUtil::stringtok<std::vector<string> >(tokens, args); 376 FbTk::StringUtil::stringtok<std::vector<string> >(tokens, args);
374 if (!tokens.empty()) { 377 if (!tokens.empty()) {
375 string arg = FbTk::StringUtil::toLower(tokens[0]); 378 string arg = FbTk::StringUtil::toLower(tokens[0]);
376 if (arg == "nearestcorner") 379 if (arg == "center")
377 mode = FluxboxWindow::QUADRANTRESIZE;
378 else if (arg == "nearestedge")
379 mode = FluxboxWindow::NEARESTEDGERESIZE;
380 else if (arg == "center")
381 mode = FluxboxWindow::CENTERRESIZE; 380 mode = FluxboxWindow::CENTERRESIZE;
382 else if (arg == "topleft") 381 else if (arg == "topleft")
383 mode = FluxboxWindow::TOPLEFTRESIZE; 382 mode = FluxboxWindow::TOPLEFTRESIZE;
@@ -395,8 +394,35 @@ FbTk::Command<void> *StartResizingCmd::parse(const string &cmd, const string &ar
395 mode = FluxboxWindow::BOTTOMRESIZE; 394 mode = FluxboxWindow::BOTTOMRESIZE;
396 else if (arg == "bottomright") 395 else if (arg == "bottomright")
397 mode = FluxboxWindow::BOTTOMRIGHTRESIZE; 396 mode = FluxboxWindow::BOTTOMRIGHTRESIZE;
397 else if (arg == "nearestcorner") {
398 mode = FluxboxWindow::EDGEORCORNERRESIZE;
399 corner_size_pc = 100;
400 } else if (arg == "nearestedge") {
401 mode = FluxboxWindow::EDGEORCORNERRESIZE;
402 } else if (arg == "nearestcorneroredge") {
403 mode = FluxboxWindow::EDGEORCORNERRESIZE;
404 /* The NearestCornerOrEdge can be followed by a corner size in
405 * one of three forms:
406 * <size in pixels>
407 * <size in pixels> <size in percent>
408 * <size in percent>%
409 * If no corner size is given then it defaults to 50 pixels, 30%. */
410 if (tokens.size() > 1) {
411 const char * size1 = tokens[1].c_str();
412 if (size1[strlen(size1)-1] == '%')
413 corner_size_pc = atoi(size1);
414 else {
415 corner_size_px = atoi(size1);
416 if (tokens.size() > 2)
417 corner_size_pc = atoi(tokens[2].c_str());
418 }
419 } else {
420 corner_size_px = 50;
421 corner_size_pc = 30;
422 }
423 }
398 } 424 }
399 return new StartResizingCmd(mode); 425 return new StartResizingCmd(mode, corner_size_px, corner_size_pc);
400} 426}
401 427
402REGISTER_COMMAND_PARSER(startresizing, StartResizingCmd::parse, void); 428REGISTER_COMMAND_PARSER(startresizing, StartResizingCmd::parse, void);
@@ -422,7 +448,8 @@ void StartResizingCmd::real_execute() {
422 x -= fbwindow().x() - fbwindow().frame().window().borderWidth(); 448 x -= fbwindow().x() - fbwindow().frame().window().borderWidth();
423 y -= fbwindow().y() - fbwindow().frame().window().borderWidth(); 449 y -= fbwindow().y() - fbwindow().frame().window().borderWidth();
424 450
425 fbwindow().startResizing(x, y, fbwindow().getResizeDirection(x, y, m_mode)); 451 fbwindow().startResizing(x, y, fbwindow().getResizeDirection(
452 x, y, m_mode, m_corner_size_px, m_corner_size_pc));
426} 453}
427 454
428REGISTER_COMMAND(starttabbing, StartTabbingCmd, void); 455REGISTER_COMMAND(starttabbing, StartTabbingCmd, void);
diff --git a/src/CurrentWindowCmd.hh b/src/CurrentWindowCmd.hh
index f406796..95175f2 100644
--- a/src/CurrentWindowCmd.hh
+++ b/src/CurrentWindowCmd.hh
@@ -124,13 +124,16 @@ protected:
124// begin resizing with mouse 124// begin resizing with mouse
125class StartResizingCmd: public WindowHelperCmd { 125class StartResizingCmd: public WindowHelperCmd {
126public: 126public:
127 explicit StartResizingCmd(FluxboxWindow::ResizeModel mode):m_mode(mode) { } 127 explicit StartResizingCmd(FluxboxWindow::ResizeModel mode, int corner_size_px, int corner_size_pc):
128 m_mode(mode), m_corner_size_px(corner_size_px), m_corner_size_pc(corner_size_pc) { }
128 static FbTk::Command<void> *parse(const std::string &command, 129 static FbTk::Command<void> *parse(const std::string &command,
129 const std::string &args, bool trusted); 130 const std::string &args, bool trusted);
130protected: 131protected:
131 void real_execute(); 132 void real_execute();
132private: 133private:
133 const FluxboxWindow::ResizeModel m_mode; 134 const FluxboxWindow::ResizeModel m_mode;
135 const int m_corner_size_px; // Corner size in pixels
136 const int m_corner_size_pc; // and in percent of half window width/height
134}; 137};
135 138
136// begin tabbing with mouse 139// begin tabbing with mouse
diff --git a/src/Window.cc b/src/Window.cc
index 33a4c9e..0b8d1e5 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -251,6 +251,18 @@ private:
251 int m_mode; 251 int m_mode;
252}; 252};
253 253
254
255// Helper class for getResizeDirection below
256// Tests whether a point is on an edge or the corner.
257struct TestEdgeHelper {
258 int corner_size_px, corner_size_pc;
259 inline bool operator()(int xy, int wh)
260 {
261 /* The % checking must be right: 0% must fail, 100% must succeed. */
262 return xy < corner_size_px || 100 * xy < corner_size_pc * wh;
263 }
264};
265
254} 266}
255 267
256 268
@@ -3004,30 +3016,44 @@ void FluxboxWindow::doSnapping(int &orig_left, int &orig_top) {
3004 3016
3005} 3017}
3006 3018
3019
3007FluxboxWindow::ReferenceCorner FluxboxWindow::getResizeDirection(int x, int y, 3020FluxboxWindow::ReferenceCorner FluxboxWindow::getResizeDirection(int x, int y,
3008 ResizeModel model) const { 3021 ResizeModel model, int corner_size_px, int corner_size_pc) const
3022{
3023 if (model == TOPLEFTRESIZE) return LEFTTOP;
3024 if (model == TOPRESIZE) return TOP;
3025 if (model == TOPRIGHTRESIZE) return RIGHTTOP;
3026 if (model == LEFTRESIZE) return LEFT;
3027 if (model == RIGHTRESIZE) return RIGHT;
3028 if (model == BOTTOMLEFTRESIZE) return LEFTBOTTOM;
3029 if (model == BOTTOMRESIZE) return BOTTOM;
3030 if (model == CENTERRESIZE) return CENTER;
3031
3032 if (model == EDGEORCORNERRESIZE)
3033 {
3034 int w = frame().width();
3035 int h = frame().height();
3036 int cx = w / 2;
3037 int cy = h / 2;
3038 TestEdgeHelper test_edge = { corner_size_px, corner_size_pc };
3039 if (x < cx && test_edge(x, cx)) {
3040 if (y < cy && test_edge(y, cy))
3041 return LEFTTOP;
3042 else if (test_edge(h - y - 1, h - cy))
3043 return LEFTBOTTOM;
3044 } else if (test_edge(w - x - 1, w - cx)) {
3045 if (y < cy && test_edge(y, cy))
3046 return RIGHTTOP;
3047 else if (test_edge(h - y - 1, h - cy))
3048 return RIGHTBOTTOM;
3049 }
3009 3050
3010 int cx = frame().width() / 2; 3051 /* Nope, not a corner; find the nearest edge instead. */
3011 int cy = frame().height() / 2;
3012 if (model == CENTERRESIZE)
3013 return CENTER;
3014 if (model == NEARESTEDGERESIZE) {
3015 if (cy - abs(y - cy) < cx - abs(x - cx)) // y is nearest 3052 if (cy - abs(y - cy) < cx - abs(x - cx)) // y is nearest
3016 return (y > cy) ? BOTTOM : TOP; 3053 return (y > cy) ? BOTTOM : TOP;
3017 return (x > cx) ? RIGHT : LEFT; 3054 else
3018 } 3055 return (x > cx) ? RIGHT : LEFT;
3019 if (model == QUADRANTRESIZE) { 3056 }
3020 if (x < cx)
3021 return (y < cy) ? LEFTTOP : LEFTBOTTOM;
3022 return (y < cy) ? RIGHTTOP : RIGHTBOTTOM;
3023 }
3024 if (model == TOPLEFTRESIZE) return LEFTTOP;
3025 if (model == TOPRESIZE) return TOP;
3026 if (model == TOPRIGHTRESIZE) return RIGHTTOP;
3027 if (model == LEFTRESIZE) return LEFT;
3028 if (model == RIGHTRESIZE) return RIGHT;
3029 if (model == BOTTOMLEFTRESIZE) return LEFTBOTTOM;
3030 if (model == BOTTOMRESIZE) return BOTTOM;
3031 return RIGHTBOTTOM; 3057 return RIGHTBOTTOM;
3032} 3058}
3033 3059
diff --git a/src/Window.hh b/src/Window.hh
index 09374af..b7975f5 100644
--- a/src/Window.hh
+++ b/src/Window.hh
@@ -89,9 +89,7 @@ public:
89 89
90 /// Different resize modes when resizing a window 90 /// Different resize modes when resizing a window
91 enum ResizeModel { 91 enum ResizeModel {
92 QUADRANTRESIZE, ///< resizes from one quadrant
93 CENTERRESIZE, ///< resizes from center 92 CENTERRESIZE, ///< resizes from center
94 NEARESTEDGERESIZE, ///< resizes the nearest edge
95 TOPLEFTRESIZE, ///< resizes top left corner 93 TOPLEFTRESIZE, ///< resizes top left corner
96 TOPRESIZE, ///< resizes top edge 94 TOPRESIZE, ///< resizes top edge
97 TOPRIGHTRESIZE, ///< resizes top right corner 95 TOPRIGHTRESIZE, ///< resizes top right corner
@@ -100,6 +98,7 @@ public:
100 BOTTOMLEFTRESIZE, ///< resizes bottom left corner 98 BOTTOMLEFTRESIZE, ///< resizes bottom left corner
101 BOTTOMRESIZE, ///< resizes bottom edge 99 BOTTOMRESIZE, ///< resizes bottom edge
102 BOTTOMRIGHTRESIZE, ///< resizes bottom right corner 100 BOTTOMRIGHTRESIZE, ///< resizes bottom right corner
101 EDGEORCORNERRESIZE, ///< resizes nearest edge or corner
103 DEFAULTRESIZE = BOTTOMRIGHTRESIZE ///< default resize mode 102 DEFAULTRESIZE = BOTTOMRIGHTRESIZE ///< default resize mode
104 }; 103 };
105 104
@@ -341,7 +340,7 @@ public:
341 */ 340 */
342 void startResizing(int x, int y, ReferenceCorner dir); 341 void startResizing(int x, int y, ReferenceCorner dir);
343 /// determine which edge or corner to resize 342 /// determine which edge or corner to resize
344 ReferenceCorner getResizeDirection(int x, int y, ResizeModel model) const; 343 ReferenceCorner getResizeDirection(int x, int y, ResizeModel model, int corner_size_px, int corner_size_pc) const;
345 /// stops the resizing 344 /// stops the resizing
346 void stopResizing(bool interrupted = false); 345 void stopResizing(bool interrupted = false);
347 /// starts tabbing 346 /// starts tabbing