summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/TextEdit.xml2
-rw-r--r--doc/classes/Vector2.xml2
-rw-r--r--editor/animation_bezier_editor.cpp1
-rw-r--r--editor/editor_properties.cpp38
-rw-r--r--editor/import/resource_importer_scene.cpp9
-rw-r--r--main/main.cpp10
-rw-r--r--misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj32
-rw-r--r--misc/dist/ios_xcode/godot_ios/godot_ios-Info.plist2
-rw-r--r--modules/gdnative/gdnative.cpp20
-rw-r--r--modules/gdnative/gdnative_library_editor_plugin.cpp16
-rw-r--r--modules/gdnative/register_types.cpp108
-rw-r--r--platform/iphone/export/export.cpp112
-rw-r--r--platform/osx/display_server_osx.h8
-rw-r--r--platform/osx/display_server_osx.mm60
-rw-r--r--platform/windows/display_server_windows.cpp21
-rw-r--r--scene/animation/animation_player.cpp2
-rw-r--r--scene/gui/base_button.cpp5
-rw-r--r--scene/gui/control.cpp10
-rw-r--r--scene/gui/graph_node.cpp4
-rw-r--r--scene/gui/rich_text_label.cpp2
-rw-r--r--scene/main/viewport.cpp6
-rw-r--r--scene/main/window.cpp20
-rw-r--r--scene/main/window.h4
-rw-r--r--scene/resources/animation.cpp5
-rw-r--r--servers/physics_2d/body_pair_2d_sw.cpp6
-rw-r--r--thirdparty/README.md2
-rw-r--r--thirdparty/wslay/includes/wslay/wslayver.h2
-rw-r--r--thirdparty/wslay/wslay_event.c12
28 files changed, 417 insertions, 104 deletions
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index 0c6615c53b..d72d684ebc 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -48,6 +48,7 @@
<return type="void">
</return>
<description>
+ Centers the viewport on the line the editing cursor is at. This also resets the [member scroll_horizontal] value to [code]0[/code].
</description>
</method>
<method name="clear_colors">
@@ -458,6 +459,7 @@
<member name="selecting_enabled" type="bool" setter="set_selecting_enabled" getter="is_selecting_enabled" default="true">
</member>
<member name="shortcut_keys_enabled" type="bool" setter="set_shortcut_keys_enabled" getter="is_shortcut_keys_enabled" default="true">
+ If [code]true[/code], shortcut keys for context menu items are enabled, even if the context menu is disabled.
</member>
<member name="show_line_numbers" type="bool" setter="set_show_line_numbers" getter="is_show_line_numbers_enabled" default="false">
If [code]true[/code], line numbers are displayed to the left of the text.
diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml
index 7f4a212679..32895310d1 100644
--- a/doc/classes/Vector2.xml
+++ b/doc/classes/Vector2.xml
@@ -44,7 +44,7 @@
</return>
<description>
Returns the vector's angle in radians with respect to the X axis, or [code](1, 0)[/code] vector.
- Equivalent to the result of [method @GDScript.atan2] when called with the vector's [member x] and [member y] as parameters: [code]atan2(x, y)[/code].
+ Equivalent to the result of [method @GDScript.atan2] when called with the vector's [member y] and [member x] as parameters: [code]atan2(y, x)[/code].
</description>
</method>
<method name="angle_to">
diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp
index e52f234218..17b03fd479 100644
--- a/editor/animation_bezier_editor.cpp
+++ b/editor/animation_bezier_editor.cpp
@@ -559,6 +559,7 @@ void AnimationBezierTrackEdit::set_root(Node *p_root) {
void AnimationBezierTrackEdit::_zoom_changed() {
update();
+ play_position->update();
}
String AnimationBezierTrackEdit::get_tooltip(const Point2 &p_pos) const {
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 23db6ebb4e..8f9c92ea15 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -2983,8 +2983,16 @@ bool EditorPropertyResource::_is_drop_valid(const Dictionary &p_drag_data) const
String allowed_type = base_type;
Dictionary drag_data = p_drag_data;
- if (drag_data.has("type") && String(drag_data["type"]) == "resource") {
- Ref<Resource> res = drag_data["resource"];
+
+ Ref<Resource> res;
+ if (drag_data.has("type") && String(drag_data["type"]) == "script_list_element") {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(drag_data["script_list_element"]);
+ res = se->get_edited_resource();
+ } else if (drag_data.has("type") && String(drag_data["type"]) == "resource") {
+ res = drag_data["resource"];
+ }
+
+ if (res.is_valid()) {
for (int i = 0; i < allowed_type.get_slice_count(","); i++) {
String at = allowed_type.get_slice(",", i).strip_edges();
if (res.is_valid() && ClassDB::is_parent_class(res->get_class(), at)) {
@@ -3022,13 +3030,19 @@ void EditorPropertyResource::drop_data_fw(const Point2 &p_point, const Variant &
ERR_FAIL_COND(!_is_drop_valid(p_data));
Dictionary drag_data = p_data;
- if (drag_data.has("type") && String(drag_data["type"]) == "resource") {
- Ref<Resource> res = drag_data["resource"];
- if (res.is_valid()) {
- emit_changed(get_edited_property(), res);
- update_property();
- return;
- }
+
+ Ref<Resource> res;
+ if (drag_data.has("type") && String(drag_data["type"]) == "script_list_element") {
+ ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(drag_data["script_list_element"]);
+ res = se->get_edited_resource();
+ } else if (drag_data.has("type") && String(drag_data["type"]) == "resource") {
+ res = drag_data["resource"];
+ }
+
+ if (res.is_valid()) {
+ emit_changed(get_edited_property(), res);
+ update_property();
+ return;
}
if (drag_data.has("type") && String(drag_data["type"]) == "files") {
@@ -3036,9 +3050,9 @@ void EditorPropertyResource::drop_data_fw(const Point2 &p_point, const Variant &
if (files.size() == 1) {
String file = files[0];
- RES res = ResourceLoader::load(file);
- if (res.is_valid()) {
- emit_changed(get_edited_property(), res);
+ RES file_res = ResourceLoader::load(file);
+ if (file_res.is_valid()) {
+ emit_changed(get_edited_property(), file_res);
update_property();
return;
}
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 65ebf9dc4f..5dcdf6bec4 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -943,9 +943,9 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
ERR_CONTINUE(anim.is_null());
if (!p_animations.has(anim)) {
- // We are making external files so they are modifiable
+ // Tracks from source file should be set as imported, anything else is a custom track.
for (int i = 0; i < anim->get_track_count(); i++) {
- anim->track_set_imported(i, false);
+ anim->track_set_imported(i, true);
}
String ext_name;
@@ -957,10 +957,9 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
}
if (FileAccess::exists(ext_name) && p_keep_animations) {
- //try to keep custom animation tracks
+ // Copy custom animation tracks from previously imported files.
Ref<Animation> old_anim = ResourceLoader::load(ext_name, "Animation", true);
if (old_anim.is_valid()) {
- //meergeee
for (int i = 0; i < old_anim->get_track_count(); i++) {
if (!old_anim->track_is_imported(i)) {
old_anim->copy_track(i, anim);
@@ -970,7 +969,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
}
}
- anim->set_path(ext_name, true); //if not set, then its never saved externally
+ anim->set_path(ext_name, true); // Set path to save externally.
ResourceSaver::save(ext_name, anim, ResourceSaver::FLAG_CHANGE_PATH);
p_animations[anim] = anim;
}
diff --git a/main/main.cpp b/main/main.cpp
index 76175780a3..96b71c1663 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1895,10 +1895,10 @@ bool Main::start() {
Size2i stretch_size = Size2(GLOBAL_DEF("display/window/size/width", 0), GLOBAL_DEF("display/window/size/height", 0));
Window::ContentScaleMode cs_sm = Window::CONTENT_SCALE_MODE_DISABLED;
- if (stretch_mode == "objects") {
- cs_sm = Window::CONTENT_SCALE_MODE_OBJECTS;
- } else if (stretch_mode == "pixels") {
- cs_sm = Window::CONTENT_SCALE_MODE_PIXELS;
+ if (stretch_mode == "canvas_items") {
+ cs_sm = Window::CONTENT_SCALE_MODE_CANVAS_ITEMS;
+ } else if (stretch_mode == "viewport") {
+ cs_sm = Window::CONTENT_SCALE_MODE_VIEWPORT;
}
Window::ContentScaleAspect cs_aspect = Window::CONTENT_SCALE_ASPECT_IGNORE;
@@ -1954,7 +1954,7 @@ bool Main::start() {
} else {
GLOBAL_DEF("display/window/stretch/mode", "disabled");
- ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/mode", PropertyInfo(Variant::STRING, "display/window/stretch/mode", PROPERTY_HINT_ENUM, "disabled,2d,viewport"));
+ ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/mode", PropertyInfo(Variant::STRING, "display/window/stretch/mode", PROPERTY_HINT_ENUM, "disabled,canvas_items,viewport"));
GLOBAL_DEF("display/window/stretch/aspect", "ignore");
ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/aspect", PropertyInfo(Variant::STRING, "display/window/stretch/aspect", PROPERTY_HINT_ENUM, "ignore,keep,keep_width,keep_height,expand"));
GLOBAL_DEF("display/window/stretch/shrink", 1.0);
diff --git a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj
index 2ae3564faf..8c92ae2a7c 100644
--- a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj
+++ b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj
@@ -16,6 +16,20 @@
D0BCFE7818AEBFEB004A7AAE /* $binary.pck in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE7718AEBFEB004A7AAE /* $binary.pck */; };
/* End PBXBuildFile section */
+/* Begin PBXCopyFilesBuildPhase section */
+ 90A13CD024AA68E500E8464F /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ $pbx_embeded_frameworks
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
/* Begin PBXFileReference section */
1F1575711F582BE20003B888 /* dylibs */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dylibs; path = "$binary/dylibs"; sourceTree = "<group>"; };
DEADBEEF1F582BE20003B888 /* $binary.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = godot; path = "$binary.a"; sourceTree = "<group>"; };
@@ -105,6 +119,7 @@
D0BCFE3018AEBDA2004A7AAE /* Sources */,
D0BCFE3118AEBDA2004A7AAE /* Frameworks */,
D0BCFE3218AEBDA2004A7AAE /* Resources */,
+ 90A13CD024AA68E500E8464F /* Embed Frameworks */,
);
buildRules = (
);
@@ -230,7 +245,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 1F1575721F582BE20003B888 /* dylibs in Resources */,
D07CD44E1C5D589C00B7FB28 /* Images.xcassets in Resources */,
D0BCFE7818AEBFEB004A7AAE /* $binary.pck in Resources */,
D0BCFE4618AEBDA2004A7AAE /* InfoPlist.strings in Resources */,
@@ -284,7 +298,9 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "$code_sign_identity_debug";
COPY_PHASE_STRIP = NO;
ENABLE_BITCODE = NO;
- "FRAMEWORK_SEARCH_PATHS[arch=*]" = "$binary/**";
+ "FRAMEWORK_SEARCH_PATHS[arch=*]" = (
+ "$(PROJECT_DIR)/**",
+ );
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
@@ -327,7 +343,9 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "$code_sign_identity_release";
COPY_PHASE_STRIP = YES;
ENABLE_BITCODE = NO;
- "FRAMEWORK_SEARCH_PATHS[arch=*]" = "$binary/**";
+ "FRAMEWORK_SEARCH_PATHS[arch=*]" = (
+ "$(PROJECT_DIR)/**",
+ );
ENABLE_NS_ASSERTIONS = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -357,6 +375,10 @@
DEVELOPMENT_TEAM = $team_id;
INFOPLIST_FILE = "$binary/$binary-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)",
@@ -383,6 +405,10 @@
DEVELOPMENT_TEAM = $team_id;
INFOPLIST_FILE = "$binary/$binary-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)",
diff --git a/misc/dist/ios_xcode/godot_ios/godot_ios-Info.plist b/misc/dist/ios_xcode/godot_ios/godot_ios-Info.plist
index add2f6c084..e0cad2e7d1 100644
--- a/misc/dist/ios_xcode/godot_ios/godot_ios-Info.plist
+++ b/misc/dist/ios_xcode/godot_ios/godot_ios-Info.plist
@@ -26,6 +26,8 @@
<string>$signature</string>
<key>CFBundleVersion</key>
<string>$version</string>
+ <key>ITSAppUsesNonExemptEncryption</key>
+ <false />
<key>LSRequiresIPhoneOS</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index 3d747ba41e..bb2da70c3a 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -291,8 +291,26 @@ bool GDNative::initialize() {
return false;
}
#ifdef IPHONE_ENABLED
- // on iOS we use static linking
+ // On iOS we use static linking by default.
String path = "";
+
+ // On iOS dylibs is not allowed, but can be replaced with .framework or .xcframework.
+ // If they are used, we can run dlopen on them.
+ // They should be located under Frameworks directory, so we need to replace library path.
+ if (!lib_path.ends_with(".a")) {
+ path = ProjectSettings::get_singleton()->globalize_path(lib_path);
+
+ if (!FileAccess::exists(path)) {
+ String lib_name = lib_path.get_basename().get_file();
+ String framework_path_format = "Frameworks/$name.framework/$name";
+
+ Dictionary format_dict;
+ format_dict["name"] = lib_name;
+ String framework_path = framework_path_format.format(format_dict, "$_");
+
+ path = OS::get_singleton()->get_executable_path().get_base_dir().plus_file(framework_path);
+ }
+ }
#elif defined(ANDROID_ENABLED)
// On Android dynamic libraries are located separately from resource assets,
// we should pass library name to dlopen(). The library name is flattened
diff --git a/modules/gdnative/gdnative_library_editor_plugin.cpp b/modules/gdnative/gdnative_library_editor_plugin.cpp
index 5896da4640..1d4d188f23 100644
--- a/modules/gdnative/gdnative_library_editor_plugin.cpp
+++ b/modules/gdnative/gdnative_library_editor_plugin.cpp
@@ -127,15 +127,24 @@ void GDNativeLibraryEditor::_on_item_button(Object *item, int column, int id) {
String section = (id == BUTTON_SELECT_DEPENDENCES || id == BUTTON_CLEAR_DEPENDENCES) ? "dependencies" : "entry";
if (id == BUTTON_SELECT_LIBRARY || id == BUTTON_SELECT_DEPENDENCES) {
+ TreeItem *treeItem = Object::cast_to<TreeItem>(item)->get_parent();
EditorFileDialog::FileMode mode = EditorFileDialog::FILE_MODE_OPEN_FILE;
if (id == BUTTON_SELECT_DEPENDENCES) {
mode = EditorFileDialog::FILE_MODE_OPEN_FILES;
+ } else if (treeItem->get_text(0) == "iOS") {
+ mode = EditorFileDialog::FILE_MODE_OPEN_ANY;
}
file_dialog->set_meta("target", target);
file_dialog->set_meta("section", section);
file_dialog->clear_filters();
- file_dialog->add_filter(Object::cast_to<TreeItem>(item)->get_parent()->get_metadata(0));
+
+ String filter_string = treeItem->get_metadata(0);
+ Vector<String> filters = filter_string.split(",", false, 0);
+ for (int i = 0; i < filters.size(); i++) {
+ file_dialog->add_filter(filters[i]);
+ }
+
file_dialog->set_file_mode(mode);
file_dialog->popup_centered_ratio();
@@ -309,7 +318,9 @@ GDNativeLibraryEditor::GDNativeLibraryEditor() {
platform_ios.name = "iOS";
platform_ios.entries.push_back("armv7");
platform_ios.entries.push_back("arm64");
- platform_ios.library_extension = "*.dylib";
+ // iOS can use both Static and Dynamic libraries.
+ // Frameworks is actually a folder with files.
+ platform_ios.library_extension = "*.framework; Framework, *.xcframework; Binary Framework, *.a; Static Library, *.dylib; Dynamic Library";
platforms["iOS"] = platform_ios;
}
@@ -360,6 +371,7 @@ GDNativeLibraryEditor::GDNativeLibraryEditor() {
//file_dialog->set_resizable(true);
add_child(file_dialog);
file_dialog->connect("file_selected", callable_mp(this, &GDNativeLibraryEditor::_on_library_selected));
+ file_dialog->connect("dir_selected", callable_mp(this, &GDNativeLibraryEditor::_on_library_selected));
file_dialog->connect("files_selected", callable_mp(this, &GDNativeLibraryEditor::_on_dependencies_selected));
new_architecture_dialog = memnew(ConfirmationDialog);
diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp
index 136af5bd1e..d1b1513ac3 100644
--- a/modules/gdnative/register_types.cpp
+++ b/modules/gdnative/register_types.cpp
@@ -142,47 +142,85 @@ void GDNativeExportPlugin::_export_file(const String &p_path, const String &p_ty
}
}
+ // Add symbols for staticaly linked libraries on iOS
if (p_features.has("iOS")) {
- // Register symbols in the "fake" dynamic lookup table, because dlsym does not work well on iOS.
- LibrarySymbol expected_symbols[] = {
- { "gdnative_init", true },
- { "gdnative_terminate", false },
- { "nativescript_init", false },
- { "nativescript_frame", false },
- { "nativescript_thread_enter", false },
- { "nativescript_thread_exit", false },
- { "gdnative_singleton", false }
- };
- String declare_pattern = "extern \"C\" void $name(void)$weak;\n";
- String additional_code = "extern void register_dynamic_symbol(char *name, void *address);\n"
- "extern void add_ios_init_callback(void (*cb)());\n";
- String linker_flags = "";
- for (unsigned long i = 0; i < sizeof(expected_symbols) / sizeof(expected_symbols[0]); ++i) {
- String full_name = lib->get_symbol_prefix() + expected_symbols[i].name;
- String code = declare_pattern.replace("$name", full_name);
- code = code.replace("$weak", expected_symbols[i].is_required ? "" : " __attribute__((weak))");
- additional_code += code;
-
- if (!expected_symbols[i].is_required) {
- if (linker_flags.length() > 0) {
- linker_flags += " ";
+ bool should_fake_dynamic = false;
+
+ List<String> entry_keys;
+ config->get_section_keys("entry", &entry_keys);
+
+ for (List<String>::Element *E = entry_keys.front(); E; E = E->next()) {
+ String key = E->get();
+
+ Vector<String> tags = key.split(".");
+
+ bool skip = false;
+ for (int i = 0; i < tags.size(); i++) {
+ bool has_feature = p_features.has(tags[i]);
+
+ if (!has_feature) {
+ skip = true;
+ break;
}
- linker_flags += "-Wl,-U,_" + full_name;
}
- }
- additional_code += String("void $prefixinit() {\n").replace("$prefix", lib->get_symbol_prefix());
- String register_pattern = " if (&$name) register_dynamic_symbol((char *)\"$name\", (void *)$name);\n";
- for (unsigned long i = 0; i < sizeof(expected_symbols) / sizeof(expected_symbols[0]); ++i) {
- String full_name = lib->get_symbol_prefix() + expected_symbols[i].name;
- additional_code += register_pattern.replace("$name", full_name);
+ if (skip) {
+ continue;
+ }
+
+ String entry_lib_path = config->get_value("entry", key);
+ if (entry_lib_path.begins_with("res://") && entry_lib_path.ends_with(".a")) {
+ // If we find static library that was used for export
+ // we should add a fake loopup table.
+ // In case of dynamic library being used,
+ // this symbols will not cause any issues with library loading.
+ should_fake_dynamic = true;
+ break;
+ }
}
- additional_code += "}\n";
- additional_code += String("struct $prefixstruct {$prefixstruct() {add_ios_init_callback($prefixinit);}};\n").replace("$prefix", lib->get_symbol_prefix());
- additional_code += String("$prefixstruct $prefixstruct_instance;\n").replace("$prefix", lib->get_symbol_prefix());
- add_ios_cpp_code(additional_code);
- add_ios_linker_flags(linker_flags);
+ if (should_fake_dynamic) {
+ // Register symbols in the "fake" dynamic lookup table, because dlsym does not work well on iOS.
+ LibrarySymbol expected_symbols[] = {
+ { "gdnative_init", true },
+ { "gdnative_terminate", false },
+ { "nativescript_init", false },
+ { "nativescript_frame", false },
+ { "nativescript_thread_enter", false },
+ { "nativescript_thread_exit", false },
+ { "gdnative_singleton", false }
+ };
+ String declare_pattern = "extern \"C\" void $name(void)$weak;\n";
+ String additional_code = "extern void register_dynamic_symbol(char *name, void *address);\n"
+ "extern void add_ios_init_callback(void (*cb)());\n";
+ String linker_flags = "";
+ for (unsigned long i = 0; i < sizeof(expected_symbols) / sizeof(expected_symbols[0]); ++i) {
+ String full_name = lib->get_symbol_prefix() + expected_symbols[i].name;
+ String code = declare_pattern.replace("$name", full_name);
+ code = code.replace("$weak", expected_symbols[i].is_required ? "" : " __attribute__((weak))");
+ additional_code += code;
+
+ if (!expected_symbols[i].is_required) {
+ if (linker_flags.length() > 0) {
+ linker_flags += " ";
+ }
+ linker_flags += "-Wl,-U,_" + full_name;
+ }
+ }
+
+ additional_code += String("void $prefixinit() {\n").replace("$prefix", lib->get_symbol_prefix());
+ String register_pattern = " if (&$name) register_dynamic_symbol((char *)\"$name\", (void *)$name);\n";
+ for (unsigned long i = 0; i < sizeof(expected_symbols) / sizeof(expected_symbols[0]); ++i) {
+ String full_name = lib->get_symbol_prefix() + expected_symbols[i].name;
+ additional_code += register_pattern.replace("$name", full_name);
+ }
+ additional_code += "}\n";
+ additional_code += String("struct $prefixstruct {$prefixstruct() {add_ios_init_callback($prefixinit);}};\n").replace("$prefix", lib->get_symbol_prefix());
+ additional_code += String("$prefixstruct $prefixstruct_instance;\n").replace("$prefix", lib->get_symbol_prefix());
+
+ add_ios_cpp_code(additional_code);
+ add_ios_linker_flags(linker_flags);
+ }
}
}
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
index 194e71c9de..4393a4ae9f 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/iphone/export/export.cpp
@@ -793,17 +793,33 @@ void EditorExportPlatformIOS::_add_assets_to_project(const Ref<EditorExportPrese
String pbx_frameworks_refs;
String pbx_resources_build;
String pbx_resources_refs;
+ String pbx_embeded_frameworks;
const String file_info_format = String("$build_id = {isa = PBXBuildFile; fileRef = $ref_id; };\n") +
"$ref_id = {isa = PBXFileReference; lastKnownFileType = $file_type; name = \"$name\"; path = \"$file_path\"; sourceTree = \"<group>\"; };\n";
+
for (int i = 0; i < p_additional_assets.size(); ++i) {
+ String additional_asset_info_format = file_info_format;
+
String build_id = (++current_id).str();
String ref_id = (++current_id).str();
+ String framework_id = "";
+
const IOSExportAsset &asset = p_additional_assets[i];
String type;
if (asset.exported_path.ends_with(".framework")) {
+ additional_asset_info_format += "$framework_id = {isa = PBXBuildFile; fileRef = $ref_id; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };\n";
+ framework_id = (++current_id).str();
+ pbx_embeded_frameworks += framework_id + ",\n";
+
type = "wrapper.framework";
+ } else if (asset.exported_path.ends_with(".xcframework")) {
+ additional_asset_info_format += "$framework_id = {isa = PBXBuildFile; fileRef = $ref_id; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };\n";
+ framework_id = (++current_id).str();
+ pbx_embeded_frameworks += framework_id + ",\n";
+
+ type = "wrapper.xcframework";
} else if (asset.exported_path.ends_with(".dylib")) {
type = "compiled.mach-o.dylib";
} else if (asset.exported_path.ends_with(".a")) {
@@ -828,7 +844,10 @@ void EditorExportPlatformIOS::_add_assets_to_project(const Ref<EditorExportPrese
format_dict["name"] = asset.exported_path.get_file();
format_dict["file_path"] = asset.exported_path;
format_dict["file_type"] = type;
- pbx_files += file_info_format.format(format_dict, "$_");
+ if (framework_id.length() > 0) {
+ format_dict["framework_id"] = framework_id;
+ }
+ pbx_files += additional_asset_info_format.format(format_dict, "$_");
}
// Note, frameworks like gamekit are always included in our project.pbxprof file
@@ -862,6 +881,7 @@ void EditorExportPlatformIOS::_add_assets_to_project(const Ref<EditorExportPrese
str = str.replace("$additional_pbx_frameworks_refs", pbx_frameworks_refs);
str = str.replace("$additional_pbx_resources_build", pbx_resources_build);
str = str.replace("$additional_pbx_resources_refs", pbx_resources_refs);
+ str = str.replace("$pbx_embeded_frameworks", pbx_embeded_frameworks);
CharString cs = str.utf8();
p_project_data.resize(cs.size() - 1);
@@ -892,8 +912,39 @@ Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir
memdelete(filesystem_da);
return ERR_FILE_NOT_FOUND;
}
- String additional_dir = p_is_framework && asset.ends_with(".dylib") ? "/dylibs/" : "/";
- String destination_dir = p_out_dir + additional_dir + asset.get_base_dir().replace("res://", "");
+
+ String base_dir = asset.get_base_dir().replace("res://", "");
+ String destination_dir;
+ String destination;
+ String asset_path;
+ bool create_framework = false;
+
+ if (p_is_framework && asset.ends_with(".dylib")) {
+ // For iOS we need to turn .dylib into .framework
+ // to be able to send application to AppStore
+ destination_dir = p_out_dir.plus_file("dylibs").plus_file(base_dir);
+
+ String file_name = asset.get_basename().get_file();
+ String framework_name = file_name + ".framework";
+
+ destination_dir = destination_dir.plus_file(framework_name);
+ destination = destination_dir.plus_file(file_name);
+ asset_path = destination_dir;
+ create_framework = true;
+ } else if (p_is_framework && (asset.ends_with(".framework") || asset.ends_with(".xcframework"))) {
+ destination_dir = p_out_dir.plus_file("dylibs").plus_file(base_dir);
+
+ String file_name = asset.get_file();
+ destination = destination_dir.plus_file(file_name);
+ asset_path = destination;
+ } else {
+ destination_dir = p_out_dir.plus_file(base_dir);
+
+ String file_name = asset.get_file();
+ destination = destination_dir.plus_file(file_name);
+ asset_path = destination;
+ }
+
if (!filesystem_da->dir_exists(destination_dir)) {
Error make_dir_err = filesystem_da->make_dir_recursive(destination_dir);
if (make_dir_err) {
@@ -903,15 +954,66 @@ Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir
}
}
- String destination = destination_dir.plus_file(asset.get_file());
Error err = dir_exists ? da->copy_dir(asset, destination) : da->copy(asset, destination);
memdelete(da);
if (err) {
memdelete(filesystem_da);
return err;
}
- IOSExportAsset exported_asset = { destination, p_is_framework };
+ IOSExportAsset exported_asset = { asset_path, p_is_framework };
r_exported_assets.push_back(exported_asset);
+
+ if (create_framework) {
+ String file_name = asset.get_basename().get_file();
+ String framework_name = file_name + ".framework";
+
+ // Performing `install_name_tool -id @rpath/{name}.framework/{name} ./{name}` on dylib
+ {
+ List<String> install_name_args;
+ install_name_args.push_back("-id");
+ install_name_args.push_back(String("@rpath").plus_file(framework_name).plus_file(file_name));
+ install_name_args.push_back(destination);
+
+ OS::get_singleton()->execute("install_name_tool", install_name_args, true);
+ }
+
+ // Creating Info.plist
+ {
+ String info_plist_format = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+ "<plist version=\"1.0\">\n"
+ "<dict>\n"
+ "<key>CFBundleShortVersionString</key>\n"
+ "<string>1.0</string>\n"
+ "<key>CFBundleIdentifier</key>\n"
+ "<string>com.gdnative.framework.$name</string>\n"
+ "<key>CFBundleName</key>\n"
+ "<string>$name</string>\n"
+ "<key>CFBundleExecutable</key>\n"
+ "<string>$name</string>\n"
+ "<key>DTPlatformName</key>\n"
+ "<string>iphoneos</string>\n"
+ "<key>CFBundleInfoDictionaryVersion</key>\n"
+ "<string>6.0</string>\n"
+ "<key>CFBundleVersion</key>\n"
+ "<string>1</string>\n"
+ "<key>CFBundlePackageType</key>\n"
+ "<string>FMWK</string>\n"
+ "<key>MinimumOSVersion</key>\n"
+ "<string>10.0</string>\n"
+ "</dict>\n"
+ "</plist>";
+
+ String info_plist = info_plist_format.replace("$name", file_name);
+
+ FileAccess *f = FileAccess::open(asset_path.plus_file("Info.plist"), FileAccess::WRITE);
+ if (f) {
+ f->store_string(info_plist);
+ f->close();
+ memdelete(f);
+ }
+ }
+ }
}
}
memdelete(filesystem_da);
diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h
index ac419a821c..8e27f10dc2 100644
--- a/platform/osx/display_server_osx.h
+++ b/platform/osx/display_server_osx.h
@@ -86,6 +86,14 @@ public:
uint32_t unicode;
};
+ struct WarpEvent {
+ NSTimeInterval timestamp;
+ NSPoint delta;
+ };
+
+ List<WarpEvent> warp_events;
+ NSTimeInterval last_warp = 0;
+
Vector<KeyEvent> key_event_buffer;
int key_event_pos;
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index 220ba9ac7e..ee67f46a4c 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -848,13 +848,59 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i
ERR_FAIL_COND(!DS_OSX->windows.has(window_id));
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
+ NSPoint delta = NSMakePoint([event deltaX], [event deltaY]);
+ NSPoint mpos = [event locationInWindow];
+
+ if (DS_OSX->mouse_mode == DisplayServer::MOUSE_MODE_CONFINED) {
+ // Discard late events
+ if (([event timestamp]) < DS_OSX->last_warp) {
+ return;
+ }
+
+ // Warp affects next event delta, subtract previous warp deltas
+ List<DisplayServerOSX::WarpEvent>::Element *F = DS_OSX->warp_events.front();
+ while (F) {
+ if (F->get().timestamp < [event timestamp]) {
+ List<DisplayServerOSX::WarpEvent>::Element *E = F;
+ delta.x -= E->get().delta.x;
+ delta.y -= E->get().delta.y;
+ F = F->next();
+ DS_OSX->warp_events.erase(E);
+ } else {
+ F = F->next();
+ }
+ }
+
+ // Confine mouse position to the window, and update delta
+ NSRect frame = [wd.window_object frame];
+ NSPoint conf_pos = mpos;
+ conf_pos.x = CLAMP(conf_pos.x + delta.x, 0.f, frame.size.width);
+ conf_pos.y = CLAMP(conf_pos.y - delta.y, 0.f, frame.size.height);
+ delta.x = conf_pos.x - mpos.x;
+ delta.y = mpos.y - conf_pos.y;
+ mpos = conf_pos;
+
+ // Move mouse cursor
+ NSRect pointInWindowRect = NSMakeRect(conf_pos.x, conf_pos.y, 0, 0);
+ conf_pos = [[wd.window_view window] convertRectToScreen:pointInWindowRect].origin;
+ conf_pos.y = CGDisplayBounds(CGMainDisplayID()).size.height - conf_pos.y;
+ CGWarpMouseCursorPosition(conf_pos);
+
+ // Save warp data
+ DS_OSX->last_warp = [[NSProcessInfo processInfo] systemUptime];
+ DisplayServerOSX::WarpEvent ev;
+ ev.timestamp = DS_OSX->last_warp;
+ ev.delta = delta;
+ DS_OSX->warp_events.push_back(ev);
+ }
+
Ref<InputEventMouseMotion> mm;
mm.instance();
mm->set_window_id(window_id);
mm->set_button_mask(DS_OSX->last_button_state);
const CGFloat backingScaleFactor = (OS::get_singleton()->is_hidpi_allowed()) ? [[event window] backingScaleFactor] : 1.0;
- const Vector2i pos = _get_mouse_pos(wd, [event locationInWindow], backingScaleFactor);
+ const Vector2i pos = _get_mouse_pos(wd, mpos, backingScaleFactor);
mm->set_position(pos);
mm->set_pressure([event pressure]);
if ([event subtype] == NSEventSubtypeTabletPoint) {
@@ -863,9 +909,7 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i
}
mm->set_global_position(pos);
mm->set_speed(Input::get_singleton()->get_last_mouse_speed());
- Vector2i relativeMotion = Vector2i();
- relativeMotion.x = [event deltaX] * backingScaleFactor;
- relativeMotion.y = [event deltaY] * backingScaleFactor;
+ const Vector2i relativeMotion = Vector2i(delta.x, delta.y) * backingScaleFactor;
mm->set_relative(relativeMotion);
_get_key_modifier_state([event modifierFlags], mm);
@@ -1970,11 +2014,15 @@ void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) {
CGDisplayHideCursor(kCGDirectMainDisplay);
}
CGAssociateMouseAndMouseCursorPosition(true);
+ } else if (p_mode == MOUSE_MODE_CONFINED) {
+ CGDisplayShowCursor(kCGDirectMainDisplay);
+ CGAssociateMouseAndMouseCursorPosition(false);
} else {
CGDisplayShowCursor(kCGDirectMainDisplay);
CGAssociateMouseAndMouseCursorPosition(true);
}
+ warp_events.clear();
mouse_mode = p_mode;
}
@@ -2004,7 +2052,9 @@ void DisplayServerOSX::mouse_warp_to_position(const Point2i &p_to) {
CGEventSourceSetLocalEventsSuppressionInterval(lEventRef, 0.0);
CGAssociateMouseAndMouseCursorPosition(false);
CGWarpMouseCursorPosition(lMouseWarpPos);
- CGAssociateMouseAndMouseCursorPosition(true);
+ if (mouse_mode != MOUSE_MODE_CONFINED) {
+ CGAssociateMouseAndMouseCursorPosition(true);
+ }
}
}
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 61dc156fbc..790277ca3a 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -2864,6 +2864,27 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
WindowRect.top = p_rect.position.y;
WindowRect.bottom = p_rect.position.y + p_rect.size.y;
+ if (p_mode == WINDOW_MODE_FULLSCREEN) {
+ int nearest_area = 0;
+ Rect2i screen_rect;
+ for (int i = 0; i < get_screen_count(); i++) {
+ Rect2i r;
+ r.position = screen_get_position(i);
+ r.size = screen_get_size(i);
+ Rect2 inters = r.clip(p_rect);
+ int area = inters.size.width * inters.size.height;
+ if (area >= nearest_area) {
+ screen_rect = r;
+ nearest_area = area;
+ }
+ }
+
+ WindowRect.left = screen_rect.position.x;
+ WindowRect.right = screen_rect.position.x + screen_rect.size.x;
+ WindowRect.top = screen_rect.position.y;
+ WindowRect.bottom = screen_rect.position.y + screen_rect.size.y;
+ }
+
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
WindowID id = window_id_counter;
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 2f39c973a0..66c587e2d4 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -1055,6 +1055,8 @@ void AnimationPlayer::get_animation_list(List<StringName> *p_animations) const {
}
void AnimationPlayer::set_blend_time(const StringName &p_animation1, const StringName &p_animation2, float p_time) {
+ ERR_FAIL_COND(!animation_set.has(p_animation1));
+ ERR_FAIL_COND(!animation_set.has(p_animation2));
ERR_FAIL_COND_MSG(p_time < 0, "Blend time cannot be smaller than 0.");
BlendKey bk;
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index d8229b5f43..6fef44481a 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -271,6 +271,11 @@ BaseButton::DrawMode BaseButton::get_draw_mode() const {
}
void BaseButton::set_toggle_mode(bool p_on) {
+ // Make sure to set 'pressed' to false if we are not in toggle mode
+ if (!p_on) {
+ set_pressed(false);
+ }
+
toggle_mode = p_on;
}
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 97daeceda9..2cdee4641e 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -1173,7 +1173,17 @@ Rect2 Control::get_parent_anchorable_rect() const {
if (data.parent_canvas_item) {
parent_rect = data.parent_canvas_item->get_anchorable_rect();
} else {
+#ifdef TOOLS_ENABLED
+ Node *edited_root = get_tree()->get_edited_scene_root();
+ if (edited_root && (this == edited_root || edited_root->is_a_parent_of(this))) {
+ parent_rect.size = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height"));
+ } else {
+ parent_rect = get_viewport()->get_visible_rect();
+ }
+
+#else
parent_rect = get_viewport()->get_visible_rect();
+#endif
}
return parent_rect;
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index b6a96238dc..01b54ddaa8 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -503,9 +503,7 @@ void GraphNode::_connpos_update() {
}
}
- if (vofs > 0) {
- vofs += sep;
- }
+ vofs += sep;
vofs += size.y;
idx++;
}
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 5ae27081ea..22e5bd55f3 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -256,7 +256,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
lh = line < l.height_caches.size() ? l.height_caches[line] : 1; \
line_ascent = line < l.ascent_caches.size() ? l.ascent_caches[line] : 1; \
line_descent = line < l.descent_caches.size() ? l.descent_caches[line] : 1; \
- if (p_mode == PROCESS_DRAW) { \
+ if ((p_mode == PROCESS_DRAW) && (align != ALIGN_FILL)) { \
if (line < l.offset_caches.size()) { \
wofs = l.offset_caches[line]; \
} \
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 65a72267b1..1c259b7d32 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -2083,7 +2083,11 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Control *c = over;
Vector2 cpos = pos;
while (c) {
- cursor_shape = c->get_cursor_shape(cpos);
+ if (gui.mouse_focus_mask != 0 || c->has_point(cpos)) {
+ cursor_shape = c->get_cursor_shape(cpos);
+ } else {
+ cursor_shape = Control::CURSOR_ARROW;
+ }
cpos = c->get_transform().xform(cpos);
if (cursor_shape != Control::CURSOR_ARROW) {
break;
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 0463615d4d..48540b7bc9 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -309,6 +309,7 @@ void Window::_event_callback(DisplayServer::WindowEvent p_event) {
case DisplayServer::WINDOW_EVENT_MOUSE_ENTER: {
_propagate_window_notification(this, NOTIFICATION_WM_MOUSE_ENTER);
emit_signal("mouse_entered");
+ DisplayServer::get_singleton()->cursor_set_shape(DisplayServer::CURSOR_ARROW); //restore cursor shape
} break;
case DisplayServer::WINDOW_EVENT_MOUSE_EXIT: {
_propagate_window_notification(this, NOTIFICATION_WM_MOUSE_EXIT);
@@ -624,26 +625,25 @@ void Window::_update_viewport_size() {
// Already handled above
//_update_font_oversampling(1.0);
} break;
- case CONTENT_SCALE_MODE_OBJECTS: {
+ case CONTENT_SCALE_MODE_CANVAS_ITEMS: {
final_size = screen_size;
final_size_override = viewport_size;
attach_to_screen_rect = Rect2(margin, screen_size);
font_oversampling = screen_size.x / viewport_size.x;
+
+ Size2 scale = Vector2(screen_size) / Vector2(final_size_override);
+ stretch_transform.scale(scale);
+
} break;
- case CONTENT_SCALE_MODE_PIXELS: {
+ case CONTENT_SCALE_MODE_VIEWPORT: {
final_size = viewport_size;
attach_to_screen_rect = Rect2(margin, screen_size);
} break;
}
-
- Size2 scale = size / (Vector2(final_size) + margin * 2);
- stretch_transform.scale(scale);
- stretch_transform.elements[2] = margin * scale;
}
bool allocate = is_inside_tree() && visible && (window_id != DisplayServer::INVALID_WINDOW_ID || embedder != nullptr);
-
_set_size(final_size, final_size_override, attach_to_screen_rect, stretch_transform, allocate);
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
@@ -1372,7 +1372,7 @@ void Window::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "max_size"), "set_max_size", "get_max_size");
ADD_GROUP("Content Scale", "content_scale_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "content_scale_size"), "set_content_scale_size", "get_content_scale_size");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_mode", PROPERTY_HINT_ENUM, "Disabled,Object,Pixels"), "set_content_scale_mode", "get_content_scale_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_mode", PROPERTY_HINT_ENUM, "Disabled,CanvasItems,Viewport"), "set_content_scale_mode", "get_content_scale_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_aspect", PROPERTY_HINT_ENUM, "Ignore,Keep,KeepWidth,KeepHeight,Expand"), "set_content_scale_aspect", "get_content_scale_aspect");
ADD_GROUP("Theme", "");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme");
@@ -1403,8 +1403,8 @@ void Window::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_MAX);
BIND_ENUM_CONSTANT(CONTENT_SCALE_MODE_DISABLED);
- BIND_ENUM_CONSTANT(CONTENT_SCALE_MODE_OBJECTS);
- BIND_ENUM_CONSTANT(CONTENT_SCALE_MODE_PIXELS);
+ BIND_ENUM_CONSTANT(CONTENT_SCALE_MODE_CANVAS_ITEMS);
+ BIND_ENUM_CONSTANT(CONTENT_SCALE_MODE_VIEWPORT);
BIND_ENUM_CONSTANT(CONTENT_SCALE_ASPECT_IGNORE);
BIND_ENUM_CONSTANT(CONTENT_SCALE_ASPECT_KEEP);
diff --git a/scene/main/window.h b/scene/main/window.h
index 5fd59e06f5..c8c02b8984 100644
--- a/scene/main/window.h
+++ b/scene/main/window.h
@@ -57,8 +57,8 @@ public:
enum ContentScaleMode {
CONTENT_SCALE_MODE_DISABLED,
- CONTENT_SCALE_MODE_OBJECTS,
- CONTENT_SCALE_MODE_PIXELS,
+ CONTENT_SCALE_MODE_CANVAS_ITEMS,
+ CONTENT_SCALE_MODE_VIEWPORT,
};
enum ContentScaleAspect {
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 014b773298..479d97aadc 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -2577,7 +2577,10 @@ void Animation::copy_track(int p_track, Ref<Animation> p_to_animation) {
p_to_animation->track_set_enabled(dst_track, track_is_enabled(p_track));
p_to_animation->track_set_interpolation_type(dst_track, track_get_interpolation_type(p_track));
p_to_animation->track_set_interpolation_loop_wrap(dst_track, track_get_interpolation_loop_wrap(p_track));
- p_to_animation->value_track_set_update_mode(dst_track, value_track_get_update_mode(p_track));
+ if (track_get_type(p_track) == TYPE_VALUE) {
+ p_to_animation->value_track_set_update_mode(dst_track, value_track_get_update_mode(p_track));
+ }
+
for (int i = 0; i < track_get_key_count(p_track); i++) {
p_to_animation->track_insert_key(dst_track, track_get_key_time(p_track, i), track_get_key_value(p_track, i), track_get_key_transition(p_track, i));
}
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp
index 258979ff22..5997959432 100644
--- a/servers/physics_2d/body_pair_2d_sw.cpp
+++ b/servers/physics_2d/body_pair_2d_sw.cpp
@@ -255,9 +255,8 @@ bool BodyPair2DSW::setup(real_t p_step) {
if (B->get_continuous_collision_detection_mode() == PhysicsServer2D::CCD_MODE_CAST_SHAPE) {
motion_B = B->get_motion();
}
- //faster to set than to check..
- //bool prev_collided=collided;
+ bool prev_collided = collided;
collided = CollisionSolver2DSW::solve(shape_A_ptr, xform_A, motion_A, shape_B_ptr, xform_B, motion_B, _add_contact, this, &sep_axis);
if (!collided) {
@@ -285,8 +284,7 @@ bool BodyPair2DSW::setup(real_t p_step) {
return false;
}
- //if (!prev_collided) {
- {
+ if (!prev_collided) {
if (A->is_shape_set_as_one_way_collision(shape_A)) {
Vector2 direction = xform_A.get_axis(1).normalized();
bool valid = false;
diff --git a/thirdparty/README.md b/thirdparty/README.md
index e9ab0aeb20..43cd448a00 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -623,7 +623,7 @@ Patches in the `patches` directory should be re-applied after updates.
## wslay
- Upstream: https://github.com/tatsuhiro-t/wslay
-- Version: 1.1.0 (2018)
+- Version: 1.1.1 (2020)
- License: MIT
File extracted from upstream release tarball:
diff --git a/thirdparty/wslay/includes/wslay/wslayver.h b/thirdparty/wslay/includes/wslay/wslayver.h
index 2c3e282e9d..28f2018039 100644
--- a/thirdparty/wslay/includes/wslay/wslayver.h
+++ b/thirdparty/wslay/includes/wslay/wslayver.h
@@ -26,6 +26,6 @@
#define WSLAYVER_H
/* Version number of wslay release */
-#define WSLAY_VERSION "1.1.0"
+#define WSLAY_VERSION "1.1.1"
#endif /* WSLAYVER_H */
diff --git a/thirdparty/wslay/wslay_event.c b/thirdparty/wslay/wslay_event.c
index 57415c51e0..140f7c01da 100644
--- a/thirdparty/wslay/wslay_event.c
+++ b/thirdparty/wslay/wslay_event.c
@@ -730,11 +730,11 @@ int wslay_event_recv(wslay_event_context_ptr ctx)
return r;
}
} else if(ctx->imsg->opcode == WSLAY_PING) {
- struct wslay_event_msg arg;
- arg.opcode = WSLAY_PONG;
- arg.msg = msg;
- arg.msg_length = ctx->imsg->msg_length;
- if((r = wslay_event_queue_msg(ctx, &arg)) &&
+ struct wslay_event_msg pong_arg;
+ pong_arg.opcode = WSLAY_PONG;
+ pong_arg.msg = msg;
+ pong_arg.msg_length = ctx->imsg->msg_length;
+ if((r = wslay_event_queue_msg(ctx, &pong_arg)) &&
r != WSLAY_ERR_NO_MORE_MSG) {
ctx->read_enabled = 0;
free(msg);
@@ -885,7 +885,7 @@ int wslay_event_send(wslay_event_context_ptr ctx)
r = ctx->omsg->read_callback(ctx, ctx->obuf, sizeof(ctx->obuf),
&ctx->omsg->source,
&eof, ctx->user_data);
- if(r == 0) {
+ if(r == 0 && eof == 0) {
break;
} else if(r < 0) {
ctx->write_enabled = 0;