AnchorDocking: Prevent crash on drag-and-dock tab page. Issue #34371, patch from accorp.

git-svn-id: trunk@59228 -
This commit is contained in:
juha 2018-10-02 12:59:27 +00:00
parent baad25dec4
commit 53541c694b
2 changed files with 17 additions and 8 deletions

View File

@ -649,6 +649,7 @@ type
// simplification/garbage collection // simplification/garbage collection
procedure BeginUpdate; procedure BeginUpdate;
procedure EndUpdate; procedure EndUpdate;
function IsReleasing(AControl: TControl): Boolean;
procedure NeedSimplify(AControl: TControl); procedure NeedSimplify(AControl: TControl);
procedure NeedFree(AControl: TControl); procedure NeedFree(AControl: TControl);
procedure SimplifyPendingLayouts; procedure SimplifyPendingLayouts;
@ -3439,6 +3440,11 @@ begin
SimplifyPendingLayouts; SimplifyPendingLayouts;
end; end;
function TAnchorDockMaster.IsReleasing(AControl: TControl): Boolean;
begin
Result := fNeedFree.IndexOf(AControl) >= 0;
end;
procedure TAnchorDockMaster.NeedSimplify(AControl: TControl); procedure TAnchorDockMaster.NeedSimplify(AControl: TControl);
begin begin
if Self=nil then exit; if Self=nil then exit;
@ -3460,7 +3466,7 @@ end;
procedure TAnchorDockMaster.NeedFree(AControl: TControl); procedure TAnchorDockMaster.NeedFree(AControl: TControl);
begin begin
//debugln(['TAnchorDockMaster.NeedFree ',DbgSName(AControl),' ',csDestroying in AControl.ComponentState]); //debugln(['TAnchorDockMaster.NeedFree ',DbgSName(AControl),' ',csDestroying in AControl.ComponentState]);
if fNeedFree.IndexOf(AControl)>=0 then exit; if IsReleasing(AControl) then exit;
if csDestroying in AControl.ComponentState then exit; if csDestroying in AControl.ComponentState then exit;
fNeedFree.Add(AControl); fNeedFree.Add(AControl);
AControl.DisableAutoSizing{$IFDEF DebugDisableAutoSizing}(ADAutoSizingReason){$ENDIF}; AControl.DisableAutoSizing{$IFDEF DebugDisableAutoSizing}(ADAutoSizingReason){$ENDIF};
@ -3484,7 +3490,7 @@ begin
while i>=0 do begin while i>=0 do begin
AControl:=TControl(fNeedSimplify[i]); AControl:=TControl(fNeedSimplify[i]);
if (csDestroying in AControl.ComponentState) if (csDestroying in AControl.ComponentState)
or (fNeedFree.IndexOf(AControl)>=0) then begin or IsReleasing(AControl) then begin
fNeedSimplify.Delete(i); fNeedSimplify.Delete(i);
Changed:=true; Changed:=true;
end else if (AControl is TAnchorDockHostSite) then begin end else if (AControl is TAnchorDockHostSite) then begin
@ -3513,7 +3519,7 @@ begin
// free unneeded controls // free unneeded controls
for i := fNeedFree.Count - 1 downto 0 do for i := fNeedFree.Count - 1 downto 0 do
if not (csDestroying in TControl(fNeedFree[i]).ComponentState) then if not (csDestroying in TControl(fNeedFree[i]).ComponentState) then
TControl(fNeedFree[i]).Free; Application.ReleaseComponent(TComponent(fNeedFree[i]));
fNeedFree.Clear; fNeedFree.Clear;
finally finally
fSimplifying:=false; fSimplifying:=false;
@ -3736,7 +3742,7 @@ begin
try try
BeginUpdateLayout; BeginUpdateLayout;
try try
DockMaster.QueueSimplify:=True; DockMaster.SimplifyPendingLayouts;
NewControl.DisableAutoSizing{$IFDEF DebugDisableAutoSizing}('TAnchorDockHostSite.ExecuteDock NewControl'){$ENDIF}; NewControl.DisableAutoSizing{$IFDEF DebugDisableAutoSizing}('TAnchorDockHostSite.ExecuteDock NewControl'){$ENDIF};
if (NewControl.Parent=Self) and (SiteType=adhstLayout) then begin if (NewControl.Parent=Self) and (SiteType=adhstLayout) then begin
@ -4470,6 +4476,7 @@ var
Site: TAnchorDockHostSite; Site: TAnchorDockHostSite;
begin begin
if Pages=nil then exit; if Pages=nil then exit;
if DockMaster.IsReleasing(Pages) then exit;
if Pages.PageCount=1 then begin if Pages.PageCount=1 then begin
{$IFDEF VerboseAnchorDockPages} {$IFDEF VerboseAnchorDockPages}
debugln(['TAnchorDockHostSite.SimplifyPages "',Caption,'" PageCount=1']); debugln(['TAnchorDockHostSite.SimplifyPages "',Caption,'" PageCount=1']);
@ -4486,7 +4493,7 @@ begin
if SiteType=adhstPages then if SiteType=adhstPages then
FSiteType:=adhstOneControl; FSiteType:=adhstOneControl;
// free Pages // free Pages
FreePages; DockMaster.NeedFree(Pages);
if SiteType=adhstOneControl then if SiteType=adhstOneControl then
SimplifyOneControl; SimplifyOneControl;
finally finally
@ -4731,7 +4738,7 @@ procedure TAnchorDockHostSite.DoDock(NewDockSite: TWinControl; var ARect: TRect)
begin begin
inherited DoDock(NewDockSite, ARect); inherited DoDock(NewDockSite, ARect);
if DockMaster <> nil then if DockMaster <> nil then
DockMaster.QueueSimplify:=True; // Async call to SimplifyPendingLayouts; DockMaster.SimplifyPendingLayouts;
end; end;
procedure TAnchorDockHostSite.SetParent(NewParent: TWinControl); procedure TAnchorDockHostSite.SetParent(NewParent: TWinControl);
@ -6706,7 +6713,7 @@ begin
if Site=nil then exit; if Site=nil then exit;
DockMaster.RestoreLayouts.Add(DockMaster.CreateRestoreLayout(Site),true); DockMaster.RestoreLayouts.Add(DockMaster.CreateRestoreLayout(Site),true);
Site.CloseSite; Site.CloseSite;
DockMaster.QueueSimplify:=True; DockMaster.SimplifyPendingLayouts;
end; end;
procedure TAnchorDockPageControl.MoveLeftButtonClick(Sender: TObject); procedure TAnchorDockPageControl.MoveLeftButtonClick(Sender: TObject);

View File

@ -2202,7 +2202,9 @@ begin
MessI.Result := 0; MessI.Result := 0;
NotifyApplicationUserInput(AWinControl, MessI.Msg); NotifyApplicationUserInput(AWinControl, MessI.Msg);
DeliverMessage(AWinControl, MessI); DeliverMessage(AWinControl, MessI);
if MessI.Result <> 0 then if not AWinControl.HandleAllocated then
Result := True
else if MessI.Result <> 0 then
begin begin
// issue #19914 // issue #19914
if GTK_IS_NOTEBOOK(Widget) then if GTK_IS_NOTEBOOK(Widget) then