Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37858979
en ru br
Репозитории ALT
S:3.4.2-alt1
5.1: 1.2.38pre1-alt1
4.1: 1.2.35-alt2.1
4.0: 1.2.32-alt2.1
3.0: 1.2.23-alt1
+backports:1.2.30-alt1.M30.1
www.altlinux.org/Changes

Группа :: Графические оболочки/Icewm
Пакет: icewm

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: icewm-alt-misc.patch
Скачать


 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<const YFrameWindow *const *>(a);
+    const YFrameWindow *w2 = *static_cast<const YFrameWindow *const *>(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<const YFrameWindow *const *>(a);
+    const YFrameWindow *w2 = *static_cast<const YFrameWindow *const *>(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<const YFrameWindow *const *>(a);
+    const YFrameWindow *w2 = *static_cast<const YFrameWindow *const *>(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<const YFrameWindow *const *>(a);
+    const YFrameWindow *w2 = *static_cast<const YFrameWindow *const *>(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<const YFrameWindow *const *>(a);
+    const YFrameWindow *w2 = *static_cast<const YFrameWindow *const *>(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<const YFrameWindow *const *>(a);
+    const YFrameWindow *w2 = *static_cast<const YFrameWindow *const *>(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<const YFrameWindow *const *>(a);
+    const YFrameWindow *w2 = *static_cast<const YFrameWindow *const *>(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<const YFrameWindow *const *>(a);
+    const YFrameWindow *w2 = *static_cast<const YFrameWindow *const *>(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;
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin