Browse Source

macOS: Fix file dialogs in embedded views (#20719)

pull/20731/head
Julien Lebosquain 4 weeks ago
committed by GitHub
parent
commit
4b9a2d96a1
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 60
      native/Avalonia.Native/src/OSX/StorageProvider.mm
  2. 6
      src/Avalonia.Native/StorageProviderApi.cs
  3. 6
      src/Avalonia.Native/avn.idl

60
native/Avalonia.Native/src/OSX/StorageProvider.mm

@ -148,8 +148,23 @@ public:
[fileUri stopAccessingSecurityScopedResource];
}
}
static NSWindow* GetEffectiveNSWindow(IAvnTopLevel* topLevel)
{
auto windowHolder = dynamic_cast<INSWindowHolder*>(topLevel);
if (windowHolder != nullptr)
return windowHolder->GetNSWindow();
auto viewHolder = dynamic_cast<INSViewHolder*>(topLevel);
if (viewHolder != nullptr) {
auto view = (NSView*)viewHolder->GetNSView();
return [view window];
}
return nullptr;
}
virtual void SelectFolderDialog (IAvnWindow* parentWindowHandle,
virtual void SelectFolderDialog (IAvnTopLevel* parentTopLevel,
IAvnSystemDialogEvents* events,
bool allowMultiple,
const char* title,
@ -176,6 +191,8 @@ public:
panel.directoryURL = [NSURL URLWithString:directoryString];
}
auto parentWindow = GetEffectiveNSWindow(parentTopLevel);
auto handler = ^(NSModalResponse result) {
if(result == NSFileHandlingPanelOKButton)
{
@ -188,10 +205,9 @@ public:
[panel orderOut:panel];
if(parentWindowHandle != nullptr)
if (parentWindow != nullptr)
{
auto windowHolder = dynamic_cast<INSWindowHolder*>(parentWindowHandle);
[windowHolder->GetNSWindow() makeKeyAndOrderFront:windowHolder->GetNSWindow()];
[parentWindow makeKeyAndOrderFront:parentWindow];
}
return;
@ -202,11 +218,9 @@ public:
};
if(parentWindowHandle != nullptr)
if (parentWindow != nullptr)
{
auto windowBase = dynamic_cast<INSWindowHolder*>(parentWindowHandle);
[panel beginSheetModalForWindow:windowBase->GetNSWindow() completionHandler:handler];
[panel beginSheetModalForWindow:parentWindow completionHandler:handler];
}
else
{
@ -215,7 +229,7 @@ public:
}
}
virtual void OpenFileDialog (IAvnWindow* parentWindowHandle,
virtual void OpenFileDialog (IAvnTopLevel* parentTopLevel,
IAvnSystemDialogEvents* events,
bool allowMultiple,
const char* title,
@ -249,6 +263,8 @@ public:
panel.directoryURL = [NSURL URLWithString:directoryString];
}
auto parentWindow = GetEffectiveNSWindow(parentTopLevel);
auto handler = ^(NSModalResponse result) {
if(result == NSFileHandlingPanelOKButton)
{
@ -261,10 +277,9 @@ public:
[panel orderOut:panel];
if(parentWindowHandle != nullptr)
if (parentWindow != nullptr)
{
auto windowHolder = dynamic_cast<INSWindowHolder*>(parentWindowHandle);
[windowHolder->GetNSWindow() makeKeyAndOrderFront:windowHolder->GetNSWindow()];
[parentWindow makeKeyAndOrderFront:parentWindow];
}
return;
@ -275,11 +290,9 @@ public:
};
if(parentWindowHandle != nullptr)
if (parentWindow != nullptr)
{
auto windowHolder = dynamic_cast<INSWindowHolder*>(parentWindowHandle);
[panel beginSheetModalForWindow:windowHolder->GetNSWindow() completionHandler:handler];
[panel beginSheetModalForWindow:parentWindow completionHandler:handler];
}
else
{
@ -288,7 +301,7 @@ public:
}
}
virtual void SaveFileDialog (IAvnWindow* parentWindowHandle,
virtual void SaveFileDialog (IAvnTopLevel* parentTopLevel,
IAvnSystemDialogEvents* events,
const char* title,
const char* initialDirectory,
@ -319,6 +332,8 @@ public:
panel.directoryURL = [NSURL URLWithString:directoryString];
}
auto parentWindow = GetEffectiveNSWindow(parentTopLevel);
auto handler = ^(NSModalResponse result) {
int selectedIndex = -1;
if (panel.accessoryView != nil)
@ -339,10 +354,9 @@ public:
[panel orderOut:panel];
if(parentWindowHandle != nullptr)
if (parentWindow != nullptr)
{
auto windowHolder = dynamic_cast<INSWindowHolder*>(parentWindowHandle);
[windowHolder->GetNSWindow() makeKeyAndOrderFront:windowHolder->GetNSWindow()];
[parentWindow makeKeyAndOrderFront:parentWindow];
}
return;
@ -352,11 +366,9 @@ public:
};
if(parentWindowHandle != nullptr)
if (parentWindow != nullptr)
{
auto windowBase = dynamic_cast<INSWindowHolder*>(parentWindowHandle);
[panel beginSheetModalForWindow:windowBase->GetNSWindow() completionHandler:handler];
[panel beginSheetModalForWindow:parentWindow completionHandler:handler];
}
else
{

6
src/Avalonia.Native/StorageProviderApi.cs

@ -158,7 +158,7 @@ internal class StorageProviderApi(IAvnStorageProvider native, bool sandboxEnable
var (items, _) = await OpenDialogAsync(events =>
{
_native.OpenFileDialog((IAvnWindow?)topLevel?.Native,
_native.OpenFileDialog(topLevel?.Native,
events,
options.AllowMultiple.AsComBool(),
options.Title ?? string.Empty,
@ -177,7 +177,7 @@ internal class StorageProviderApi(IAvnStorageProvider native, bool sandboxEnable
var (items, selectedFilterIndex) = await OpenDialogAsync(events =>
{
_native.SaveFileDialog((IAvnWindow?)topLevel?.Native,
_native.SaveFileDialog(topLevel?.Native,
events,
options.Title ?? string.Empty,
suggestedDirectory,
@ -201,7 +201,7 @@ internal class StorageProviderApi(IAvnStorageProvider native, bool sandboxEnable
var (items, _) = await OpenDialogAsync(events =>
{
_native.SelectFolderDialog((IAvnWindow?)topLevel?.Native,
_native.SelectFolderDialog(topLevel?.Native,
events,
options.AllowMultiple.AsComBool(),
options.Title ?? "",

6
src/Avalonia.Native/avn.idl

@ -938,13 +938,13 @@ interface IAvnSystemDialogEvents : IUnknown
[uuid(4d7a47db-a944-4061-abe7-62cb6aa0ffd5)]
interface IAvnStorageProvider : IUnknown
{
void SelectFolderDialog(IAvnWindow* parentWindowHandle,
void SelectFolderDialog(IAvnTopLevel* parentTopLevel,
IAvnSystemDialogEvents* events,
bool allowMultiple,
[const] char* title,
[const] char* initialPath);
void OpenFileDialog(IAvnWindow* parentWindowHandle,
void OpenFileDialog(IAvnTopLevel* parentTopLevel,
IAvnSystemDialogEvents* events,
bool allowMultiple,
[const] char* title,
@ -952,7 +952,7 @@ interface IAvnStorageProvider : IUnknown
[const] char* initialFile,
IAvnFilePickerFileTypes* filters);
void SaveFileDialog(IAvnWindow* parentWindowHandle,
void SaveFileDialog(IAvnTopLevel* parentTopLevel,
IAvnSystemDialogEvents* events,
[const] char* title,
[const] char* initialDirectory,

Loading…
Cancel
Save