diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index f6ff6da0c3e..a5234c7d5c3 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -166,7 +166,7 @@
- [code]"values"[/code] - [PackedStringArray] of values. If empty, boolean option (check box) is used.
- [code]"default"[/code] - default selected option index ([int]) or default boolean value ([bool]).
Callbacks have the following arguments: [code]status: bool, selected_paths: PackedStringArray, selected_filter_index: int, selected_option: Dictionary[/code].
- [b]Note:[/b] This method is implemented if the display server has the [constant FEATURE_NATIVE_DIALOG_FILE] feature. Supported platforms include Linux (X11/Wayland), Windows, and macOS.
+ [b]Note:[/b] This method is implemented if the display server has the [constant FEATURE_NATIVE_DIALOG_FILE_EXTRA] feature. Supported platforms include Linux (X11/Wayland), Windows, and macOS.
[b]Note:[/b] [param current_directory] might be ignored.
[b]Note:[/b] On Linux (X11), [param show_hidden] is ignored.
[b]Note:[/b] On macOS, native file dialogs have no title.
@@ -1889,7 +1889,10 @@
Display server supports spawning text input dialogs using the operating system's native look-and-feel. See [method dialog_input_text]. [b]Windows, macOS[/b]
- Display server supports spawning dialogs for selecting files or directories using the operating system's native look-and-feel. See [method file_dialog_show] and [method file_dialog_with_options_show]. [b]Windows, macOS, Linux (X11/Wayland)[/b]
+ Display server supports spawning dialogs for selecting files or directories using the operating system's native look-and-feel. See [method file_dialog_show]. [b]Windows, macOS, Linux (X11/Wayland)[/b]
+
+
+ The display server supports all features of [constant FEATURE_NATIVE_DIALOG_FILE], with the added functionality of Options and native dialog file access to [code]res://[/code] and [code]user://[/code] paths. See [method file_dialog_show] and [method file_dialog_with_options_show]. [b]Windows, macOS, Linux (X11/Wayland)[/b]
Makes the mouse cursor visible if it is hidden.
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index f5032eaa408..c88cd6859c5 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -73,6 +73,7 @@ bool DisplayServerAndroid::has_feature(Feature p_feature) const {
//case FEATURE_NATIVE_DIALOG:
case FEATURE_NATIVE_DIALOG_INPUT:
//case FEATURE_NATIVE_DIALOG_FILE:
+ //case FEATURE_NATIVE_DIALOG_FILE_EXTRA:
//case FEATURE_NATIVE_ICON:
//case FEATURE_WINDOW_TRANSPARENCY:
case FEATURE_CLIPBOARD:
diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm
index 76498281895..5d9179bd9a7 100644
--- a/platform/ios/display_server_ios.mm
+++ b/platform/ios/display_server_ios.mm
@@ -370,6 +370,7 @@ bool DisplayServerIOS::has_feature(Feature p_feature) const {
// case FEATURE_NATIVE_DIALOG:
// case FEATURE_NATIVE_DIALOG_INPUT:
// case FEATURE_NATIVE_DIALOG_FILE:
+ // case FEATURE_NATIVE_DIALOG_FILE_EXTRA:
// case FEATURE_NATIVE_ICON:
// case FEATURE_WINDOW_TRANSPARENCY:
case FEATURE_CLIPBOARD:
diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp
index d5271f9ad4b..fe359532bb0 100644
--- a/platform/linuxbsd/wayland/display_server_wayland.cpp
+++ b/platform/linuxbsd/wayland/display_server_wayland.cpp
@@ -216,7 +216,8 @@ bool DisplayServerWayland::has_feature(Feature p_feature) const {
//case FEATURE_NATIVE_DIALOG:
//case FEATURE_NATIVE_DIALOG_INPUT:
#ifdef DBUS_ENABLED
- case FEATURE_NATIVE_DIALOG_FILE: {
+ case FEATURE_NATIVE_DIALOG_FILE:
+ case FEATURE_NATIVE_DIALOG_FILE_EXTRA: {
return true;
} break;
#endif
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index 48ff06cad28..a9c94bd8238 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -129,6 +129,7 @@ bool DisplayServerX11::has_feature(Feature p_feature) const {
case FEATURE_ICON:
#ifdef DBUS_ENABLED
case FEATURE_NATIVE_DIALOG_FILE:
+ case FEATURE_NATIVE_DIALOG_FILE_EXTRA:
#endif
//case FEATURE_NATIVE_DIALOG:
//case FEATURE_NATIVE_DIALOG_INPUT:
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index 714df18228d..f1078d9868f 100644
--- a/platform/macos/display_server_macos.mm
+++ b/platform/macos/display_server_macos.mm
@@ -752,6 +752,7 @@ bool DisplayServerMacOS::has_feature(Feature p_feature) const {
case FEATURE_NATIVE_DIALOG:
case FEATURE_NATIVE_DIALOG_INPUT:
case FEATURE_NATIVE_DIALOG_FILE:
+ case FEATURE_NATIVE_DIALOG_FILE_EXTRA:
case FEATURE_IME:
case FEATURE_WINDOW_TRANSPARENCY:
case FEATURE_HIDPI:
diff --git a/platform/web/display_server_web.cpp b/platform/web/display_server_web.cpp
index 4e55cc137a3..b2db62ea2fc 100644
--- a/platform/web/display_server_web.cpp
+++ b/platform/web/display_server_web.cpp
@@ -1133,6 +1133,7 @@ bool DisplayServerWeb::has_feature(Feature p_feature) const {
//case FEATURE_NATIVE_DIALOG:
//case FEATURE_NATIVE_DIALOG_INPUT:
//case FEATURE_NATIVE_DIALOG_FILE:
+ //case FEATURE_NATIVE_DIALOG_FILE_EXTRA:
//case FEATURE_NATIVE_ICON:
//case FEATURE_WINDOW_TRANSPARENCY:
//case FEATURE_KEEP_SCREEN_ON:
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 07424a3b4c7..3bc32fc2184 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -129,6 +129,7 @@ bool DisplayServerWindows::has_feature(Feature p_feature) const {
case FEATURE_NATIVE_DIALOG:
case FEATURE_NATIVE_DIALOG_INPUT:
case FEATURE_NATIVE_DIALOG_FILE:
+ case FEATURE_NATIVE_DIALOG_FILE_EXTRA:
case FEATURE_SWAP_BUFFERS:
case FEATURE_KEEP_SCREEN_ON:
case FEATURE_TEXT_TO_SPEECH:
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 111b8579ec6..18864b12892 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -67,7 +67,18 @@ void FileDialog::_native_popup() {
} else if (access == ACCESS_USERDATA) {
root = OS::get_singleton()->get_user_data_dir();
}
- DisplayServer::get_singleton()->file_dialog_with_options_show(get_title(), ProjectSettings::get_singleton()->globalize_path(dir->get_text()), root, file->get_text().get_file(), show_hidden_files, DisplayServer::FileDialogMode(mode), filters, _get_options(), callable_mp(this, &FileDialog::_native_dialog_cb));
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE_EXTRA)) {
+ DisplayServer::get_singleton()->file_dialog_with_options_show(get_title(), ProjectSettings::get_singleton()->globalize_path(dir->get_text()), root, file->get_text().get_file(), show_hidden_files, DisplayServer::FileDialogMode(mode), filters, _get_options(), callable_mp(this, &FileDialog::_native_dialog_cb_with_options));
+ } else {
+ DisplayServer::get_singleton()->file_dialog_show(get_title(), ProjectSettings::get_singleton()->globalize_path(dir->get_text()), file->get_text().get_file(), show_hidden_files, DisplayServer::FileDialogMode(mode), filters, callable_mp(this, &FileDialog::_native_dialog_cb));
+ }
+}
+
+bool FileDialog::_can_use_native_popup() {
+ if (access == ACCESS_RESOURCES || access == ACCESS_USERDATA || options.size() > 0) {
+ return DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE_EXTRA);
+ }
+ return DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE);
}
void FileDialog::popup(const Rect2i &p_rect) {
@@ -80,7 +91,7 @@ void FileDialog::popup(const Rect2i &p_rect) {
}
#endif
- if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE) && (use_native_dialog || OS::get_singleton()->is_sandboxed())) {
+ if (_can_use_native_popup() && (use_native_dialog || OS::get_singleton()->is_sandboxed())) {
_native_popup();
} else {
ConfirmationDialog::popup(p_rect);
@@ -99,7 +110,7 @@ void FileDialog::set_visible(bool p_visible) {
}
#endif
- if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE) && (use_native_dialog || OS::get_singleton()->is_sandboxed())) {
+ if (_can_use_native_popup() && (use_native_dialog || OS::get_singleton()->is_sandboxed())) {
if (p_visible) {
_native_popup();
}
@@ -108,7 +119,11 @@ void FileDialog::set_visible(bool p_visible) {
}
}
-void FileDialog::_native_dialog_cb(bool p_ok, const Vector &p_files, int p_filter, const Dictionary &p_selected_options) {
+void FileDialog::_native_dialog_cb(bool p_ok, const Vector &p_files, int p_filter) {
+ _native_dialog_cb_with_options(p_ok, p_files, p_filter, Dictionary());
+}
+
+void FileDialog::_native_dialog_cb_with_options(bool p_ok, const Vector &p_files, int p_filter, const Dictionary &p_selected_options) {
if (!p_ok) {
file->set_text("");
emit_signal(SNAME("canceled"));
@@ -182,7 +197,7 @@ void FileDialog::_notification(int p_what) {
#endif
// Replace the built-in dialog with the native one if it started visible.
- if (is_visible() && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE) && (use_native_dialog || OS::get_singleton()->is_sandboxed())) {
+ if (is_visible() && _can_use_native_popup() && (use_native_dialog || OS::get_singleton()->is_sandboxed())) {
ConfirmationDialog::set_visible(false);
_native_popup();
}
@@ -1487,7 +1502,7 @@ void FileDialog::set_use_native_dialog(bool p_native) {
#endif
// Replace the built-in dialog with the native one if it's currently visible.
- if (is_inside_tree() && is_visible() && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_NATIVE_DIALOG_FILE) && (use_native_dialog || OS::get_singleton()->is_sandboxed())) {
+ if (is_inside_tree() && is_visible() && _can_use_native_popup() && (use_native_dialog || OS::get_singleton()->is_sandboxed())) {
ConfirmationDialog::set_visible(false);
_native_popup();
}
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index 6ef60a0f4f5..28978dbed38 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -188,8 +188,10 @@ private:
virtual void shortcut_input(const Ref &p_event) override;
+ bool _can_use_native_popup();
void _native_popup();
- void _native_dialog_cb(bool p_ok, const Vector &p_files, int p_filter, const Dictionary &p_selected_options);
+ void _native_dialog_cb(bool p_ok, const Vector &p_files, int p_filter);
+ void _native_dialog_cb_with_options(bool p_ok, const Vector &p_files, int p_filter, const Dictionary &p_selected_options);
bool _is_open_should_be_disabled();
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index 7059e7ed491..82ac62bc9fa 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -1056,6 +1056,7 @@ void DisplayServer::_bind_methods() {
BIND_ENUM_CONSTANT(FEATURE_NATIVE_HELP);
BIND_ENUM_CONSTANT(FEATURE_NATIVE_DIALOG_INPUT);
BIND_ENUM_CONSTANT(FEATURE_NATIVE_DIALOG_FILE);
+ BIND_ENUM_CONSTANT(FEATURE_NATIVE_DIALOG_FILE_EXTRA);
BIND_ENUM_CONSTANT(MOUSE_MODE_VISIBLE);
BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN);
diff --git a/servers/display_server.h b/servers/display_server.h
index 670afb36469..f9831451933 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -152,6 +152,7 @@ public:
FEATURE_NATIVE_HELP,
FEATURE_NATIVE_DIALOG_INPUT,
FEATURE_NATIVE_DIALOG_FILE,
+ FEATURE_NATIVE_DIALOG_FILE_EXTRA,
};
virtual bool has_feature(Feature p_feature) const = 0;