Bug 1930101 - Move AsyncShowFilePicker to cocoa/nsFilePicker; r=win-reviewers,mac-reviewers,emilio,rkraesig,bradwerth

Then other plaforms don't need to implement Show() method.
No functional changes.

Differential Revision: https://phabricator.services.mozilla.com/D228418
This commit is contained in:
Edgar Chen 2024-11-18 23:38:16 +00:00
parent 836e13f637
commit 23549ec84f
10 changed files with 53 additions and 93 deletions

View File

@ -17,6 +17,8 @@ class nsILocalFileMac;
@class NSArray;
class nsFilePicker : public nsBaseFilePicker {
class AsyncShowFilePicker;
public:
nsFilePicker();
using nsIFilePicker::ResultCode;
@ -24,6 +26,7 @@ class nsFilePicker : public nsBaseFilePicker {
NS_DECL_ISUPPORTS
// nsIFilePicker (less what's in nsBaseFilePicker)
NS_IMETHOD Open(nsIFilePickerShownCallback* aCallback) override;
NS_IMETHOD GetDefaultString(nsAString& aDefaultString) override;
NS_IMETHOD SetDefaultString(const nsAString& aDefaultString) override;
NS_IMETHOD GetDefaultExtension(nsAString& aDefaultExtension) override;
@ -47,7 +50,7 @@ class nsFilePicker : public nsBaseFilePicker {
virtual ~nsFilePicker();
virtual void InitNative(nsIWidget* aParent, const nsAString& aTitle) override;
nsresult Show(ResultCode* _retval) override;
nsresult Show(ResultCode* _retval);
// actual implementations of get/put dialogs using NSOpenPanel & NSSavePanel
// aFile is an existing but unspecified file. These functions must specify it.

View File

@ -14,6 +14,7 @@
#include "nsArrayEnumerator.h"
#include "nsIStringBundle.h"
#include "nsCocoaUtils.h"
#include "nsThreadUtils.h"
#include "mozilla/Preferences.h"
// This must be included last:
@ -88,6 +89,42 @@ static void SetShowHiddenFileState(NSSavePanel* panel) {
NS_OBJC_END_TRY_IGNORE_BLOCK;
}
/**
* A runnable to dispatch from the main thread to the main thread to display
* the file picker while letting the showAsync method return right away.
*/
class nsFilePicker::AsyncShowFilePicker : public mozilla::Runnable {
public:
AsyncShowFilePicker(nsFilePicker* aFilePicker,
nsIFilePickerShownCallback* aCallback)
: mozilla::Runnable("AsyncShowFilePicker"),
mFilePicker(aFilePicker),
mCallback(aCallback) {}
NS_IMETHOD Run() override {
NS_ASSERTION(NS_IsMainThread(),
"AsyncShowFilePicker should be on the main thread!");
// macOS requires require GUI operations to be on the main thread, so that's
// why we're not dispatching to another thread and calling back to the main
// after it's done.
nsIFilePicker::ResultCode result = nsIFilePicker::returnCancel;
nsresult rv = mFilePicker->Show(&result);
if (NS_FAILED(rv)) {
NS_ERROR("FilePicker's Show() implementation failed!");
}
if (mCallback) {
mCallback->Done(result);
}
return NS_OK;
}
private:
RefPtr<nsFilePicker> mFilePicker;
RefPtr<nsIFilePickerShownCallback> mCallback;
};
nsFilePicker::nsFilePicker() : mSelectedTypeIndex(0) {}
nsFilePicker::~nsFilePicker() {}
@ -237,6 +274,17 @@ nsresult nsFilePicker::Show(ResultCode* retval) {
return NS_OK;
}
NS_IMETHODIMP
nsFilePicker::Open(nsIFilePickerShownCallback* aCallback) {
if (MaybeBlockFilePicker(aCallback)) {
return NS_OK;
}
nsCOMPtr<nsIRunnable> filePickerEvent =
new AsyncShowFilePicker(this, aCallback);
return NS_DispatchToMainThread(filePickerEvent);
}
static void UpdatePanelFileTypes(NSOpenPanel* aPanel, NSArray* aFilters) {
// If we show all file types, also "expose" bundles' contents.
[aPanel setTreatsFilePackagesAsDirectories:!aFilters];

View File

@ -399,20 +399,6 @@ nsFilePicker::GetFiles(nsISimpleEnumerator** aFiles) {
return NS_ERROR_FAILURE;
}
nsresult nsFilePicker::Show(nsIFilePicker::ResultCode* aReturn) {
NS_ENSURE_ARG_POINTER(aReturn);
nsresult rv = Open(nullptr);
if (NS_FAILED(rv)) return rv;
while (mFileChooser) {
g_main_context_iteration(nullptr, TRUE);
}
*aReturn = mResult;
return NS_OK;
}
NS_IMETHODIMP
nsFilePicker::Open(nsIFilePickerShownCallback* aCallback) {
// Can't show two dialogs concurrently with the same filepicker
@ -702,8 +688,6 @@ void nsFilePicker::Done(void* file_chooser, gint response) {
if (mCallback) {
mCallback->Done(result);
mCallback = nullptr;
} else {
mResult = result;
}
NS_RELEASE_THIS();
}

View File

@ -47,7 +47,6 @@ class nsFilePicker : public nsBaseFilePicker {
protected:
virtual ~nsFilePicker();
nsresult Show(nsIFilePicker::ResultCode* aReturn) override;
void ReadValuesFromFileChooser(void* file_chooser);
bool WarnForNonReadableFile(void* file_chooser);
@ -62,7 +61,6 @@ class nsFilePicker : public nsBaseFilePicker {
nsCOMArray<nsIFile> mFiles;
int16_t mSelectedType;
nsIFilePicker::ResultCode mResult;
bool mAllowURLs;
nsCString mFileURL;
nsString mTitle;

View File

@ -23,7 +23,6 @@
#include "mozilla/StaticPrefs_widget.h"
#include "WidgetUtils.h"
#include "nsSimpleEnumerator.h"
#include "nsThreadUtils.h"
#include "nsContentUtils.h"
#include "nsBaseFilePicker.h"
@ -67,46 +66,6 @@ nsresult LocalFileToDirectoryOrBlob(nsPIDOMWindowInner* aWindow,
} // anonymous namespace
#ifndef XP_WIN
/**
* A runnable to dispatch from the main thread to the main thread to display
* the file picker while letting the showAsync method return right away.
*
* Not needed on Windows, where nsFilePicker::Open() is fully async.
*/
class nsBaseFilePicker::AsyncShowFilePicker : public mozilla::Runnable {
public:
AsyncShowFilePicker(nsBaseFilePicker* aFilePicker,
nsIFilePickerShownCallback* aCallback)
: mozilla::Runnable("AsyncShowFilePicker"),
mFilePicker(aFilePicker),
mCallback(aCallback) {}
NS_IMETHOD Run() override {
NS_ASSERTION(NS_IsMainThread(),
"AsyncShowFilePicker should be on the main thread!");
// It's possible that some widget implementations require GUI operations
// to be on the main thread, so that's why we're not dispatching to another
// thread and calling back to the main after it's done.
nsIFilePicker::ResultCode result = nsIFilePicker::returnCancel;
nsresult rv = mFilePicker->Show(&result);
if (NS_FAILED(rv)) {
NS_ERROR("FilePicker's Show() implementation failed!");
}
if (mCallback) {
mCallback->Done(result);
}
return NS_OK;
}
private:
RefPtr<nsBaseFilePicker> mFilePicker;
RefPtr<nsIFilePickerShownCallback> mCallback;
};
#endif
class nsBaseFilePickerEnumerator : public nsSimpleEnumerator {
public:
nsBaseFilePickerEnumerator(nsPIDOMWindowOuter* aParent,
@ -199,19 +158,6 @@ nsBaseFilePicker::IsModeSupported(nsIFilePicker::Mode aMode, JSContext* aCx,
return NS_OK;
}
#ifndef XP_WIN
NS_IMETHODIMP
nsBaseFilePicker::Open(nsIFilePickerShownCallback* aCallback) {
if (MaybeBlockFilePicker(aCallback)) {
return NS_OK;
}
nsCOMPtr<nsIRunnable> filePickerEvent =
new AsyncShowFilePicker(this, aCallback);
return NS_DispatchToMainThread(filePickerEvent);
}
#endif
NS_IMETHODIMP
nsBaseFilePicker::AppendFilters(int32_t aFilterMask) {
nsCOMPtr<nsIStringBundleService> stringService =

View File

@ -20,10 +20,6 @@ class nsPIDOMWindowOuter;
class nsIWidget;
class nsBaseFilePicker : public nsIFilePicker {
#ifndef XP_WIN
class AsyncShowFilePicker;
#endif
public:
nsBaseFilePicker();
virtual ~nsBaseFilePicker();
@ -32,9 +28,6 @@ class nsBaseFilePicker : public nsIFilePicker {
const nsAString& aTitle, nsIFilePicker::Mode aMode) override;
NS_IMETHOD IsModeSupported(nsIFilePicker::Mode aMode, JSContext* aCx,
mozilla::dom::Promise** aPromise) override;
#ifndef XP_WIN
NS_IMETHOD Open(nsIFilePickerShownCallback* aCallback) override;
#endif
NS_IMETHOD AppendFilters(int32_t filterMask) override;
NS_IMETHOD AppendRawFilter(const nsAString& aFilter) override;
NS_IMETHOD GetCapture(nsIFilePicker::CaptureTarget* aCapture) override;
@ -59,7 +52,6 @@ class nsBaseFilePicker : public nsIFilePicker {
protected:
virtual void InitNative(nsIWidget* aParent, const nsAString& aTitle) = 0;
virtual nsresult Show(nsIFilePicker::ResultCode* _retval) = 0;
virtual nsresult ResolveSpecialDirectory(const nsAString& aSpecialDirectory);
bool MaybeBlockFilePicker(nsIFilePickerShownCallback* aCallback);

View File

@ -121,11 +121,6 @@ nsFilePickerProxy::GetFiles(nsISimpleEnumerator** aFiles) {
return NS_ERROR_FAILURE;
}
nsresult nsFilePickerProxy::Show(nsIFilePicker::ResultCode* aReturn) {
MOZ_ASSERT(false, "Show is unimplemented; use Open");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFilePickerProxy::Open(nsIFilePickerShownCallback* aCallback) {
mCallback = aCallback;

View File

@ -22,7 +22,7 @@ class nsPIDOMWindowInner;
/**
This class creates a proxy file picker to be used in content processes.
The file picker just collects the initialization data and when Show() is
The file picker just collects the initialization data and when Open() is
called, remotes everything to the chrome process which in turn can show a
platform specific file picker.
*/
@ -64,7 +64,6 @@ class nsFilePickerProxy : public nsBaseFilePicker,
private:
~nsFilePickerProxy();
void InitNative(nsIWidget*, const nsAString&) override;
nsresult Show(nsIFilePicker::ResultCode* aReturn) override;
nsresult ResolveSpecialDirectory(const nsAString& aSpecialDirectory) override;
void ActorDestroy(ActorDestroyReason aWhy) override;

View File

@ -875,10 +875,6 @@ nsresult nsFilePicker::Open(nsIFilePickerShownCallback* aCallback) {
return NS_OK;
}
nsresult nsFilePicker::Show(nsIFilePicker::ResultCode* aReturnVal) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFilePicker::GetFile(nsIFile** aFile) {
NS_ENSURE_ARG_POINTER(aFile);

View File

@ -82,7 +82,6 @@ class nsFilePicker final : public nsBaseWinFilePicker {
protected:
/* method from nsBaseFilePicker */
virtual void InitNative(nsIWidget* aParent, const nsAString& aTitle) override;
nsresult Show(nsIFilePicker::ResultCode* aReturnVal) override;
void GetFilterListArray(nsString& aFilterList);
NS_IMETHOD Open(nsIFilePickerShownCallback* aCallback) override;