diff options
author | rathnor <rathnor> | 2003-04-20 02:47:15 (GMT) |
---|---|---|
committer | rathnor <rathnor> | 2003-04-20 02:47:15 (GMT) |
commit | e75378d0e6d5891536e24389fcbeabeb7a9d579a (patch) | |
tree | 0cd085d6d1b6c81af4e96bc440c2bd38cb49354c /src | |
parent | b42b0620f49e396aea5d6ee68ce252b1139b4ab4 (diff) | |
download | fluxbox_lack-e75378d0e6d5891536e24389fcbeabeb7a9d579a.zip fluxbox_lack-e75378d0e6d5891536e24389fcbeabeb7a9d579a.tar.bz2 |
Add window snapping (Simon)
Diffstat (limited to 'src')
-rw-r--r-- | src/Window.cc | 143 | ||||
-rw-r--r-- | src/Window.hh | 5 |
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 | */ | ||
2647 | inline 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 | */ | ||
2680 | void 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); |