- wright = dx + frame.rect.width() - 1,
- wtop = dy,
- wbottom = dy + frame.rect.height() - 1;
-
- int dleft = std::abs(wleft - srect.left()),
- dright = std::abs(wright - srect.right()),
- dtop = std::abs(wtop - srect.top()),
- dbottom = std::abs(wbottom - srect.bottom());
-
- // snap left?
- if (dleft < snap_distance && dleft < dright)
- dx = srect.left();
- // snap right?
- else if (dright < snap_distance && dright < dleft)
- dx = srect.right() - frame.rect.width() + 1;
-
- // snap top?
- if (dtop < snap_distance && dtop < dbottom)
- dy = srect.top();
- // snap bottom?
- else if (dbottom < snap_distance && dbottom < dtop)
- dy = srect.bottom() - frame.rect.height() + 1;
-
- srect = screen->getRect(); // now get the full screen
-
- dleft = std::abs(wleft - srect.left()),
- dright = std::abs(wright - srect.right()),
- dtop = std::abs(wtop - srect.top()),
- dbottom = std::abs(wbottom - srect.bottom());
-
- // snap left?
- if (dleft < snap_distance && dleft < dright)
- dx = srect.left();
- // snap right?
- else if (dright < snap_distance && dright < dleft)
- dx = srect.right() - frame.rect.width() + 1;
-
- // snap top?
- if (dtop < snap_distance && dtop < dbottom)
- dy = srect.top();
- // snap bottom?
- else if (dbottom < snap_distance && dbottom < dtop)
- dy = srect.bottom() - frame.rect.height() + 1;
+ wright = dx + frame.rect.width() - 1,
+ wtop = dy,
+ wbottom = dy + frame.rect.height() - 1;
+
+ if (screen->getWindowToWindowSnap()) {
+ Workspace *w = screen->getWorkspace(getWorkspaceNumber());
+ assert(w);
+
+ // try snap to another window
+ for (unsigned int i = 0, c = w->getCount(); i < c; ++i) {
+ BlackboxWindow *snapwin = w->getWindow(i);
+ if (snapwin == this)
+ continue; // don't snap to self
+
+ bool snapped = False;
+
+ const Rect &winrect = snapwin->frameRect();
+ int dleft = abs(wright - winrect.left()),
+ dright = abs(wleft - winrect.right()),
+ dtop = abs(wbottom - winrect.top()),
+ dbottom = abs(wtop - winrect.bottom());
+
+ if (wtop >= (signed)(winrect.y() - frame.rect.height() + 1) &&
+ wtop < (signed)(winrect.y() + winrect.height() - 1)) {
+
+ // snap left of other window?
+ if (dleft < snap_distance && dleft <= dright) {
+ dx = winrect.left() - frame.rect.width();
+ snapped = True;
+ }
+ // snap right of other window?
+ else if (dright < snap_distance) {
+ dx = winrect.right() + 1;
+ snapped = True;
+ }
+
+ if (snapped) {
+ if (screen->getWindowCornerSnap()) {
+ // try corner-snap to its other sides
+ dtop = abs(wtop - winrect.top());
+ dbottom = abs(wbottom - winrect.bottom());
+ if (dtop < snap_distance && dtop <= dbottom)
+ dy = winrect.top();
+ else if (dbottom < snap_distance)
+ dy = winrect.bottom() - frame.rect.height() + 1;
+ }
+
+ continue;
+ }
+ }
+
+ if (wleft >= (signed)(winrect.x() - frame.rect.width() + 1) &&
+ wleft < (signed)(winrect.x() + winrect.width() - 1)) {
+
+ // snap top of other window?
+ if (dtop < snap_distance && dtop <= dbottom) {
+ dy = winrect.top() - frame.rect.height();
+ snapped = True;
+ }
+ // snap bottom of other window?
+ else if (dbottom < snap_distance) {
+ dy = winrect.bottom() + 1;
+ snapped = True;
+ }
+
+ if (snapped) {
+ if (screen->getWindowCornerSnap()) {
+ // try corner-snap to its other sides
+ dleft = abs(wleft - winrect.left());
+ dright = abs(wright - winrect.right());
+ if (dleft < snap_distance && dleft <= dright)
+ dx = winrect.left();
+ else if (dright < snap_distance)
+ dx = winrect.right() - frame.rect.width() + 1;
+ }
+
+ continue;
+ }
+ }
+ }
+ }
+
+ RectList snaplist; // the list of rects we will try to snap to
+
+ // snap to the strut (and screen boundaries for xinerama)
+#ifdef XINERAMA
+ if (screen->isXineramaActive() && blackbox->doXineramaSnapping()) {
+ if (! screen->doFullMax())
+ snaplist.insert(snaplist.begin(),
+ screen->allAvailableAreas().begin(),
+ screen->allAvailableAreas().end());
+
+ // always snap to the screen edges
+ snaplist.insert(snaplist.begin(),
+ screen->getXineramaAreas().begin(),
+ screen->getXineramaAreas().end());
+ } else
+#endif // XINERAMA
+ {
+ if (! screen->doFullMax())
+ snaplist.push_back(screen->availableArea());
+
+ // always snap to the screen edges
+ snaplist.push_back(screen->getRect());
+ }
+
+ RectList::const_iterator it, end = snaplist.end();
+ for (it = snaplist.begin(); it != end; ++it) {
+ const Rect &srect = *it;
+
+ // if we're not in the rectangle then don't snap to it.
+ if (! srect.intersects(Rect(wleft, wtop, frame.rect.width(),
+ frame.rect.height())))
+ continue;
+
+ int dleft = abs(wleft - srect.left()),
+ dright = abs(wright - srect.right()),
+ dtop = abs(wtop - srect.top()),
+ dbottom = abs(wbottom - srect.bottom());
+
+ // snap left?
+ if (dleft < snap_distance && dleft <= dright)
+ dx = srect.left();
+ // snap right?
+ else if (dright < snap_distance)
+ dx = srect.right() - frame.rect.width() + 1;
+
+ // snap top?
+ if (dtop < snap_distance && dtop <= dbottom)
+ dy = srect.top();
+ // snap bottom?
+ else if (dbottom < snap_distance)
+ dy = srect.bottom() - frame.rect.height() + 1;
+ }