Search code examples
macosdelphifiremonkeydelphi-xe7nsopenpanel

ShowModal form that opens NSOpenPanel is force closed in Delphi Firemonkey OSX


I am using the code @ http://jed-software.com/blog/?p=538 to open a dialog on OSX for selecting a folder

I'm creating a form using Form2.ShowModal, and on this form I am calling the above SelectDirectory function through a button. The form created with ShowModal is then instantly closed as soon as the NSOpenPanel is also closed... The forms OnClose event does not fire, and the ModalResult of the Form2.ShowModal call is mrNone (0), so I haven't been able to find a way to stop this unwanted behaviour. Somehow the LOpenDir.runModal; result is forcing my Form2 to close too

Any help would be fantastic, thanks.


Solution

  • You need to set the FRestartModal flag inside the platformservice.

    LDlgResult := LOpenDir.runModal;
    RestartModal;
    

    Unfortunately this is a bit nasty, because that flag is hidden in the TPlatformCocoa class in the implementation part of the unit. I don't like hacks using RTTI, but unfortunately I haven't found a better way. So here you go:

    procedure RestartModal;
    //Hack: Set the FRestartModal flag in TPlatformCocoa
    var
      Context: TRttiContext;
      RttiType: TRttiType;
      Field: TRttiField;
      FModalStack: TStack<TObject>;
      FPlatformService: TObject;
    begin
      FPlatformService := TObject(TPlatformServices.Current.GetPlatformService(IFMXWindowService));  // trick for getting the MacOS Platformservice
      RttiType := Context.GetType(FPlatformService.ClassType);
      Field := RttiType.GetField('FModalStack');       // get private field using RTTI
      Assert(Field <> nil);
      FModalStack := PPointer(Field.GetValue(FPlatformService).GetReferenceToRawData)^;
      if (FModalStack <> nil) and (FModalStack.Count > 0) then
      begin
        Field := RttiType.GetField('FRestartModal');
        Field.SetValue(FPlatformService, True);
      end;
    end;