View Issue Details

IDProjectCategoryView StatusLast Update
0038556LazarusPackagespublic2021-03-10 22:03
ReporterAnton Kavalenka Assigned ToMichl  
PrioritynormalSeverityminorReproducibilityalways
Status feedbackResolutionopen 
Product Version2.1 (SVN) 
Summary0038556: anchordocking: Allow developer have multiple DockMaster instances.
DescriptionThe purpose of the patch - Allow complex form instances to have different layouts.
Previously this was impossible due to single DockMaster instance per application.

With this patch the form can create its own TAnchorDockMaster instance and save/load layouts without interfering with other instances of such form.

It is possible to continue use global dockmaster (compatibility) or create desired amount of separated instances with different layout/settings.
TagsNo tags attached.
Fixed in Revision
LazTarget-
WidgetsetGTK 2, GTK 3, Win32/Win64, Cocoa, QT, QT5
Attached Files

Activities

Anton Kavalenka

2021-02-28 11:02

reporter  

anchordocking.diff (42,308 bytes)   
Index: components/anchordocking/anchordocking.pas
===================================================================
--- components/anchordocking/anchordocking.pas	(revision 64680)
+++ components/anchordocking/anchordocking.pas	(working copy)
@@ -143,6 +143,7 @@
 
 type
   TAnchorDockHostSite = class;
+  TAnchorDockMaster = class;
 
   { TAnchorDockCloseButton
     Close button used in TAnchorDockHeader, uses the close button glyph of the
@@ -222,6 +223,7 @@
     procedure PopupMenuPopup(Sender: TObject); virtual;
   public
     constructor Create(TheOwner: TComponent); override;
+    function GetDockMaster:TAnchorDockMaster;
     property CloseButton: TCustomSpeedButton read FCloseButton;
     property MinimizeButton: TCustomSpeedButton read FMinimizeButton;
     property HeaderPosition: TADLHeaderPosition read FHeaderPosition write SetHeaderPosition;
@@ -256,6 +258,7 @@
   public
     constructor Create(TheOwner: TComponent); override;
     destructor Destroy; override;
+    function GetDockMaster:TAnchorDockMaster;
     property DockBounds: TRect read FDockBounds;
     property DockParentClientSize: TSize read FDockParentClientSize;
     procedure UpdateDockBounds;
@@ -287,6 +290,7 @@
     procedure InsertControl(AControl: TControl; Index: integer); override;
     procedure RemoveControl(AControl: TControl); override;
     function GetSite: TAnchorDockHostSite;
+    function GetDockMaster():TAnchorDockMaster;
   end;
   TAnchorDockPageClass = class of TAnchorDockPage;
 
@@ -311,6 +315,8 @@
     function GetPageClass: TCustomPageClass;override;
   public
     constructor Create(TheOwner: TComponent); override;
+    function GetPopupMenu:TPopupMenu;override;
+    function GetDockMaster:TAnchorDockMaster;
     procedure UpdateDockCaption(Exclude: TControl = nil); override;
     property DockPages[Index: integer]: TAnchorDockPage read GetDockPages;
     procedure RemoveControl(AControl: TControl); override;
@@ -339,6 +345,8 @@
     adhstPages  // the "Pages" (TAnchorDockPageControl) with several pages
     );
 
+
+
   TAnchorDockHostSite = class(TCustomForm)
   private
     FDockRestoreBounds: TRect;
@@ -407,6 +415,7 @@
     destructor Destroy; override;
     function CloseQuery: boolean; override;
     function CloseSite: boolean; virtual;
+    function GetDockMaster:TAnchorDockMaster;
     procedure MinimizeSite; virtual;
     procedure AsyncMinimizeSite({%H-}Data: PtrInt);
     procedure ShowMinimizedControl;
@@ -461,10 +470,12 @@
     FResizePolicy: TADMResizePolicy;
     FStoredConstraints: TRect;
     FSite: TWinControl;
+    FDockMaster: TAnchorDockMaster;
     FSiteClientRect: TRect;
     procedure SetPreferredSiteSizeAsSiteMinimum(const AValue: boolean);
   public
     constructor Create(ADockSite: TWinControl); override;
