diff --git a/packages/ide/fpconst.pas b/packages/ide/fpconst.pas
index f0ebc0b3c5..454639562c 100644
--- a/packages/ide/fpconst.pas
+++ b/packages/ide/fpconst.pas
@@ -166,6 +166,9 @@ const
 
      { Command constants }
      cmShowClipboard     = 201;
+     cmStepped           = 203;
+     cmSteppedRevers     = 204;
+     cmTileVertical      = 205;
      cmFindProcedure     = 206;
      cmObjects           = 207;
      cmModules           = 208;
@@ -412,6 +415,9 @@ const
      hcTarget            = hcShift+cmTarget;
      hcPrimaryFile       = hcShift+cmPrimaryFile;
      hcClearPrimary      = hcShift+cmClearPrimary;
+     hcTileVertical      = hcShift+cmTileVertical;
+     hcStepped           = hcShift+cmStepped;
+     hcSteppedRevers     = hcShift+cmSteppedRevers;
      hcWindowList        = hcShift+cmWindowList;
      hcNewFromTemplate   = hcShift+cmNewFromTemplate;
      hcHelpTopicSearch   = hcShift+cmHelpTopicSearch;
diff --git a/packages/ide/fphelp.pas b/packages/ide/fphelp.pas
index f6c365241c..c6ab40a5e8 100644
--- a/packages/ide/fphelp.pas
+++ b/packages/ide/fphelp.pas
@@ -214,6 +214,7 @@ const
       hint_windowmenu        = 'Windows management commands';
       hint_tile              = 'Arrange windows on desktop by tiling';
       hint_cascade           = 'Arrange windows on desktop by cascading';
+      hint_stepped           = 'Arrange windows on desktop by stepping';
       hint_closeall          = 'Close all windows on the desktop';
       hint_resize            = 'Change the size/postion of the active window';
       hint_zoom              = 'Enlarge or restore the size of the active window';
@@ -391,6 +392,7 @@ begin
     hcWindowMenu    : S:=hint_windowmenu;
     hcTile          : S:=hint_tile;
     hcCascade       : S:=hint_cascade;
+    hcStepped       : S:=hint_stepped;
     hcCloseAll      : S:=hint_closeall;
     hcResize        : S:=hint_resize;
     hcZoom          : S:=hint_zoom;
diff --git a/packages/ide/fpide.pas b/packages/ide/fpide.pas
index 8fcf73405f..2542e0fa05 100644
--- a/packages/ide/fpide.pas
+++ b/packages/ide/fpide.pas
@@ -133,6 +133,10 @@ type
       procedure OpenINI;
       procedure SaveINI;
       procedure SaveAsINI;
+      procedure TileVertical;
+      procedure Stepped(aDirection:boolean);
+      procedure UpdateTileMenu;
+      procedure UpdateSteppedMenu;
       procedure CloseAll;
       procedure WindowList;
       procedure HelpContents;
@@ -340,7 +344,10 @@ resourcestring  menu_local_gotosource = '~G~oto source';
 
                 menu_window            = '~W~indow';
                 menu_window_tile       = '~T~ile';
+                menu_window_tile_vertical = '~T~ile (vertical)';
                 menu_window_cascade    = 'C~a~scade';
+                menu_window_stepped    = 'Steppe~d~';
+                menu_window_stepped_revers = 'Steppe~d~ (revers)';
                 menu_window_closeall   = 'Cl~o~se all';
                 menu_window_resize     = '~S~ize/Move';
                 menu_window_zoom       = '~Z~oom';
