icewm/src/base.h | 6 +- icewm/src/default.h | 4 + icewm/src/movesize.cc | 431 ++++++++++++++++++++++++++++++++++++++-- icewm/src/wmapp.cc | 6 +- icewm/src/wmframe.cc | 522 ++++++++++++++++++++++++++++++++++++++++--------- icewm/src/wmframe.h | 39 ++++ 6 files changed, 888 insertions(+), 120 deletions(-) diff --git a/icewm/src/base.h b/icewm/src/base.h index ccd0f85..84965fc 100644 --- a/icewm/src/base.h +++ b/icewm/src/base.h @@ -1,10 +1,8 @@ #ifndef __BASE_H #define __BASE_H -#if ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3 -#define deprecated __attribute__((deprecated)) -#else -#define deprecated +#if !(defined(__GNUC__) || defined(__GNUG__) || defined(__attribute__)) +#define __attribute__(p) /* nothing */ #endif /*** Atomar Data Types ********************************************************/ diff --git a/icewm/src/default.h b/icewm/src/default.h index b0a86d5..700687f 100644 --- a/icewm/src/default.h +++ b/icewm/src/default.h @@ -123,6 +123,7 @@ XIV(bool, confirmLogout, true) #ifdef CONFIG_SHAPED_DECORATION XIV(bool, protectClientWindow, true) #endif +XIV(bool, instantResizeKeys, true) XIV(int, MenuMaximalWidth, 0) XIV(int, EdgeResistance, 32) XIV(int, snapDistance, 8) @@ -147,6 +148,7 @@ XIV(int, taskBarCPUSamples, 20) XIV(int, focusRequestFlashTime, 0) XIV(int, nestedThemeMenuMinNumber, 15) XIV(int, batteryPollingPeriod, 10) +XIV(int, sizeMoveAltModMap, kfShift) #ifdef CONFIG_APPLET_APM XSV(const char *, acpiIgnoreBatteries, 0) @@ -319,6 +321,7 @@ cfoption icewm_preferences[] = { #ifdef CONFIG_SHAPED_DECORATION OBV("ShapesProtectClientWindow", &protectClientWindow, "Don't cut client windows by shapes set trough frame corner pixmap"), #endif + OBV("InstantResizeKeys", &instantResizeKeys, "First press in a resize operation of a directional key also resizes the window"), OBV("DoubleBuffer", &doubleBuffer, "Use double buffering when redrawing the display"), OIV("ClickMotionDistance", &ClickMotionDistance, 0, 32, "Pointer motion distance before click gets interpreted as drag"), OIV("ClickMotionDelay", &ClickMotionDelay, 0, 2000, "Delay before click gets interpreted as drag"), @@ -363,6 +366,7 @@ cfoption icewm_preferences[] = { OIV("FocusRequestFlashTime", &focusRequestFlashTime, 0, (3600 * 24), "Number of seconds the taskbar app will blink when requesting focus"), OIV("NestedThemeMenuMinNumber", &nestedThemeMenuMinNumber, 0, 1234, "Minimal number of themes after which the Themes menu becomes nested (0=disabled)"), OIV("BatteryPollingPeriod", &batteryPollingPeriod, 2, 3600, "Delay between power status updates (seconds)"), + OIV("SizeMoveAltModMap", &sizeMoveAltModMap, 1, 127, "Bitmap of modifiers that enables the relative move and resize commands in these modes, respectively. Valid modifiers: Shift: 1, Ctrl: 2, Alt: 4, Meta: 8, Super: 16, Hyper: 32, AltGr: 64"), /// OSV("Theme", &themeName, "Theme name"), OSV("IconPath", &iconPath, "Icon search path (colon separated)"), OSV("MailBoxPath", &mailBoxPath, "Mailbox path (use $MAIL instead)"), diff --git a/icewm/src/movesize.cc b/icewm/src/movesize.cc index a591bbc..4460079 100644 --- a/icewm/src/movesize.cc +++ b/icewm/src/movesize.cc @@ -209,6 +209,7 @@ int YFrameWindow::handleMoveKeys(const XKeyEvent &key, int &newX, int &newY) { KeySym k = XKeycodeToKeysym(xapp->display(), (KeyCode)key.keycode, 0); int m = KEY_MODMASK(key.state); int factor = 1; + int mod = sizeMoveAltModMap; int mx, my, Mx, My; manager->getWorkArea(this, &mx, &my, &Mx, &My); @@ -218,25 +219,67 @@ int YFrameWindow::handleMoveKeys(const XKeyEvent &key, int &newX, int &newY) { if (m & ControlMask) factor<<= 4; - if (k == XK_Left || k == XK_KP_Left) + if (k == XK_Left) newX -= factor; - else if (k == XK_Right || k == XK_KP_Right) + else if (k == XK_Right) newX += factor; - else if (k == XK_Up || k == XK_KP_Up) + else if (k == XK_Up) newY -= factor; - else if (k == XK_Down || k == XK_KP_Down) + else if (k == XK_Down) newY += factor; - else if (k == XK_Home || k == XK_KP_Home) + else if (k == XK_Home) newX = mx - borderX(); - else if (k == XK_End || k == XK_KP_End) + else if (k == XK_End) newX = Mx - width() + borderX(); - else if (k == XK_Prior || k == XK_KP_Prior) + else if (k == XK_Prior) newY = my - borderY(); - else if (k == XK_Next || k == XK_KP_Next) + else if (k == XK_Next) newY = My - height() + borderY(); - else if (k == XK_KP_Begin) { - newX = (mx + Mx - (int)width()) / 2; - newY = (my + My - (int)height()) / 2; + else if (k == XK_KP_Up || k == XK_KP_8) { + if (m & mod) + getSnapMovePos(waTop, waCenter, newX, newY); + else + getArrangePos(waTop, waCenter, newX, newY); + } else if (k == XK_KP_Prior || k == XK_KP_9) { + if (m & mod) + getSnapMovePos(waTop, waRight, newX, newY); + else + getArrangePos(waTop, waRight, newX, newY); + } else if (k == XK_KP_Right || k == XK_KP_6) { + if (m & mod) + getSnapMovePos(waCenter, waRight, newX, newY); + else + getArrangePos(waCenter, waRight, newX, newY); + } else if (k == XK_KP_Next || k == XK_KP_3) { + if (m & mod) + getSnapMovePos(waBottom, waRight, newX, newY); + else + getArrangePos(waBottom, waRight, newX, newY); + } else if (k == XK_KP_Down || k == XK_KP_2) { + if (m & mod) + getSnapMovePos(waBottom, waCenter, newX, newY); + else + getArrangePos(waBottom, waCenter, newX, newY); + } else if (k == XK_KP_End || k == XK_KP_1) { + if (m & mod) + getSnapMovePos(waBottom, waLeft, newX, newY); + else + getArrangePos(waBottom, waLeft, newX, newY); + } else if (k == XK_KP_Left || k == XK_KP_4) { + if (m & mod) + getSnapMovePos(waCenter, waLeft, newX, newY); + else + getArrangePos(waCenter, waLeft, newX, newY); + } else if (k == XK_KP_Home || k == XK_KP_7) { + if (m & mod) + getSnapMovePos(waTop, waLeft, newX, newY); + else + getArrangePos(waTop, waLeft, newX, newY); + } else if (k == XK_KP_Begin || k == XK_KP_5) { + if (m & mod) + manager->getSmartPlace(true, this, newX, newY, width(), height(), getScreen()); + else + getArrangePos(waCenter, waCenter, newX, newY); } else if (k == XK_Return || k == XK_KP_Enter) return -1; else if (k == XK_Escape) { @@ -249,7 +292,6 @@ int YFrameWindow::handleMoveKeys(const XKeyEvent &key, int &newX, int &newY) { } /******************************************************************************/ - int YFrameWindow::handleResizeKeys(const XKeyEvent &key, int &newX, int &newY, int &newWidth, int &newHeight, int incX, int incY) @@ -257,15 +299,19 @@ int YFrameWindow::handleResizeKeys(const XKeyEvent &key, KeySym k = XKeycodeToKeysym(xapp->display(), (KeyCode)key.keycode, 0); int m = KEY_MODMASK(key.state); int factor = 1; + int newGrabX = grabX, newGrabY = grabY; + int mod = sizeMoveAltModMap; if (m & ShiftMask) factor = 4; if (m & ControlMask) factor<<= 4; - if (k == XK_Left || k == XK_KP_Left) { + if (k == XK_Left) { if (grabX == 0) { - grabX = -1; + newGrabX = -1; + if (instantResizeKeys) + grabX = newGrabX; } if (grabX == 1) { newWidth -= incX * factor; @@ -273,9 +319,12 @@ int YFrameWindow::handleResizeKeys(const XKeyEvent &key, newWidth += incX * factor; newX -= incX * factor; } - } else if (k == XK_Right || k == XK_KP_Right) { + + } else if (k == XK_Right) { if (grabX == 0) { - grabX = 1; + newGrabX = 1; + if (instantResizeKeys) + grabX = newGrabX; } if (grabX == 1) { newWidth += incX * factor; @@ -283,9 +332,12 @@ int YFrameWindow::handleResizeKeys(const XKeyEvent &key, newWidth -= incX * factor; newX += incX * factor; } - } else if (k == XK_Up || k == XK_KP_Up) { + + } else if (k == XK_Up) { if (grabY == 0) { - grabY = -1; + newGrabY = -1; + if (instantResizeKeys) + grabY = newGrabY; } if (grabY == 1) { newHeight -= incY * factor; @@ -293,9 +345,12 @@ int YFrameWindow::handleResizeKeys(const XKeyEvent &key, newHeight += incY * factor; newY -= incY * factor; } - } else if (k == XK_Down || k == XK_KP_Down) { + + } else if (k == XK_Down) { if (grabY == 0) { - grabY = 1; + newGrabY = 1; + if (instantResizeKeys) + grabY = newGrabY; } if (grabY == 1) { newHeight += incY * factor; @@ -303,6 +358,147 @@ int YFrameWindow::handleResizeKeys(const XKeyEvent &key, newHeight -= incY * factor; newY += incY * factor; } + + } else if (k == XK_KP_Up || k == XK_KP_8) { + int diffY = 0, diffH = 0; + + if (grabY == 0) { + newGrabY = -1; + if (instantResizeKeys) + grabY = newGrabY; + } + + extendUp(newX, newY, newWidth, newHeight, incX, incY, diffY, diffH, !!(m & mod)); + newY += diffY; + newHeight += diffH; + + } else if (k == XK_KP_Prior || k == XK_KP_9) { + int diffX = 0, diffW = 0; + int diffY = 0, diffH = 0; + + if (grabX == 0) { + newGrabX = 1; + if (instantResizeKeys) + grabX = newGrabX; + } + if (grabY == 0) { + newGrabY = -1; + if (instantResizeKeys) + grabY = newGrabY; + } + + extendRight(newX, newY, newWidth, newHeight, incX, incY, diffX, diffW, !!(m & mod)); + extendUp(newX, newY, newWidth, newHeight, incX, incY, diffY, diffH, !!(m & mod)); + newX += diffX; + newY += diffY; + newWidth += diffW; + newHeight += diffH; + + } else if (k == XK_KP_Right || k == XK_KP_6) { + int diffX = 0, diffW = 0; + + if (grabX == 0) { + newGrabX = 1; + if (instantResizeKeys) + grabX = newGrabX; + } + + extendRight(newX, newY, newWidth, newHeight, incX, incY, diffX, diffW, !!(m & mod)); + newX += diffX; + newWidth += diffW; + + } else if (k == XK_KP_Next || k == XK_KP_3) { + int diffX = 0, diffW = 0; + int diffY = 0, diffH = 0; + + if (grabX == 0) { + newGrabX = 1; + if (instantResizeKeys) + grabX = newGrabX; + } + if (grabY == 0) { + newGrabY = 1; + if (instantResizeKeys) + grabY = newGrabY; + } + + extendRight(newX, newY, newWidth, newHeight, incX, incY, diffX, diffW, !!(m & mod)); + extendDown(newX, newY, newWidth, newHeight, incX, incY, diffY, diffH, !!(m & mod)); + newX += diffX; + newY += diffY; + newWidth += diffW; + newHeight += diffH; + + } else if (k == XK_KP_Down || k == XK_KP_2) { + int diffY = 0, diffH = 0; + + if (grabY == 0) { + newGrabY = 1; + if (instantResizeKeys) + grabY = newGrabY; + } + + extendDown(newX, newY, newWidth, newHeight, incX, incY, diffY, diffH, !!(m & mod)); + newY += diffY; + newHeight += diffH; + + } else if (k == XK_KP_End || k == XK_KP_1) { + int diffX = 0, diffW = 0; + int diffY = 0, diffH = 0; + + if (grabX == 0) { + newGrabX = -1; + if (instantResizeKeys) + grabX = newGrabX; + } + if (grabY == 0) { + newGrabY = 1; + if (instantResizeKeys) + grabY = newGrabY; + } + + extendLeft(newX, newY, newWidth, newHeight, incX, incY, diffX, diffW, !!(m & mod)); + extendDown(newX, newY, newWidth, newHeight, incX, incY, diffY, diffH, !!(m & mod)); + newX += diffX; + newY += diffY; + newWidth += diffW; + newHeight += diffH; + + } else if (k == XK_KP_Left || k == XK_KP_4) { + int diffX = 0, diffW = 0; + + if (grabX == 0) { + newGrabX = -1; + if (instantResizeKeys) + grabX = newGrabX; + } + + extendLeft(newX, newY, newWidth, newHeight, incX, incY, diffX, diffW, !!(m & mod)); + newX += diffX; + newWidth += diffW; + + } else if (k == XK_KP_Home || k == XK_KP_7) { + int diffX = 0, diffW = 0; + int diffY = 0, diffH = 0; + + if (grabX == 0) { + newGrabX = -1; + if (instantResizeKeys) + grabX = newGrabX; + } + if (grabY == 0) { + newGrabY = -1; + if (instantResizeKeys) + grabY = newGrabY; + } + + extendLeft(newX, newY, newWidth, newHeight, incX, incY, diffX, diffW, !!(m & mod)); + extendUp(newX, newY, newWidth, newHeight, incX, incY, diffY, diffH, !!(m & mod)); + newX += diffX; + newY += diffY; + newWidth += diffW; + newHeight += diffH; + } else if (k == XK_Return || k == XK_KP_Enter) return -1; else if (k == XK_Escape) { @@ -313,6 +509,10 @@ int YFrameWindow::handleResizeKeys(const XKeyEvent &key, return -2; } else return 0; + + grabY = newGrabY; + grabX = newGrabX; + return 1; } @@ -1130,3 +1330,194 @@ void YFrameWindow::handleMotion(const XMotionEvent &motion) { YWindow::handleMotion(motion); } +void YFrameWindow::extendUp(int newX, int newY, int newWidth, int newHeight, + int incX, int incY, int &diffY, int &diffH, + bool alt) +{ + int mx, my, Mx, My; + YRect outer(newX - incX + 1, newY - incY + 1, + newWidth + 2 * (incX - 1), newHeight + 2 * (incY - 1)); + YRect inner(newX + incX - 1, newY + incY - 1, + newWidth - 2 * (incX - 1), newHeight - 2 * (incY - 1)); + + manager->getWorkArea(this, &mx, &my, &Mx, &My, getScreen()); + + if (grabY == 1) { + if (alt) { + int nextB = getBottomCoordRev(newY, inner); + + if ((newY + newHeight) > (origY + origH) + && nextB < (origY + origH)) + nextB = origY + origH; + + if (nextB == newY) + nextB = newY + newHeight; + + nextB -= incY - 1; + diffH = ((nextB - (newY + newHeight)) / incY) * incY; + + } else if (newHeight > origH) + diffH = origH - newHeight; + + } else if (grabY == -1) { + int nextT = my; + + if (alt) { + nextT = getTopCoord(my, outer); + + if (newY > origY && nextT < origY) + nextT = origY; + } + + if (!considerVertBorder && nextT == my) + nextT -= borderY(); + + diffH = ((newY - nextT) / incY) * incY; + diffY = -diffH; + } +} + +void YFrameWindow::extendRight(int newX, int newY, int newWidth, int newHeight, + int incX, int incY, int &diffW, int &diffX, + bool alt) +{ + int mx, my, Mx, My; + YRect outer(newX - incX + 1, newY - incY + 1, + newWidth + 2 * (incX - 1), newHeight + 2 * (incY - 1)); + YRect inner(newX + incX - 1, newY + incY - 1, + newWidth - 2 * (incX - 1), newHeight - 2 * (incY - 1)); + + manager->getWorkArea(this, &mx, &my, &Mx, &My, getScreen()); + + if (grabX == 1) { + int nextR = Mx; + + if (alt) { + nextR = getRightCoord(Mx, outer); + + if ((newX + newWidth) < (origX + origW) + && nextR > (origX + origW)) + nextR = origX + origW; + } + + if (!considerHorizBorder && nextR == Mx) + nextR += borderX(); + + diffW = ((nextR - (newX + newWidth)) / incX) * incX; + + } else if (grabX == -1) { + if (alt) { + int nextL = getLeftCoordRev(newX + newWidth, inner); + + if (newX < origX && nextL > origX) + nextL = origX; + + if (nextL == newX + newWidth) + nextL = newX; + + nextL += incX - 1; + diffW = ((newX - nextL) / incX) * incX; + diffX = -diffW; + + } else if (newWidth > origW) { + diffX = origX - newX; + diffW = origW - newWidth; + } + } +} + +void YFrameWindow::extendDown(int newX, int newY, int newWidth, int newHeight, + int incX, int incY, int &diffY, int &diffH, + bool alt) +{ + int mx, my, Mx, My; + YRect outer(newX - incX + 1, newY - incY + 1, + newWidth + 2 * (incX - 1), newHeight + 2 * (incY - 1)); + YRect inner(newX + incX - 1, newY + incY - 1, + newWidth - 2 * (incX - 1), newHeight - 2 * (incY - 1)); + + manager->getWorkArea(this, &mx, &my, &Mx, &My, getScreen()); + + if (grabY == 1) { + int nextB = My; + + if (alt) { + nextB = getBottomCoord(My, outer); + + if ((newY + newHeight) < (origY + origH) + && nextB > (origY + origH)) + nextB = origY + origH; + } + + if (!considerVertBorder && nextB == My) + nextB += borderY(); + + diffH = ((nextB - (newY + newHeight)) / incY) * incY; + + } else if (grabY == -1) { + if (alt) { + int nextT = getTopCoordRev(newY + newHeight, inner); + + if (newY < origY && nextT > origY) + nextT = origY; + + if (nextT == newY + newHeight) + nextT = newY; + + nextT += incY - 1; + diffH = ((newY - nextT) / incY) * incY; + diffY = -diffH; + + } else if (newHeight > origH) { + diffY = origY - newY; + diffH = origH - newHeight; + } + } +} + +void YFrameWindow::extendLeft(int newX, int newY, int newWidth, int newHeight, + int incX, int incY, int &diffX, int &diffW, + bool alt) +{ + int mx, my, Mx, My; + YRect outer(newX - incX + 1, newY - incY + 1, + newWidth + 2 * (incX - 1), newHeight + 2 * (incY - 1)); + YRect inner(newX + incX - 1, newY + incY - 1, + newWidth - 2 * (incX - 1), newHeight - 2 * (incY - 1)); + + manager->getWorkArea(this, &mx, &my, &Mx, &My, getScreen()); + + if (grabX == 1) { + if (alt) { + int nextR = getRightCoordRev(newX, inner); + + if ((newX + newWidth) > (origX + origW) + && nextR < (origX + origW)) + nextR = origX + origW; + + if (nextR == newX) + nextR = newX + newWidth; + + nextR -= incX - 1; + diffW = ((nextR - (newX + newWidth)) / incX) * incX; + + } else if (newWidth > origW) + diffW = origW - newWidth; + + } else if (grabX == -1) { + int nextL = mx; + + if (alt) { + nextL = getLeftCoord(mx, outer); + + if (newX > origX && nextL < origX) + nextL = origX; + } + + if (!considerHorizBorder && nextL == mx) + nextL -= borderX(); + + diffW = ((newX - nextL) / incX) * incX; + diffX = -diffW; + } +} diff --git a/icewm/src/wmapp.cc b/icewm/src/wmapp.cc index d4dc269..744cb27 100644 --- a/icewm/src/wmapp.cc +++ b/icewm/src/wmapp.cc @@ -336,7 +336,7 @@ static void initFontPath() { MSG(("Font path element %d: %s", n, newFontPath[n])); #endif - char * icewmFontPath; // ---------- find death icewm's font path --- + unsigned char * icewmFontPath; // ---------- find death icewm's font path --- Atom r_type; int r_format; unsigned long count, bytes_remain; @@ -346,11 +346,11 @@ static void initFontPath() { 0, PATH_MAX, False, XA_STRING, &r_type, &r_format, &count, &bytes_remain, - (unsigned char **) &icewmFontPath) == + &icewmFontPath) == Success && icewmFontPath) { if (r_type == XA_STRING && r_format == 8) { for (int n(ndirs - 1); n > 0; --n) // ---- remove death paths --- - if (!strcmp(icewmFontPath, newFontPath[n])) { + if (!strcmp((char *) icewmFontPath, newFontPath[n])) { memmove(newFontPath + n, newFontPath + n + 1, (ndirs - n) * sizeof(char *)); --ndirs; diff --git a/icewm/src/wmframe.cc b/icewm/src/wmframe.cc index 4a17d89..99021d7 100644 --- a/icewm/src/wmframe.cc +++ b/icewm/src/wmframe.cc @@ -3464,10 +3464,32 @@ int YFrameWindow::getScreen() { } void YFrameWindow::wmArrange(int tcb, int lcr) { - int mx, my, Mx, My, newX = 0, newY = 0; + int newX, newY; + getArrangePos(tcb, lcr, newX, newY); + + MSG(("wmArrange: setPosition(x = %d, y = %d)", newX, newY)); + + setCurrentPositionOuter(newX, newY); +} + +void YFrameWindow::wmSnapMove(int tcb, int lcr) { + int newX, newY; + + getSnapMovePos(tcb, lcr, newX, newY); + + MSG(("wmSnapMove: setPosition(x = %d, y = %d)", newX, newY)); + + setCurrentPositionOuter(newX, newY); +} + +void YFrameWindow::getArrangePos(int tcb, int lcr, int &newX, int &newY) { + int mx, my, Mx, My; int xiscreen = manager->getScreenForRect(x(), y(), width(), height()); + newX = 0; + newY = 0; + manager->getWorkArea(this, &mx, &my, &Mx, &My, xiscreen); switch (tcb) { @@ -3493,148 +3515,462 @@ void YFrameWindow::wmArrange(int tcb, int lcr) { newX = Mx - width() + (considerHorizBorder ? 0 : borderX()); break; } - - MSG(("wmArrange: setPosition(x = %d, y = %d)", newX, newY)); - - setCurrentPositionOuter(newX, newY); } -void YFrameWindow::wmSnapMove(int tcb, int lcr) { - int mx, my, Mx, My, newX = 0, newY = 0; - +void YFrameWindow::getSnapMovePos(int tcb, int lcr, int &newX, int &newY) { + int mx, my, Mx, My; int xiscreen = manager->getScreenForRect(x(), y(), width(), height()); YFrameWindow **w = 0; int count = 0; + newX = x(); + newY = y(); + manager->getWindowsToArrange(&w, &count); + if (!w) + return; manager->getWorkArea(this, &mx, &my, &Mx, &My, xiscreen); MSG(("WorkArea: mx = %d, my = %d, Mx = %d, My = %d", mx, my, Mx, My)); MSG(("thisFrame: x = %d, y = %d, w = %d, h = %d, bx = %d, by = %d, ty = %d", - x(), y(), width(), height(), borderX(), borderY(), titleY())); + x(), y(), width(), height(), borderX(), borderY(), titleY())); MSG(("thisClient: w = %d, h = %d", client()->width(), client()->height())); switch (tcb) { - case waTop: - newY = getTopCoord(my, w, count); - if (!considerVertBorder && newY == my) - newY -= borderY(); - break; - case waCenter: - newY = y(); - break; - case waBottom: - newY = getBottomCoord(My, w, count) - height(); - if (!considerVertBorder && (newY + height()) == My) - newY += borderY(); - break; + case waTop: + newY = getTopCoord(my, w, count); + if (!considerVertBorder && newY == my) + newY -= borderY(); + break; + case waBottom: + newY = getBottomCoord(My, w, count) - height(); + if (!considerVertBorder && (newY + height()) == My) + newY += borderY(); + break; } switch (lcr) { - case waLeft: - newX = getLeftCoord(mx, w, count); - if (!considerHorizBorder && newX == mx) - newX -= borderX(); - break; - case waCenter: - newX = x(); - break; - case waRight: - newX = getRightCoord(Mx, w, count) - width(); - if (!considerHorizBorder && (newX + width()) == Mx) - newX += borderX(); - break; - } - - MSG(("NewPosition: x = %d, y = %d", newX, newY)); - - setCurrentPositionOuter(newX, newY); + case waLeft: + newX = getLeftCoord(mx, w, count); + if (!considerHorizBorder && newX == mx) + newX -= borderX(); + break; + case waRight: + newX = getRightCoord(Mx, w, count) - width(); + if (!considerHorizBorder && (newX + width()) == Mx) + newX += borderX(); + break; + } - delete [] w; + delete[] w; } int YFrameWindow::getTopCoord(int my, YFrameWindow **w, int count) { - int i, n; - - if (y() < my) - return y(); - - for (i = y() - 2; i > my; i--) { - for (n = 0; n < count; n++) { - if ( (this != w[n]) - && (i == (w[n]->y() + w[n]->height())) - && ( x() < (w[n]->x() + w[n]->width())) - && ((x() + width()) > (w[n]->x())) ) { - return i; - } + return getTopCoord(my, w, count, YRect(x(), y(), width(), height())); +} + +int YFrameWindow::getTopCoord(int my, const YRect &r) +{ + YFrameWindow **w = 0; + int count = 0; + + manager->getWindowsToArrange(&w, &count); + if (!w) + return my; + + my = getTopCoord(my, w, count, r); + + delete[] w; + + return my; +} + +static int sortTop(const void *a, const void *b) +{ + const YFrameWindow *w1 = *static_cast(a); + const YFrameWindow *w2 = *static_cast(b); + int w1s = w1->y() + w1->height(); + int w2s = w2->y() + w2->height(); + + return (w1s < w2s) - (w1s > w2s); +} + +int YFrameWindow::getTopCoord(int my, YFrameWindow **w, int count, const YRect &r) +{ + int n; + + if (r.y() <= my) + return r.y(); + + qsort(w, count, sizeof(YFrameWindow *), sortTop); + + for (n = 0; n < count; n++) { + if (r.y() > w[n]->y() + w[n]->height() + && r.x() < w[n]->x() + w[n]->width() + && r.x() + r.width() > w[n]->x()) { + return w[n]->y() + w[n]->height(); } } return my; } +int YFrameWindow::getTopCoordRev(int My, YFrameWindow **w, int count) +{ + return getTopCoordRev(My, w, count, YRect(x(), y(), width(), height())); +} + +int YFrameWindow::getTopCoordRev(int My, const YRect &r) +{ + YFrameWindow **w = 0; + int count = 0; + + manager->getWindowsToArrange(&w, &count); + if (!w) + return My; + + My = getTopCoordRev(My, w, count, r); + + delete[] w; + + return My; +} + +static int sortTopRev(const void *a, const void *b) +{ + const YFrameWindow *w1 = *static_cast(a); + const YFrameWindow *w2 = *static_cast(b); + int w1s = w1->y() + w1->height(); + int w2s = w2->y() + w2->height(); + + return (w1s > w2s) - (w1s < w2s); +} + +int YFrameWindow::getTopCoordRev(int My, YFrameWindow **w, int count, const YRect &r) +{ + int n; + + if (r.y() >= My) + return r.y(); + + qsort(w, count, sizeof(YFrameWindow *), sortTopRev); + + for (n = 0; n < count; n++) { + if (r.y() < w[n]->y() + w[n]->height() + && r.x() < w[n]->x() + w[n]->width() + && r.x() + r.width() > w[n]->x()) { + return w[n]->y() + w[n]->height(); + } + } + + return My; +} + int YFrameWindow::getBottomCoord(int My, YFrameWindow **w, int count) { - int i, n; - - if ((y() + height()) > My) - return y() + height(); - - for (i = y() + height() + 2; i < My; i++) { - for (n = 0; n < count; n++) { - if ( (this != w[n]) - && (i == w[n]->y()) - && ( x() < (w[n]->x() + w[n]->width())) - && ((x() + width()) > (w[n]->x())) ) { - return i; - } + return getBottomCoord(My, w, count, YRect(x(), y(), width(), height())); +} + +int YFrameWindow::getBottomCoord(int My, const YRect &r) +{ + YFrameWindow **w = 0; + int count = 0; + + manager->getWindowsToArrange(&w, &count); + if (!w) + return My; + + My = getBottomCoord(My, w, count, r); + + delete[] w; + + return My; +} + +static int sortBottom(const void *a, const void *b) +{ + const YFrameWindow *w1 = *static_cast(a); + const YFrameWindow *w2 = *static_cast(b); + int w1s = w1->y(); + int w2s = w2->y(); + + return (w1s > w2s) - (w1s < w2s); +} + +int YFrameWindow::getBottomCoord(int My, YFrameWindow **w, int count, const YRect &r) +{ + int n; + + if ((r.y() + r.height()) >= My) + return r.y() + r.height(); + + qsort(w, count, sizeof(YFrameWindow *), sortBottom); + + for (n = 0; n < count; n++) { + if (r.y() + r.height() < w[n]->y() + && r.x() < w[n]->x() + w[n]->width() + && r.x() + r.width() > w[n]->x()) { + return w[n]->y(); } } return My; } +int YFrameWindow::getBottomCoordRev(int my, YFrameWindow **w, int count) +{ + return getBottomCoordRev(my, w, count, YRect(x(), y(), width(), height())); +} + +int YFrameWindow::getBottomCoordRev(int my, const YRect &r) +{ + YFrameWindow **w = 0; + int count = 0; + + manager->getWindowsToArrange(&w, &count); + if (!w) + return my; + + my = getBottomCoordRev(my, w, count, r); + + delete[] w; + + return my; +} + +static int sortBottomRev(const void *a, const void *b) +{ + const YFrameWindow *w1 = *static_cast(a); + const YFrameWindow *w2 = *static_cast(b); + int w1s = w1->y(); + int w2s = w2->y(); + + return (w1s < w2s) - (w1s > w2s); +} + +int YFrameWindow::getBottomCoordRev(int my, YFrameWindow **w, int count, const YRect &r) +{ + int n; + + if ((r.y() + r.height()) <= my) + return r.y() + r.height(); + + qsort(w, count, sizeof(YFrameWindow *), sortBottomRev); + + for (n = 0; n < count; n++) { + if (r.y() + r.height() > w[n]->y() + && r.x() < w[n]->x() + w[n]->width() + && r.x() + r.width() > w[n]->x()) { + return w[n]->y(); + } + } + + return my; +} + int YFrameWindow::getLeftCoord(int mx, YFrameWindow **w, int count) { - int i, n; - - if (x() < mx) - return x(); - - for (i = x() - 2; i > mx; i--) { - for (n = 0; n < count; n++) { - if ( (this != w[n]) - && (i == (w[n]->x() + w[n]->width())) - && ( y() < (w[n]->y() + w[n]->height())) - && ((y() + height()) > (w[n]->y())) ) { - return i; - } + return getLeftCoord(mx, w, count, YRect(x(), y(), width(), height())); +} + +int YFrameWindow::getLeftCoord(int mx, const YRect &r) +{ + YFrameWindow **w = 0; + int count = 0; + + manager->getWindowsToArrange(&w, &count); + if (!w) + return mx; + + mx = getLeftCoord(mx, w, count, r); + + delete[] w; + + return mx; +} + +static int sortLeft(const void *a, const void *b) +{ + const YFrameWindow *w1 = *static_cast(a); + const YFrameWindow *w2 = *static_cast(b); + int w1s = w1->x() + w1->width(); + int w2s = w2->x() + w2->width(); + + return (w1s < w2s) - (w1s > w2s); +} + +int YFrameWindow::getLeftCoord(int mx, YFrameWindow **w, int count, const YRect &r) +{ + int n; + + if (r.x() <= mx) + return r.x(); + + qsort(w, count, sizeof(YFrameWindow *), sortLeft); + + for (n = 0; n < count; n++) { + if (r.x() > w[n]->x() + w[n]->width() + && r.y() < w[n]->y() + w[n]->height() + && r.y() + r.height() > w[n]->y()) { + return w[n]->x() + w[n]->width(); } } return mx; } +int YFrameWindow::getLeftCoordRev(int Mx, YFrameWindow **w, int count) +{ + return getLeftCoordRev(Mx, w, count, YRect(x(), y(), width(), height())); +} + +int YFrameWindow::getLeftCoordRev(int Mx, const YRect &r) +{ + YFrameWindow **w = 0; + int count = 0; + + manager->getWindowsToArrange(&w, &count); + if (!w) + return Mx; + + Mx = getLeftCoordRev(Mx, w, count, r); + + delete[] w; + + return Mx; +} + +static int sortLeftRev(const void *a, const void *b) +{ + const YFrameWindow *w1 = *static_cast(a); + const YFrameWindow *w2 = *static_cast(b); + int w1s = w1->x() + w1->width(); + int w2s = w2->x() + w2->width(); + + return (w1s > w2s) - (w1s < w2s); +} + +int YFrameWindow::getLeftCoordRev(int Mx, YFrameWindow **w, int count, const YRect &r) +{ + int n; + + if (r.x() >= Mx) + return r.x(); + + qsort(w, count, sizeof(YFrameWindow *), sortLeftRev); + + for (n = 0; n < count; n++) { + if (r.x() < w[n]->x() + w[n]->width() + && r.y() < w[n]->y() + w[n]->height() + && r.y() + r.height() > w[n]->y()) { + return w[n]->x() + w[n]->width(); + } + } + + return Mx; +} + int YFrameWindow::getRightCoord(int Mx, YFrameWindow **w, int count) { - int i, n; - - if ((x() + width()) > Mx) - return x() + width(); - - for (i = x() + width() + 2; i < Mx; i++) { - for (n = 0; n < count; n++) { - if ( (this != w[n]) - && (i == w[n]->x()) - && ( y() < (w[n]->y() + w[n]->height())) - && ((y() + height()) > (w[n]->y())) ) { - return i; - } + return getRightCoord(Mx, w, count, YRect(x(), y(), width(), height())); +} + +int YFrameWindow::getRightCoord(int Mx, const YRect &r) +{ + YFrameWindow **w = 0; + int count = 0; + + manager->getWindowsToArrange(&w, &count); + if (!w) + return Mx; + + Mx = getRightCoord(Mx, w, count, r); + + delete[] w; + + return Mx; +} + +static int sortRight(const void *a, const void *b) +{ + const YFrameWindow *w1 = *static_cast(a); + const YFrameWindow *w2 = *static_cast(b); + int w1s = w1->x(); + int w2s = w2->x(); + + return (w1s > w2s) - (w1s < w2s); +} + +int YFrameWindow::getRightCoord(int Mx, YFrameWindow **w, int count, const YRect &r) +{ + int n; + + if ((r.x() + r.width()) >= Mx) + return r.x() + r.width(); + + qsort(w, count, sizeof(YFrameWindow *), sortRight); + + for (n = 0; n < count; n++) { + if (r.x() + r.width() < w[n]->x() + && r.y() < w[n]->y() + w[n]->height() + && r.y() + r.height() > w[n]->y()) { + return w[n]->x(); } } return Mx; } + +int YFrameWindow::getRightCoordRev(int mx, YFrameWindow **w, int count) +{ + return getRightCoordRev(mx, w, count, YRect(x(), y(), width(), height())); +} + +int YFrameWindow::getRightCoordRev(int mx, const YRect &r) +{ + YFrameWindow **w = 0; + int count = 0; + + manager->getWindowsToArrange(&w, &count); + if (!w) + return mx; + + mx = getRightCoordRev(mx, w, count, r); + + delete[] w; + + return mx; +} + +static int sortRightRev(const void *a, const void *b) +{ + const YFrameWindow *w1 = *static_cast(a); + const YFrameWindow *w2 = *static_cast(b); + int w1s = w1->x(); + int w2s = w2->x(); + + return (w1s < w2s) - (w1s > w2s); +} + +int YFrameWindow::getRightCoordRev(int mx, YFrameWindow **w, int count, const YRect &r) +{ + int n; + + if ((r.x() + r.width()) <= mx) + return r.x() + r.width(); + + qsort(w, count, sizeof(YFrameWindow *), sortRightRev); + + for (n = 0; n < count; n++) { + if (r.x() + r.width() > w[n]->x() + && r.y() < w[n]->y() + w[n]->height() + && r.y() + r.height() > w[n]->y()) { + return w[n]->x(); + } + } + + return mx; +} diff --git a/icewm/src/wmframe.h b/icewm/src/wmframe.h index bfa3b28..ee46ed9 100644 --- a/icewm/src/wmframe.h +++ b/icewm/src/wmframe.h @@ -546,10 +546,49 @@ private: }; void wmArrange(int tcb, int lcr); void wmSnapMove(int tcb, int lcr); + void getArrangePos(int tcb, int lcr, int &newX, int &newY); + void getSnapMovePos(int tcb, int lcr, int &newX, int &newY); + int getTopCoord(int my, YFrameWindow **w, int count); + int getTopCoord(int my, const YRect &r); + int getTopCoord(int my, YFrameWindow **w, int count, const YRect &r); + + int getTopCoordRev(int My, YFrameWindow **w, int count); + int getTopCoordRev(int My, const YRect &r); + int getTopCoordRev(int My, YFrameWindow **w, int count, const YRect &r); + int getBottomCoord(int My, YFrameWindow **w, int count); + int getBottomCoord(int My, const YRect &r); + int getBottomCoord(int My, YFrameWindow **w, int count, const YRect &r); + + int getBottomCoordRev(int my, YFrameWindow **w, int count); + int getBottomCoordRev(int my, const YRect &r); + int getBottomCoordRev(int my, YFrameWindow **w, int count, const YRect &r); + int getLeftCoord(int mx, YFrameWindow **w, int count); + int getLeftCoord(int mx, const YRect &r); + int getLeftCoord(int mx, YFrameWindow **w, int count, const YRect &r); + + int getLeftCoordRev(int Mx, YFrameWindow **w, int count); + int getLeftCoordRev(int Mx, const YRect &r); + int getLeftCoordRev(int Mx, YFrameWindow **w, int count, const YRect &r); + int getRightCoord(int Mx, YFrameWindow **w, int count); + int getRightCoord(int Mx, const YRect &r); + int getRightCoord(int Mx, YFrameWindow **w, int count, const YRect &r); + + int getRightCoordRev(int mx, YFrameWindow **w, int count); + int getRightCoordRev(int mx, const YRect &r); + int getRightCoordRev(int mx, YFrameWindow **w, int count, const YRect &r); + + void extendUp(int newX, int newY, int newWidth, int newHeight, + int incX, int incY, int &diffY, int &diffH, bool alt); + void extendRight(int newX, int newY, int newWidth, int newHeight, + int incX, int incY, int &diffX, int &diffW, bool alt); + void extendDown(int newX, int newY, int newWidth, int newHeight, + int incX, int incY, int &diffY, int &diffH, bool alt); + void extendLeft(int newX, int newY, int newWidth, int newHeight, + int incX, int incY, int &diffX, int &diffW, bool alt); // only focus if mouse moves //static int fMouseFocusX, fMouseFocusY;