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