#include #include #include #include #include #include #include #include #include #include #ifdef WASABI_COMPILE_WNDMGR #include #endif #ifdef WASABI_COMPILE_SCRIPT #include #include #include // for appbar define #endif #ifdef WASABI_COMPILE_WNDMGR #include #include #endif #ifdef WASABI_COMPILE_SYSCB //#include #endif WindowTracker *windowTracker; WindowTracker::WindowTracker() : coopcache(0), coopcachewnd(NULL) { wascoop = 0; disabledock = 0; dock_enabled = 1; } WindowTracker::~WindowTracker() { coopList.deleteAll(); } void WindowTracker::addWindow(ifc_window *wnd) { ASSERT(wnd); desktopwnds.addItem(wnd); } void WindowTracker::removeWindow(ifc_window *wnd) { ASSERT(wnd); ASSERTPR(desktopwnds.haveItem(wnd), "removewindow on invalid wnd"); desktopwnds.removeItem(wnd); } int WindowTracker::checkWindow(ifc_window *wnd) { return allWnd.haveItem(wnd); } ifc_window *WindowTracker::enumWindows(int n) { return desktopwnds.enumItem(n); } ifc_window *WindowTracker::getNextDesktopWindow(ifc_window *w, int next) { ifc_window *nw = NULL; if (w == NULL) nw = desktopwnds.getFirst(); else { w = w->getDesktopParent(); int pos = desktopwnds.searchItem(w); if (pos == -1) nw = desktopwnds.getFirst(); else { pos += next; if (pos > desktopwnds.getNumItems() - 1) pos = 0; if (pos == -1) pos = desktopwnds.getNumItems() - 1; nw = desktopwnds.enumItem(pos); } } if (nw == w) return w; if (!nw->isVisible()) return getNextDesktopWindow(nw, next); return nw; } ifc_window *WindowTracker::enumAllWindows(int n) { return allWnd.enumItem(n); } int WindowTracker::getNumWindows() { return desktopwnds.getNumItems(); } int WindowTracker::getNumAllWindows() { return allWnd.getNumItems(); } void WindowTracker::invalidateAllWindows() { for (int i = allWnd.getNumItems() - 1;i >= 0;i--) { ifc_window *w = allWnd[i]; w->triggerEvent(TRIGGER_INVALIDATE); w->invalidate(); if (!w->isVirtual()) continue; w->triggerEvent(TRIGGER_ONRESIZE); } } RECT WindowTracker::findOpenRect(const RECT &prev, ifc_window *exclude) { POINT pp = { 0, 0 }; //CUT if (prev != NULL) { pp.x = prev.left; pp.y = prev.top; //CUT } RECT vr; // viewport rect Wasabi::Std::getViewport(&vr, &pp); // make a rect list PtrList list; for (int i = 0; ; i++) { ifc_window *wnd = enumWindows(i); if (wnd == NULL) break; if (wnd == exclude) continue; if (!wnd->isPostOnInit() && !wnd->isVisible()) continue; RECT *r = new RECT; wnd->getWindowRect(r); snapAdjustWindowRect(wnd, r); list.addItem(r); } FindOpenRect fr; RECT ret = fr.find(vr, list, prev); list.deleteAll(); return ret; } void WindowTracker::setDockDistance(int dd) { dockDist = MINMAX(dd, MIN_DOCK_DIST, MAX_DOCK_DIST); } int WindowTracker::getDockDistance() { if (dock_enabled) return dockDist; return 0; } void WindowTracker::setEnableDocking(int ed) { dock_enabled = ed; } bool WindowTracker::touches(const RECT &r2, const RECT &r1) { if (r2.left == r1.right || r2.right == r1.left || r2.right == r1.right || r2.left == r1.left) { if (r2.bottom >= r1.top && r2.top <= r1.bottom) return true; } if (r2.top == r1.bottom || r2.bottom == r1.top || r2.bottom == r1.bottom || r2.top == r1.top) { if (r2.right >= r1.left && r2.left <= r1.right) return true; } return false; } void WindowTracker::endCooperativeMove() { wascoop = 1; flushCoopWnds(); coopWnd = NULL; recursList.removeAll(); } void WindowTracker::startCooperativeMove(ifc_window *thiswnd) { coopWnd = thiswnd; wascoop = 1; flushCoopWnds(); if (recursList.getNumItems() > 0) recursList.removeAll(); addCooperative(thiswnd); foreach_reverse(recursList) // FG> we need to prevent windows from excessively activating our windows or focus is gonna blow up // thiswnd->bringToFront(); #ifdef WIN32 SetWindowPos(recursList.getfor()->gethWnd(), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOSENDCHANGING); #else recursList.getfor()->bringToFront(); #endif endfor; } int WindowTracker::getNumDocked() { return recursList.getNumItems(); } ifc_window *WindowTracker::enumDocked(int n) { return recursList.enumItem(n); } void WindowTracker::addCooperative(ifc_window *thiswnd) { int i; RECT r; RECT thisr; bool forceall = false; if (Std::keyModifier(STDKEY_ALT)) { forceall = TRUE; } #ifdef WASABI_COMPILE_WNDMGR Layout *l = static_cast(thiswnd->getInterface(layoutGuid)); if (l) { for (int i = 0; i < l->getNumLockedLayouts(); i++) { ifc_window *wnd = l->enumLockedLayout(i); addCoopWnd(wnd, 1); addCooperative(wnd); } } #endif if (recursList.searchItem(thiswnd) != -1) return ; recursList.addItem(thiswnd); if (Std::keyModifier(STDKEY_SHIFT)) return ; thiswnd->getWindowRect(&thisr); snapAdjustWindowRect(thiswnd, &thisr); for (i = 0; i < desktopwnds.getNumItems(); i++) { ifc_window *wnd = desktopwnds.enumItem(i); if (!wnd->isVisible()) continue; if (hasCoopWnd(wnd)) continue; if (wnd == thiswnd) continue; Layout *l = (Layout*)wnd->getInterface(layoutGuid); if (l && (l->getNoDock() #ifdef USEAPPBAR || l->appbar_isDocked() #endif )) continue; wnd->getWindowRect(&r); snapAdjustWindowRect(wnd, &r); #ifdef WASABI_COMPILE_WNDMGR int snap = SnapPoint::match(thiswnd, NULL, wnd, KEEPSIZE, NULL, NULL, 0, 0); if (forceall || snap || (touches(r, thisr) && !Wasabi::Std::rectIntersect(r, thisr))) { #else if (forceall || (touches(r, thisr) && !Std::rectIntersect(r, thisr))) { #endif addCoopWnd(wnd); addCooperative(wnd); } } } bool WindowTracker::autoDock(ifc_window *thishWnd, RECT *newPosition, int mask) { return autoDock(thishWnd, newPosition, NULL, mask); } bool WindowTracker::autoDock(ifc_window *thiswnd, RECT *z, RECT *_oldPosition, int mask) { int i = 0; RECT r = {0}; #ifdef WASABI_COMPILE_CONFIG extern _bool cfg_options_docking; extern _int cfg_options_dockingdistance; dockDist = cfg_options_dockingdistance; dock_enabled = cfg_options_docking; #else #warning check these values dockDist = 4; dock_enabled = 4; #endif #ifdef USEAPPBAR // Layout *_l = static_cast(thiswnd->getInterface(layoutGuid)); // if (_l->appbar_isDocked()) return 0; #endif RECT z_snapAdjust = {0}; snapAdjustWindowRect(thiswnd, z, &z_snapAdjust); RECT *oldPosition = _oldPosition; if (oldPosition) { oldPosition->left += z_snapAdjust.left; oldPosition->top += z_snapAdjust.top; } if (!coopWnd) wascoop = 0; disabledock = 0; if (Std::keyModifier(STDKEY_SHIFT)) { for (int i = 0;i < coopList.getNumItems();i++) { coopEntry *e = coopList.enumItem(i); if (!e->locked) { delete e; coopList.removeByPos(i); coopcachewnd = NULL; i--; } } disabledock = 1; } int f = 0, s = 0; int w = z->right - z->left; int h = z->bottom - z->top; POINT done = {0}; if (!disabledock) { ifc_window *wnd = NULL; for (i = desktopwnds.getNumItems(); i > -1; i--) { if (i == desktopwnds.getNumItems()) { #ifdef USEAPPBAR Layout *l = static_cast(thiswnd->getInterface(layoutGuid)); if (l->appbar_isDocked()) continue; #endif Wasabi::Std::getViewport(&r, thiswnd->gethWnd()); wnd = NULL; } else { wnd = desktopwnds.enumItem(i); if (coopWnd != NULL && hasCoopWnd(wnd)) continue; Layout *l = (Layout*)wnd->getInterface(layoutGuid); if (l && (l->getNoDock() #ifdef USEAPPBAR || l->appbar_isDocked() #endif )) continue; if (wnd->isVisible()) { wnd->getWindowRect(&r); snapAdjustWindowRect(wnd, &r); } else continue; } if (coopWnd != NULL && coopWnd == wnd || (i >= 0 && hasCoopWnd(desktopwnds.enumItem(i)))) continue; if (thiswnd == wnd) continue; RECT oz = *z; POINT thisdone = {0}; #ifdef WASABI_COMPILE_WNDMGR if (SnapPoint::match(thiswnd, z, wnd, mask, (int *)&thisdone.x, (int *)&thisdone.y, w, h)) s++; #endif if (z->left > r.left - getDockDistance() && z->left < r.left + getDockDistance() && (mask & LEFT) && !thisdone.x) { z->left = r.left; thisdone.x = 1; if (mask & KEEPSIZE) z->right = r.left + w; f++; } if (i != desktopwnds.getNumItems() && z->right > r.left - getDockDistance() && z->right < r.left + getDockDistance() && (mask & RIGHT) && !thisdone.x) { z->right = r.left; thisdone.x = 1; if (mask & KEEPSIZE) z->left = r.left - w; f++; } if (z->top > r.top - getDockDistance() && z->top < r.top + getDockDistance() && (mask & TOP) && !thisdone.y) { z->top = r.top; thisdone.y = 1; if (mask & KEEPSIZE) z->bottom = r.top + h; f++; } if (i != desktopwnds.getNumItems() && z->bottom > r.top - getDockDistance() && z->bottom < r.top + getDockDistance() && (mask & BOTTOM) && !thisdone.y) { z->bottom = r.top; thisdone.y = 1; if (mask & KEEPSIZE) z->top = r.top - h; f++; } if (z->right > r.right - getDockDistance() && z->right < r.right + getDockDistance() && (mask & RIGHT) && !thisdone.x) { z->right = r.right; thisdone.x = 1; if (mask & KEEPSIZE) z->left = r.right - w; f++; } if (i != desktopwnds.getNumItems() && z->left > r.right - getDockDistance() && z->left < r.right + getDockDistance() && (mask & LEFT) && !thisdone.x) { z->left = r.right; thisdone.x = 1; if (mask & KEEPSIZE) z->right = r.right + w; f++; } if (z->bottom > r.bottom - getDockDistance() && z->bottom < r.bottom + getDockDistance() && (mask & BOTTOM) && !thisdone.y) { z->bottom = r.bottom; thisdone.y = 1; if (mask & KEEPSIZE) z->top = r.bottom - h; f++; } if (i != desktopwnds.getNumItems() && z->top > r.bottom - getDockDistance() && z->top < r.bottom + getDockDistance() && (mask & TOP) && !thisdone.y) { z->top = r.bottom; thisdone.y = 1; if (mask & KEEPSIZE) z->bottom = r.bottom + h; f++; } if (((wnd != NULL && (mask & NOINTERSECT) && Wasabi::Std::rectIntersect(*z, r)) || !touches(*z, r)) && !s) { *z = oz; thisdone.x = 0; thisdone.y = 0; } done.x |= thisdone.x; done.y |= thisdone.y; } } if (coopWnd == thiswnd && oldPosition) { POINT s = {0}, redock = {0}; TList rlist; s.x = z->left - oldPosition->left; s.y = z->top - oldPosition->top; for (i = 0;i < coopList.getNumItems();i++) { RECT r = {0}; ifc_window *W = coopList.enumItem(i)->wnd; if (!checkWindow(W)) { coopEntry *e = coopList.enumItem(i); delete e; coopList.removeByPos(i); i--; continue; } if (W != (BaseWnd*) - 1) { W->getWindowRect(&r); //snapAdjustWindowRect(W, &r); } #ifdef WIN32 else GetWindowRect(WASABI_API_WND->main_getRootWnd()->gethWnd(), &r); #endif int w = r.right - r.left, h = r.bottom - r.top; r.left += s.x; r.top += s.y; r.right = r.left + w; r.bottom = r.top + h; RECT cr = r; if (autoDock(W, &cr, LEFT | RIGHT | TOP | BOTTOM | NOINTERSECT | KEEPSIZE)) { if (redock.x == 0) redock.x = cr.left - r.left; if (redock.y == 0) redock.y = cr.top - r.top; } rlist.addItem(r); } if (redock.x || redock.y) { Wasabi::Std::offsetRect(z, redock.x, redock.y); f++; } #ifdef WIN32 HDWP hd = NULL; if (coopList.getNumItems() > 0) hd = BeginDeferWindowPos(coopList.getNumItems()); #endif for (i = 0;i < coopList.getNumItems();i++) { RECT r = rlist.enumItem(i); ifc_window *W = coopList.enumItem(i)->wnd; r.left += redock.x; r.top += redock.y; //unsnapAdjustWindowRect(W, &r); #ifdef WIN32 W->notifyDeferredMove(r.left, r.top); //if (GetWindow(W->gethWnd(), GW_OWNER)) // SetWindowPos(W->gethWnd(), NULL, r.left, r.top, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); // else hd = DeferWindowPos(hd, W->gethWnd(), NULL, r.left, r.top, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER); #else W->move( r.left, r.top ); #endif } foreach(coopList) ifc_window *w = coopList.getfor()->wnd; if (w != coopWnd) { Layout *l = static_cast(w->getInterface(layoutGuid)); if (l) { l->beginMove(); } } endfor; #ifdef WIN32 if (coopList.getNumItems() > 0) EndDeferWindowPos(hd); #endif foreach(coopList) ifc_window *w = coopList.getfor()->wnd; if (w != coopWnd) { Layout *l = static_cast(w->getInterface(layoutGuid)); if (l) { l->onMove(); l->endMove(); } } endfor; rlist.removeAll(); } z->left -= z_snapAdjust.left; z->top -= z_snapAdjust.top; z->right += z_snapAdjust.right; z->bottom += z_snapAdjust.bottom; return ((f + s) != 0); } int WindowTracker::hasCoopWnd(ifc_window *w) { if (coopcachewnd == w) return coopcache; coopcachewnd = w; coopcache = 0; for (int i = 0;i < coopList.getNumItems();i++) if (coopList.enumItem(i)->wnd == w) { coopcache = 1; break; } return coopcache; } void WindowTracker::addCoopWnd(ifc_window *w, int forced) { coopList.addItem(new coopEntry(w, forced)); coopcachewnd = NULL; } void WindowTracker::flushCoopWnds() { coopList.deleteAll(); coopcachewnd = NULL; } void WindowTracker::addRootWnd(ifc_window *wnd) { ASSERT(!allWnd.haveItem(wnd)); allWnd.addItem(wnd); if (!wnd->isVirtual()) { ASSERT(!nonvirtuals.haveItem(wnd)); nonvirtuals.addItem(wnd); } } void WindowTracker::removeRootWnd(ifc_window *wnd) { allWnd.delItem(wnd); if (allWnd.getNumItems() == 0) allWnd.deleteAll(); // avoid fortify fals alarm on static int n = nonvirtuals.searchItem(wnd); if (n > -1) nonvirtuals.removeByPos(n); } ifc_window *WindowTracker::rootWndFromPoint(POINT *pt) { /* api_window *last = NULL; api_window *last_parent = NULL; for (int i=0;igetRootWndParent() != last_parent) return checkGhost(last, (signed short)pt->x, (signed short)pt->y); if (w->pointInWnd(pt)) { if (!w->getRootWndParent() || w->gethWnd() != w->getRootWndParent()->gethWnd()) return checkGhost(w, (signed short)pt->x, (signed short)pt->y); last = w; last_parent = w->getRootWndParent(); } } return NULL;*/ // Get window's top level window for pt #ifdef _WIN32 OSWINDOWHANDLE t = WindowFromPoint(*pt); if (!t) return NULL; //CHECK IF SAFE ! if (!rootWndFromHwnd(t)) return NULL; // Find its rootWnd for (int i = nonvirtuals.getNumItems() - 1;i >= 0;i--) { ifc_window *r = nonvirtuals[i]; if (r->gethWnd() == t) { POINT p = *pt; r->screenToClient((int*)&p.x, (int *)&p.y); return r->findRootWndChild(p.x, p.y); } } #else #warning port me! #endif return NULL; } ifc_window *WindowTracker::rootWndFromHwnd(OSWINDOWHANDLE h) { if (!h) return NULL; // Find its rootWnd for (int i = 0;i < allWnd.getNumItems();i++) { ifc_window *r = allWnd[i]; if (r->gethWnd() == h) return r; } return NULL; } int WindowTracker::wasCooperativeMove() { return wascoop; } // TODO: can be moved to a static function - doesn't seem to use any class data void WindowTracker::snapAdjustWindowRect(ifc_window *w, RECT *r, RECT *adjustvals) { #ifdef WASABI_COMPILE_WNDMGR if (w->getInterface(layoutGuid)) { RECT snapAdjust = {0}; static_cast(w)->getSnapAdjust(&snapAdjust); double rr = w->getRenderRatio(); if (rr != 1.0) { snapAdjust.left = (int)((double)(snapAdjust.left) * rr); snapAdjust.top = (int)((double)(snapAdjust.top) * rr); snapAdjust.right = (int)((double)(snapAdjust.right) * rr); snapAdjust.bottom = (int)((double)(snapAdjust.bottom) * rr); } r->left += snapAdjust.left; r->top += snapAdjust.top; r->right -= snapAdjust.right; r->bottom -= snapAdjust.bottom; if (adjustvals) *adjustvals = snapAdjust; } else { adjustvals = NULL; } #else if (adjustvals) MEMSET(adjustvals, 0, sizeof(RECT)); #endif } void WindowTracker::unsnapAdjustWindowRect(ifc_window *w, RECT *r, RECT *adjustvals) { #ifdef WASABI_COMPILE_WNDMGR if (w->getInterface(layoutGuid)) { RECT snapAdjust = {0}; static_cast(w)->getSnapAdjust(&snapAdjust); if (w->getRenderRatio() != 1.0) { double rr = w->getRenderRatio(); snapAdjust.left = (int)((double)(snapAdjust.left) * rr); snapAdjust.top = (int)((double)(snapAdjust.top) * rr); snapAdjust.right = (int)((double)(snapAdjust.right) * rr); snapAdjust.bottom = (int)((double)(snapAdjust.bottom) * rr); } r->left -= snapAdjust.left; r->top -= snapAdjust.top; r->right += snapAdjust.right; r->bottom += snapAdjust.bottom; if (adjustvals) *adjustvals = snapAdjust; } else { adjustvals = NULL; } #else if (adjustvals) MEMSET(adjustvals, 0, sizeof(RECT)); #endif } void WindowTracker::recursAddToMoveWindows(ifc_window *wnd, redock_struct *rs, int v) { if (!rs) return ; RECT r1; if (wnd != NULL) { wnd->getWindowRect(&r1); snapAdjustWindowRect(wnd, &r1); } else { wnd = rs->l; r1 = rs->original_rect; if (!WASABI_API_WND->rootwndIsValid(wnd)) return ; } { Layout *l = (Layout*)wnd->getInterface(layoutGuid); if (l && (l->getNoDock() #ifdef USEAPPBAR || l->appbar_isDocked() #endif )) return ; } // add all touching windows for (int i = 0; i < desktopwnds.getNumItems(); i++) { ifc_window *w = desktopwnds[i]; if (!w->isVisible()) continue; if (w == wnd) continue; Layout *l = (Layout*)w->getInterface(layoutGuid); if (l && (l->getNoDock() #ifdef USEAPPBAR || l->appbar_isDocked() #endif )) continue; RECT r2; w->getWindowRect(&r2); snapAdjustWindowRect(w, &r2); // check for bottom touch if ((v == 1 || v == -1) && r2.top == r1.bottom && !tomoveWindows_bottom.haveItem(w)) { if (r2.right >= r1.left && r2.left <= r1.right) { tomoveWindows_bottom.addItem(w); recursAddToMoveWindows(w, rs, 1); } } // check for right touch if ((v == 0 || v == -1) && r2.left == r1.right && !tomoveWindows_right.haveItem(w)) { if (r2.bottom >= r1.top && r2.top <= r1.bottom) { tomoveWindows_right.addItem(w); recursAddToMoveWindows(w, rs, 0); } } // check for left touch if ((v == 0 || v == -1) && r2.right == r1.left && !tomoveWindows_left.haveItem(w)) { if (r2.bottom >= r1.top && r2.top <= r1.bottom) { tomoveWindows_left.addItem(w); recursAddToMoveWindows(w, rs, 0); } } // check for top touch if ((v == 1 || v == -1) && r2.bottom == r1.top && !tomoveWindows_top.haveItem(w)) { if (r2.right >= r1.left && r2.left <= r1.right) { tomoveWindows_top.addItem(w); recursAddToMoveWindows(w, rs, 1); } } } } void WindowTracker::beforeRedock(Layout *l, redock_struct *rs) { if (!l) return ; rs->l = l; l->getWindowRect(&rs->original_rect); snapAdjustWindowRect(rs->l, &rs->original_rect); } void WindowTracker::afterRedock(Layout *l, redock_struct *rs) { RECT nr; if (!rs) return ; if (!WASABI_API_WND->rootwndIsValid(l)) return ; if (!WASABI_API_WND->rootwndIsValid(rs->l)) return ; recursAddToMoveWindows(NULL, rs); l->getWindowRect(&nr); snapAdjustWindowRect(l, &nr); if (l->isUnlinked() || rs->l->isUnlinked()) return ; #ifdef WIN32 HDWP hdwp = BeginDeferWindowPos(desktopwnds.getNumItems()); #endif PtrList toendmove; int diff = rs->original_rect.bottom - nr.bottom; if (diff) { // check for bottom side dock changes for (int i = 0;i < tomoveWindows_bottom.getNumItems();i++) { ifc_window *w = tomoveWindows_bottom[i]; if (w == l) continue; if (w == rs->l) continue; if (!allWnd.haveItem(w)) continue; RECT r; w->getWindowRect(&r); r.top -= diff; r.bottom -= diff; #ifdef WIN32 w->notifyDeferredMove(r.left, r.top); DeferWindowPos(hdwp, w->gethWnd(), NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOZORDER | SWP_NOACTIVATE); #else w->move( r.left, r.top ); #endif Layout *l = static_cast(w->getInterface(layoutGuid)); if (l) toendmove.addItem(l); } } diff = rs->original_rect.top - nr.top; if (diff) { // check for top side dock changes for (int i = 0;i < tomoveWindows_top.getNumItems();i++) { ifc_window *w = tomoveWindows_top[i]; if (w == l) continue; if (w == rs->l) continue; if (!allWnd.haveItem(w)) continue; RECT r; w->getWindowRect(&r); r.top -= diff; r.bottom -= diff; #ifdef WIN32 w->notifyDeferredMove(r.left, r.top); DeferWindowPos(hdwp, w->gethWnd(), NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOZORDER | SWP_NOACTIVATE); #else w->move( r.left, r.top ); #endif Layout *l = static_cast(w->getInterface(layoutGuid)); if (l) toendmove.addItem(l); } } diff = rs->original_rect.right - nr.right; if (diff) { // check for right side dock changes for (int i = 0;i < tomoveWindows_right.getNumItems();i++) { ifc_window *w = tomoveWindows_right[i]; if (w == l) continue; if (w == rs->l) continue; if (!allWnd.haveItem(w)) continue; RECT r; w->getWindowRect(&r); r.left -= diff; r.right -= diff; Layout *l = static_cast(w->getInterface(layoutGuid)); if (l) l->beginMove(); #ifdef WIN32 w->notifyDeferredMove(r.left, r.top); DeferWindowPos(hdwp, w->gethWnd(), NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOZORDER | SWP_NOACTIVATE); #else w->move( r.left, r.top ); #endif if (l) toendmove.addItem(l); } } diff = rs->original_rect.left - nr.left; if (diff) { // check for left side dock changes for (int i = 0;i < tomoveWindows_left.getNumItems();i++) { ifc_window *w = tomoveWindows_left[i]; if (w == l) continue; if (w == rs->l) continue; if (!allWnd.haveItem(w)) continue; RECT r; w->getWindowRect(&r); r.left -= diff; r.right -= diff; Layout *l = static_cast(w->getInterface(layoutGuid)); if (l) l->beginMove(); #ifdef WIN32 w->notifyDeferredMove(r.left, r.top); DeferWindowPos(hdwp, w->gethWnd(), NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOZORDER | SWP_NOACTIVATE); #else w->move( r.left, r.top ); #endif if (l) toendmove.addItem(l); } } #ifdef WIN32 EndDeferWindowPos(hdwp); #endif tomoveWindows_left.removeAll(); tomoveWindows_top.removeAll(); tomoveWindows_right.removeAll(); tomoveWindows_bottom.removeAll(); rs->l = NULL; foreach(toendmove) toendmove.getfor()->onMove(); toendmove.getfor()->endMove(); endfor; } void WindowTracker::layoutChanged(Layout *previouswnd, Layout *newwnd) { redock_struct rs; beforeRedock(previouswnd, &rs); afterRedock(newwnd, &rs); } ifc_window *WindowTracker::coopWnd = NULL; PtrList WindowTracker::desktopwnds; PtrList WindowTracker::nonvirtuals; PtrList WindowTracker::coopList; PtrList WindowTracker::recursList; PtrList WindowTracker::tomoveWindows_left; PtrList WindowTracker::tomoveWindows_top; PtrList WindowTracker::tomoveWindows_right; PtrList WindowTracker::tomoveWindows_bottom; PtrList WindowTracker::allWnd; int WindowTracker::dockDist = DEFAULT_DOCK_DIST; int WindowTracker::dock_enabled = 1;