mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-07 16:20:32 +02:00
cocoa: Fixes crash due to cyclic calls to CreateHandle in modal forms, bug #30527
git-svn-id: trunk@52998 -
This commit is contained in:
parent
1d7b19f9f2
commit
0428e3cab5
@ -435,6 +435,8 @@ type
|
||||
public
|
||||
isembedded: Boolean; // true - if the content is inside of another control, false - if the content is in its own window;
|
||||
ownwin: NSWindow;
|
||||
popup_parent: HWND; // if not 0, indicates that we should set the popup parent
|
||||
procedure resolvePopupParent(); message 'resolvePopupParent';
|
||||
function lclOwnWindow: NSWindow; message 'lclOwnWindow';
|
||||
procedure lclSetFrame(const r: TRect); override;
|
||||
procedure viewDidMoveToSuperview; override;
|
||||
@ -924,6 +926,28 @@ begin
|
||||
callback.DidResignKeyNotification;
|
||||
end;
|
||||
|
||||
procedure TCocoaWindowContent.resolvePopupParent();
|
||||
var
|
||||
lWindow: NSWindow;
|
||||
begin
|
||||
lWindow := nil;
|
||||
if (popup_parent <> 0) then
|
||||
begin
|
||||
if (NSObject(popup_parent).isKindOfClass(TCocoaWindowContent)) then
|
||||
begin
|
||||
if (not TCocoaWindowContent(popup_parent).isembedded) then
|
||||
lWindow := TCocoaWindowContent(popup_parent).window;
|
||||
end
|
||||
else
|
||||
begin
|
||||
lWindow := NSWindow(popup_parent);
|
||||
end;
|
||||
end;
|
||||
if lWindow <> nil then
|
||||
lWindow.addChildWindow_ordered(Self.window, NSWindowAbove);
|
||||
popup_parent := 0;
|
||||
end;
|
||||
|
||||
function TCocoaWindowContent.lclOwnWindow: NSWindow;
|
||||
begin
|
||||
if not isembedded then
|
||||
|
@ -97,6 +97,7 @@ type
|
||||
class procedure UpdateWindowMask(AWindow: NSWindow; ABorderStyle: TFormBorderStyle; ABorderIcons: TBorderIcons);
|
||||
public
|
||||
class function GetWindowFromHandle(const ACustomForm: TCustomForm): TCocoaWindow;
|
||||
class function GetWindowContentFromHandle(const ACustomForm: TCustomForm): TCocoaWindowContent;
|
||||
published
|
||||
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
|
||||
|
||||
@ -431,6 +432,13 @@ begin
|
||||
Result := TCocoaWindow(TCocoaWindowContent(ACustomForm.Handle).lclOwnWindow);
|
||||
end;
|
||||
|
||||
class function TCocoaWSCustomForm.GetWindowContentFromHandle(const ACustomForm: TCustomForm): TCocoaWindowContent;
|
||||
begin
|
||||
Result := nil;
|
||||
if not ACustomForm.HandleAllocated then Exit;
|
||||
Result := TCocoaWindowContent(ACustomForm.Handle);
|
||||
end;
|
||||
|
||||
class function TCocoaWSCustomForm.CreateHandle(const AWinControl: TWinControl;
|
||||
const AParams: TCreateParams): TLCLIntfHandle;
|
||||
var
|
||||
@ -488,13 +496,10 @@ var
|
||||
win.LCLForm := Form;
|
||||
win.setContentView(cnt);
|
||||
|
||||
if (AParams.WndParent <> 0) then
|
||||
begin
|
||||
if (NSObject(AParams.WndParent).isKindOfClass(TCocoaWindowContent)) and (not TCocoaWindowContent(AParams.WndParent).isembedded) then
|
||||
TCocoaWindowContent(AParams.WndParent).window.addChildWindow_ordered(win, NSWindowAbove)
|
||||
else
|
||||
NSWindow(AParams.WndParent).addChildWindow_ordered(win, NSWindowAbove);
|
||||
end;
|
||||
// Don't call addChildWindow_ordered here because this function can cause
|
||||
// events to arrive for this window, creating a second call to TCocoaWSCustomForm.CreateHandle
|
||||
// while the first didn't finish yet, instead delay the call
|
||||
cnt.popup_parent := AParams.WndParent;
|
||||
|
||||
// support for drag & drop
|
||||
win.registerForDraggedTypes(NSArray.arrayWithObjects_count(@NSFilenamesPboardType, 1));
|
||||
@ -582,11 +587,16 @@ end;
|
||||
class procedure TCocoaWSCustomForm.ShowModal(const ACustomForm: TCustomForm);
|
||||
var
|
||||
win: TCocoaWindow;
|
||||
lWinContent: TCocoaWindowContent;
|
||||
begin
|
||||
// Another possible implementation is to have modal started in ShowHide with (fsModal in AForm.FormState)
|
||||
win := TCocoaWSCustomForm.GetWindowFromHandle(ACustomForm);
|
||||
if win = nil then Exit;
|
||||
|
||||
// Handle PopupParent
|
||||
lWinContent := GetWindowContentFromHandle(ACustomForm);
|
||||
lWinContent.resolvePopupParent();
|
||||
|
||||
{ Another possible implementation is using a session, but this requires
|
||||
disabling the other windows ourselves
|
||||
CurModalSession: NSModalSession;
|
||||
|
Loading…
Reference in New Issue
Block a user