summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/export/export_plugin.cpp69
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt (renamed from platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.java)143
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt (renamed from platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.java)10
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.kt (renamed from platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.java)9
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java3
-rw-r--r--platform/iphone/export/export_plugin.cpp10
-rw-r--r--platform/javascript/SCsub6
-rw-r--r--platform/javascript/detect.py15
-rw-r--r--platform/javascript/emscripten_helpers.py6
-rw-r--r--platform/javascript/export/export_plugin.cpp49
-rw-r--r--platform/javascript/export/export_plugin.h15
-rw-r--r--platform/linuxbsd/export/export_plugin.cpp20
-rw-r--r--platform/linuxbsd/export/export_plugin.h2
-rw-r--r--platform/linuxbsd/key_mapping_x11.cpp42
-rw-r--r--platform/osx/export/export_plugin.cpp113
-rw-r--r--platform/osx/key_mapping_osx.mm29
-rw-r--r--platform/windows/export/export_plugin.cpp72
-rw-r--r--platform/windows/export/export_plugin.h2
-rw-r--r--platform/windows/key_mapping_windows.cpp17
19 files changed, 405 insertions, 227 deletions
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index c692f10fd1..73c6fcc7e8 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -1818,7 +1818,7 @@ Error EditorExportPlatformAndroid::run(const Ref<EditorExportPreset> &p_preset,
String can_export_error;
bool can_export_missing_templates;
if (!can_export(p_preset, can_export_error, can_export_missing_templates)) {
- EditorNode::add_io_error(can_export_error);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Run"), can_export_error);
return ERR_UNCONFIGURED;
}
@@ -1897,7 +1897,7 @@ Error EditorExportPlatformAndroid::run(const Ref<EditorExportPreset> &p_preset,
err = OS::get_singleton()->execute(adb, args, &output, &rv, true);
print_verbose(output);
if (err || rv != 0) {
- EditorNode::add_io_error(vformat(TTR("Could not install to device: %s"), output));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Run"), vformat(TTR("Could not install to device: %s"), output));
CLEANUP_AND_RETURN(ERR_CANT_CREATE);
}
@@ -1975,7 +1975,7 @@ Error EditorExportPlatformAndroid::run(const Ref<EditorExportPreset> &p_preset,
err = OS::get_singleton()->execute(adb, args, &output, &rv, true);
print_verbose(output);
if (err || rv != 0) {
- EditorNode::add_io_error(TTR("Could not execute on device."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Run"), TTR("Could not execute on device."));
CLEANUP_AND_RETURN(ERR_CANT_CREATE);
}
@@ -2030,7 +2030,7 @@ String EditorExportPlatformAndroid::get_apksigner_path() {
da->list_dir_end();
if (apksigner_path.is_empty()) {
- EditorNode::get_singleton()->show_warning(TTR("Unable to find the 'apksigner' tool."));
+ print_error("Unable to find the 'apksigner' tool.");
}
return apksigner_path;
@@ -2335,7 +2335,7 @@ Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_pre
String apksigner = get_apksigner_path();
print_verbose("Starting signing of the " + export_label + " binary using " + apksigner);
if (!FileAccess::exists(apksigner)) {
- EditorNode::add_io_error(vformat(TTR("'apksigner' could not be found.\nPlease check the command is available in the Android SDK build-tools directory.\nThe resulting %s is unsigned."), export_label));
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("'apksigner' could not be found. Please check that the command is available in the Android SDK build-tools directory. The resulting %s is unsigned."), export_label));
return OK;
}
@@ -2368,7 +2368,7 @@ Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_pre
}
if (!FileAccess::exists(keystore)) {
- EditorNode::add_io_error(TTR("Could not find keystore, unable to export."));
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Could not find keystore, unable to export."));
return ERR_FILE_CANT_OPEN;
}
@@ -2389,10 +2389,14 @@ Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_pre
}
int retval;
output.clear();
- OS::get_singleton()->execute(apksigner, args, &output, &retval, true);
+ Error err = OS::get_singleton()->execute(apksigner, args, &output, &retval, true);
+ if (err != OK) {
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Could not start apksigner executable."));
+ return err;
+ }
print_verbose(output);
if (retval) {
- EditorNode::add_io_error(vformat(TTR("'apksigner' returned with error #%d"), retval));
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("'apksigner' returned with error #%d"), retval));
return ERR_CANT_CREATE;
}
@@ -2409,10 +2413,14 @@ Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_pre
}
output.clear();
- OS::get_singleton()->execute(apksigner, args, &output, &retval, true);
+ err = OS::get_singleton()->execute(apksigner, args, &output, &retval, true);
+ if (err != OK) {
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Could not start apksigner executable."));
+ return err;
+ }
print_verbose(output);
if (retval) {
- EditorNode::add_io_error(vformat(TTR("'apksigner' verification of %s failed."), export_label));
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("'apksigner' verification of %s failed."), export_label));
return ERR_CANT_CREATE;
}
@@ -2520,22 +2528,21 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
if (export_format == EXPORT_FORMAT_AAB) {
if (!p_path.ends_with(".aab")) {
- EditorNode::get_singleton()->show_warning(TTR("Invalid filename! Android App Bundle requires the *.aab extension."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Invalid filename! Android App Bundle requires the *.aab extension."));
return ERR_UNCONFIGURED;
}
if (apk_expansion) {
- EditorNode::get_singleton()->show_warning(TTR("APK Expansion not compatible with Android App Bundle."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("APK Expansion not compatible with Android App Bundle."));
return ERR_UNCONFIGURED;
}
}
if (export_format == EXPORT_FORMAT_APK && !p_path.ends_with(".apk")) {
- EditorNode::get_singleton()->show_warning(
- TTR("Invalid filename! Android APK requires the *.apk extension."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Invalid filename! Android APK requires the *.apk extension."));
return ERR_UNCONFIGURED;
}
if (export_format > EXPORT_FORMAT_AAB || export_format < EXPORT_FORMAT_APK) {
- EditorNode::add_io_error(TTR("Unsupported export format!\n"));
- return ERR_UNCONFIGURED; //TODO: is this the right error?
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Unsupported export format!"));
+ return ERR_UNCONFIGURED;
}
if (use_custom_build) {
@@ -2545,13 +2552,13 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
print_verbose("Checking build version..");
Ref<FileAccess> f = FileAccess::open("res://android/.build_version", FileAccess::READ);
if (f.is_null()) {
- EditorNode::get_singleton()->show_warning(TTR("Trying to build from a custom built template, but no version info for it exists. Please reinstall from the 'Project' menu."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Trying to build from a custom built template, but no version info for it exists. Please reinstall from the 'Project' menu."));
return ERR_UNCONFIGURED;
}
String version = f->get_line().strip_edges();
print_verbose("- build version: " + version);
if (version != VERSION_FULL_CONFIG) {
- EditorNode::get_singleton()->show_warning(vformat(TTR("Android build version mismatch:\n Template installed: %s\n Godot Version: %s\nPlease reinstall Android build template from 'Project' menu."), version, VERSION_FULL_CONFIG));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Android build version mismatch: Template installed: %s, Godot version: %s. Please reinstall Android build template from 'Project' menu."), version, VERSION_FULL_CONFIG));
return ERR_UNCONFIGURED;
}
}
@@ -2564,7 +2571,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
String project_name = get_project_name(p_preset->get("package/name"));
err = _create_project_name_strings_files(p_preset, project_name); //project name localization.
if (err != OK) {
- EditorNode::add_io_error(TTR("Unable to overwrite res://android/build/res/*.xml files with project name"));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Unable to overwrite res://android/build/res/*.xml files with project name."));
}
// Copies the project icon files into the appropriate Gradle project directory.
_copy_icons_to_gradle_project(p_preset, processed_splash_config_xml, splash_image, splash_bg_color_image, main_image, foreground, background);
@@ -2581,7 +2588,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
user_data.debug = p_debug;
err = export_project_files(p_preset, p_debug, rename_and_store_file_in_gradle_project, &user_data, copy_gradle_so);
if (err != OK) {
- EditorNode::add_io_error(TTR("Could not export project files to gradle project\n"));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Could not export project files to gradle project."));
return err;
}
if (user_data.libs.size() > 0) {
@@ -2593,7 +2600,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
print_verbose("Saving apk expansion file..");
err = save_apk_expansion_file(p_preset, p_debug, p_path);
if (err != OK) {
- EditorNode::add_io_error(TTR("Could not write expansion package file!"));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Could not write expansion package file!"));
return err;
}
}
@@ -2678,7 +2685,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
debug_keystore = OS::get_singleton()->get_resource_dir().plus_file(debug_keystore).simplify_path();
}
if (!FileAccess::exists(debug_keystore)) {
- EditorNode::add_io_error(TTR("Could not find keystore, unable to export."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Code Signing"), TTR("Could not find keystore, unable to export."));
return ERR_FILE_CANT_OPEN;
}
@@ -2694,7 +2701,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
release_keystore = OS::get_singleton()->get_resource_dir().plus_file(release_keystore).simplify_path();
}
if (!FileAccess::exists(release_keystore)) {
- EditorNode::add_io_error(TTR("Could not find keystore, unable to export."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Code Signing"), TTR("Could not find keystore, unable to export."));
return ERR_FILE_CANT_OPEN;
}
@@ -2706,7 +2713,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
int result = EditorNode::get_singleton()->execute_and_show_output(TTR("Building Android Project (gradle)"), build_command, cmdline);
if (result != 0) {
- EditorNode::get_singleton()->show_warning(TTR("Building of Android project failed, check output for the error.\nAlternatively visit docs.godotengine.org for Android build documentation."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Building of Android project failed, check output for the error. Alternatively visit docs.godotengine.org for Android build documentation."));
return ERR_CANT_CREATE;
}
@@ -2736,7 +2743,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
print_verbose("Copying Android binary using gradle command: " + String("\n") + build_command + " " + join_list(copy_args, String(" ")));
int copy_result = EditorNode::get_singleton()->execute_and_show_output(TTR("Moving output"), build_command, copy_args);
if (copy_result != 0) {
- EditorNode::get_singleton()->show_warning(TTR("Unable to copy and rename export file, check gradle project directory for outputs."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Unable to copy and rename export file, check gradle project directory for outputs."));
return ERR_CANT_CREATE;
}
@@ -2758,7 +2765,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
src_apk = find_export_template("android_release.apk");
}
if (src_apk.is_empty()) {
- EditorNode::add_io_error(vformat(TTR("Package not found: %s"), src_apk));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Package not found: \"%s\"."), src_apk));
return ERR_FILE_NOT_FOUND;
}
}
@@ -2776,7 +2783,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
unzFile pkg = unzOpen2(src_apk.utf8().get_data(), &io);
if (!pkg) {
- EditorNode::add_io_error(vformat(TTR("Could not find template APK to export:\n%s"), src_apk));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not find template APK to export: \"%s\"."), src_apk));
return ERR_FILE_NOT_FOUND;
}
@@ -2907,7 +2914,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
if (!invalid_abis.is_empty()) {
String unsupported_arch = String(", ").join(invalid_abis);
- EditorNode::add_io_error(vformat(TTR("Missing libraries in the export template for the selected architectures: %s.\nPlease build a template with all required libraries, or uncheck the missing architectures in the export preset."), unsupported_arch));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Missing libraries in the export template for the selected architectures: %s. Please build a template with all required libraries, or uncheck the missing architectures in the export preset."), unsupported_arch));
CLEANUP_AND_RETURN(ERR_FILE_NOT_FOUND);
}
@@ -2925,7 +2932,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
if (apk_expansion) {
err = save_apk_expansion_file(p_preset, p_debug, p_path);
if (err != OK) {
- EditorNode::add_io_error(TTR("Could not write expansion package file!"));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Could not write expansion package file!"));
return err;
}
} else {
@@ -2938,7 +2945,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
if (err != OK) {
unzClose(pkg);
- EditorNode::add_io_error(TTR("Could not export project files"));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not export project files.")));
CLEANUP_AND_RETURN(ERR_SKIP);
}
@@ -2974,7 +2981,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
unzFile tmp_unaligned = unzOpen2(tmp_unaligned_path.utf8().get_data(), &io);
if (!tmp_unaligned) {
- EditorNode::add_io_error(TTR("Could not unzip temporary unaligned APK."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not unzip temporary unaligned APK.")));
CLEANUP_AND_RETURN(ERR_FILE_NOT_FOUND);
}
diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.java b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt
index c05ed965ca..a1ade722e8 100644
--- a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.java
+++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* GodotEditor.java */
+/* GodotEditor.kt */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,23 +28,17 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-package org.godotengine.editor;
+package org.godotengine.editor
-import org.godotengine.godot.FullScreenGodotApp;
-import org.godotengine.godot.utils.PermissionsUtil;
-
-import android.content.Intent;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Debug;
-
-import androidx.annotation.Nullable;
-import androidx.window.layout.WindowMetrics;
-import androidx.window.layout.WindowMetricsCalculator;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
+import android.content.Intent
+import android.os.Build
+import android.os.Bundle
+import android.os.Debug
+import androidx.window.layout.WindowMetricsCalculator
+import org.godotengine.godot.FullScreenGodotApp
+import org.godotengine.godot.utils.PermissionsUtil
+import java.util.*
+import kotlin.math.min
/**
* Base class for the Godot Android Editor activities.
@@ -55,97 +49,98 @@ import java.util.List;
*
* It also plays the role of the primary editor window.
*/
-public class GodotEditor extends FullScreenGodotApp {
- private static final boolean WAIT_FOR_DEBUGGER = false;
- private static final String COMMAND_LINE_PARAMS = "command_line_params";
+open class GodotEditor : FullScreenGodotApp() {
- private static final String EDITOR_ARG = "--editor";
- private static final String PROJECT_MANAGER_ARG = "--project-manager";
+ companion object {
+ private const val WAIT_FOR_DEBUGGER = false
- private final List<String> commandLineParams = new ArrayList<>();
+ private const val COMMAND_LINE_PARAMS = "command_line_params"
- @Override
- public void onCreate(Bundle savedInstanceState) {
- PermissionsUtil.requestManifestPermissions(this);
+ private const val EDITOR_ARG = "--editor"
+ private const val PROJECT_MANAGER_ARG = "--project-manager"
+ }
- String[] params = getIntent().getStringArrayExtra(COMMAND_LINE_PARAMS);
- updateCommandLineParams(params);
+ private val commandLineParams = ArrayList<String>()
- if (BuildConfig.BUILD_TYPE.equals("debug") && WAIT_FOR_DEBUGGER) {
- Debug.waitForDebugger();
+ override fun onCreate(savedInstanceState: Bundle?) {
+ PermissionsUtil.requestManifestPermissions(this)
+
+ val params = intent.getStringArrayExtra(COMMAND_LINE_PARAMS)
+ updateCommandLineParams(params)
+
+ if (BuildConfig.BUILD_TYPE == "debug" && WAIT_FOR_DEBUGGER) {
+ Debug.waitForDebugger()
}
- super.onCreate(savedInstanceState);
+
+ super.onCreate(savedInstanceState)
}
- private void updateCommandLineParams(@Nullable String[] args) {
+ private fun updateCommandLineParams(args: Array<String>?) {
// Update the list of command line params with the new args
- commandLineParams.clear();
- if (args != null && args.length > 0) {
- commandLineParams.addAll(Arrays.asList(args));
+ commandLineParams.clear()
+ if (args != null && args.isNotEmpty()) {
+ commandLineParams.addAll(listOf(*args))
}
}
- @Override
- public List<String> getCommandLine() {
- return commandLineParams;
- }
+ override fun getCommandLine() = commandLineParams
- @Override
- public void onNewGodotInstanceRequested(String[] args) {
+ override fun onNewGodotInstanceRequested(args: Array<String>) {
// Parse the arguments to figure out which activity to start.
- Class<?> targetClass = GodotGame.class;
+ var targetClass: Class<*> = GodotGame::class.java
+
// Whether we should launch the new godot instance in an adjacent window
// https://developer.android.com/reference/android/content/Intent#FLAG_ACTIVITY_LAUNCH_ADJACENT
- boolean launchAdjacent = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && (isInMultiWindowMode() || isLargeScreen());
-
- for (String arg : args) {
- if (EDITOR_ARG.equals(arg)) {
- targetClass = GodotEditor.class;
- launchAdjacent = false;
- break;
+ var launchAdjacent =
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && (isInMultiWindowMode || isLargeScreen)
+
+ for (arg in args) {
+ if (EDITOR_ARG == arg) {
+ targetClass = GodotEditor::class.java
+ launchAdjacent = false
+ break
}
- if (PROJECT_MANAGER_ARG.equals(arg)) {
- targetClass = GodotProjectManager.class;
- launchAdjacent = false;
- break;
+ if (PROJECT_MANAGER_ARG == arg) {
+ targetClass = GodotProjectManager::class.java
+ launchAdjacent = false
+ break
}
}
// Launch a new activity
- Intent newInstance = new Intent(this, targetClass)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- .putExtra(COMMAND_LINE_PARAMS, args);
+ val newInstance = Intent(this, targetClass)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .putExtra(COMMAND_LINE_PARAMS, args)
if (launchAdjacent) {
- newInstance.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
+ newInstance.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT)
}
- startActivity(newInstance);
+ startActivity(newInstance)
}
- protected boolean isLargeScreen() {
- WindowMetrics metrics =
- WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this);
+ // Get the screen's density scale
+ protected val isLargeScreen: Boolean
+ // Get the minimum window size // Correspond to the EXPANDED window size class.
+ get() {
+ val metrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this)
- // Get the screen's density scale
- float scale = getResources().getDisplayMetrics().density;
+ // Get the screen's density scale
+ val scale = resources.displayMetrics.density
- // Get the minimum window size
- float minSize = Math.min(metrics.getBounds().width(), metrics.getBounds().height());
- float minSizeDp = minSize / scale;
- return minSizeDp >= 840f; // Correspond to the EXPANDED window size class.
- }
+ // Get the minimum window size
+ val minSize = min(metrics.bounds.width(), metrics.bounds.height()).toFloat()
+ val minSizeDp = minSize / scale
+ return minSizeDp >= 840f // Correspond to the EXPANDED window size class.
+ }
- @Override
- public void setRequestedOrientation(int requestedOrientation) {
+ override fun setRequestedOrientation(requestedOrientation: Int) {
if (!overrideOrientationRequest()) {
- super.setRequestedOrientation(requestedOrientation);
+ super.setRequestedOrientation(requestedOrientation)
}
}
/**
* The Godot Android Editor sets its own orientation via its AndroidManifest
*/
- protected boolean overrideOrientationRequest() {
- return true;
- }
+ protected open fun overrideOrientationRequest() = true
}
diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.java b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt
index 12766775a8..783095f93a 100644
--- a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.java
+++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* GodotGame.java */
+/* GodotGame.kt */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,13 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-package org.godotengine.editor;
+package org.godotengine.editor
/**
* Drives the 'run project' window of the Godot Editor.
*/
-public class GodotGame extends GodotEditor {
- protected boolean overrideOrientationRequest() {
- return false;
- }
+class GodotGame : GodotEditor() {
+ override fun overrideOrientationRequest() = false
}
diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.java b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.kt
index d30f66bb8c..bcf4659603 100644
--- a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.java
+++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.kt
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* GodotProjectManager.java */
+/* GodotProjectManager.kt */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,14 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-package org.godotengine.editor;
+package org.godotengine.editor
/**
* Launcher activity for the Godot Android Editor.
*
* It presents the user with the project manager interface.
* Upon selection of a project, this activity (via its parent logic) starts the
- * {@link GodotEditor} activity.
+ * [GodotEditor] activity.
*/
-public class GodotProjectManager extends GodotEditor {
-}
+class GodotProjectManager : GodotEditor()
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
index 8694bb91e1..ccfb865b1a 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
@@ -186,6 +186,9 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
if (mJoystickIds.indexOfKey(deviceId) >= 0) {
final int godotJoyId = mJoystickIds.get(deviceId);
Joystick joystick = mJoysticksDevices.get(deviceId);
+ if (joystick == null) {
+ return true;
+ }
for (int i = 0; i < joystick.axes.size(); i++) {
final int axis = joystick.axes.get(i);
diff --git a/platform/iphone/export/export_plugin.cpp b/platform/iphone/export/export_plugin.cpp
index 1f5e378098..4cf1c279eb 100644
--- a/platform/iphone/export/export_plugin.cpp
+++ b/platform/iphone/export/export_plugin.cpp
@@ -817,7 +817,11 @@ Error EditorExportPlatformIOS::_codesign(String p_file, void *p_userdata) {
codesign_args.push_back("-s");
codesign_args.push_back(sign_id);
codesign_args.push_back(p_file);
- return OS::get_singleton()->execute("codesign", codesign_args);
+ String str;
+ Error err = OS::get_singleton()->execute("codesign", codesign_args, &str, nullptr, true);
+ print_verbose("codesign (" + p_file + "):\n" + str);
+
+ return err;
}
return OK;
}
@@ -1392,7 +1396,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
String err;
src_pkg_name = find_export_template("iphone.zip", &err);
if (src_pkg_name.is_empty()) {
- EditorNode::add_io_error(err);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), TTR("Export template not found."));
return ERR_FILE_NOT_FOUND;
}
}
@@ -1487,7 +1491,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
zlib_filefunc_def io = zipio_create_io(&io_fa);
unzFile src_pkg_zip = unzOpen2(src_pkg_name.utf8().get_data(), &io);
if (!src_pkg_zip) {
- EditorNode::add_io_error("Could not open export template (not a zip file?):\n" + src_pkg_name);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), TTR("Could not open export template (not a zip file?): \"%s\".", src_pkg_name));
return ERR_CANT_OPEN;
}
diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub
index 8d9ba82fd4..4827dc4627 100644
--- a/platform/javascript/SCsub
+++ b/platform/javascript/SCsub
@@ -37,6 +37,8 @@ for ext in env["JS_EXTERNS"]:
build = []
if env["gdnative_enabled"]:
build_targets = ["#bin/godot${PROGSUFFIX}.js", "#bin/godot${PROGSUFFIX}.wasm"]
+ if env["threads_enabled"]:
+ build_targets.append("#bin/godot${PROGSUFFIX}.worker.js")
# Reset libraries. The main runtime will only link emscripten libraries, not godot ones.
sys_env["LIBS"] = []
# We use IDBFS. Since Emscripten 1.39.1 it needs to be linked explicitly.
@@ -58,7 +60,7 @@ if env["gdnative_enabled"]:
wasm_env.Append(CCFLAGS=["-s", "SIDE_MODULE=2"])
wasm_env.Append(LINKFLAGS=["-s", "SIDE_MODULE=2"])
wasm = wasm_env.add_program("#bin/godot.side${PROGSUFFIX}.wasm", javascript_files)
- build = [sys[0], sys[1], wasm[0]]
+ build = sys + [wasm[0]]
else:
build_targets = ["#bin/godot${PROGSUFFIX}.js", "#bin/godot${PROGSUFFIX}.wasm"]
if env["threads_enabled"]:
@@ -87,5 +89,5 @@ wrap_list = [
js_wrapped = env.Textfile("#bin/godot", [env.File(f) for f in wrap_list], TEXTFILESUFFIX="${PROGSUFFIX}.wrapped.js")
# Extra will be the thread worker, or the GDNative side, or None
-extra = build[2] if len(build) > 2 else None
+extra = build[2:] if len(build) > 2 else None
env.CreateTemplateZip(js_wrapped, build[1], extra)
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index 4a9652fc1c..a769260f01 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -185,10 +185,6 @@ def configure(env):
if env["javascript_eval"]:
env.Append(CPPDEFINES=["JAVASCRIPT_EVAL_ENABLED"])
- if env["threads_enabled"] and env["gdnative_enabled"]:
- print("Threads and GDNative support can't be both enabled due to WebAssembly limitations")
- sys.exit(255)
-
# Thread support (via SharedArrayBuffer).
if env["threads_enabled"]:
env.Append(CPPDEFINES=["PTHREAD_NO_RENAME"])
@@ -201,9 +197,14 @@ def configure(env):
env.Append(CPPDEFINES=["NO_THREADS"])
if env["gdnative_enabled"]:
- major, minor, patch = get_compiler_version(env)
- if major < 2 or (major == 2 and minor == 0 and patch < 10):
- print("GDNative support requires emscripten >= 2.0.10, detected: %s.%s.%s" % (major, minor, patch))
+ cc_version = get_compiler_version(env)
+ cc_semver = (int(cc_version["major"]), int(cc_version["minor"]), int(cc_version["patch"]))
+ if cc_semver < (2, 0, 10):
+ print("GDNative support requires emscripten >= 2.0.10, detected: %s.%s.%s" % cc_semver)
+ sys.exit(255)
+
+ if env["threads_enabled"] and cc_semver < (3, 1, 14):
+ print("Threads and GDNative requires emscripten >= 3.1.14, detected: %s.%s.%s" % cc_semver)
sys.exit(255)
env.Append(CCFLAGS=["-s", "RELOCATABLE=1"])
env.Append(LINKFLAGS=["-s", "RELOCATABLE=1"])
diff --git a/platform/javascript/emscripten_helpers.py b/platform/javascript/emscripten_helpers.py
index 4dad2d5204..3cb1d75e52 100644
--- a/platform/javascript/emscripten_helpers.py
+++ b/platform/javascript/emscripten_helpers.py
@@ -52,10 +52,10 @@ def create_template_zip(env, js, wasm, extra):
]
# GDNative/Threads specific
if env["gdnative_enabled"]:
- in_files.append(extra) # Runtime
+ in_files.append(extra.pop()) # Runtime
out_files.append(zip_dir.File(binary_name + ".side.wasm"))
- elif env["threads_enabled"]:
- in_files.append(extra) # Worker
+ if env["threads_enabled"]:
+ in_files.append(extra.pop()) # Worker
out_files.append(zip_dir.File(binary_name + ".worker.js"))
service_worker = "#misc/dist/html/service-worker.js"
diff --git a/platform/javascript/export/export_plugin.cpp b/platform/javascript/export/export_plugin.cpp
index 3334e7394b..901580c140 100644
--- a/platform/javascript/export/export_plugin.cpp
+++ b/platform/javascript/export/export_plugin.cpp
@@ -38,12 +38,12 @@ Error EditorExportPlatformJavaScript::_extract_template(const String &p_template
unzFile pkg = unzOpen2(p_template.utf8().get_data(), &io);
if (!pkg) {
- EditorNode::get_singleton()->show_warning(TTR("Could not open template for export:") + "\n" + p_template);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Could not open template for export: \"%s\"."), p_template));
return ERR_FILE_NOT_FOUND;
}
if (unzGoToFirstFile(pkg) != UNZ_OK) {
- EditorNode::get_singleton()->show_warning(TTR("Invalid export template:") + "\n" + p_template);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Invalid export template: \"%s\"."), p_template));
unzClose(pkg);
return ERR_FILE_CORRUPT;
}
@@ -56,6 +56,11 @@ Error EditorExportPlatformJavaScript::_extract_template(const String &p_template
String file = String::utf8(fname);
+ // Skip folders.
+ if (file.ends_with("/")) {
+ continue;
+ }
+
// Skip service worker and offline page if not exporting pwa.
if (!pwa && (file == "godot.service.worker.js" || file == "godot.offline.html")) {
continue;
@@ -72,7 +77,7 @@ Error EditorExportPlatformJavaScript::_extract_template(const String &p_template
String dst = p_dir.plus_file(file.replace("godot", p_name));
Ref<FileAccess> f = FileAccess::open(dst, FileAccess::WRITE);
if (f.is_null()) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + dst);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Could not write file: \"%s\"."), dst));
unzClose(pkg);
return ERR_FILE_CANT_WRITE;
}
@@ -86,7 +91,7 @@ Error EditorExportPlatformJavaScript::_extract_template(const String &p_template
Error EditorExportPlatformJavaScript::_write_or_error(const uint8_t *p_content, int p_size, String p_path) {
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE);
if (f.is_null()) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + p_path);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not write file: \"%s\"."), p_path));
return ERR_FILE_CANT_WRITE;
}
f->store_buffer(p_content, p_size);
@@ -163,7 +168,7 @@ Error EditorExportPlatformJavaScript::_add_manifest_icon(const String &p_path, c
icon.instantiate();
const Error err = ImageLoader::load_image(p_icon, icon);
if (err != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not read file:") + "\n" + p_icon);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Icon Creation"), vformat(TTR("Could not read file: \"%s\"."), p_icon));
return err;
}
if (icon->get_width() != p_size || icon->get_height() != p_size) {
@@ -175,7 +180,7 @@ Error EditorExportPlatformJavaScript::_add_manifest_icon(const String &p_path, c
}
const Error err = icon->save_png(icon_dest);
if (err != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + icon_dest);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Icon Creation"), vformat(TTR("Could not write file: \"%s\"."), icon_dest));
return err;
}
Dictionary icon_dict;
@@ -210,7 +215,7 @@ Error EditorExportPlatformJavaScript::_build_pwa(const Ref<EditorExportPreset> &
cache_files.push_back(name + ".icon.png");
cache_files.push_back(name + ".apple-touch-icon.png");
}
- if (mode == EXPORT_MODE_THREADS) {
+ if (mode & EXPORT_MODE_THREADS) {
cache_files.push_back(name + ".worker.js");
cache_files.push_back(name + ".audio.worklet.js");
}
@@ -220,7 +225,7 @@ Error EditorExportPlatformJavaScript::_build_pwa(const Ref<EditorExportPreset> &
Array opt_cache_files;
opt_cache_files.push_back(name + ".wasm");
opt_cache_files.push_back(name + ".pck");
- if (mode == EXPORT_MODE_GDNATIVE) {
+ if (mode & EXPORT_MODE_GDNATIVE) {
opt_cache_files.push_back(name + ".side.wasm");
for (int i = 0; i < p_shared_objects.size(); i++) {
opt_cache_files.push_back(p_shared_objects[i].path.get_file());
@@ -233,7 +238,7 @@ Error EditorExportPlatformJavaScript::_build_pwa(const Ref<EditorExportPreset> &
{
Ref<FileAccess> f = FileAccess::open(sw_path, FileAccess::READ);
if (f.is_null()) {
- EditorNode::get_singleton()->show_warning(TTR("Could not read file:") + "\n" + sw_path);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("PWA"), vformat(TTR("Could not read file: \"%s\"."), sw_path));
return ERR_FILE_CANT_READ;
}
sw.resize(f->get_length());
@@ -252,7 +257,7 @@ Error EditorExportPlatformJavaScript::_build_pwa(const Ref<EditorExportPreset> &
const String offline_dest = dir.plus_file(name + ".offline.html");
err = da->copy(ProjectSettings::get_singleton()->globalize_path(offline_page), offline_dest);
if (err != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not read file:") + "\n" + offline_dest);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("PWA"), vformat(TTR("Could not read file: \"%s\"."), offline_dest));
return err;
}
}
@@ -312,9 +317,10 @@ void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportP
}
}
ExportMode mode = (ExportMode)(int)p_preset->get("variant/export_type");
- if (mode == EXPORT_MODE_THREADS) {
+ if (mode & EXPORT_MODE_THREADS) {
r_features->push_back("threads");
- } else if (mode == EXPORT_MODE_GDNATIVE) {
+ }
+ if (mode & EXPORT_MODE_GDNATIVE) {
r_features->push_back("wasm32");
}
}
@@ -438,7 +444,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
}
if (!template_path.is_empty() && !FileAccess::exists(template_path)) {
- EditorNode::get_singleton()->show_warning(TTR("Template file not found:") + "\n" + template_path);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Template file not found: \"%s\"."), template_path));
return ERR_FILE_NOT_FOUND;
}
@@ -447,7 +453,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
String pck_path = base_path + ".pck";
Error error = save_pack(p_preset, p_debug, pck_path, &shared_objects);
if (error != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + pck_path);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not write file: \"%s\"."), pck_path));
return error;
}
@@ -457,7 +463,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
String dst = base_dir.plus_file(shared_objects[i].path.get_file());
error = da->copy(shared_objects[i].path, dst);
if (error != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + shared_objects[i].path.get_file());
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not write file: \"%s\"."), shared_objects[i].path.get_file()));
return error;
}
}
@@ -485,7 +491,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
Vector<uint8_t> html;
f = FileAccess::open(html_path, FileAccess::READ);
if (f.is_null()) {
- EditorNode::get_singleton()->show_warning(TTR("Could not read HTML shell:") + "\n" + html_path);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not read HTML shell: \"%s\"."), html_path));
return ERR_FILE_CANT_READ;
}
html.resize(f->get_length());
@@ -503,7 +509,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
Ref<Image> splash = _get_project_splash();
const String splash_png_path = base_path + ".png";
if (splash->save_png(splash_png_path) != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + splash_png_path);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not write file: \"%s\"."), splash_png_path));
return ERR_FILE_CANT_WRITE;
}
@@ -513,13 +519,13 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
Ref<Image> favicon = _get_project_icon();
const String favicon_png_path = base_path + ".icon.png";
if (favicon->save_png(favicon_png_path) != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + favicon_png_path);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not write file: \"%s\"."), favicon_png_path));
return ERR_FILE_CANT_WRITE;
}
favicon->resize(180, 180);
const String apple_icon_png_path = base_path + ".apple-touch-icon.png";
if (favicon->save_png(apple_icon_png_path) != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + apple_icon_png_path);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not write file: \"%s\"."), apple_icon_png_path));
return ERR_FILE_CANT_WRITE;
}
}
@@ -579,10 +585,11 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese
if (!da->dir_exists(dest)) {
Error err = da->make_dir_recursive(dest);
if (err != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Could not create HTTP server directory:") + "\n" + dest);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Run"), vformat(TTR("Could not create HTTP server directory: %s."), dest));
return err;
}
}
+
const String basepath = dest.plus_file("tmp_js_export");
Error err = export_project(p_preset, true, basepath + ".html", p_debug_flags);
if (err != OK) {
@@ -625,7 +632,7 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese
err = server->listen(bind_port, bind_ip, use_ssl, ssl_key, ssl_cert);
}
if (err != OK) {
- EditorNode::get_singleton()->show_warning(TTR("Error starting HTTP server:") + "\n" + itos(err));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Run"), vformat(TTR("Error starting HTTP server: %d."), err));
return err;
}
diff --git a/platform/javascript/export/export_plugin.h b/platform/javascript/export/export_plugin.h
index 2d6cbfde38..1aaec5454d 100644
--- a/platform/javascript/export/export_plugin.h
+++ b/platform/javascript/export/export_plugin.h
@@ -61,19 +61,16 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform {
EXPORT_MODE_NORMAL = 0,
EXPORT_MODE_THREADS = 1,
EXPORT_MODE_GDNATIVE = 2,
+ EXPORT_MODE_THREADS_GDNATIVE = 3,
};
String _get_template_name(ExportMode p_mode, bool p_debug) const {
String name = "webassembly";
- switch (p_mode) {
- case EXPORT_MODE_THREADS:
- name += "_threads";
- break;
- case EXPORT_MODE_GDNATIVE:
- name += "_gdnative";
- break;
- default:
- break;
+ if (p_mode & EXPORT_MODE_GDNATIVE) {
+ name += "_gdnative";
+ }
+ if (p_mode & EXPORT_MODE_THREADS) {
+ name += "_threads";
}
if (p_debug) {
name += "_debug.zip";
diff --git a/platform/linuxbsd/export/export_plugin.cpp b/platform/linuxbsd/export/export_plugin.cpp
index 9f7fab6ee8..4e14920e79 100644
--- a/platform/linuxbsd/export/export_plugin.cpp
+++ b/platform/linuxbsd/export/export_plugin.cpp
@@ -35,7 +35,10 @@
Error EditorExportPlatformLinuxBSD::_export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path) {
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE);
- ERR_FAIL_COND_V(f.is_null(), ERR_CANT_CREATE);
+ if (f.is_null()) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Debug Script Export"), vformat(TTR("Could not open file \"%s\"."), p_path));
+ return ERR_CANT_CREATE;
+ }
f->store_line("#!/bin/sh");
f->store_line("echo -ne '\\033c\\033]0;" + p_app_name + "\\a'");
@@ -67,6 +70,9 @@ Error EditorExportPlatformLinuxBSD::export_project(const Ref<EditorExportPreset>
String scr_path = p_path.get_basename() + ".sh";
err = _export_debug_script(p_preset, app_name, p_path.get_file(), scr_path);
FileAccess::set_unix_permissions(scr_path, 0755);
+ if (err != OK) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Debug Script Export"), TTR("Could not create console script."));
+ }
}
}
@@ -98,11 +104,12 @@ List<String> EditorExportPlatformLinuxBSD::get_binary_extensions(const Ref<Edito
return list;
}
-Error EditorExportPlatformLinuxBSD::fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) const {
+Error EditorExportPlatformLinuxBSD::fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) {
// Patch the header of the "pck" section in the ELF file so that it corresponds to the embedded data
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ_WRITE);
if (f.is_null()) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), vformat(TTR("Failed to open executable file \"%s\"."), p_path));
return ERR_CANT_OPEN;
}
@@ -110,6 +117,7 @@ Error EditorExportPlatformLinuxBSD::fixup_embedded_pck(const String &p_path, int
{
uint32_t magic = f->get_32();
if (magic != 0x464c457f) { // 0x7F + "ELF"
+ add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("Executable file header corrupted."));
return ERR_FILE_CORRUPT;
}
}
@@ -119,7 +127,7 @@ Error EditorExportPlatformLinuxBSD::fixup_embedded_pck(const String &p_path, int
int bits = f->get_8() * 32;
if (bits == 32 && p_embedded_size >= 0x100000000) {
- ERR_FAIL_V_MSG(ERR_INVALID_DATA, "32-bit executables cannot have embedded data >= 4 GiB.");
+ add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("32-bit executables cannot have embedded data >= 4 GiB."));
}
// Get info about the section header table
@@ -196,5 +204,9 @@ Error EditorExportPlatformLinuxBSD::fixup_embedded_pck(const String &p_path, int
memfree(strings);
- return found ? OK : ERR_FILE_CORRUPT;
+ if (!found) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("Executable \"pck\" section not found."));
+ return ERR_FILE_CORRUPT;
+ }
+ return OK;
}
diff --git a/platform/linuxbsd/export/export_plugin.h b/platform/linuxbsd/export/export_plugin.h
index 9ae5cf827a..e04bcc20f9 100644
--- a/platform/linuxbsd/export/export_plugin.h
+++ b/platform/linuxbsd/export/export_plugin.h
@@ -46,7 +46,7 @@ public:
virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override;
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override;
virtual String get_template_file_name(const String &p_target, const String &p_arch) const override;
- virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) const override;
+ virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) override;
};
#endif
diff --git a/platform/linuxbsd/key_mapping_x11.cpp b/platform/linuxbsd/key_mapping_x11.cpp
index afe965e038..047ee74671 100644
--- a/platform/linuxbsd/key_mapping_x11.cpp
+++ b/platform/linuxbsd/key_mapping_x11.cpp
@@ -135,6 +135,25 @@ static _XTranslatePair _xkeysym_to_keycode[] = {
{ XK_F14, Key::F14 },
{ XK_F15, Key::F15 },
{ XK_F16, Key::F16 },
+ { XK_F17, Key::F17 },
+ { XK_F18, Key::F18 },
+ { XK_F19, Key::F19 },
+ { XK_F20, Key::F20 },
+ { XK_F21, Key::F21 },
+ { XK_F22, Key::F22 },
+ { XK_F23, Key::F23 },
+ { XK_F24, Key::F24 },
+ { XK_F25, Key::F25 },
+ { XK_F26, Key::F26 },
+ { XK_F27, Key::F27 },
+ { XK_F28, Key::F28 },
+ { XK_F29, Key::F29 },
+ { XK_F30, Key::F30 },
+ { XK_F31, Key::F31 },
+ { XK_F32, Key::F32 },
+ { XK_F33, Key::F33 },
+ { XK_F34, Key::F34 },
+ { XK_F35, Key::F35 },
// media keys
{ XF86XK_Back, Key::BACK },
@@ -294,6 +313,29 @@ static _TranslatePair _scancode_to_keycode[] = {
{ Key::SUPER_L, 0x85 },
{ Key::SUPER_R, 0x86 },
{ Key::MENU, 0x87 },
+ { Key::F13, 0xBF },
+ { Key::F14, 0xC0 },
+ { Key::F15, 0xC1 },
+ { Key::F16, 0xC2 },
+ { Key::F17, 0xC3 },
+ { Key::F18, 0xC4 },
+ { Key::F19, 0xC5 },
+ { Key::F20, 0xC6 },
+ { Key::F21, 0xC7 },
+ { Key::F22, 0xC8 },
+ { Key::F23, 0xC9 },
+ { Key::F24, 0xCA },
+ { Key::F25, 0xCB },
+ { Key::F26, 0xCC },
+ { Key::F27, 0xCD },
+ { Key::F28, 0xCE },
+ { Key::F29, 0xCF },
+ { Key::F30, 0xD0 },
+ { Key::F31, 0xD1 },
+ { Key::F32, 0xD2 },
+ { Key::F33, 0xD3 },
+ { Key::F34, 0xD4 },
+ { Key::F35, 0xD5 },
{ Key::UNKNOWN, 0 }
};
diff --git a/platform/osx/export/export_plugin.cpp b/platform/osx/export/export_plugin.cpp
index 9309b9f89b..7010709123 100644
--- a/platform/osx/export/export_plugin.cpp
+++ b/platform/osx/export/export_plugin.cpp
@@ -261,7 +261,8 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_
if (f.is_null()) {
// Clean up generated file.
DirAccess::remove_file_or_error(path);
- ERR_FAIL();
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Icon Creation"), vformat(TTR("Could not open icon file \"%s\"."), path));
+ return;
}
int ofs = data.size();
@@ -441,18 +442,25 @@ Error EditorExportPlatformOSX::_notarize(const Ref<EditorExportPreset> &p_preset
String str;
Error err = OS::get_singleton()->execute("xcrun", args, &str, nullptr, true);
- ERR_FAIL_COND_V(err != OK, err);
+ if (err != OK || (str.find("not found") != -1) || (str.find("not recognized") != -1)) {
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Notarization"), TTR("Could not start xcrun executable."));
+ return err;
+ }
print_verbose("altool (" + p_path + "):\n" + str);
- if (str.find("RequestUUID") == -1) {
- EditorNode::add_io_error("altool: " + str);
+ int rq_offset = str.find("RequestUUID");
+ if (rq_offset == -1) {
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Notarization"), TTR("Notarization failed."));
return FAILED;
} else {
- print_line(TTR("Note: The notarization process generally takes less than an hour. When the process is completed, you'll receive an email."));
- print_line(" " + TTR("You can check progress manually by opening a Terminal and running the following command:"));
- print_line(" \"xcrun altool --notarization-history 0 -u <your email> -p <app-specific pwd>\"");
- print_line(" " + TTR("Run the following command to staple the notarization ticket to the exported application (optional):"));
- print_line(" \"xcrun stapler staple <app path>\"");
+ int next_nl = str.find("\n", rq_offset);
+ String request_uuid = (next_nl == -1) ? str.substr(rq_offset + 14, -1) : str.substr(rq_offset + 14, next_nl - rq_offset - 14);
+ add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), vformat(TTR("Notarization request UUID: \"%s\""), request_uuid));
+ add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), TTR("The notarization process generally takes less than an hour. When the process is completed, you'll receive an email."));
+ add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t" + TTR("You can check progress manually by opening a Terminal and running the following command:"));
+ add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t\t\"xcrun altool --notarization-history 0 -u <your email> -p <app-specific pwd>\"");
+ add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t" + TTR("Run the following command to staple the notarization ticket to the exported application (optional):"));
+ add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t\t\"xcrun stapler staple <app path>\"");
}
#endif
@@ -470,21 +478,21 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
#ifdef OSX_ENABLED
if (p_preset->get("codesign/timestamp") && p_warn) {
- WARN_PRINT("Timestamping is not compatible with ad-hoc signature, and was disabled!");
+ add_message(EXPORT_MESSAGE_INFO, TTR("Code Signing"), TTR("Timestamping is not compatible with ad-hoc signature, and was disabled!"));
}
if (p_preset->get("codesign/hardened_runtime") && p_warn) {
- WARN_PRINT("Hardened Runtime is not compatible with ad-hoc signature, and was disabled!");
+ add_message(EXPORT_MESSAGE_INFO, TTR("Code Signing"), TTR("Hardened Runtime is not compatible with ad-hoc signature, and was disabled!"));
}
#endif
String error_msg;
Error err = CodeSign::codesign(false, p_preset->get("codesign/replace_existing_signature"), p_path, p_ent_path, error_msg);
if (err != OK) {
- EditorNode::add_io_error("Built-in CodeSign: " + error_msg);
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("Built-in CodeSign failed with error \"%s\"."), error_msg));
return FAILED;
}
#else
- ERR_FAIL_V_MSG(FAILED, "Built-in CodeSign require regex module");
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Built-in CodeSign require regex module."));
#endif
return OK;
} else {
@@ -493,7 +501,7 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
if (p_preset->get("codesign/timestamp")) {
if (ad_hoc) {
if (p_warn) {
- WARN_PRINT("Timestamping is not compatible with ad-hoc signature, and was disabled!");
+ add_message(EXPORT_MESSAGE_INFO, TTR("Code Signing"), TTR("Timestamping is not compatible with ad-hoc signature, and was disabled!"));
}
} else {
args.push_back("--timestamp");
@@ -502,7 +510,7 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
if (p_preset->get("codesign/hardened_runtime")) {
if (ad_hoc) {
if (p_warn) {
- WARN_PRINT("Hardened Runtime is not compatible with ad-hoc signature, and was disabled!");
+ add_message(EXPORT_MESSAGE_INFO, TTR("Code Signing"), TTR("Hardened Runtime is not compatible with ad-hoc signature, and was disabled!"));
}
} else {
args.push_back("--options");
@@ -540,15 +548,18 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
String str;
Error err = OS::get_singleton()->execute("codesign", args, &str, nullptr, true);
- ERR_FAIL_COND_V(err != OK, err);
+ if (err != OK || (str.find("not found") != -1) || (str.find("not recognized") != -1)) {
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Could not start codesign executable, make sure Xcode command line tools are installed."));
+ return err;
+ }
print_verbose("codesign (" + p_path + "):\n" + str);
if (str.find("no identity found") != -1) {
- EditorNode::add_io_error("CodeSign: " + TTR("No identity found."));
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("No identity found."));
return FAILED;
}
if ((str.find("unrecognized blob type") != -1) || (str.find("cannot read entitlement data") != -1)) {
- EditorNode::add_io_error("CodeSign: " + TTR("Invalid entitlements file."));
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Invalid entitlements file."));
return FAILED;
}
return OK;
@@ -593,7 +604,7 @@ Error EditorExportPlatformOSX::_code_sign_directory(const Ref<EditorExportPreset
return code_sign_error;
}
} else if (p_should_error_on_non_code) {
- ERR_PRINT(vformat("Cannot sign file %s.", current_file));
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("Cannot sign file %s."), current_file));
return Error::FAILED;
}
@@ -611,7 +622,7 @@ Error EditorExportPlatformOSX::_copy_and_sign_files(Ref<DirAccess> &dir_access,
Error err{ OK };
if (dir_access->dir_exists(p_src_path)) {
#ifndef UNIX_ENABLED
- WARN_PRINT("Relative symlinks are not supported, exported " + p_src_path.get_file() + " might be broken!");
+ add_message(EXPORT_MESSAGE_INFO, TTR("Export"), vformat(TTR("Relative symlinks are not supported, exported \"%s\" might be broken!"), p_src_path.get_file()));
#endif
print_verbose("export framework: " + p_src_path + " -> " + p_in_app_path);
err = dir_access->make_dir_recursive(p_in_app_path);
@@ -668,14 +679,17 @@ Error EditorExportPlatformOSX::_create_dmg(const String &p_dmg_path, const Strin
String str;
Error err = OS::get_singleton()->execute("hdiutil", args, &str, nullptr, true);
- ERR_FAIL_COND_V(err != OK, err);
+ if (err != OK) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("DMG Creation"), TTR("Could not start hdiutil executable."));
+ return err;
+ }
print_verbose("hdiutil returned: " + str);
if (str.find("create failed") != -1) {
if (str.find("File exists") != -1) {
- EditorNode::add_io_error("hdiutil: " + TTR("DMG creation failed, file already exists."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("DMG Creation"), TTR("`hdiutil create` failed - file exists."));
} else {
- EditorNode::add_io_error("hdiutil: " + TTR("DMG create failed."));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("DMG Creation"), TTR("`hdiutil create` failed."));
}
return FAILED;
}
@@ -685,7 +699,10 @@ Error EditorExportPlatformOSX::_create_dmg(const String &p_dmg_path, const Strin
Error EditorExportPlatformOSX::_export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path) {
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE);
- ERR_FAIL_COND_V(f.is_null(), ERR_CANT_CREATE);
+ if (f.is_null()) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Debug Script Export"), vformat(TTR("Could not open file \"%s\"."), p_path));
+ return ERR_CANT_CREATE;
+ }
f->store_line("#!/bin/sh");
f->store_line("echo -ne '\\033c\\033]0;" + p_app_name + "\\a'");
@@ -713,12 +730,13 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
String err;
src_pkg_name = find_export_template("osx.zip", &err);
if (src_pkg_name.is_empty()) {
- EditorNode::add_io_error(err);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), TTR("Export template not found."));
return ERR_FILE_NOT_FOUND;
}
}
if (!DirAccess::exists(p_path.get_base_dir())) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), TTR("The given export path doesn't exist."));
return ERR_FILE_BAD_PATH;
}
@@ -731,7 +749,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
unzFile src_pkg_zip = unzOpen2(src_pkg_name.utf8().get_data(), &io);
if (!src_pkg_zip) {
- EditorNode::add_io_error(TTR("Could not find template app to export:") + "\n" + src_pkg_name);
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Templates"), vformat(TTR("Could not find template app to export: \"%s\"."), src_pkg_name));
return ERR_FILE_NOT_FOUND;
}
@@ -756,7 +774,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
} else if (p_path.ends_with("app")) {
export_format = "app";
} else {
- EditorNode::add_io_error("Invalid export format");
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Invalid export format."));
return ERR_CANT_CREATE;
}
@@ -781,13 +799,16 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
Ref<DirAccess> tmp_app_dir = DirAccess::create_for_path(tmp_base_path_name);
if (tmp_app_dir.is_null()) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not create directory: \"%s\"."), tmp_base_path_name));
err = ERR_CANT_CREATE;
}
DirAccess::remove_file_or_error(scr_path);
if (DirAccess::exists(tmp_app_path_name)) {
+ String old_dir = tmp_app_dir->get_current_dir();
if (tmp_app_dir->change_dir(tmp_app_path_name) == OK) {
tmp_app_dir->erase_contents_recursive();
+ tmp_app_dir->change_dir(old_dir);
}
}
@@ -797,21 +818,33 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
if (err == OK) {
print_verbose("Creating " + tmp_app_path_name + "/Contents/MacOS");
err = tmp_app_dir->make_dir_recursive(tmp_app_path_name + "/Contents/MacOS");
+ if (err != OK) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not create directory \"%s\"."), tmp_app_path_name + "/Contents/MacOS"));
+ }
}
if (err == OK) {
print_verbose("Creating " + tmp_app_path_name + "/Contents/Frameworks");
err = tmp_app_dir->make_dir_recursive(tmp_app_path_name + "/Contents/Frameworks");
+ if (err != OK) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not create directory \"%s\"."), tmp_app_path_name + "/Contents/Frameworks"));
+ }
}
if ((err == OK) && helpers.size() > 0) {
print_line("Creating " + tmp_app_path_name + "/Contents/Helpers");
err = tmp_app_dir->make_dir_recursive(tmp_app_path_name + "/Contents/Helpers");
+ if (err != OK) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not create directory \"%s\"."), tmp_app_path_name + "/Contents/Helpers"));
+ }
}
if (err == OK) {
print_verbose("Creating " + tmp_app_path_name + "/Contents/Resources");
err = tmp_app_dir->make_dir_recursive(tmp_app_path_name + "/Contents/Resources");
+ if (err != OK) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not create directory \"%s\"."), tmp_app_path_name + "/Contents/Resources"));
+ }
}
Dictionary appnames = ProjectSettings::get_singleton()->get("application/config/name_localized");
@@ -955,16 +988,22 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
if (((info.external_fa >> 16L) & 0120000) == 0120000) {
#ifndef UNIX_ENABLED
- WARN_PRINT(vformat("Relative symlinks are not supported on this OS, the exported project might be broken!"));
+ add_message(EXPORT_MESSAGE_INFO, TTR("Export"), TTR("Relative symlinks are not supported on this OS, the exported project might be broken!"));
#endif
// Handle symlinks in the archive.
file = tmp_app_path_name.plus_file(file);
if (err == OK) {
err = tmp_app_dir->make_dir_recursive(file.get_base_dir());
+ if (err != OK) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not create directory \"%s\"."), file.get_base_dir()));
+ }
}
if (err == OK) {
String lnk_data = String::utf8((const char *)data.ptr(), data.size());
err = tmp_app_dir->create_link(lnk_data, file);
+ if (err != OK) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not created symlink \"%s\" -> \"%s\"."), lnk_data, file));
+ }
print_verbose(vformat("ADDING SYMLINK %s => %s\n", file, lnk_data));
}
@@ -1039,6 +1078,9 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
file = tmp_app_path_name.plus_file(file);
if (err == OK) {
err = tmp_app_dir->make_dir_recursive(file.get_base_dir());
+ if (err != OK) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not create directory \"%s\"."), file.get_base_dir()));
+ }
}
if (err == OK) {
Ref<FileAccess> f = FileAccess::open(file, FileAccess::WRITE);
@@ -1049,6 +1091,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
FileAccess::set_unix_permissions(file, 0755);
}
} else {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Could not open \"%s\"."), file));
err = ERR_CANT_CREATE;
}
}
@@ -1061,7 +1104,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
unzClose(src_pkg_zip);
if (!found_binary) {
- ERR_PRINT(vformat("Requested template binary '%s' not found. It might be missing from your template archive.", binary_to_use));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Requested template binary \"%s\" not found. It might be missing from your template archive."), binary_to_use));
err = ERR_FILE_NOT_FOUND;
}
@@ -1071,6 +1114,9 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
if ((con_scr == 1 && p_debug) || (con_scr == 2)) {
err = _export_debug_script(p_preset, pkg_name, tmp_app_path_name.get_file() + "/Contents/MacOS/" + pkg_name, scr_path);
FileAccess::set_unix_permissions(scr_path, 0755);
+ if (err != OK) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Could not create console script."));
+ }
}
}
@@ -1214,6 +1260,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
ent_f->store_line("</dict>");
ent_f->store_line("</plist>");
} else {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Code Signing"), TTR("Could not create entitlements file."));
err = ERR_CANT_CREATE;
}
@@ -1231,6 +1278,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
ent_f->store_line("</dict>");
ent_f->store_line("</plist>");
} else {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Code Signing"), TTR("Could not create helper entitlements file."));
err = ERR_CANT_CREATE;
}
}
@@ -1258,7 +1306,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
ad_hoc = (sign_identity == "" || sign_identity == "-");
bool lib_validation = p_preset->get("codesign/entitlements/disable_library_validation");
if ((!dylibs_found.is_empty() || !shared_objects.is_empty()) && sign_enabled && ad_hoc && !lib_validation) {
- ERR_PRINT("Ad-hoc signed applications require the 'Disable Library Validation' entitlement to load dynamic libraries.");
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Code Signing"), TTR("Ad-hoc signed applications require the 'Disable Library Validation' entitlement to load dynamic libraries."));
err = ERR_CANT_CREATE;
}
}
@@ -1342,7 +1390,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
bool noto_enabled = p_preset->get("notarization/enable");
if (err == OK && noto_enabled) {
if (export_format == "app") {
- WARN_PRINT("Notarization requires the app to be archived first, select the DMG or ZIP export format instead.");
+ add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), TTR("Notarization requires the app to be archived first, select the DMG or ZIP export format instead."));
} else {
if (ep.step(TTR("Sending archive for notarization"), 4)) {
return ERR_SKIP;
@@ -1467,7 +1515,8 @@ void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String
Ref<FileAccess> fa = FileAccess::open(dir.plus_file(f), FileAccess::READ);
if (fa.is_null()) {
- ERR_FAIL_MSG(vformat("Can't open file to read from path \"%s\".", dir.plus_file(f)));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("ZIP Creation"), vformat(TTR("Could not open file to read from path \"%s\"."), dir.plus_file(f)));
+ return;
}
const int bufsize = 16384;
uint8_t buf[bufsize];
diff --git a/platform/osx/key_mapping_osx.mm b/platform/osx/key_mapping_osx.mm
index bfec45de58..0bf6bc7d1c 100644
--- a/platform/osx/key_mapping_osx.mm
+++ b/platform/osx/key_mapping_osx.mm
@@ -130,7 +130,7 @@ static const Key _osx_to_godot_table[128] = {
/* 3d */ Key::ALT,
/* 3e */ Key::CTRL,
/* 3f */ Key::UNKNOWN, /* Function */
- /* 40 */ Key::UNKNOWN, /* F17 */
+ /* 40 */ Key::F17,
/* 41 */ Key::KP_PERIOD,
/* 42 */ Key::UNKNOWN,
/* 43 */ Key::KP_MULTIPLY,
@@ -145,8 +145,8 @@ static const Key _osx_to_godot_table[128] = {
/* 4c */ Key::KP_ENTER,
/* 4d */ Key::UNKNOWN,
/* 4e */ Key::KP_SUBTRACT,
- /* 4f */ Key::UNKNOWN, /* F18 */
- /* 50 */ Key::UNKNOWN, /* F19 */
+ /* 4f */ Key::F18,
+ /* 50 */ Key::F19,
/* 51 */ Key::EQUAL, /* KeypadEqual */
/* 52 */ Key::KP_0,
/* 53 */ Key::KP_1,
@@ -156,7 +156,7 @@ static const Key _osx_to_godot_table[128] = {
/* 57 */ Key::KP_5,
/* 58 */ Key::KP_6,
/* 59 */ Key::KP_7,
- /* 5a */ Key::UNKNOWN, /* F20 */
+ /* 5a */ Key::F20,
/* 5b */ Key::KP_8,
/* 5c */ Key::KP_9,
/* 5d */ Key::YEN, /* JIS Yen */
@@ -366,7 +366,26 @@ static const _KeyCodeText _native_keycodes[] = {
{Key::F13 ,NSF13FunctionKey},
{Key::F14 ,NSF14FunctionKey},
{Key::F15 ,NSF15FunctionKey},
- {Key::F16 ,NSF16FunctionKey}, //* ... NSF35FunctionKey */
+ {Key::F16 ,NSF16FunctionKey},
+ {Key::F17 ,NSF17FunctionKey},
+ {Key::F18 ,NSF18FunctionKey},
+ {Key::F19 ,NSF19FunctionKey},
+ {Key::F20 ,NSF20FunctionKey},
+ {Key::F21 ,NSF21FunctionKey},
+ {Key::F22 ,NSF22FunctionKey},
+ {Key::F23 ,NSF23FunctionKey},
+ {Key::F24 ,NSF24FunctionKey},
+ {Key::F25 ,NSF25FunctionKey},
+ {Key::F26 ,NSF26FunctionKey},
+ {Key::F27 ,NSF27FunctionKey},
+ {Key::F28 ,NSF28FunctionKey},
+ {Key::F29 ,NSF29FunctionKey},
+ {Key::F30 ,NSF30FunctionKey},
+ {Key::F31 ,NSF31FunctionKey},
+ {Key::F32 ,NSF32FunctionKey},
+ {Key::F33 ,NSF33FunctionKey},
+ {Key::F34 ,NSF34FunctionKey},
+ {Key::F35 ,NSF35FunctionKey},
{Key::MENU ,NSMenuFunctionKey},
{Key::HELP ,NSHelpFunctionKey},
{Key::STOP ,NSStopFunctionKey},
diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp
index 45281f037c..16c67345e0 100644
--- a/platform/windows/export/export_plugin.cpp
+++ b/platform/windows/export/export_plugin.cpp
@@ -43,7 +43,10 @@ Error EditorExportPlatformWindows::sign_shared_object(const Ref<EditorExportPres
Error EditorExportPlatformWindows::_export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path) {
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE);
- ERR_FAIL_COND_V(f.is_null(), ERR_CANT_CREATE);
+ if (f.is_null()) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Debug Script Export"), vformat(TTR("Could not open file \"%s\"."), p_path));
+ return ERR_CANT_CREATE;
+ }
f->store_line("@echo off");
f->store_line("title \"" + p_app_name + "\"");
@@ -55,10 +58,9 @@ Error EditorExportPlatformWindows::_export_debug_script(const Ref<EditorExportPr
Error EditorExportPlatformWindows::modify_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
if (p_preset->get("application/modify_resources")) {
- return _rcedit_add_data(p_preset, p_path);
- } else {
- return OK;
+ _rcedit_add_data(p_preset, p_path);
}
+ return OK;
}
Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
@@ -68,12 +70,15 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset>
}
Error err = EditorExportPlatformPC::export_project(p_preset, p_debug, pck_path, p_flags);
if (p_preset->get("codesign/enable") && err == OK) {
- err = _code_sign(p_preset, pck_path);
+ _code_sign(p_preset, pck_path);
}
if (p_preset->get("binary_format/embed_pck") && err == OK) {
Ref<DirAccess> tmp_dir = DirAccess::create_for_path(p_path.get_base_dir());
err = tmp_dir->rename(pck_path, p_path);
+ if (err != OK) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), vformat(TTR("Failed to rename temporary file \"%s\"."), pck_path));
+ }
}
String app_name;
@@ -89,7 +94,9 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset>
int con_scr = p_preset->get("debug/export_console_script");
if ((con_scr == 1 && p_debug) || (con_scr == 2)) {
String scr_path = p_path.get_basename() + ".cmd";
- err = _export_debug_script(p_preset, app_name, p_path.get_file(), scr_path);
+ if (_export_debug_script(p_preset, app_name, p_path.get_file(), scr_path) != OK) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Debug Script Export"), TTR("Could not create console script."));
+ }
}
}
@@ -142,7 +149,7 @@ Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset
String rcedit_path = EditorSettings::get_singleton()->get("export/windows/rcedit");
if (rcedit_path != String() && !FileAccess::exists(rcedit_path)) {
- ERR_PRINT("Could not find rcedit executable at " + rcedit_path + ", aborting.");
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), vformat(TTR("Could not find rcedit executable at \"%s\"."), rcedit_path));
return ERR_FILE_NOT_FOUND;
}
@@ -155,7 +162,7 @@ Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset
String wine_path = EditorSettings::get_singleton()->get("export/windows/wine");
if (!wine_path.is_empty() && !FileAccess::exists(wine_path)) {
- ERR_PRINT("Could not find wine executable at " + wine_path + ", aborting.");
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), vformat(TTR("Could not find wine executable at \"%s\"."), wine_path));
return ERR_FILE_NOT_FOUND;
}
@@ -222,10 +229,14 @@ Error EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset
String str;
Error err = OS::get_singleton()->execute(rcedit_path, args, &str, nullptr, true);
- ERR_FAIL_COND_V_MSG(err != OK, err, "Could not start rcedit executable, configure rcedit path in the Editor Settings (Export > Windows > Rcedit).");
+ if (err != OK || (str.find("not found") != -1) || (str.find("not recognized") != -1)) {
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), TTR("Could not start rcedit executable, configure rcedit path in the Editor Settings (Export > Windows > Rcedit)."));
+ return err;
+ }
print_line("rcedit (" + p_path + "): " + str);
if (str.find("Fatal error") != -1) {
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Resources Modification"), vformat(TTR("rcedit failed to modify executable:\n%s"), str));
return FAILED;
}
@@ -238,7 +249,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
#ifdef WINDOWS_ENABLED
String signtool_path = EditorSettings::get_singleton()->get("export/windows/signtool");
if (!signtool_path.is_empty() && !FileAccess::exists(signtool_path)) {
- ERR_PRINT("Could not find signtool executable at " + signtool_path + ", aborting.");
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("Could not find signtool executable at \"%s\"."), signtool_path));
return ERR_FILE_NOT_FOUND;
}
if (signtool_path.is_empty()) {
@@ -247,7 +258,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
#else
String signtool_path = EditorSettings::get_singleton()->get("export/windows/osslsigncode");
if (!signtool_path.is_empty() && !FileAccess::exists(signtool_path)) {
- ERR_PRINT("Could not find osslsigncode executable at " + signtool_path + ", aborting.");
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("Could not find osslsigncode executable at \"%s\"."), signtool_path));
return ERR_FILE_NOT_FOUND;
}
if (signtool_path.is_empty()) {
@@ -267,7 +278,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
args.push_back("/f");
args.push_back(p_preset->get("codesign/identity"));
} else {
- EditorNode::add_io_error("codesign: no identity found");
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("No identity found."));
return FAILED;
}
} else if (id_type == 2) { //Windows certificate store
@@ -275,11 +286,11 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
args.push_back("/sha1");
args.push_back(p_preset->get("codesign/identity"));
} else {
- EditorNode::add_io_error("codesign: no identity found");
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("No identity found."));
return FAILED;
}
} else {
- EditorNode::add_io_error("codesign: invalid identity type");
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Invalid identity type."));
return FAILED;
}
#else
@@ -287,7 +298,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
args.push_back("-pkcs12");
args.push_back(p_preset->get("codesign/identity"));
} else {
- EditorNode::add_io_error("codesign: no identity found");
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("No identity found."));
return FAILED;
}
#endif
@@ -319,7 +330,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
args.push_back(p_preset->get("codesign/timestamp_server_url"));
#endif
} else {
- EditorNode::add_io_error("codesign: invalid timestamp server");
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Invalid timestamp server."));
return FAILED;
}
}
@@ -366,7 +377,10 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
String str;
Error err = OS::get_singleton()->execute(signtool_path, args, &str, nullptr, true);
- ERR_FAIL_COND_V_MSG(err != OK, err, "Could not start signtool executable, configure signtool path in the Editor Settings (Export > Windows > Signtool).");
+ if (err != OK || (str.find("not found") != -1) || (str.find("not recognized") != -1)) {
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), TTR("Could not start signtool executable, configure signtool path in the Editor Settings (Export > Windows > Signtool)."));
+ return err;
+ }
print_line("codesign (" + p_path + "): " + str);
#ifndef WINDOWS_ENABLED
@@ -374,6 +388,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
#else
if (str.find("Failed") != -1) {
#endif
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("Signtool failed to sign executable:\n%s"), str));
return FAILED;
}
@@ -381,10 +396,16 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
Ref<DirAccess> tmp_dir = DirAccess::create_for_path(p_path.get_base_dir());
err = tmp_dir->remove(p_path);
- ERR_FAIL_COND_V(err != OK, err);
+ if (err != OK) {
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("Failed to remove temporary file \"%s\"."), p_path));
+ return err;
+ }
err = tmp_dir->rename(p_path + "_signed", p_path);
- ERR_FAIL_COND_V(err != OK, err);
+ if (err != OK) {
+ add_message(EXPORT_MESSAGE_WARNING, TTR("Code Signing"), vformat(TTR("Failed to rename temporary file \"%s\"."), p_path + "_signed"));
+ return err;
+ }
#endif
return OK;
@@ -433,15 +454,17 @@ bool EditorExportPlatformWindows::can_export(const Ref<EditorExportPreset> &p_pr
return valid;
}
-Error EditorExportPlatformWindows::fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) const {
+Error EditorExportPlatformWindows::fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) {
// Patch the header of the "pck" section in the PE file so that it corresponds to the embedded data
if (p_embedded_size + p_embedded_start >= 0x100000000) { // Check for total executable size
- ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Windows executables cannot be >= 4 GiB.");
+ add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("Windows executables cannot be >= 4 GiB."));
+ return ERR_INVALID_DATA;
}
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ_WRITE);
if (f.is_null()) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), vformat(TTR("Failed to open executable file \"%s\"."), p_path));
return ERR_CANT_OPEN;
}
@@ -453,6 +476,7 @@ Error EditorExportPlatformWindows::fixup_embedded_pck(const String &p_path, int6
f->seek(pe_pos);
uint32_t magic = f->get_32();
if (magic != 0x00004550) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("Executable file header corrupted."));
return ERR_FILE_CORRUPT;
}
}
@@ -502,5 +526,9 @@ Error EditorExportPlatformWindows::fixup_embedded_pck(const String &p_path, int6
}
}
- return found ? OK : ERR_FILE_CORRUPT;
+ if (!found) {
+ add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("Executable \"pck\" section not found."));
+ return ERR_FILE_CORRUPT;
+ }
+ return OK;
}
diff --git a/platform/windows/export/export_plugin.h b/platform/windows/export/export_plugin.h
index 61184a8987..51f98365a9 100644
--- a/platform/windows/export/export_plugin.h
+++ b/platform/windows/export/export_plugin.h
@@ -51,7 +51,7 @@ public:
virtual bool get_export_option_visibility(const String &p_option, const HashMap<StringName, Variant> &p_options) const override;
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const override;
virtual String get_template_file_name(const String &p_target, const String &p_arch) const override;
- virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) const override;
+ virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) override;
};
#endif
diff --git a/platform/windows/key_mapping_windows.cpp b/platform/windows/key_mapping_windows.cpp
index e32dc0d1a6..2d8d68a575 100644
--- a/platform/windows/key_mapping_windows.cpp
+++ b/platform/windows/key_mapping_windows.cpp
@@ -179,7 +179,14 @@ static _WinTranslatePair _vk_to_keycode[] = {
{ Key::F14, VK_F14 }, // (0x7D)
{ Key::F15, VK_F15 }, // (0x7E)
{ Key::F16, VK_F16 }, // (0x7F)
- // We have no mappings for F17-F24. (0x80-87)
+ { Key::F17, VK_F17 }, // (0x80)
+ { Key::F18, VK_F18 }, // (0x81)
+ { Key::F19, VK_F19 }, // (0x82)
+ { Key::F20, VK_F20 }, // (0x83)
+ { Key::F21, VK_F21 }, // (0x84)
+ { Key::F22, VK_F22 }, // (0x85)
+ { Key::F23, VK_F23 }, // (0x86)
+ { Key::F24, VK_F24 }, // (0x87)
// 0x88-8F are reserved for UI navigation.
{ Key::NUMLOCK, VK_NUMLOCK }, // (0x90)
{ Key::SCROLLLOCK, VK_SCROLL }, // (0x91)
@@ -409,6 +416,14 @@ static _WinTranslatePair _scancode_to_keycode[] = {
{ Key::F14, 0x65 },
{ Key::F15, 0x66 },
{ Key::F16, 0x67 },
+ { Key::F17, 0x68 },
+ { Key::F18, 0x69 },
+ { Key::F19, 0x6A },
+ { Key::F20, 0x6B },
+ { Key::F21, 0x6C },
+ { Key::F22, 0x6D },
+ { Key::F23, 0x6E },
+ { Key::F24, 0x76 },
{ Key::UNKNOWN, 0 }
};