summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/export/export_plugin.cpp4
-rw-r--r--platform/android/java/lib/AndroidManifest.xml10
-rw-r--r--platform/android/java/lib/res/xml/godot_provider_paths.xml11
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotIO.java38
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp19
-rw-r--r--platform/macos/display_server_macos.mm17
-rw-r--r--platform/windows/display_server_windows.cpp19
8 files changed, 103 insertions, 17 deletions
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index 9ebb8aa102..0902be9595 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -1027,6 +1027,10 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
encode_uint32(is_resizeable, &p_manifest.write[iofs + 16]);
}
+ if (tname == "provider" && attrname == "authorities") {
+ string_table.write[attr_value] = get_package_name(package_name) + String(".fileprovider");
+ }
+
if (tname == "supports-screens") {
if (attrname == "smallScreens") {
encode_uint32(screen_support_small ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml
index 1f77e2fc34..f03a1dd47a 100644
--- a/platform/android/java/lib/AndroidManifest.xml
+++ b/platform/android/java/lib/AndroidManifest.xml
@@ -20,6 +20,16 @@
android:exported="false"
/>
+ <provider
+ android:name="androidx.core.content.FileProvider"
+ android:authorities="${applicationId}.fileprovider"
+ android:exported="false"
+ android:grantUriPermissions="true">
+ <meta-data
+ android:name="android.support.FILE_PROVIDER_PATHS"
+ android:resource="@xml/godot_provider_paths" />
+ </provider>
+
</application>
</manifest>
diff --git a/platform/android/java/lib/res/xml/godot_provider_paths.xml b/platform/android/java/lib/res/xml/godot_provider_paths.xml
new file mode 100644
index 0000000000..1255f576bf
--- /dev/null
+++ b/platform/android/java/lib/res/xml/godot_provider_paths.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<paths xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <external-path
+ name="public"
+ path="." />
+
+ <external-files-path
+ name="app"
+ path="." />
+</paths>
diff --git a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
index 65032d6a68..677c9d8f13 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
@@ -99,7 +99,7 @@ public abstract class FullScreenGodotApp extends FragmentActivity implements God
// from scratch. Therefore, we need to kill the whole app process and relaunch it.
//
// Restarting only the activity, wouldn't be enough unless it did proper cleanup (including
- // releasing and reloading native libs or resetting their state somehow and clearing statics).
+ // releasing and reloading native libs or resetting their state somehow and clearing static data).
Log.v(TAG, "Restarting Godot instance...");
ProcessPhoenix.triggerRebirth(FullScreenGodotApp.this);
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
index 41d06a6458..edcd9c4d1f 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
@@ -49,6 +49,9 @@ import android.view.Display;
import android.view.DisplayCutout;
import android.view.WindowInsets;
+import androidx.core.content.FileProvider;
+
+import java.io.File;
import java.util.List;
import java.util.Locale;
@@ -84,29 +87,42 @@ public class GodotIO {
// MISCELLANEOUS OS IO
/////////////////////////
- public int openURI(String p_uri) {
+ public int openURI(String uriString) {
try {
- String path = p_uri;
- String type = "";
- if (path.startsWith("/")) {
- //absolute path to filesystem, prepend file://
- path = "file://" + path;
- if (p_uri.endsWith(".png") || p_uri.endsWith(".jpg") || p_uri.endsWith(".gif") || p_uri.endsWith(".webp")) {
- type = "image/*";
+ Uri dataUri;
+ String dataType = "";
+ boolean grantReadUriPermission = false;
+
+ if (uriString.startsWith("/") || uriString.startsWith("file://")) {
+ String filePath = uriString;
+ // File uris needs to be provided via the FileProvider
+ grantReadUriPermission = true;
+ if (filePath.startsWith("file://")) {
+ filePath = filePath.replace("file://", "");
}
+
+ File targetFile = new File(filePath);
+ dataUri = FileProvider.getUriForFile(activity, activity.getPackageName() + ".fileprovider", targetFile);
+ dataType = activity.getContentResolver().getType(dataUri);
+ } else {
+ dataUri = Uri.parse(uriString);
}
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
- if (!type.equals("")) {
- intent.setDataAndType(Uri.parse(path), type);
+ if (TextUtils.isEmpty(dataType)) {
+ intent.setData(dataUri);
} else {
- intent.setData(Uri.parse(path));
+ intent.setDataAndType(dataUri, dataType);
+ }
+ if (grantReadUriPermission) {
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
activity.startActivity(intent);
return 0;
} catch (ActivityNotFoundException e) {
+ Log.e(TAG, "Unable to open uri " + uriString, e);
return 1;
}
}
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index c09da2f7b3..8377e81a53 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -3672,8 +3672,23 @@ Rect2i DisplayServerX11::window_get_popup_safe_rect(WindowID p_window) const {
void DisplayServerX11::popup_open(WindowID p_window) {
_THREAD_SAFE_METHOD_
+ bool has_popup_ancestor = false;
+ WindowID transient_root = p_window;
+ while (true) {
+ WindowID parent = windows[transient_root].transient_parent;
+ if (parent == INVALID_WINDOW_ID) {
+ break;
+ } else {
+ transient_root = parent;
+ if (windows[parent].is_popup) {
+ has_popup_ancestor = true;
+ break;
+ }
+ }
+ }
+
WindowData &wd = windows[p_window];
- if (wd.is_popup) {
+ if (wd.is_popup || has_popup_ancestor) {
// Find current popup parent, or root popup if new window is not transient.
List<WindowID>::Element *C = nullptr;
List<WindowID>::Element *E = popup_list.back();
@@ -4897,7 +4912,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V
// handling decorations and placement.
// On the other hand, focus changes need to be handled manually when this is set.
// - save_under is a hint for the WM to keep the content of windows behind to avoid repaint.
- if (wd.is_popup || wd.no_focus) {
+ if (wd.no_focus) {
windowAttributes.override_redirect = True;
windowAttributes.save_under = True;
valuemask |= CWOverrideRedirect | CWSaveUnder;
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index 2832495693..b1880c2fb6 100644
--- a/platform/macos/display_server_macos.mm
+++ b/platform/macos/display_server_macos.mm
@@ -3681,8 +3681,23 @@ Rect2i DisplayServerMacOS::window_get_popup_safe_rect(WindowID p_window) const {
void DisplayServerMacOS::popup_open(WindowID p_window) {
_THREAD_SAFE_METHOD_
+ bool has_popup_ancestor = false;
+ WindowID transient_root = p_window;
+ while (true) {
+ WindowID parent = windows[transient_root].transient_parent;
+ if (parent == INVALID_WINDOW_ID) {
+ break;
+ } else {
+ transient_root = parent;
+ if (windows[parent].is_popup) {
+ has_popup_ancestor = true;
+ break;
+ }
+ }
+ }
+
WindowData &wd = windows[p_window];
- if (wd.is_popup) {
+ if (wd.is_popup || has_popup_ancestor) {
bool was_empty = popup_list.is_empty();
// Find current popup parent, or root popup if new window is not transient.
List<WindowID>::Element *C = nullptr;
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index cc230575c8..777d05584c 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -2360,8 +2360,23 @@ Rect2i DisplayServerWindows::window_get_popup_safe_rect(WindowID p_window) const
void DisplayServerWindows::popup_open(WindowID p_window) {
_THREAD_SAFE_METHOD_
- const WindowData &wd = windows[p_window];
- if (wd.is_popup) {
+ bool has_popup_ancestor = false;
+ WindowID transient_root = p_window;
+ while (true) {
+ WindowID parent = windows[transient_root].transient_parent;
+ if (parent == INVALID_WINDOW_ID) {
+ break;
+ } else {
+ transient_root = parent;
+ if (windows[parent].is_popup) {
+ has_popup_ancestor = true;
+ break;
+ }
+ }
+ }
+
+ WindowData &wd = windows[p_window];
+ if (wd.is_popup || has_popup_ancestor) {
// Find current popup parent, or root popup if new window is not transient.
List<WindowID>::Element *C = nullptr;
List<WindowID>::Element *E = popup_list.back();