@@ -1076,6 +1083,7 @@ begin
     NewSubMenu(menu_window, hcWindowMenu, NewMenu(
       NewItem(menu_window_tile,'', kbNoKey, cmTile, hcTile,
       NewItem(menu_window_cascade,'', kbNoKey, cmCascade, hcCascade,
+      NewItem(menu_window_stepped,'', kbNoKey, cmStepped, hcStepped,
       NewItem(menu_window_closeall,'', kbNoKey, cmCloseAll, hcCloseAll,
       NewLine(
       NewItem(menu_window_resize,menu_key_window_resize, kbCtrlF5, cmResize, hcResize,
@@ -1087,7 +1095,7 @@ begin
       NewLine(
       NewItem(menu_window_list,menu_key_window_list, kbAlt0, cmWindowList, hcWindowList,
       NewItem(menu_window_update,'', kbNoKey, cmUpdate, hcUpdate,
-      nil)))))))))))))),
+      nil))))))))))))))),
     NewSubMenu(menu_help, hcHelpMenu, NewMenu(
       NewItem(menu_help_contents,'', kbNoKey, cmHelpContents, hcHelpContents,
       NewItem(menu_help_index,menu_key_help_helpindex, kbShiftF1, cmHelpIndex, hcHelpIndex,
@@ -1419,6 +1427,10 @@ begin
              cmToolsBase+MaxToolCount
                              : ExecuteTool(Event.Command-cmToolsBase);
            { -- Window menu -- }
+             cmTile          : begin UpdateTileMenu; Tile; end;
+             cmTileVertical  : begin UpdateTileMenu; TileVertical; end;
+             cmStepped       : begin UpdateSteppedMenu; Stepped(True); end;
+             cmSteppedRevers : begin UpdateSteppedMenu; Stepped(False); end;
              cmCloseAll      : CloseAll;
              cmWindowList    : WindowList;
              cmUserScreenWindow: DoUserScreenWindow;
@@ -1695,8 +1707,9 @@ procedure TIDEApp.Update;
 begin
   SetCmdState([cmSaveAll],IsThereAnyEditor);
   SetCmdState([cmCloseAll,cmWindowList],IsThereAnyWindow);
-  SetCmdState([cmTile,cmCascade],IsThereAnyVisibleEditorWindow);
+  SetCmdState([cmTile,cmCascade,cmTileVertical,cmStepped,cmSteppedRevers],IsThereAnyVisibleEditorWindow);
   SetCmdState([cmFindProcedure,cmObjects,cmModules,cmGlobals,cmSymbol],IsSymbolInfoAvailable);
+
 {$ifndef NODEBUG}
   SetCmdState([cmResetDebugger,cmUntilReturn],assigned(debugger) and debugger^.debuggee_started);
 {$endif}
diff --git a/packages/ide/fpmwnd.inc b/packages/ide/fpmwnd.inc
index ef41850699..e64b159e51 100644
--- a/packages/ide/fpmwnd.inc
+++ b/packages/ide/fpmwnd.inc
@@ -13,6 +13,95 @@
 
  **********************************************************************}
 
+procedure TIDEApp.TileVertical;
+begin
+  if not assigned(Desktop) then exit;
+  Desktop^.TileColumnsFirst:=True;
+  Tile;
+  Desktop^.TileColumnsFirst:=False;
+end;
+
+FUNCTION Tileable (P: PView): Boolean;
+BEGIN
+   Tileable := (P^.Options AND ofTileable <> 0) AND   { View is tileable }
+     (P^.State AND sfVisible <> 0);                   { View is visible }
+END;
+
+{ This pritty much copy of window cascade }
+{ added extra variable `Count` }
+{ calculate one of `NR.A.Y` or `NR.A.X` in revers }
+procedure TIDEApp.Stepped(aDirection:boolean);
+var R: TRect;
+VAR CascadeNum, Count: SmallInt; LastView: PView; Min, Max: TPoint;
+
+   PROCEDURE DoCount (P: PView);
+   BEGIN
+     If Tileable(P) Then Begin
+       Inc(CascadeNum); LastView := P;                { Count steppable }
+     End;
+   END;
+
+   PROCEDURE DoCascade (P: PView);
+   VAR PState: Word; NR: TRect;
+   BEGIN
+     If Tileable(P) AND (CascadeNum >= 0) Then Begin  { View steppable }
+       NR.Copy(R);                                    { Copy rect area }
+       if aDirection then
+       begin
+         {option 1 active window in lowest position, window titles visible}
+         Inc(NR.A.X, Count*1-CascadeNum*1-1);         { Inc x position }
+         Inc(NR.A.Y, CascadeNum);                     { Inc y position }
+       end else
+       begin
+         {option 2 active window in highest position, window titles not visible}
+         Inc(NR.A.X, CascadeNum*1);                     { Inc x position }
+         Inc(NR.A.Y, Count-CascadeNum-1);               { Inc y position }
+       end;
+       PState := P^.State;                            { Hold view state }
+       P^.State := P^.State AND NOT sfVisible;        { Temp stop draw }
+       P^.Locate(NR);                                 { Locate the view }
+       P^.State := PState;                            { Now allow draws }
+       Dec(CascadeNum);                               { Dec count }
+     End;
+   END;
+
+begin
+   if not assigned(Desktop) then exit;
+   GetTileRect(R);                                    { Tileable area }
+   CascadeNum := 0;                                   { Zero step count }
+   Desktop^.ForEach(TCallbackProcParam(@DoCount));    { Count stepable }
+   Count:=CascadeNum;                                 { Keep count in Count }
+   If (CascadeNum>0) Then Begin
+     LastView^.SizeLimits(Min, Max);                  { Check size limits }
+     If (Min.X > R.B.X - R.A.X - CascadeNum) OR
+     (Min.Y > R.B.Y - R.A.Y - CascadeNum) Then
+     Desktop^.TileError Else Begin                    { Check for error }
+       Dec(CascadeNum);                               { One less view }
+       Desktop^.ForEach(TCallbackProcParam(@DoCascade)); { Stepped view }
+       Desktop^.DrawView;                             { Redraw now }
+     End;
+   End;
+end;
+
+
+procedure TIDEApp.UpdateTileMenu;
+var MenuItem : PMenuItem;
+    bFirst : boolean;
+begin
+  MenuItem:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cmTileVertical);
+  bFirst:=assigned(MenuItem);
+  ChangeMenu(PAdvancedMenuBar(MenuBar),bFirst,cmTile,menu_window_tile,cmTileVertical,menu_window_tile_vertical);
+end;
+
+procedure TIDEApp.UpdateSteppedMenu;
+var MenuItem : PMenuItem;
+    bFirst : boolean;
+begin
+  MenuItem:=PAdvancedMenuBar(MenuBar)^.GetMenuItem(cmSteppedRevers);
+  bFirst:=assigned(MenuItem);
+  ChangeMenu(PAdvancedMenuBar(MenuBar),bFirst,cmStepped,menu_window_stepped,cmSteppedRevers,menu_window_stepped_revers);
+end;
+
 procedure TIDEApp.CloseAll;
 
   procedure SendClose(P: PView);