aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorrathnor <rathnor>2003-04-20 02:47:15 (GMT)
committerrathnor <rathnor>2003-04-20 02:47:15 (GMT)
commite75378d0e6d5891536e24389fcbeabeb7a9d579a (patch)
tree0cd085d6d1b6c81af4e96bc440c2bd38cb49354c /src
parentb42b0620f49e396aea5d6ee68ce252b1139b4ab4 (diff)
downloadfluxbox-e75378d0e6d5891536e24389fcbeabeb7a9d579a.zip
fluxbox-e75378d0e6d5891536e24389fcbeabeb7a9d579a.tar.bz2
Add window snapping (Simon)
Diffstat (limited to 'src')
-rw-r--r--src/Window.cc143
-rw-r--r--src/Window.hh5
2 files changed, 133 insertions, 15 deletions
diff --git a/src/Window.cc b/src/Window.cc
index cbd5b84..890a4e0 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -22,7 +22,7 @@
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23// DEALINGS IN THE SOFTWARE. 23// DEALINGS IN THE SOFTWARE.
24 24
25// $Id: Window.cc,v 1.143 2003/04/16 22:17:46 fluxgen Exp $ 25// $Id: Window.cc,v 1.144 2003/04/20 02:47:14 rathnor Exp $
26 26
27#include "Window.hh" 27#include "Window.hh"
28 28
@@ -2303,18 +2303,19 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
2303 dx += me.x_root - button_grab_x; 2303 dx += me.x_root - button_grab_x;
2304 } 2304 }
2305 } 2305 }
2306 2306 // dx = current left side, dy = current top
2307 doSnapping(dx, dy);
2307 2308
2308 if (! screen.doOpaqueMove()) { 2309 if (! screen.doOpaqueMove()) {
2309 XDrawRectangle(display, screen.getRootWindow(), screen.getOpGC(), 2310 XDrawRectangle(display, screen.getRootWindow(), screen.getOpGC(),
2310 last_move_x, last_move_y, 2311 last_move_x, last_move_y,
2311 m_frame.width() + 2*frame().window().borderWidth(), 2312 m_frame.width() + 2*frame().window().borderWidth()-1,
2312 m_frame.height() + 2*frame().window().borderWidth()); 2313 m_frame.height() + 2*frame().window().borderWidth()-1);
2313 2314
2314 XDrawRectangle(display, screen.getRootWindow(), screen.getOpGC(), 2315 XDrawRectangle(display, screen.getRootWindow(), screen.getOpGC(),
2315 dx, dy, 2316 dx, dy,
2316 m_frame.width() + 2*frame().window().borderWidth(), 2317 m_frame.width() + 2*frame().window().borderWidth()-1,
2317 m_frame.height() + 2*frame().window().borderWidth()); 2318 m_frame.height() + 2*frame().window().borderWidth()-1);
2318 last_move_x = dx; 2319 last_move_x = dx;
2319 last_move_y = dy; 2320 last_move_y = dy;
2320 } else { 2321 } else {
@@ -2577,8 +2578,8 @@ void FluxboxWindow::startMoving(Window win) {
2577 fluxbox->grab(); 2578 fluxbox->grab();
2578 XDrawRectangle(display, screen.getRootWindow(), screen.getOpGC(), 2579 XDrawRectangle(display, screen.getRootWindow(), screen.getOpGC(),
2579 frame().x(), frame().y(), 2580 frame().x(), frame().y(),
2580 frame().width() + 2*frame().window().borderWidth(), 2581 frame().width() + 2*frame().window().borderWidth()-1,
2581 frame().height() + 2*frame().window().borderWidth()); 2582 frame().height() + 2*frame().window().borderWidth()-1);
2582 screen.showPosition(frame().x(), frame().y()); 2583 screen.showPosition(frame().x(), frame().y());
2583 } 2584 }
2584} 2585}
@@ -2593,8 +2594,8 @@ void FluxboxWindow::stopMoving() {
2593 if (! screen.doOpaqueMove()) { 2594 if (! screen.doOpaqueMove()) {
2594 XDrawRectangle(FbTk::App::instance()->display(), screen.getRootWindow(), screen.getOpGC(), 2595 XDrawRectangle(FbTk::App::instance()->display(), screen.getRootWindow(), screen.getOpGC(),
2595 last_move_x, last_move_y, 2596 last_move_x, last_move_y,
2596 frame().width() + 2*frame().window().borderWidth(), 2597 frame().width() + 2*frame().window().borderWidth()-1,
2597 frame().height() + 2*frame().window().borderWidth()); 2598 frame().height() + 2*frame().window().borderWidth()-1);
2598 moveResize(last_move_x, last_move_y, m_frame.width(), m_frame.height()); 2599 moveResize(last_move_x, last_move_y, m_frame.width(), m_frame.height());
2599 if (workspace_number != getScreen().getCurrentWorkspaceID()) { 2600 if (workspace_number != getScreen().getCurrentWorkspaceID()) {
2600 screen.reassociateWindow(this, getScreen().getCurrentWorkspaceID(), true); 2601 screen.reassociateWindow(this, getScreen().getCurrentWorkspaceID(), true);
@@ -2617,8 +2618,8 @@ void FluxboxWindow::pauseMoving() {
2617 2618
2618 XDrawRectangle(display, getScreen().getRootWindow(), getScreen().getOpGC(), 2619 XDrawRectangle(display, getScreen().getRootWindow(), getScreen().getOpGC(),
2619 last_move_x, last_move_y, 2620 last_move_x, last_move_y,
2620 m_frame.width() + 2*frame().window().borderWidth(), 2621 m_frame.width() + 2*frame().window().borderWidth()-1,
2621 m_frame.height() + 2*frame().window().borderWidth()); 2622 m_frame.height() + 2*frame().window().borderWidth()-1);
2622 2623
2623} 2624}
2624 2625
@@ -2634,8 +2635,122 @@ void FluxboxWindow::resumeMoving() {
2634 XSync(display,false); 2635 XSync(display,false);
2635 XDrawRectangle(display, screen.getRootWindow(), screen.getOpGC(), 2636 XDrawRectangle(display, screen.getRootWindow(), screen.getOpGC(),
2636 last_move_x, last_move_y, 2637 last_move_x, last_move_y,
2637 m_frame.width() + 2*frame().window().borderWidth(), 2638 m_frame.width() + 2*frame().window().borderWidth()-1,
2638 m_frame.height() + 2*frame().window().borderWidth()); 2639 m_frame.height() + 2*frame().window().borderWidth()-1);
2640
2641}
2642
2643/**
2644 * Helper function that snaps a window to another window
2645 * We snap if we're closer than the x/ylimits.
2646 */
2647inline void snapToWindow(int &xlimit, int &ylimit,
2648 int left, int right, int top, int bottom,
2649 int oleft, int oright, int otop, int obottom) {
2650 // Only snap if we're adjacent to the edge we're looking at
2651
2652 // for left + right, need to be in the right y range
2653 if (top <= obottom && bottom >= otop) {
2654 // left
2655 if (abs(left-oleft) < abs(xlimit)) xlimit = -(left-oleft);
2656 if (abs(right-oleft) < abs(xlimit)) xlimit = -(right-oleft);
2657
2658 // right
2659 if (abs(left-oright) < abs(xlimit)) xlimit = -(left-oright);
2660 if (abs(right-oright) < abs(xlimit)) xlimit = -(right-oright);
2661 }
2662
2663 // for top + bottom, need to be in the right x range
2664 if (left <= oright && right >= oleft) {
2665 // top
2666 if (abs(top-otop) < abs(ylimit)) ylimit = -(top-otop);
2667 if (abs(bottom-otop) < abs(ylimit)) ylimit = -(bottom-otop);
2668
2669 // bottom
2670 if (abs(top-obottom) < abs(ylimit)) ylimit = -(top-obottom);
2671 if (abs(bottom-obottom) < abs(ylimit)) ylimit = -(bottom-obottom);
2672 }
2673
2674}
2675
2676/*
2677 * Do Whatever snapping magic is necessary, and return using the left and top variables
2678 * to indicate the new x,y position
2679 */
2680void FluxboxWindow::doSnapping(int &orig_left, int &orig_top) {
2681 /*
2682 * Snap to screen edge
2683 * Snap to windows
2684 * Snap to toolbar
2685 * Snap to slit
2686 * TODO:
2687 * Xinerama screen edge?
2688 */
2689
2690 if (screen.getEdgeSnapThreshold() == 0) return;
2691
2692 // Keep track of our best offsets so far
2693 // We need to find things less than or equal to the threshold
2694 int dx = screen.getEdgeSnapThreshold() + 1;
2695 int dy = screen.getEdgeSnapThreshold() + 1;
2696
2697 // we only care about the left/top etc that includes borders
2698 int borderW = m_frame.window().borderWidth();
2699
2700 int top = orig_top; // orig include the borders
2701 int left = orig_left;
2702 int right = orig_left + getWidth() + 2*borderW;
2703 int bottom = orig_top + getHeight() + 2*borderW;
2704
2705 /////////////////////////////////////
2706 // begin by checking the screen edges
2707
2708 snapToWindow(dx, dy, left, right, top, bottom, 0, screen.getWidth(), 0, screen.getHeight());
2709
2710 /////////////////////////////////////
2711 // now check window edges
2712
2713 Workspace::Windows &wins =
2714 screen.getCurrentWorkspace()->getWindowList();
2715
2716 Workspace::Windows::iterator it = wins.begin();
2717 Workspace::Windows::iterator it_end = wins.end();
2718
2719 for (; it != it_end; it++) {
2720 if ((*it) == this) continue; // skip myself
2721
2722 snapToWindow(dx, dy, left, right, top, bottom,
2723 (*it)->getXFrame(),
2724 (*it)->getXFrame() + (*it)->getWidth() + 2*borderW,
2725 (*it)->getYFrame(),
2726 (*it)->getYFrame() + (*it)->getHeight() + 2*borderW);
2727 }
2728
2729 /////////////////////////////////////
2730 // now the toolbar
2731
2732 Toolbar *tbar = screen.getToolbar();
2733 if (tbar)
2734 snapToWindow(dx, dy, left, right, top, bottom,
2735 tbar->x(), tbar->x() + tbar->width() + 2*borderW,
2736 tbar->y(), tbar->y() + tbar->height() + 2*borderW);
2737
2738 /////////////////////////////////////
2739 // and the slit
2740
2741#ifdef SLIT
2742 Slit *slit = screen.getSlit();
2743 if (slit)
2744 snapToWindow(dx, dy, left, right, top, bottom,
2745 slit->x(), slit->x() + slit->width() + 2*borderW,
2746 slit->y(), slit->y() + slit->height() + 2*borderW);
2747#endif // SLIT
2748
2749 // commit
2750 if (dx <= screen.getEdgeSnapThreshold())
2751 orig_left += dx;
2752 if (dy <= screen.getEdgeSnapThreshold())
2753 orig_top += dy;
2639 2754
2640} 2755}
2641 2756
diff --git a/src/Window.hh b/src/Window.hh
index ba1413b..31be752 100644
--- a/src/Window.hh
+++ b/src/Window.hh
@@ -22,7 +22,7 @@
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23// DEALINGS IN THE SOFTWARE. 23// DEALINGS IN THE SOFTWARE.
24 24
25// $Id: Window.hh,v 1.58 2003/04/16 12:28:39 fluxgen Exp $ 25// $Id: Window.hh,v 1.59 2003/04/20 02:47:15 rathnor Exp $
26 26
27#ifndef WINDOW_HH 27#ifndef WINDOW_HH
28#define WINDOW_HH 28#define WINDOW_HH
@@ -348,6 +348,9 @@ private:
348 void setState(unsigned long stateval); 348 void setState(unsigned long stateval);
349 void upsize(); 349 void upsize();
350 void downsize(); 350 void downsize();
351
352 // modifies left and top if snap is necessary
353 void doSnapping(int &left, int &top);
351 void right_fixsize(int *x = 0, int *y = 0); 354 void right_fixsize(int *x = 0, int *y = 0);
352 void left_fixsize(int *x = 0, int *y = 0); 355 void left_fixsize(int *x = 0, int *y = 0);
353 void resizeClient(WinClient &client, unsigned int width, unsigned int height); 356 void resizeClient(WinClient &client, unsigned int width, unsigned int height);