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

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

6
src/Avalonia.Native/StorageProviderApi.cs

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

6
src/Avalonia.Native/avn.idl

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

Loading…
Cancel
Save