+    function GetDockMaster:TAnchorDockMaster;
     procedure GetControlBounds(Control: TControl; out AControlBounds: TRect);
       override;
     procedure InsertControl(Control: TControl; InsertAt: TAlign;
@@ -567,8 +578,6 @@
 
   TMapMinimizedControls = specialize TFPGMap <Pointer, Pointer>;
 
-  TAnchorDockMaster = class;
-
   { TAnchorDockMaster
     The central instance that connects all sites and manages all global
     settings. Its global variable is the DockMaster.
@@ -626,8 +635,9 @@
     WorkArea, SrcWorkArea: TRect;
     FOverlappingForm:TAnchorDockOverlappingForm;
     CurrentADHeaderStyle:TADHeaderStyle;
-    FHeaderStyleName2ADHeaderStyle:THeaderStyleName2ADHeaderStylesMap;
 
+    DockTimer: TTimer;
+
     function GetControls(Index: integer): TControl;
     function GetLocalizedHeaderHint: string;
     procedure MarkCorrectlyLocatedControl(Tree: TAnchorDockLayoutTree);
@@ -688,7 +698,6 @@
     procedure StopHideOverlappingTimer;
     procedure AsyncSimplify({%H-}Data: PtrInt);
   public
-    procedure RegisterHeaderStyle(StyleName: THeaderStyleName; DrawProc:TDrawADHeaderProc; NeedDrawHeaderAfterText,NeedHighlightText: boolean);
     procedure ShowOverlappingForm;
     procedure HideOverlappingForm(Sender: TObject);
     constructor Create(AOwner: TComponent); override;
@@ -803,16 +812,16 @@
     property HeaderClass: TAnchorDockHeaderClass read FHeaderClass write FHeaderClass;
     property PageControlClass: TAnchorDockPageControlClass read FPageControlClass write FPageControlClass;
     property PageClass: TAnchorDockPageClass read FPageClass write FPageClass;
-    property HeaderStyleName2ADHeaderStyle:THeaderStyleName2ADHeaderStylesMap read FHeaderStyleName2ADHeaderStyle;
+    //property HeaderStyleName2ADHeaderStyle:THeaderStyleName2ADHeaderStylesMap read FHeaderStyleName2ADHeaderStyle;
   end;
 
 var
   DockMaster: TAnchorDockMaster = nil;
-  DockTimer: TTimer = nil;
 
   PreferredButtonWidth:integer=-1;
   PreferredButtonHeight:integer=-1;
 
+  FHeaderStyleName2ADHeaderStyle:THeaderStyleName2ADHeaderStylesMap;
 
 const
   HardcodedButtonSize:integer=13;
@@ -819,6 +828,7 @@
 
 function dbgs(SiteType: TAnchorDockHostSiteType): string; overload;
 
+procedure RegisterHeaderStyle(StyleName: THeaderStyleName; DrawProc:TDrawADHeaderProc; NeedDrawHeaderAfterText,NeedHighlightText: boolean);
 
 procedure CopyAnchorBounds(Source, Target: TControl);
 procedure AnchorAndChangeBounds(AControl: TControl; Side: TAnchorKind;
@@ -2802,7 +2812,7 @@
     EnableAllAutoSizing;
 end;
 
-procedure TAnchorDockMaster.RegisterHeaderStyle(StyleName: THeaderStyleName; DrawProc:TDrawADHeaderProc; NeedDrawHeaderAfterText,NeedHighlightText: boolean);
+procedure RegisterHeaderStyle(StyleName: THeaderStyleName; DrawProc:TDrawADHeaderProc; NeedDrawHeaderAfterText,NeedHighlightText: boolean);
 var
   TempStyle:TADHeaderStyle;
 begin
@@ -2813,8 +2823,8 @@
   FHeaderStyleName2ADHeaderStyle.AddOrSetData(uppercase(StyleName), TempStyle);
   if FHeaderStyleName2ADHeaderStyle.Count=1 then
   begin
-    CurrentADHeaderStyle:=TempStyle;
-    HeaderStyle:=StyleName;
+    DockMaster.CurrentADHeaderStyle:=TempStyle;
+    DockMaster.HeaderStyle:=StyleName;
   end;
 end;
 
@@ -2865,7 +2875,7 @@
   FHeaderHighlightFocused:=false;
   FDockSitesCanBeMinimized:=false;
   FOverlappingForm:=nil;
-  FHeaderStyleName2ADHeaderStyle:=THeaderStyleName2ADHeaderStylesMap.create;
+  DockTimer:=TTimer.Create(Self);
 end;
 
 destructor TAnchorDockMaster.Destroy;
@@ -3143,6 +3153,7 @@
       AForm.FreeNotification(Self);
     end;
     AManager:=ManagerClass.Create(AForm);
+    AManager.fDockMaster:=Self;
     AManager.DockableSites:=Sites;
     AManager.InsideDockingAllowed:=AllowInside;
     AManager.ResizePolicy:=ResizePolicy;
@@ -4034,6 +4045,14 @@
                       DragDockObject.DropAlign);
 end;
 
+function TAnchorDockHostSite.GetDockMaster:TAnchorDockMaster;
+begin
+  if owner is TAnchorDockHostSite then
+  Result:=TAnchorDockHostSite(Owner).GetDockMaster
+  else
+  Result:=TAnchorDockMaster(Owner);
+end;
+
 function TAnchorDockHostSite.ExecuteDock(NewControl, DropOnControl: TControl;
   DockAlign: TAlign): boolean;
 begin
@@ -4044,7 +4063,7 @@
   try
     BeginUpdateLayout;
     try
-      DockMaster.SimplifyPendingLayouts;
+      GetDockMaster.SimplifyPendingLayouts;
       NewControl.DisableAutoSizing{$IFDEF DebugDisableAutoSizing}('TAnchorDockHostSite.ExecuteDock NewControl'){$ENDIF};
 
       if (NewControl.Parent=Self) and (SiteType=adhstLayout) then begin
@@ -4174,13 +4193,13 @@
     RaiseGDBException('TAnchorDockHostSite.DockAnotherControl inconsistency');
 
   // add a splitter
-  Splitter:=DockMaster.CreateSplitter;
+  Splitter:=GetDockMaster.CreateSplitter;
   if DockAlign in [alLeft,alRight] then begin
     Splitter.ResizeAnchor:=akLeft;
-    Splitter.Width:=DockMaster.SplitterWidth;
+    Splitter.Width:=GetDockMaster.SplitterWidth;
   end else begin
     Splitter.ResizeAnchor:=akTop;
-    Splitter.Height:=DockMaster.SplitterWidth;
+    Splitter.Height:=GetDockMaster.SplitterWidth;
   end;
   Splitter.Parent:=Self;
 
@@ -4211,7 +4230,7 @@
       end;
       BoundsRect:=NewBounds;
       BoundsIncreased:=true;
-    end else if DockMaster.IsCustomSite(Parent) then begin
+    end else if GetDockMaster.IsCustomSite(Parent) then begin
       // Parent is a custom docksite
       // => expand Self and Parent
       // expand Parent (the custom docksite)
@@ -4419,7 +4438,7 @@
 begin
   if FPages<>nil then
     RaiseGDBException('');
-  FPages:=DockMaster.PageControlClass.Create(nil); // do not own it, pages can be moved to another site
+  FPages:=GetDockMaster.PageControlClass.Create(nil); // do not own it, pages can be moved to another site
   FPages.FreeNotification(Self);
   FPages.Parent:=Self;
   FPages.Align:=alClient;
@@ -4542,7 +4561,7 @@
         end;
         if (sibling is TAnchorDockHostSite) then
         if (sibling as TAnchorDockHostSite).Minimized then begin
-          DockMaster.FMapMinimizedControls.Remove((sibling as TAnchorDockHostSite).FMinimizedControl);
+          GetDockMaster.FMapMinimizedControls.Remove((sibling as TAnchorDockHostSite).FMinimizedControl);
           (sibling as TAnchorDockHostSite).FMinimizedControl.Parent:=(sibling as TAnchorDockHostSite);
           (sibling as TAnchorDockHostSite).FMinimizedControl.Visible:=True;
           (sibling as TAnchorDockHostSite).FMinimizedControl:=nil;
@@ -4584,7 +4603,7 @@
         p:=ClientOrigin;
         OffsetRect(NewBounds,p.x,p.y);
         BoundsRect:=NewBounds;
-      end else if DockMaster.IsCustomSite(Parent) then begin
+      end else if GetDockMaster.IsCustomSite(Parent) then begin
         // parent is a custom dock site
         // shrink this site and the parent
         NewParentBounds:=Parent.BoundsRect;
@@ -4622,7 +4641,7 @@
       OnlySiteLeft.Align:=alClient;
       Header.Parent:=Self;
       if OnlySiteLeft.Minimized then begin
-        DockMaster.FMapMinimizedControls.Remove(OnlySiteLeft.FMinimizedControl);
+        GetDockMaster.FMapMinimizedControls.Remove(OnlySiteLeft.FMinimizedControl);
         OnlySiteLeft.FMinimizedControl.Parent:=OnlySiteLeft;
         OnlySiteLeft.FMinimizedControl.Visible:=True;
         OnlySiteLeft.FMinimizedControl:=nil;
@@ -4633,7 +4652,7 @@
       //debugln(['TAnchorDockHostSite.RemoveControlFromLayout.ConvertToOneControlType AFTER CONVERT "',Caption,'" to onecontrol OnlySiteLeft="',OnlySiteLeft.Caption,'"']);
       //DebugWriteChildAnchors(GetParentForm(Self),true,true);
 
-      DockMaster.NeedSimplify(Self);
+      GetDockMaster.NeedSimplify(Self);
     finally
       EndUpdateLayout;
     end;
@@ -4684,7 +4703,7 @@
 procedure TAnchorDockHostSite.RemoveMinimizedControl;
 begin
   FMinimizedControl:=nil;
-  DockMaster.FMapMinimizedControls.Remove(FMinimizedControl);
+  GetDockMaster.FMapMinimizedControls.Remove(FMinimizedControl);
 end;
 
 procedure TAnchorDockHostSite.RemoveSpiralSplitter(AControl: TControl);
@@ -4798,7 +4817,7 @@
     if AControl is TAnchorDockHostSite then
       SimplifyOneControl
     else if ((AControl=nil) or (csDestroying in AControl.ComponentState)) then
-      DockMaster.NeedFree(Self);
+      GetDockMaster.NeedFree(Self);
   end;
 end;
 
@@ -4808,7 +4827,7 @@
   Site: TAnchorDockHostSite;
 begin
   if Pages=nil then exit;
-  if DockMaster.IsReleasing(Pages) then exit;
+  if GetDockMaster.IsReleasing(Pages) then exit;
   if Pages.PageCount=1 then begin
     {$IFDEF VerboseAnchorDockPages}
     debugln(['TAnchorDockHostSite.SimplifyPages "',Caption,'" PageCount=1']);
@@ -4825,7 +4844,7 @@
       if SiteType=adhstPages then
         FSiteType:=adhstOneControl;
       // free Pages
-      DockMaster.NeedFree(Pages);
+      GetDockMaster.NeedFree(Pages);
       if SiteType=adhstOneControl then
         SimplifyOneControl;
     finally
@@ -4838,7 +4857,7 @@
     //debugln(['TAnchorDockHostSite.SimplifyPages "',Caption,'" PageCount=0 Self=',dbgs(Pointer(Self))]);
     FSiteType:=adhstNone;
     FreePages;
-    DockMaster.NeedSimplify(Self);
+    GetDockMaster.NeedSimplify(Self);
   end;
 end;
 
@@ -4913,7 +4932,7 @@
 
     // delete Site
     Site.FSiteType:=adhstNone;
-    DockMaster.NeedFree(Site);
+    GetDockMaster.NeedFree(Site);
   finally
     EndUpdateLayout;
     EnableAutoSizing{$IFDEF DebugDisableAutoSizing}('TAnchorDockHostSite.SimplifyOneControl'){$ENDIF};
@@ -5004,7 +5023,7 @@
   if AControl is TAnchorDockHostSite then
     Result:=TAnchorDockHostSite(AControl)
   else begin
-    Result:=DockMaster.CreateSite;
+    Result:=GetDockMaster.CreateSite;
     try
       AControl.ManualDock(Result,nil,alClient);
     finally
@@ -5041,8 +5060,8 @@
   inherited AlignControls(AControl, ARect);
   if csDestroying in ComponentState then exit;
 
-  if DockMaster.ScaleOnResize and (not UpdatingLayout)
-  and (not DockMaster.Restoring) then begin
+  if GetDockMaster.ScaleOnResize and (not UpdatingLayout)
+  and (not GetDockMaster.Restoring) then begin
     // scale splitters
     for i:=0 to ControlCount-1 do begin
       Child:=Controls[i];
@@ -5094,8 +5113,8 @@
 procedure TAnchorDockHostSite.DoDock(NewDockSite: TWinControl; var ARect: TRect);
 begin
   inherited DoDock(NewDockSite, ARect);
-  if DockMaster <> nil then
-    DockMaster.SimplifyPendingLayouts;
+  if GetDockMaster <> nil then
+    GetDockMaster.SimplifyPendingLayouts;
 end;
 
 procedure TAnchorDockHostSite.SetParent(NewParent: TWinControl);
@@ -5131,7 +5150,7 @@
 begin
   Result:=(SiteType<>adhstLayout)
       and (not (Parent is TAnchorDockPage))
-      and Assigned(DockMaster) and DockMaster.ShowHeader;
+      and Assigned(GetDockMaster) and GetDockMaster.ShowHeader;
 end;
 
 procedure TAnchorDockHostSite.DoClose(var CloseAction: TCloseAction);
@@ -5194,7 +5213,7 @@
       end;
     end;
     Parent:=nil;
-    DockMaster.NeedFree(Self);
+    GetDockMaster.NeedFree(Self);
   finally
     ParentSite.EndUpdateLayout;
     // not needed, because this site is freed: EnableAutoSizing;
@@ -5390,10 +5409,10 @@
     if Sibling.AnchorSide[BehindSide].Control<>Splitter then continue;
     if not (Sibling is TAnchorDockSplitter) then continue;
     if Side in [akLeft,akRight] then begin
-      if Sibling.Top<Top-DockMaster.SplitterWidth then continue;
+      if Sibling.Top<Top-GetDockMaster.SplitterWidth then continue;
       if Sibling.Top>Top+Height then continue;
     end else begin
-      if Sibling.Left<Left-DockMaster.SplitterWidth then continue;
+      if Sibling.Left<Left-GetDockMaster.SplitterWidth then continue;
       if Sibling.Left>Left+Width then continue;
     end;
     if RotateSplitter=nil then
@@ -5407,12 +5426,12 @@
   for i:=0 to RotateSplitter.AnchoredControlCount-1 do begin
     Sibling:=RotateSplitter.AnchoredControls[i];
     if Side in [akLeft,akRight] then begin
-      if (Sibling.Top>Top-DockMaster.SplitterWidth)
-      and (Sibling.Top+Sibling.Height<Top+Height+DockMaster.SplitterWidth) then
+      if (Sibling.Top>Top-GetDockMaster.SplitterWidth)
+      and (Sibling.Top+Sibling.Height<Top+Height+GetDockMaster.SplitterWidth) then
         exit;
     end else begin
-      if (Sibling.Left>Left-DockMaster.SplitterWidth)
-      and (Sibling.Left+Sibling.Width<Left+Width+DockMaster.SplitterWidth) then
+      if (Sibling.Left>Left-GetDockMaster.SplitterWidth)
+      and (Sibling.Left+Sibling.Width<Left+Width+GetDockMaster.SplitterWidth) then
         exit;
     end;
   end;
@@ -5444,10 +5463,10 @@
     AnchorAndChangeBounds(RotateSplitter,CWSide,CCWSplitter);
     if Side in [akLeft,akRight] then begin
       RotateSplitter.Left:=Splitter.Left;
-      RotateSplitter.Width:=DockMaster.SplitterWidth;
+      RotateSplitter.Width:=GetDockMaster.SplitterWidth;
     end else begin
       RotateSplitter.Top:=Splitter.Top;
-      RotateSplitter.Height:=DockMaster.SplitterWidth;
+      RotateSplitter.Height:=GetDockMaster.SplitterWidth;
     end;
     // shrink Splitter
     AnchorAndChangeBounds(Splitter,CCWSide,CWSplitter);
@@ -5474,7 +5493,7 @@
 procedure TAnchorDockHostSite.CreateBoundSplitter(Disabled: boolean);
 begin
   if BoundSplitter<>nil then exit;
-  FBoundSplitter:=DockMaster.CreateSplitter;
+  FBoundSplitter:=GetDockMaster.CreateSplitter;
   BoundSplitter.FreeNotification(Self);
   BoundSplitter.Align:=Align;
   BoundSplitter.Parent:=Parent;
@@ -5590,7 +5609,7 @@
       FMinimizedControl:=AControl;
       AControl.Visible:=False;
       AControl.Parent:=nil;
-      DockMaster.FMapMinimizedControls.Add(AControl,Self);
+      GetDockMaster.FMapMinimizedControls.Add(AControl,Self);
     end else begin
       MaxSize:=ReturnAnchoredControlsSize(Splitter,SplitterAnchorKind);
       case SplitterAnchorKind of
@@ -5610,12 +5629,12 @@
       AControl.Parent:=self;
       AControl.Visible:=True;
       FMinimizedControl:=nil;
-      DockMaster.FMapMinimizedControls.Remove(AControl);
+      GetDockMaster.FMapMinimizedControls.Remove(AControl);
     end;
     Splitter.Enabled:=AControl.Visible;
     UpdateHeaderAlign;
-    dockmaster.UpdateHeaders;
-    dockmaster.InvalidateHeaders;
+    GetDockmaster.UpdateHeaders;
+    GetDockmaster.InvalidateHeaders;
     Splitter.SetBoundsPercentually;
   end;
 end;
@@ -5635,14 +5654,14 @@
        akRight:OverlappingFormRect.Right:=SpliterRect.Left;
       akBottom:OverlappingFormRect.Bottom:=SpliterRect.Top;
     end;
-    DockMaster.FOverlappingForm:=TAnchorDockOverlappingForm.CreateNew(self);
-    DockMaster.FOverlappingForm.BoundsRect:=OverlappingFormRect;
-    DockMaster.FOverlappingForm.Parent:=GetParentFormOrDockPanel(self,false);
-    DockMaster.FOverlappingForm.AnchorDockHostSite:=self;
-    header.Parent:=DockMaster.FOverlappingForm;
-    FMinimizedControl.Parent:=DockMaster.FOverlappingForm.Panel;
+    GetDockMaster.FOverlappingForm:=TAnchorDockOverlappingForm.CreateNew(self);
+    GetDockMaster.FOverlappingForm.BoundsRect:=OverlappingFormRect;
+    GetDockMaster.FOverlappingForm.Parent:=GetParentFormOrDockPanel(self,false);
+    GetDockMaster.FOverlappingForm.AnchorDockHostSite:=self;
+    header.Parent:=GetDockMaster.FOverlappingForm;
+    FMinimizedControl.Parent:=GetDockMaster.FOverlappingForm.Panel;
     FMinimizedControl.Show;
-    DockMaster.ShowOverlappingForm;
+    GetDockMaster.ShowOverlappingForm;
   end;
 end;
 
@@ -5652,7 +5671,7 @@
    header.Parent:=self;
    header.UpdateHeaderControls;
    FMinimizedControl.Parent:=nil;
-   FreeAndNil(DockMaster.FOverlappingForm);
+   FreeAndNil(GetDockMaster.FOverlappingForm);
 end;
 
 function TAnchorDockHostSite.CloseSite: boolean;
@@ -5768,7 +5787,7 @@
         if (SiteType=adhstLayout) then
           RemoveControlFromLayout(AControl)
         else
-          DockMaster.NeedSimplify(Self);
+          GetDockMaster.NeedSimplify(Self);
         UpdateDockCaption;
         //debugln(['TAnchorDockHostSite.RemoveControl END ',Caption,' ',dbgs(SiteType),' ',DbgSName(AControl)]);
       end;
@@ -5839,9 +5858,9 @@
 begin
   GetWindowRect(Handle, InfluenceRect);
 
-  if (Parent=nil) or DockMaster.IsCustomSite(Parent) then begin
+  if (Parent=nil) or GetDockMaster.IsCustomSite(Parent) then begin
     // allow docking outside => enlarge margins
-    ADockMargin:=DockMaster.DockOutsideMargin;
+    ADockMargin:=GetDockMaster.DockOutsideMargin;
     //debugln(['TAnchorDockHostSite.GetSiteInfo ',DbgSName(Self),' allow outside ADockMargin=',ADockMargin,' ',dbgs(InfluenceRect)]);
     InfluenceRect.Left := InfluenceRect.Left-ADockMargin;
     InfluenceRect.Top := InfluenceRect.Top-ADockMargin;
@@ -5849,7 +5868,7 @@
     InfluenceRect.Bottom := InfluenceRect.Bottom+ADockMargin;
   end else if Parent is TAnchorDockHostSite then begin
     // do not cover parent site => shrink margins
-    ADockMargin:=DockMaster.DockParentMargin;
+    ADockMargin:=GetDockMaster.DockParentMargin;
     ADockMargin:=Min(ADockMargin,Min(ClientWidth,ClientHeight) div 10);
     ADockMargin:=Max(0,ADockMargin);
     //debugln(['TAnchorDockHostSite.GetSiteInfo ',DbgSName(Self),' do not cover parent ADockMargin=',ADockMargin,' ',dbgs(InfluenceRect)]);
@@ -5860,7 +5879,7 @@
   end;
 
   CanDock:=(Client is TAnchorDockHostSite)
-           and not DockMaster.AutoFreedIfControlIsRemoved(Self,Client)
+           and not GetDockMaster.AutoFreedIfControlIsRemoved(Self,Client)
            and not Minimized;
   //debugln(['TAnchorDockHostSite.GetSiteInfo ',DbgSName(Self),' ',dbgs(BoundsRect),' ',Caption,' CanDock=',CanDock,' PtIn=',PtInRect(InfluenceRect,MousePos)]);
 
@@ -5870,10 +5889,10 @@
 
 function TAnchorDockHostSite.GetPageArea: TRect;
 begin
-  Result:=Rect(0,0,Width*DockMaster.PageAreaInPercent div 100,
-               Height*DockMaster.PageAreaInPercent div 100);
-  OffsetRect(Result,(Width*(100-DockMaster.PageAreaInPercent)) div 200,
-                    (Height*(100-DockMaster.PageAreaInPercent)) div 200);
+  Result:=Rect(0,0,Width*GetDockMaster.PageAreaInPercent div 100,
+               Height*GetDockMaster.PageAreaInPercent div 100);
+  OffsetRect(Result,(Width*(100-GetDockMaster.PageAreaInPercent)) div 200,
+                    (Height*(100-GetDockMaster.PageAreaInPercent)) div 200);
 end;
 
 procedure TAnchorDockHostSite.ChangeBounds(ALeft, ATop, AWidth,
@@ -5901,11 +5920,11 @@
   adlhpAuto:
     if Header.Align in [alLeft,alRight] then begin
       if (ClientHeight>0)
-      and ((ClientWidth*100 div ClientHeight)<=DockMaster.HeaderAlignTop) then
+      and ((ClientWidth*100 div ClientHeight)<=GetDockMaster.HeaderAlignTop) then
         Header.Align:=alTop;
     end else begin
       if (ClientHeight>0)
-      and ((ClientWidth*100 div ClientHeight)>=DockMaster.HeaderAlignLeft) then
+      and ((ClientWidth*100 div ClientHeight)>=GetDockMaster.HeaderAlignLeft) then
       begin
         if Application.BidiMode=bdRightToLeft then
           Header.Align:=alRight
@@ -5928,7 +5947,7 @@
   if Header=nil then exit;
   if HeaderNeedsShowing then begin
     Header.Parent:=Self;
-    Header.MinimizeButton.Visible:=(DockMaster.DockSitesCanBeMinimized and CanBeMinimized(Splitter,SplitterAnchorKind))or Minimized;
+    Header.MinimizeButton.Visible:=(GetDockMaster.DockSitesCanBeMinimized and CanBeMinimized(Splitter,SplitterAnchorKind))or Minimized;
     Header.MinimizeButton.Parent:=Header;
   end
   else
@@ -5938,7 +5957,7 @@
 procedure TAnchorDockHostSite.BeginUpdateLayout;
 begin
   inc(FUpdateLayout);
-  if FUpdateLayout=1 then DockMaster.BeginUpdate;
+  if FUpdateLayout=1 then GetDockMaster.BeginUpdate;
 end;
 
 procedure TAnchorDockHostSite.EndUpdateLayout;
@@ -5946,7 +5965,7 @@
   if FUpdateLayout=0 then RaiseGDBException('TAnchorDockHostSite.EndUpdateLayout');
   dec(FUpdateLayout);
   if FUpdateLayout=0 then
-    DockMaster.EndUpdate;
+    GetDockMaster.EndUpdate;
 end;
 
 function TAnchorDockHostSite.UpdatingLayout: boolean;
@@ -6045,13 +6064,13 @@
   FMinimizedControl:=Nil;
   Visible:=false;
   FHeaderSide:=akTop;
-  FHeader:=DockMaster.HeaderClass.Create(Self);
+  FHeader:=GetDockMaster.HeaderClass.Create(Self);
   FHeader.Align:=alTop;
   FHeader.Parent:=Self;
   FSiteType:=adhstNone;
   UpdateHeaderAlign;
   DragKind:=dkDock;
-  DockManager:=DockMaster.ManagerClass.Create(Self);
+  DockManager:=GetDockMaster.ManagerClass.Create(Self);
   UseDockManager:=true;
   DragManager.RegisterDockSite(Self,true);
 end;
@@ -6091,15 +6110,15 @@
   SideCaptions[akBottom]:=adrsBottom;
 
   // menu items: undock, merge
-  DockMaster.AddRemovePopupMenuItem(ParentSite.CanUndock,'UndockMenuItem',
+  GetDockMaster.AddRemovePopupMenuItem(ParentSite.CanUndock,'UndockMenuItem',
                                     adrsUndock,@UndockButtonClick);
-  DockMaster.AddRemovePopupMenuItem(ParentSite.CanMerge,'MergeMenuItem',
+  GetDockMaster.AddRemovePopupMenuItem(ParentSite.CanMerge,'MergeMenuItem',
                                     adrsMerge, @MergeButtonClick);
 
   // menu items: header position
-  HeaderPosItem:=DockMaster.AddPopupMenuItem('HeaderPosMenuItem',
+  HeaderPosItem:=GetDockMaster.AddPopupMenuItem('HeaderPosMenuItem',
                                              adrsHeaderPosition, nil);
-  Item:=DockMaster.AddPopupMenuItem('HeaderPosAutoMenuItem', adrsAutomatically,
+  Item:=GetDockMaster.AddPopupMenuItem('HeaderPosAutoMenuItem', adrsAutomatically,
                    @HeaderPositionItemClick, HeaderPosItem);
   if Item<>nil then begin
     Item.Tag:=ord(adlhpAuto);
@@ -6106,7 +6125,7 @@
     Item.Checked:=HeaderPosition=TADLHeaderPosition(Item.Tag);
   end;
   for Side:=Low(TAnchorKind) to High(TAnchorKind) do begin
-    Item:=DockMaster.AddPopupMenuItem('HeaderPos'+DbgS(Side)+'MenuItem',
+    Item:=GetDockMaster.AddPopupMenuItem('HeaderPos'+DbgS(Side)+'MenuItem',
                      SideCaptions[Side], @HeaderPositionItemClick,
                      HeaderPosItem);
     if Item=nil then continue;
@@ -6116,7 +6135,7 @@
 
   // menu items: enlarge
   for Side:=Low(TAnchorKind) to High(TAnchorKind) do begin
-    Item:=DockMaster.AddRemovePopupMenuItem(ParentSite.EnlargeSide(Side,true),
+    Item:=GetDockMaster.AddRemovePopupMenuItem(ParentSite.EnlargeSide(Side,true),
       'Enlarge'+DbgS(Side)+'MenuItem', Format(adrsEnlargeSide, [
         SideCaptions[Side]]),@EnlargeSideClick);
     if Item<>nil then Item.Tag:=ord(Side);
@@ -6128,7 +6147,7 @@
     s:=Format(adrsQuit, [Application.Title])
   else
     s:=adrsClose;
-  DockMaster.AddRemovePopupMenuItem(CloseButton.Visible,'CloseMenuItem',s,
+  GetDockMaster.AddRemovePopupMenuItem(CloseButton.Visible,'CloseMenuItem',s,
                                     @CloseButtonClick);
 end;
 
@@ -6137,12 +6156,12 @@
   HeaderParent:TAnchorDockHostSite;
 begin
   TWinControl(HeaderParent):=Parent;
-  if HeaderParent=TWinControl(DockMaster.FOverlappingForm) then begin
-    HeaderParent:=DockMaster.FOverlappingForm.AnchorDockHostSite;
+  if HeaderParent=TWinControl(GetDockMaster.FOverlappingForm) then begin
+    HeaderParent:=GetDockMaster.FOverlappingForm.AnchorDockHostSite;
     HeaderParent.HideMinimizedControl;
   end;
   if HeaderParent is TAnchorDockHostSite then begin
-    DockMaster.RestoreLayouts.Add(DockMaster.CreateRestoreLayout(HeaderParent),true);
+    GetDockMaster.RestoreLayouts.Add(GetDockMaster.CreateRestoreLayout(HeaderParent),true);
     HeaderParent.CloseSite;
   end;
 end;
@@ -6152,8 +6171,8 @@
   HeaderParent:TAnchorDockHostSite;
 begin
   TWinControl(HeaderParent):=Parent;
-  if HeaderParent=TWinControl(DockMaster.FOverlappingForm) then begin
-    HeaderParent:=DockMaster.FOverlappingForm.AnchorDockHostSite;
+  if HeaderParent=TWinControl(GetDockMaster.FOverlappingForm) then begin
+    HeaderParent:=GetDockMaster.FOverlappingForm.AnchorDockHostSite;
     HeaderParent.HideMinimizedControl;
   end;
   if HeaderParent is TAnchorDockHostSite then begin
@@ -6210,9 +6229,9 @@
       HeaderStyle.DrawProc(Canvas,HeaderStyle.StyleDesc,r,not(Align in [alLeft,alRight]),FFocused);
   end else begin
     Canvas.Brush.Color := clForm;
-    if DockMaster.HeaderFilled then
+    if GetDockMaster.HeaderFilled then
        Canvas.FillRect(r);
-    if not DockMaster.HeaderFlatten then
+    if not GetDockMaster.HeaderFlatten then
        Canvas.Frame3d(r,1,bvRaised);
   end;
   {case DockMaster.HeaderStyle of
@@ -6237,7 +6256,7 @@
 
   // caption
   if Caption<>'' then begin
-    if FFocused and DockMaster.HeaderHighlightFocused and HeaderStyle.StyleDesc.NeedHighlightText then
+    if FFocused and GetDockMaster.HeaderHighlightFocused and HeaderStyle.StyleDesc.NeedHighlightText then
       Canvas.Font.Bold:=true
     else
       Canvas.Font.Bold:=False;
@@ -6295,7 +6314,7 @@
 
 procedure TAnchorDockHeader.Paint;
 begin
-  draw(DockMaster.CurrentADHeaderStyle);
+  draw(GetDockMaster.CurrentADHeaderStyle);
 end;
 
 procedure TAnchorDockHeader.CalculatePreferredSize(var PreferredWidth,
@@ -6354,11 +6373,11 @@
   end else
     begin
       if parent<>nil then
-        if DockMaster.FOverlappingForm<>nil then
+        if GetDockMaster.FOverlappingForm<>nil then
           //if parent=DockMaster.FOverlappingForm.Panel then
-            DockMaster.HideOverlappingForm(nil);
-      if (Button=mbLeft) and (DockMaster.AllowDragging) and (DockMaster.FOverlappingForm=nil) then
-        DragManager.DragStart(Parent,false,DockMaster.DragTreshold);
+            GetDockMaster.HideOverlappingForm(nil);
+      if (Button=mbLeft) and (GetDockMaster.AllowDragging) and (GetDockMaster.FOverlappingForm=nil) then
+        DragManager.DragStart(Parent,false,GetDockMaster.DragTreshold);
     end;
 end;
 
@@ -6368,7 +6387,7 @@
   if parent<>nil then
     if parent is TAnchorDockHostSite then
       if (parent as TAnchorDockHostSite).Minimized then
-        if DockMaster.FOverlappingForm=nil then
+        if GetDockMaster.FOverlappingForm=nil then
           if FMouseTimeStartX=EmptyMouseTimeStartX then
             StartMouseNoMoveTimer
           else begin
@@ -6375,7 +6394,7 @@
             if (abs(FMouseTimeStartX-X)>MouseNoMoveDelta) or (abs(FMouseTimeStartY-Y)>MouseNoMoveDelta)then
             StopMouseNoMoveTimer;
           end;
-  if (parent is TAnchorDockHostSite) and (DockMaster.FOverlappingForm=nil)then
+  if (parent is TAnchorDockHostSite) and (GetDockMaster.FOverlappingForm=nil)then
     FUseTimer:=true;
 end;
 
@@ -6386,20 +6405,26 @@
 end;
 
 procedure TAnchorDockHeader.StartMouseNoMoveTimer;
+var
+  tmr:TTimer;
 begin
   if FUseTimer then begin
-    if DockTimer.Enabled then DockTimer.Enabled:=false;
-    DockTimer.Interval:=MouseNoMoveTime;
-    DockTimer.OnTimer:=@DoMouseNoMoveTimer;
-    DockTimer.Enabled:=true;
+    tmr:=GetDockMaster.DockTimer;
+    if tmr.Enabled then tmr.Enabled:=false;
+    tmr.Interval:=MouseNoMoveTime;
+    tmr.OnTimer:=@DoMouseNoMoveTimer;
+    tmr.Enabled:=true;
   end;
 end;
 
 procedure TAnchorDockHeader.StopMouseNoMoveTimer;
+var
+  tmr:TTimer;
 begin
   FMouseTimeStartX:=EmptyMouseTimeStartX;
-  DockTimer.OnTimer:=nil;
-  DockTimer.Enabled:=false;
+  tmr:=GetDockMaster.DockTimer;
+  tmr.OnTimer:=nil;
+  tmr.Enabled:=false;
 end;
 
 procedure TAnchorDockHeader.DoMouseNoMoveTimer(Sender: TObject);
@@ -6470,7 +6495,7 @@
   p: LongInt;
   c: String;
 begin
-  s:=DockMaster.GetLocalizedHeaderHint;
+  s:=GetDockMaster.GetLocalizedHeaderHint;
   p:=Pos('%s',s);
   if p>0 then begin
     if Parent<>nil then
@@ -6513,12 +6538,17 @@
   Align:=alTop;
   AutoSize:=true;
   ShowHint:=true;
-  PopupMenu:=DockMaster.GetPopupMenu;
+  PopupMenu:=GetDockMaster.GetPopupMenu;
   FFocused:=false;
   FMouseTimeStartX:=EmptyMouseTimeStartX;
   FUseTimer:=true;
 end;
 
+function TAnchorDockHeader.GetDockMaster: TAnchorDockMaster;
+begin
+  Result:=TAnchorDockHostSite(Owner).GetDockMaster;
+end;
+
 { TAnchorDockCloseButton }
 
 function TAnchorDockCloseButton.GetDrawDetails: TThemedElementDetails;
@@ -6644,6 +6674,11 @@
     FDockSite:=TAnchorDockHostSite(ADockSite);
 end;
 
+function TAnchorDockManager.GetDockMaster: TAnchorDockMaster;
+begin
+  Result:=fDockMaster;
+end;
+
 procedure TAnchorDockManager.GetControlBounds(Control: TControl; out
   AControlBounds: TRect);
 begin
@@ -6689,7 +6724,7 @@
       if Child is TAnchorDockHostSite then begin
         ChildSite:=TAnchorDockHostSite(Child);
         ChildSite.CreateBoundSplitter(Site is TAnchorDockPanel);
-        SplitterWidth:=DockMaster.SplitterWidth;
+        SplitterWidth:=GetDockMaster.SplitterWidth;
       end;
 
       if Site is TAnchorDockPanel then
@@ -6860,7 +6895,7 @@
       if Control is TAnchorDockHostSite then begin
         ChildSite:=TAnchorDockHostSite(Control);
         if ChildSite.BoundSplitter<>nil then
-          SplitterWidth:=DockMaster.SplitterWidth;
+          SplitterWidth:=GetDockMaster.SplitterWidth;
       end;
 
       // shrink Site
@@ -6908,7 +6943,7 @@
     SiteMinSize: TPoint;
     Child: TAnchorDockHostSite;
   begin
-    if ClientRectChanged and DockMaster.Restoring then begin
+    if ClientRectChanged and GetDockMaster.Restoring then begin
       // ClientRect changed => restore bounds
       for i:=0 to Site.ControlCount-1 do begin
         AControl:=Site.Controls[i];
@@ -6930,12 +6965,12 @@
             b.Top:=Max(0,Min(b.Top,Site.ClientHeight-10));
           if TAnchorDockSplitter(AControl).ResizeAnchor in [akLeft,akRight] then
           begin
-            b.Right:=b.Left+DockMaster.SplitterWidth;
+            b.Right:=b.Left+GetDockMaster.SplitterWidth;
             b.Bottom:=Max(1,Min(b.Bottom,Site.ClientHeight-b.Top));
           end
           else begin
             b.Right:=Max(1,Min(b.Right,Site.ClientWidth-b.Left));
-            b.Bottom:=b.Top+DockMaster.SplitterWidth;
+            b.Bottom:=b.Top+GetDockMaster.SplitterWidth;
           end;
         end;
 
@@ -6953,8 +6988,8 @@
     {$IFDEF VerboseAnchorDockRestore}
     debugln(['TAnchorDockManager.ResetBounds ',DbgSName(Site),' ',dbgs(Child.BaseBounds),' ',WidthDiff,',',HeightDiff]);
     {$ENDIF}
-    ChildMaxSize:=Point(Site.ClientWidth-DockMaster.SplitterWidth,
-                        Site.ClientHeight-DockMaster.SplitterWidth);
+    ChildMaxSize:=Point(Site.ClientWidth-GetDockMaster.SplitterWidth,
+                        Site.ClientHeight-GetDockMaster.SplitterWidth);
     if PreferredSiteSizeAsSiteMinimum then begin
       SiteMinSize:=GetSitePreferredClientSize;
       if Child.Align in [alLeft,alRight] then begin
@@ -6999,8 +7034,8 @@
   if ClientRectChanged or PreferredSiteSizeAsSiteMinimum then
     AlignChilds;
   if ClientRectChanged then
-    if DockMaster.FOverlappingForm<>nil then
-      DockMaster.HideOverlappingForm(nil);
+    if GetDockMaster.FOverlappingForm<>nil then
+      GetDockMaster.HideOverlappingForm(nil);
 end;
 
 procedure TAnchorDockManager.SaveToStream(Stream: TStream);
@@ -7216,7 +7251,7 @@
 
 function TAnchorDockManager.IsEnabledControl(Control: TControl):Boolean;
 begin
-  Result := (DockMaster <> nil) and DockMaster.IsSite(Control);
+  Result := (GetDockMaster <> nil) and GetDockMaster.IsSite(Control);
 end;
 
 { TAnchorDockSplitter }
@@ -7502,7 +7537,7 @@
   // make sure the splitter never vanish
   Constraints.MinWidth:=2;
   Constraints.MinHeight:=2;
-  PopupMenu:=DockMaster.GetPopupMenu;
+  PopupMenu:=GetDockMaster.GetPopupMenu;
   FPercentPosition:=-1;
 end;
 
@@ -7512,6 +7547,17 @@
   inherited Destroy;
 end;
 
+function TAnchorDockSplitter.GetDockMaster: TAnchorDockMaster;
+begin
+  if (Owner is TAnchorDockMaster) then
+    Result:=TAnchorDockMaster(Owner)
+  else
+  if (Owner is TAnchorDockHostSite) then
+    Result:=TAnchorDockHostSite(Owner).GetDockMaster
+  else
+    Result:=nil;
+end;
+
 { TAnchorDockPageControl }
 
 function TAnchorDockPageControl.GetDockPages(Index: integer): TAnchorDockPage;
@@ -7528,13 +7574,13 @@
 begin
   inherited MouseDown(Button, Shift, X, Y);
   ATabIndex := IndexOfPageAt(X, Y);
-  if (Button = mbLeft) and DockMaster.AllowDragging and (ATabIndex >= 0) and (DockMaster.FOverlappingForm=nil) then
+  if (Button = mbLeft) and GetDockMaster.AllowDragging and (ATabIndex >= 0) and (GetDockMaster.FOverlappingForm=nil) then
   begin
     APage:=Page[ATabIndex];
     if (APage.ControlCount>0) and (APage.Controls[0] is TAnchorDockHostSite) then
     begin
       Site:=TAnchorDockHostSite(APage.Controls[0]);
-      DragManager.DragStart(Site,false,DockMaster.DragTreshold);
+      DragManager.DragStart(Site,false,GetDockMaster.DragTreshold);
     end;
   end;
   if (Button = mbRight) then
@@ -7555,21 +7601,21 @@
 begin
   // movement
   if PageIndex>0 then
-    DockMaster.AddPopupMenuItem('MoveLeftMenuItem', adrsMovePageLeft,
+    GetDockMaster.AddPopupMenuItem('MoveLeftMenuItem', adrsMovePageLeft,
                                               @MoveLeftButtonClick);
   if PageIndex>1 then
-    DockMaster.AddPopupMenuItem('MoveLeftMostMenuItem', adrsMovePageLeftmost,
+    GetDockMaster.AddPopupMenuItem('MoveLeftMostMenuItem', adrsMovePageLeftmost,
                                               @MoveLeftMostButtonClick);
 
   if PageIndex<PageCount-1 then
-    DockMaster.AddPopupMenuItem('MoveRightMenuItem', adrsMovePageRight,
+    GetDockMaster.AddPopupMenuItem('MoveRightMenuItem', adrsMovePageRight,
                                               @MoveRightButtonClick);
   if PageIndex<PageCount-2 then
-    DockMaster.AddPopupMenuItem('MoveRightMostMenuItem', adrsMovePageRightmost,
+    GetDockMaster.AddPopupMenuItem('MoveRightMostMenuItem', adrsMovePageRightmost,
                                               @MoveRightMostButtonClick);
 
   // tab position
-  TabPositionSection:=DockMaster.AddPopupMenuItem('TabPositionMenuItem',
+  TabPositionSection:=GetDockMaster.AddPopupMenuItem('TabPositionMenuItem',
                                                   adrsTabPosition,nil);
   for tp:=Low(TTabPosition) to high(TTabPosition) do begin
     case tp of
@@ -7578,7 +7624,7 @@
     tpLeft: s:=adrsLeft;
     tpRight: s:=adrsRight;
     end;
-    Item:=DockMaster.AddPopupMenuItem('TabPos'+ADLTabPostionNames[tp]+'MenuItem',
+    Item:=GetDockMaster.AddPopupMenuItem('TabPos'+ADLTabPostionNames[tp]+'MenuItem',
                               s,@TabPositionClick,TabPositionSection);
     Item.ShowAlwaysCheckable:=true;
     Item.Checked:=TabPosition=tp;
@@ -7591,7 +7637,7 @@
     s:=Format(adrsQuit, [Application.Title])
   else
     s:=adrsClose;
-  DockMaster.AddPopupMenuItem('CloseMenuItem',s,@CloseButtonClick);
+  GetDockMaster.AddPopupMenuItem('CloseMenuItem',s,@CloseButtonClick);
 end;
 
 procedure TAnchorDockPageControl.CloseButtonClick(Sender: TObject);
@@ -7600,9 +7646,9 @@
 begin
   Site:=GetActiveSite;
   if Site=nil then exit;
-  DockMaster.RestoreLayouts.Add(DockMaster.CreateRestoreLayout(Site),true);
+  GetDockMaster.RestoreLayouts.Add(GetDockMaster.CreateRestoreLayout(Site),true);
   Site.CloseSite;
-  DockMaster.SimplifyPendingLayouts;
+  GetDockMaster.SimplifyPendingLayouts;
 end;
 
 procedure TAnchorDockPageControl.MoveLeftButtonClick(Sender: TObject);
@@ -7648,7 +7694,7 @@
   inherited RemoveControl(AControl);
   if (not (csDestroying in ComponentState)) then begin
     if (PageCount<=1) and (Parent is TAnchorDockHostSite) then
-      DockMaster.NeedSimplify(Parent);
+      GetDockMaster.NeedSimplify(Parent);
   end;
 end;
 
@@ -7667,12 +7713,22 @@
 constructor TAnchorDockPageControl.Create(TheOwner: TComponent);
 begin
   inherited Create(TheOwner);
-  PopupMenu:=DockMaster.GetPopupMenu;
+
 end;
 
+function TAnchorDockPageControl.GetPopupMenu: TPopupMenu;
+begin
+  Result:=GetDockMaster.GetPopupMenu;
+end;
+
+function TAnchorDockPageControl.GetDockMaster: TAnchorDockMaster;
+begin
+  Result:=TAnchorDockHostSite(Parent).GetDockMaster;
+end;
+
 function TAnchorDockPageControl.GetPageClass: TCustomPageClass;
 begin
-  Result:=DockMaster.PageClass;
+  Result:=GetDockMaster.PageClass;
 end;
 
 { TAnchorDockOverlappingForm }
@@ -7729,7 +7785,7 @@
   inherited RemoveControl(AControl);
   if (GetSite=nil) and (not (csDestroying in ComponentState))
   and (Parent<>nil) and (not (csDestroying in Parent.ComponentState)) then
-    DockMaster.NeedSimplify(Self);
+    GetDockMaster.NeedSimplify(Self);
 end;
 
 function TAnchorDockPage.GetSite: TAnchorDockHostSite;
@@ -7740,6 +7796,14 @@
   Result:=TAnchorDockHostSite(Controls[0]);
 end;
 
+function TAnchorDockPage.GetDockMaster(): TAnchorDockMaster;
+begin
+  if Owner is TAnchorDockPageControl then
+    Result:=TAnchorDockPageControl(Owner).GetDockMaster
+  else
+    Result:=nil
+end;
+
 procedure DrawFrame3DHeader(Canvas: TCanvas; {%H-}Style: TADHeaderStyleDesc; r: TRect;
   {%H-}Horizontal: boolean; {%H-}Focused: boolean);
 begin
@@ -7862,18 +7926,16 @@
 end;
 
 initialization
+  FHeaderStyleName2ADHeaderStyle:=THeaderStyleName2ADHeaderStylesMap.create;
   DockMaster:=TAnchorDockMaster.Create(nil);
-  DockMaster.RegisterHeaderStyle('Frame3D', @DrawFrame3DHeader, true, true);
-  DockMaster.RegisterHeaderStyle('Line', @DrawFrameLine, true, true);
-  DockMaster.RegisterHeaderStyle('Lines', @DrawFrameLines, true, true);
-  DockMaster.RegisterHeaderStyle('Points', @DrawFramePoints, true, true);
-  DockMaster.RegisterHeaderStyle('ThemedCaption', @DrawFrameThemedCaption, false, false);
-  DockMaster.RegisterHeaderStyle('ThemedButton', @DrawFrameThemedButton, false, false);
-  DockTimer:=TTimer.Create(nil);
-
+  RegisterHeaderStyle('Frame3D', @DrawFrame3DHeader, true, true);
+  RegisterHeaderStyle('Line', @DrawFrameLine, true, true);
+  RegisterHeaderStyle('Lines', @DrawFrameLines, true, true);
+  RegisterHeaderStyle('Points', @DrawFramePoints, true, true);
+  RegisterHeaderStyle('ThemedCaption', @DrawFrameThemedCaption, false, false);
+  RegisterHeaderStyle('ThemedButton', @DrawFrameThemedButton, false, false);
 finalization
   FreeAndNil(DockMaster);
-  FreeAndNil(DockTimer);
-
+  FreeAndNil(FHeaderStyleName2ADHeaderStyle);
 end.
 
Index: components/anchordocking/anchordockoptionsdlg.pas
===================================================================
--- components/anchordocking/anchordockoptionsdlg.pas	(revision 64680)
+++ components/anchordocking/anchordockoptionsdlg.pas	(working copy)
@@ -151,7 +151,7 @@
 var
  st:TADHeaderStyle;
 begin
-  st:=DockMaster.HeaderStyleName2ADHeaderStyle.Data[Index];
+  st:=fHeaderStyleName2ADHeaderStyle.Data[Index];
   st.DrawProc(Canvas,st.StyleDesc,ARect,true,true);
 end;
 
@@ -353,7 +353,7 @@
   TheSettings.HideHeaderCaptionFloatingControl:=HideHeaderCaptionForFloatingCheckBox.Checked;
   TheSettings.HeaderFlatten:=FlattenHeadersCheckBox.Checked;
   TheSettings.HeaderFilled:=FilledHeadersCheckBox.Checked;
-  TheSettings.HeaderStyle:=DockMaster.HeaderStyleName2ADHeaderStyle.Data[HeaderStyleComboBox.ItemIndex].StyleDesc.Name;
+  TheSettings.HeaderStyle:=fHeaderStyleName2ADHeaderStyle.Data[HeaderStyleComboBox.ItemIndex].StyleDesc.Name;
   TheSettings.HeaderHighlightFocused:=HighlightFocusedCheckBox.Checked;
   TheSettings.DockSitesCanBeMinimized:=DockSitesCanBeMinimized.Checked;
 end;
@@ -417,9 +417,9 @@
 
   sl:=TStringList.Create;
   try
-    for StyleIndex:=0 to DockMaster.HeaderStyleName2ADHeaderStyle.Count-1 do begin
-      sl.Add(DockMaster.HeaderStyleName2ADHeaderStyle.Data[StyleIndex].StyleDesc.Name);
-      if DockMaster.HeaderStyleName2ADHeaderStyle.Data[StyleIndex].StyleDesc.Name=TheSettings.HeaderStyle then
+    for StyleIndex:=0 to fHeaderStyleName2ADHeaderStyle.Count-1 do begin
+      sl.Add(fHeaderStyleName2ADHeaderStyle.Data[StyleIndex].StyleDesc.Name);
+      if fHeaderStyleName2ADHeaderStyle.Data[StyleIndex].StyleDesc.Name=TheSettings.HeaderStyle then
         CurrentStyleIndex:=StyleIndex;
     end;
     HeaderStyleComboBox.Items.Assign(sl);
anchordocking.diff (42,308 bytes)   

Michl

2021-03-02 22:21

developer   ~0129333

I tested the patch in the IDE. I got randomly a AV when moving a site to a other. For now I can't identify if it comes from your patch or something else is buggy. I'll test further.

Can you please add a minimal example where you use at least two independent AnchorDockMasters?

Anton Kavalenka

2021-03-03 07:04

reporter   ~0129336

Last edited: 2021-03-03 07:23

View 3 revisions

It is maximal example I have at this moment.
Each window has own DockMaster. Every of these windows belongs to one process.

Simplest I can imagine - is MinIDE example (anchordocking/minide) created another instance of mainform

Michl

2021-03-10 22:03

developer   ~0129562

Ok, you are right, simple documenting of this change can do it.

Before I can commit this patch, the SIGSEGV has to be fixed. Can you have a look at it?! IMHO the problem is, that the parent of the page isn't valid anymore.

Use AnchorDockingDsgn in Lazarus IDE:
- move a docked window to a other docked window, so that a pagecontrol is created (e.g. window "Watches" to window "SourceEditor")
- move this window back to its original position
  -> see SIGSEGV:
#0 GETDOCKMASTER(0x0) at anchordocking.pas:4054
0000001 GETDOCKMASTER(0x137da680) at anchordocking.pas:7730
0000002 GETPOPUPMENU(0x137da680) at anchordocking.pas:7725
0000003 NOTIFICATION(0x137da680, 0x11e6cbb0, OPREMOVE) at include\control.inc:3498
0000004 NOTIFICATION(0x137da680, 0x11e6cbb0, OPREMOVE) at include\customnotebook.inc:1006
0000005 CLASSES$_$TCOMPONENT_$__$$_REMOVECOMPONENT$TCOMPONENT at :0
0000006 CLASSES$_$TCOMPONENT_$__$$_DESTROY at :0
0000007 ?? at :0

The SIGSEGV is raised here:
function TAnchorDockHostSite.GetDockMaster:TAnchorDockMaster;
begin
  if Owner is TAnchorDockHostSite then // <-- here
    Result:=TAnchorDockHostSite(Owner).GetDockMaster
  else
    Result:=TAnchorDockMaster(Owner);
end;


Thank you!

Issue History

Date Modified Username Field Change
2021-02-28 11:02 Anton Kavalenka New Issue
2021-02-28 11:02 Anton Kavalenka File Added: anchordocking.diff
2021-03-01 21:19 Michl Assigned To => Michl
2021-03-01 21:19 Michl Status new => assigned
2021-03-02 22:21 Michl Note Added: 0129333
2021-03-02 22:21 Michl Status assigned => feedback
2021-03-02 22:21 Michl LazTarget => -
2021-03-03 07:04 Anton Kavalenka Note Added: 0129336
2021-03-03 07:04 Anton Kavalenka File Added: Здымак экрана, 2021-03-03 09-00-39.png
2021-03-03 07:04 Anton Kavalenka Status feedback => assigned
2021-03-03 07:06 Anton Kavalenka Note Edited: 0129336 View Revisions
2021-03-03 07:23 Anton Kavalenka Note Edited: 0129336 View Revisions
2021-03-10 22:03 Michl Note Added: 0129562
2021-03-10 22:03 Michl Status assigned => feedback