summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/input/input.cpp3
-rw-r--r--core/io/file_access.cpp74
-rw-r--r--core/io/file_access.h34
-rw-r--r--core/io/file_access_compressed.cpp32
-rw-r--r--core/io/file_access_compressed.h9
-rw-r--r--core/io/file_access_encrypted.cpp41
-rw-r--r--core/io/file_access_encrypted.h9
-rw-r--r--core/io/file_access_memory.h9
-rw-r--r--core/io/file_access_pack.h9
-rw-r--r--core/io/file_access_zip.h9
-rw-r--r--core/string/ustring.cpp2
-rw-r--r--doc/classes/Button.xml2
-rw-r--r--doc/classes/ColorPickerButton.xml2
-rw-r--r--doc/classes/FileAccess.xml87
-rw-r--r--doc/classes/MenuButton.xml2
-rw-r--r--doc/classes/NodePath.xml8
-rw-r--r--doc/classes/OptionButton.xml2
-rw-r--r--drivers/unix/file_access_unix.cpp74
-rw-r--r--drivers/unix/file_access_unix.h9
-rw-r--r--drivers/windows/file_access_windows.cpp52
-rw-r--r--drivers/windows/file_access_windows.h9
-rw-r--r--editor/debugger/editor_debugger_inspector.cpp2
-rw-r--r--editor/editor_node.cpp17
-rw-r--r--editor/editor_themes.cpp5
-rw-r--r--editor/import/resource_importer_layered_texture.cpp11
-rw-r--r--editor/import/resource_importer_layered_texture.h2
-rw-r--r--editor/import/resource_importer_scene.cpp23
-rw-r--r--editor/import/resource_importer_scene.h3
-rw-r--r--editor/import/resource_importer_texture.cpp6
-rw-r--r--editor/import/resource_importer_texture.h2
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp4
-rw-r--r--editor/plugins/debugger_editor_plugin.cpp1
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.cpp18
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.h2
-rw-r--r--editor/scene_tree_dock.cpp10
-rw-r--r--platform/android/file_access_android.h9
-rw-r--r--platform/android/file_access_filesystem_jandroid.h9
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp20
-rw-r--r--platform/linuxbsd/x11/display_server_x11.h1
-rw-r--r--platform/macos/display_server_macos.h3
-rw-r--r--platform/macos/display_server_macos.mm23
-rw-r--r--platform/macos/godot_content_view.mm6
-rw-r--r--platform/macos/godot_window_delegate.mm1
-rw-r--r--platform/windows/export/export_plugin.cpp4
-rw-r--r--scene/gui/graph_edit.h8
-rw-r--r--scene/resources/default_theme/default_theme.cpp16
-rw-r--r--scene/resources/primitive_meshes.cpp4
-rw-r--r--tests/core/io/test_json.h10
-rw-r--r--tests/servers/rendering/test_shader_preprocessor.h3
49 files changed, 583 insertions, 118 deletions
diff --git a/core/input/input.cpp b/core/input/input.cpp
index 4a32abfafa..39f1acf623 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -475,7 +475,8 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, String p_name, S
}
joy_names[p_idx] = js;
- emit_signal(SNAME("joy_connection_changed"), p_idx, p_connected);
+ // Ensure this signal is emitted on the main thread, as some platforms (e.g. Linux) call this from a different thread.
+ call_deferred("emit_signal", SNAME("joy_connection_changed"), p_idx, p_connected);
}
Vector3 Input::get_gravity() const {
diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp
index b669afdc99..6026dbf896 100644
--- a/core/io/file_access.cpp
+++ b/core/io/file_access.cpp
@@ -583,7 +583,7 @@ uint64_t FileAccess::get_modified_time(const String &p_file) {
return mt;
}
-uint32_t FileAccess::get_unix_permissions(const String &p_file) {
+BitField<FileAccess::UnixPermissionFlags> FileAccess::get_unix_permissions(const String &p_file) {
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
return 0;
}
@@ -591,11 +591,10 @@ uint32_t FileAccess::get_unix_permissions(const String &p_file) {
Ref<FileAccess> fa = create_for_path(p_file);
ERR_FAIL_COND_V_MSG(fa.is_null(), 0, "Cannot create FileAccess for path '" + p_file + "'.");
- uint32_t mt = fa->_get_unix_permissions(p_file);
- return mt;
+ return fa->_get_unix_permissions(p_file);
}
-Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissions) {
+Error FileAccess::set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) {
if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
return ERR_UNAVAILABLE;
}
@@ -607,6 +606,52 @@ Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissi
return err;
}
+bool FileAccess::get_hidden_attribute(const String &p_file) {
+ if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
+ return false;
+ }
+
+ Ref<FileAccess> fa = create_for_path(p_file);
+ ERR_FAIL_COND_V_MSG(fa.is_null(), false, "Cannot create FileAccess for path '" + p_file + "'.");
+
+ return fa->_get_hidden_attribute(p_file);
+}
+
+Error FileAccess::set_hidden_attribute(const String &p_file, bool p_hidden) {
+ if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
+ return ERR_UNAVAILABLE;
+ }
+
+ Ref<FileAccess> fa = create_for_path(p_file);
+ ERR_FAIL_COND_V_MSG(fa.is_null(), ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'.");
+
+ Error err = fa->_set_hidden_attribute(p_file, p_hidden);
+ return err;
+}
+
+bool FileAccess::get_read_only_attribute(const String &p_file) {
+ if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
+ return false;
+ }
+
+ Ref<FileAccess> fa = create_for_path(p_file);
+ ERR_FAIL_COND_V_MSG(fa.is_null(), false, "Cannot create FileAccess for path '" + p_file + "'.");
+
+ return fa->_get_read_only_attribute(p_file);
+}
+
+Error FileAccess::set_read_only_attribute(const String &p_file, bool p_ro) {
+ if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) {
+ return ERR_UNAVAILABLE;
+ }
+
+ Ref<FileAccess> fa = create_for_path(p_file);
+ ERR_FAIL_COND_V_MSG(fa.is_null(), ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'.");
+
+ Error err = fa->_set_read_only_attribute(p_file, p_ro);
+ return err;
+}
+
void FileAccess::store_string(const String &p_string) {
if (p_string.length() == 0) {
return;
@@ -865,6 +910,14 @@ void FileAccess::_bind_methods() {
ClassDB::bind_static_method("FileAccess", D_METHOD("file_exists", "path"), &FileAccess::exists);
ClassDB::bind_static_method("FileAccess", D_METHOD("get_modified_time", "file"), &FileAccess::get_modified_time);
+ ClassDB::bind_static_method("FileAccess", D_METHOD("get_unix_permissions", "file"), &FileAccess::get_unix_permissions);
+ ClassDB::bind_static_method("FileAccess", D_METHOD("set_unix_permissions", "file", "permissions"), &FileAccess::set_unix_permissions);
+
+ ClassDB::bind_static_method("FileAccess", D_METHOD("get_hidden_attribute", "file"), &FileAccess::get_hidden_attribute);
+ ClassDB::bind_static_method("FileAccess", D_METHOD("set_hidden_attribute", "file", "hidden"), &FileAccess::set_hidden_attribute);
+ ClassDB::bind_static_method("FileAccess", D_METHOD("set_read_only_attribute", "file", "ro"), &FileAccess::set_read_only_attribute);
+ ClassDB::bind_static_method("FileAccess", D_METHOD("get_read_only_attribute", "file"), &FileAccess::get_read_only_attribute);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "big_endian"), "set_big_endian", "is_big_endian");
BIND_ENUM_CONSTANT(READ);
@@ -877,4 +930,17 @@ void FileAccess::_bind_methods() {
BIND_ENUM_CONSTANT(COMPRESSION_ZSTD);
BIND_ENUM_CONSTANT(COMPRESSION_GZIP);
BIND_ENUM_CONSTANT(COMPRESSION_BROTLI);
+
+ BIND_BITFIELD_FLAG(UNIX_READ_OWNER);
+ BIND_BITFIELD_FLAG(UNIX_WRITE_OWNER);
+ BIND_BITFIELD_FLAG(UNIX_EXECUTE_OWNER);
+ BIND_BITFIELD_FLAG(UNIX_READ_GROUP);
+ BIND_BITFIELD_FLAG(UNIX_WRITE_GROUP);
+ BIND_BITFIELD_FLAG(UNIX_EXECUTE_GROUP);
+ BIND_BITFIELD_FLAG(UNIX_READ_OTHER);
+ BIND_BITFIELD_FLAG(UNIX_WRITE_OTHER);
+ BIND_BITFIELD_FLAG(UNIX_EXECUTE_OTHER);
+ BIND_BITFIELD_FLAG(UNIX_SET_USER_ID);
+ BIND_BITFIELD_FLAG(UNIX_SET_GROUP_ID);
+ BIND_BITFIELD_FLAG(UNIX_RESTRICTED_DELETE);
}
diff --git a/core/io/file_access.h b/core/io/file_access.h
index ad1ac665f3..7b9e66bb83 100644
--- a/core/io/file_access.h
+++ b/core/io/file_access.h
@@ -60,6 +60,21 @@ public:
WRITE_READ = 7,
};
+ enum UnixPermissionFlags {
+ UNIX_EXECUTE_OTHER = 0x001,
+ UNIX_WRITE_OTHER = 0x002,
+ UNIX_READ_OTHER = 0x004,
+ UNIX_EXECUTE_GROUP = 0x008,
+ UNIX_WRITE_GROUP = 0x010,
+ UNIX_READ_GROUP = 0x020,
+ UNIX_EXECUTE_OWNER = 0x040,
+ UNIX_WRITE_OWNER = 0x080,
+ UNIX_READ_OWNER = 0x100,
+ UNIX_RESTRICTED_DELETE = 0x200,
+ UNIX_SET_GROUP_ID = 0x400,
+ UNIX_SET_USER_ID = 0x800,
+ };
+
enum CompressionMode {
COMPRESSION_FASTLZ = Compression::MODE_FASTLZ,
COMPRESSION_DEFLATE = Compression::MODE_DEFLATE,
@@ -74,8 +89,13 @@ public:
bool big_endian = false;
bool real_is_double = false;
- virtual uint32_t _get_unix_permissions(const String &p_file) = 0;
- virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) = 0;
+ virtual BitField<UnixPermissionFlags> _get_unix_permissions(const String &p_file) = 0;
+ virtual Error _set_unix_permissions(const String &p_file, BitField<UnixPermissionFlags> p_permissions) = 0;
+
+ virtual bool _get_hidden_attribute(const String &p_file) = 0;
+ virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) = 0;
+ virtual bool _get_read_only_attribute(const String &p_file) = 0;
+ virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) = 0;
protected:
static void _bind_methods();
@@ -185,8 +205,13 @@ public:
static CreateFunc get_create_func(AccessType p_access);
static bool exists(const String &p_name); ///< return true if a file exists
static uint64_t get_modified_time(const String &p_file);
- static uint32_t get_unix_permissions(const String &p_file);
- static Error set_unix_permissions(const String &p_file, uint32_t p_permissions);
+ static BitField<FileAccess::UnixPermissionFlags> get_unix_permissions(const String &p_file);
+ static Error set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions);
+
+ static bool get_hidden_attribute(const String &p_file);
+ static Error set_hidden_attribute(const String &p_file, bool p_hidden);
+ static bool get_read_only_attribute(const String &p_file);
+ static Error set_read_only_attribute(const String &p_file, bool p_ro);
static void set_backup_save(bool p_enable) { backup_save = p_enable; };
static bool is_backup_save_enabled() { return backup_save; };
@@ -212,5 +237,6 @@ public:
VARIANT_ENUM_CAST(FileAccess::CompressionMode);
VARIANT_ENUM_CAST(FileAccess::ModeFlags);
+VARIANT_BITFIELD_CAST(FileAccess::UnixPermissionFlags);
#endif // FILE_ACCESS_H
diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp
index 3e5a1217dd..0f00bd292c 100644
--- a/core/io/file_access_compressed.cpp
+++ b/core/io/file_access_compressed.cpp
@@ -365,20 +365,48 @@ uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) {
}
}
-uint32_t FileAccessCompressed::_get_unix_permissions(const String &p_file) {
+BitField<FileAccess::UnixPermissionFlags> FileAccessCompressed::_get_unix_permissions(const String &p_file) {
if (f.is_valid()) {
return f->_get_unix_permissions(p_file);
}
return 0;
}
-Error FileAccessCompressed::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
+Error FileAccessCompressed::_set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) {
if (f.is_valid()) {
return f->_set_unix_permissions(p_file, p_permissions);
}
return FAILED;
}
+bool FileAccessCompressed::_get_hidden_attribute(const String &p_file) {
+ if (f.is_valid()) {
+ return f->_get_hidden_attribute(p_file);
+ }
+ return false;
+}
+
+Error FileAccessCompressed::_set_hidden_attribute(const String &p_file, bool p_hidden) {
+ if (f.is_valid()) {
+ return f->_set_hidden_attribute(p_file, p_hidden);
+ }
+ return FAILED;
+}
+
+bool FileAccessCompressed::_get_read_only_attribute(const String &p_file) {
+ if (f.is_valid()) {
+ return f->_get_read_only_attribute(p_file);
+ }
+ return false;
+}
+
+Error FileAccessCompressed::_set_read_only_attribute(const String &p_file, bool p_ro) {
+ if (f.is_valid()) {
+ return f->_set_read_only_attribute(p_file, p_ro);
+ }
+ return FAILED;
+}
+
void FileAccessCompressed::close() {
_close();
}
diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h
index 601b74a9c1..bf57eaa07c 100644
--- a/core/io/file_access_compressed.h
+++ b/core/io/file_access_compressed.h
@@ -94,8 +94,13 @@ public:
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file) override;
- virtual uint32_t _get_unix_permissions(const String &p_file) override;
- virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override;
+ virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override;
+ virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override;
+
+ virtual bool _get_hidden_attribute(const String &p_file) override;
+ virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override;
+ virtual bool _get_read_only_attribute(const String &p_file) override;
+ virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override;
virtual void close() override;
diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp
index c39d19d52b..b689f5b628 100644
--- a/core/io/file_access_encrypted.cpp
+++ b/core/io/file_access_encrypted.cpp
@@ -285,13 +285,46 @@ uint64_t FileAccessEncrypted::_get_modified_time(const String &p_file) {
return 0;
}
-uint32_t FileAccessEncrypted::_get_unix_permissions(const String &p_file) {
+BitField<FileAccess::UnixPermissionFlags> FileAccessEncrypted::_get_unix_permissions(const String &p_file) {
+ if (file.is_valid()) {
+ return file->_get_unix_permissions(p_file);
+ }
return 0;
}
-Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
- ERR_PRINT("Setting UNIX permissions on encrypted files is not implemented yet.");
- return ERR_UNAVAILABLE;
+Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) {
+ if (file.is_valid()) {
+ return file->_set_unix_permissions(p_file, p_permissions);
+ }
+ return FAILED;
+}
+
+bool FileAccessEncrypted::_get_hidden_attribute(const String &p_file) {
+ if (file.is_valid()) {
+ return file->_get_hidden_attribute(p_file);
+ }
+ return false;
+}
+
+Error FileAccessEncrypted::_set_hidden_attribute(const String &p_file, bool p_hidden) {
+ if (file.is_valid()) {
+ return file->_set_hidden_attribute(p_file, p_hidden);
+ }
+ return FAILED;
+}
+
+bool FileAccessEncrypted::_get_read_only_attribute(const String &p_file) {
+ if (file.is_valid()) {
+ return file->_get_read_only_attribute(p_file);
+ }
+ return false;
+}
+
+Error FileAccessEncrypted::_set_read_only_attribute(const String &p_file, bool p_ro) {
+ if (file.is_valid()) {
+ return file->_set_read_only_attribute(p_file, p_ro);
+ }
+ return FAILED;
}
void FileAccessEncrypted::close() {
diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h
index 9702b5a517..489d213b8f 100644
--- a/core/io/file_access_encrypted.h
+++ b/core/io/file_access_encrypted.h
@@ -85,8 +85,13 @@ public:
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file) override;
- virtual uint32_t _get_unix_permissions(const String &p_file) override;
- virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override;
+ virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override;
+ virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override;
+
+ virtual bool _get_hidden_attribute(const String &p_file) override;
+ virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override;
+ virtual bool _get_read_only_attribute(const String &p_file) override;
+ virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override;
virtual void close() override;
diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h
index 43fe6ab658..ac08e5406f 100644
--- a/core/io/file_access_memory.h
+++ b/core/io/file_access_memory.h
@@ -68,8 +68,13 @@ public:
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file) override { return 0; }
- virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; }
- virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; }
+ virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
+ virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
+
+ virtual bool _get_hidden_attribute(const String &p_file) override { return false; }
+ virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; }
+ virtual bool _get_read_only_attribute(const String &p_file) override { return false; }
+ virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; }
virtual void close() override {}
diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h
index 1538b302c2..97391a5611 100644
--- a/core/io/file_access_pack.h
+++ b/core/io/file_access_pack.h
@@ -150,8 +150,13 @@ class FileAccessPack : public FileAccess {
Ref<FileAccess> f;
virtual Error open_internal(const String &p_path, int p_mode_flags) override;
virtual uint64_t _get_modified_time(const String &p_file) override { return 0; }
- virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; }
- virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; }
+ virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
+ virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
+
+ virtual bool _get_hidden_attribute(const String &p_file) override { return false; }
+ virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; }
+ virtual bool _get_read_only_attribute(const String &p_file) override { return false; }
+ virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; }
public:
virtual bool is_open() const override;
diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h
index f8b640946c..1062a06238 100644
--- a/core/io/file_access_zip.h
+++ b/core/io/file_access_zip.h
@@ -106,8 +106,13 @@ public:
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } // todo
- virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; }
- virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; }
+ virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
+ virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
+
+ virtual bool _get_hidden_attribute(const String &p_file) override { return false; }
+ virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; }
+ virtual bool _get_read_only_attribute(const String &p_file) override { return false; }
+ virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; }
virtual void close() override;
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index 12e6423724..376d0832d4 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -1750,7 +1750,7 @@ Vector<uint8_t> String::hex_decode() const {
void String::print_unicode_error(const String &p_message, bool p_critical) const {
if (p_critical) {
- print_error(vformat("Unicode parsing error, some characters were replaced with � (U+FFFD): %s", p_message));
+ print_error(vformat(U"Unicode parsing error, some characters were replaced with � (U+FFFD): %s", p_message));
} else {
print_error(vformat("Unicode parsing error: %s", p_message));
}
diff --git a/doc/classes/Button.xml b/doc/classes/Button.xml
index 6faefcbe0d..25c71deb1f 100644
--- a/doc/classes/Button.xml
+++ b/doc/classes/Button.xml
@@ -115,7 +115,7 @@
<theme_item name="icon_pressed_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
Icon modulate [Color] used when the [Button] is being pressed.
</theme_item>
- <theme_item name="h_separation" data_type="constant" type="int" default="2">
+ <theme_item name="h_separation" data_type="constant" type="int" default="4">
The horizontal space between [Button]'s icon and text. Negative values will be treated as [code]0[/code] when used.
</theme_item>
<theme_item name="icon_max_width" data_type="constant" type="int" default="0">
diff --git a/doc/classes/ColorPickerButton.xml b/doc/classes/ColorPickerButton.xml
index 32ec27868a..f6af188998 100644
--- a/doc/classes/ColorPickerButton.xml
+++ b/doc/classes/ColorPickerButton.xml
@@ -74,7 +74,7 @@
<theme_item name="font_pressed_color" data_type="color" type="Color" default="Color(0.8, 0.8, 0.8, 1)">
Text [Color] used when the [ColorPickerButton] is being pressed.
</theme_item>
- <theme_item name="h_separation" data_type="constant" type="int" default="2">
+ <theme_item name="h_separation" data_type="constant" type="int" default="4">
The horizontal space between [ColorPickerButton]'s icon and text.
</theme_item>
<theme_item name="outline_size" data_type="constant" type="int" default="0">
diff --git a/doc/classes/FileAccess.xml b/doc/classes/FileAccess.xml
index 5c1f6775a1..85fbff7932 100644
--- a/doc/classes/FileAccess.xml
+++ b/doc/classes/FileAccess.xml
@@ -170,6 +170,14 @@
Returns the next 32 bits from the file as a floating-point number.
</description>
</method>
+ <method name="get_hidden_attribute" qualifiers="static">
+ <return type="bool" />
+ <param index="0" name="file" type="String" />
+ <description>
+ Returns [code]true[/code], if file [code]hidden[/code] attribute is set.
+ [b]Note:[/b] This method is implemented on iOS, BSD, macOS, and Windows.
+ </description>
+ </method>
<method name="get_length" qualifiers="const">
<return type="int" />
<description>
@@ -228,6 +236,14 @@
Returns the file cursor's position.
</description>
</method>
+ <method name="get_read_only_attribute" qualifiers="static">
+ <return type="bool" />
+ <param index="0" name="file" type="String" />
+ <description>
+ Returns [code]true[/code], if file [code]read only[/code] attribute is set.
+ [b]Note:[/b] This method is implemented on iOS, BSD, macOS, and Windows.
+ </description>
+ </method>
<method name="get_real" qualifiers="const">
<return type="float" />
<description>
@@ -241,6 +257,14 @@
Returns a SHA-256 [String] representing the file at the given path or an empty [String] on failure.
</description>
</method>
+ <method name="get_unix_permissions" qualifiers="static">
+ <return type="int" enum="FileAccess.UnixPermissionFlags" is_bitfield="true" />
+ <param index="0" name="file" type="String" />
+ <description>
+ Returns file UNIX permissions.
+ [b]Note:[/b] This method is implemented on iOS, Linux/BSD, and macOS.
+ </description>
+ </method>
<method name="get_var" qualifiers="const">
<return type="Variant" />
<param index="0" name="allow_objects" type="bool" default="false" />
@@ -312,6 +336,33 @@
[b]Note:[/b] This is an offset, so you should use negative numbers or the cursor will be at the end of the file.
</description>
</method>
+ <method name="set_hidden_attribute" qualifiers="static">
+ <return type="int" enum="Error" />
+ <param index="0" name="file" type="String" />
+ <param index="1" name="hidden" type="bool" />
+ <description>
+ Sets file [code]hidden[/code] attribute.
+ [b]Note:[/b] This method is implemented on iOS, BSD, macOS, and Windows.
+ </description>
+ </method>
+ <method name="set_read_only_attribute" qualifiers="static">
+ <return type="int" enum="Error" />
+ <param index="0" name="file" type="String" />
+ <param index="1" name="ro" type="bool" />
+ <description>
+ Sets file [code]read only[/code] attribute.
+ [b]Note:[/b] This method is implemented on iOS, BSD, macOS, and Windows.
+ </description>
+ </method>
+ <method name="set_unix_permissions" qualifiers="static">
+ <return type="int" enum="Error" />
+ <param index="0" name="file" type="String" />
+ <param index="1" name="permissions" type="int" enum="FileAccess.UnixPermissionFlags" is_bitfield="true" />
+ <description>
+ Sets file UNIX permissions.
+ [b]Note:[/b] This method is implemented on iOS, Linux/BSD, and macOS.
+ </description>
+ </method>
<method name="store_8">
<return type="void" />
<param index="0" name="value" type="int" />
@@ -485,5 +536,41 @@
<constant name="COMPRESSION_BROTLI" value="4" enum="CompressionMode">
Uses the [url=https://github.com/google/brotli]brotli[/url] compression method (only decompression is supported).
</constant>
+ <constant name="UNIX_READ_OWNER" value="256" enum="UnixPermissionFlags" is_bitfield="true">
+ Read for owner bit.
+ </constant>
+ <constant name="UNIX_WRITE_OWNER" value="128" enum="UnixPermissionFlags" is_bitfield="true">
+ Write for owner bit.
+ </constant>
+ <constant name="UNIX_EXECUTE_OWNER" value="64" enum="UnixPermissionFlags" is_bitfield="true">
+ Execute for owner bit.
+ </constant>
+ <constant name="UNIX_READ_GROUP" value="32" enum="UnixPermissionFlags" is_bitfield="true">
+ Read for group bit.
+ </constant>
+ <constant name="UNIX_WRITE_GROUP" value="16" enum="UnixPermissionFlags" is_bitfield="true">
+ Write for group bit.
+ </constant>
+ <constant name="UNIX_EXECUTE_GROUP" value="8" enum="UnixPermissionFlags" is_bitfield="true">
+ Execute for group bit.
+ </constant>
+ <constant name="UNIX_READ_OTHER" value="4" enum="UnixPermissionFlags" is_bitfield="true">
+ Read for other bit.
+ </constant>
+ <constant name="UNIX_WRITE_OTHER" value="2" enum="UnixPermissionFlags" is_bitfield="true">
+ Write for other bit.
+ </constant>
+ <constant name="UNIX_EXECUTE_OTHER" value="1" enum="UnixPermissionFlags" is_bitfield="true">
+ Execute for other bit.
+ </constant>
+ <constant name="UNIX_SET_USER_ID" value="2048" enum="UnixPermissionFlags" is_bitfield="true">
+ Set user id on execution bit.
+ </constant>
+ <constant name="UNIX_SET_GROUP_ID" value="1024" enum="UnixPermissionFlags" is_bitfield="true">
+ Set group id on execution bit.
+ </constant>
+ <constant name="UNIX_RESTRICTED_DELETE" value="512" enum="UnixPermissionFlags" is_bitfield="true">
+ Restricted deletion (sticky) bit.
+ </constant>
</constants>
</class>
diff --git a/doc/classes/MenuButton.xml b/doc/classes/MenuButton.xml
index 8af233427c..e3a707ba72 100644
--- a/doc/classes/MenuButton.xml
+++ b/doc/classes/MenuButton.xml
@@ -69,7 +69,7 @@
<theme_item name="font_pressed_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
Text [Color] used when the [MenuButton] is being pressed.
</theme_item>
- <theme_item name="h_separation" data_type="constant" type="int" default="3">
+ <theme_item name="h_separation" data_type="constant" type="int" default="4">
The horizontal space between [MenuButton]'s icon and text. Negative values will be treated as [code]0[/code] when used.
</theme_item>
<theme_item name="outline_size" data_type="constant" type="int" default="0">
diff --git a/doc/classes/NodePath.xml b/doc/classes/NodePath.xml
index 77a5cfa6c6..a56e80ec1f 100644
--- a/doc/classes/NodePath.xml
+++ b/doc/classes/NodePath.xml
@@ -101,12 +101,12 @@
Returns all subnames concatenated with a colon character ([code]:[/code]) as separator, i.e. the right side of the first colon in a node path.
[codeblocks]
[gdscript]
- var nodepath = NodePath("Path2D/PathFollow2D/Sprite2D:texture:load_path")
- print(nodepath.get_concatenated_subnames()) # texture:load_path
+ var node_path = NodePath("Path2D/PathFollow2D/Sprite2D:texture:load_path")
+ print(node_path.get_concatenated_subnames()) # texture:load_path
[/gdscript]
[csharp]
- var nodepath = new NodePath("Path2D/PathFollow2D/Sprite2D:texture:load_path");
- GD.Print(nodepath.GetConcatenatedSubnames()); // texture:load_path
+ var nodePath = new NodePath("Path2D/PathFollow2D/Sprite2D:texture:load_path");
+ GD.Print(nodePath.GetConcatenatedSubnames()); // texture:load_path
[/csharp]
[/codeblocks]
</description>
diff --git a/doc/classes/OptionButton.xml b/doc/classes/OptionButton.xml
index 659f08d49a..7737754fc6 100644
--- a/doc/classes/OptionButton.xml
+++ b/doc/classes/OptionButton.xml
@@ -262,7 +262,7 @@
<theme_item name="arrow_margin" data_type="constant" type="int" default="4">
The horizontal space between the arrow icon and the right edge of the button.
</theme_item>
- <theme_item name="h_separation" data_type="constant" type="int" default="2">
+ <theme_item name="h_separation" data_type="constant" type="int" default="4">
The horizontal space between [OptionButton]'s icon and text. Negative values will be treated as [code]0[/code] when used.
</theme_item>
<theme_item name="modulate_arrow" data_type="constant" type="int" default="0">
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index a80b7d449e..3b15cf60f7 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -313,19 +313,19 @@ uint64_t FileAccessUnix::_get_modified_time(const String &p_file) {
}
}
-uint32_t FileAccessUnix::_get_unix_permissions(const String &p_file) {
+BitField<FileAccess::UnixPermissionFlags> FileAccessUnix::_get_unix_permissions(const String &p_file) {
String file = fix_path(p_file);
struct stat status = {};
int err = stat(file.utf8().get_data(), &status);
if (!err) {
- return status.st_mode & 0x7FF; //only permissions
+ return status.st_mode & 0xFFF; //only permissions
} else {
ERR_FAIL_V_MSG(0, "Failed to get unix permissions for: " + p_file + ".");
}
}
-Error FileAccessUnix::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
+Error FileAccessUnix::_set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) {
String file = fix_path(p_file);
int err = chmod(file.utf8().get_data(), p_permissions);
@@ -336,6 +336,74 @@ Error FileAccessUnix::_set_unix_permissions(const String &p_file, uint32_t p_per
return FAILED;
}
+bool FileAccessUnix::_get_hidden_attribute(const String &p_file) {
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
+ String file = fix_path(p_file);
+
+ struct stat st = {};
+ int err = stat(file.utf8().get_data(), &st);
+ ERR_FAIL_COND_V_MSG(err, false, "Failed to get attributes for: " + p_file);
+
+ return (st.st_flags & UF_HIDDEN);
+#else
+ return false;
+#endif
+}
+
+Error FileAccessUnix::_set_hidden_attribute(const String &p_file, bool p_hidden) {
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
+ String file = fix_path(p_file);
+
+ struct stat st = {};
+ int err = stat(file.utf8().get_data(), &st);
+ ERR_FAIL_COND_V_MSG(err, FAILED, "Failed to get attributes for: " + p_file);
+
+ if (p_hidden) {
+ err = chflags(file.utf8().get_data(), st.st_flags | UF_HIDDEN);
+ } else {
+ err = chflags(file.utf8().get_data(), st.st_flags & ~UF_HIDDEN);
+ }
+ ERR_FAIL_COND_V_MSG(err, FAILED, "Failed to set attributes for: " + p_file);
+ return OK;
+#else
+ return ERR_UNAVAILABLE;
+#endif
+}
+
+bool FileAccessUnix::_get_read_only_attribute(const String &p_file) {
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
+ String file = fix_path(p_file);
+
+ struct stat st = {};
+ int err = stat(file.utf8().get_data(), &st);
+ ERR_FAIL_COND_V_MSG(err, false, "Failed to get attributes for: " + p_file);
+
+ return st.st_flags & UF_IMMUTABLE;
+#else
+ return false;
+#endif
+}
+
+Error FileAccessUnix::_set_read_only_attribute(const String &p_file, bool p_ro) {
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
+ String file = fix_path(p_file);
+
+ struct stat st = {};
+ int err = stat(file.utf8().get_data(), &st);
+ ERR_FAIL_COND_V_MSG(err, FAILED, "Failed to get attributes for: " + p_file);
+
+ if (p_ro) {
+ err = chflags(file.utf8().get_data(), st.st_flags | UF_IMMUTABLE);
+ } else {
+ err = chflags(file.utf8().get_data(), st.st_flags & ~UF_IMMUTABLE);
+ }
+ ERR_FAIL_COND_V_MSG(err, FAILED, "Failed to set attributes for: " + p_file);
+ return OK;
+#else
+ return ERR_UNAVAILABLE;
+#endif
+}
+
void FileAccessUnix::close() {
_close();
}
diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h
index 79c4e73636..2bfac27c4f 100644
--- a/drivers/unix/file_access_unix.h
+++ b/drivers/unix/file_access_unix.h
@@ -79,8 +79,13 @@ public:
virtual bool file_exists(const String &p_path) override; ///< return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file) override;
- virtual uint32_t _get_unix_permissions(const String &p_file) override;
- virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override;
+ virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override;
+ virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override;
+
+ virtual bool _get_hidden_attribute(const String &p_file) override;
+ virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override;
+ virtual bool _get_read_only_attribute(const String &p_file) override;
+ virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override;
virtual void close() override;
diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp
index 6e69743d4e..c1e0c3fb60 100644
--- a/drivers/windows/file_access_windows.cpp
+++ b/drivers/windows/file_access_windows.cpp
@@ -381,14 +381,62 @@ uint64_t FileAccessWindows::_get_modified_time(const String &p_file) {
}
}
-uint32_t FileAccessWindows::_get_unix_permissions(const String &p_file) {
+BitField<FileAccess::UnixPermissionFlags> FileAccessWindows::_get_unix_permissions(const String &p_file) {
return 0;
}
-Error FileAccessWindows::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
+Error FileAccessWindows::_set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) {
return ERR_UNAVAILABLE;
}
+bool FileAccessWindows::_get_hidden_attribute(const String &p_file) {
+ String file = fix_path(p_file);
+
+ DWORD attrib = GetFileAttributesW((LPCWSTR)file.utf16().get_data());
+ ERR_FAIL_COND_V_MSG(attrib == INVALID_FILE_ATTRIBUTES, false, "Failed to get attributes for: " + p_file);
+ return (attrib & FILE_ATTRIBUTE_HIDDEN);
+}
+
+Error FileAccessWindows::_set_hidden_attribute(const String &p_file, bool p_hidden) {
+ String file = fix_path(p_file);
+
+ DWORD attrib = GetFileAttributesW((LPCWSTR)file.utf16().get_data());
+ ERR_FAIL_COND_V_MSG(attrib == INVALID_FILE_ATTRIBUTES, FAILED, "Failed to get attributes for: " + p_file);
+ BOOL ok;
+ if (p_hidden) {
+ ok = SetFileAttributesW((LPCWSTR)file.utf16().get_data(), attrib | FILE_ATTRIBUTE_HIDDEN);
+ } else {
+ ok = SetFileAttributesW((LPCWSTR)file.utf16().get_data(), attrib & ~FILE_ATTRIBUTE_HIDDEN);
+ }
+ ERR_FAIL_COND_V_MSG(!ok, FAILED, "Failed to set attributes for: " + p_file);
+
+ return OK;
+}
+
+bool FileAccessWindows::_get_read_only_attribute(const String &p_file) {
+ String file = fix_path(p_file);
+
+ DWORD attrib = GetFileAttributesW((LPCWSTR)file.utf16().get_data());
+ ERR_FAIL_COND_V_MSG(attrib == INVALID_FILE_ATTRIBUTES, false, "Failed to get attributes for: " + p_file);
+ return (attrib & FILE_ATTRIBUTE_READONLY);
+}
+
+Error FileAccessWindows::_set_read_only_attribute(const String &p_file, bool p_ro) {
+ String file = fix_path(p_file);
+
+ DWORD attrib = GetFileAttributesW((LPCWSTR)file.utf16().get_data());
+ ERR_FAIL_COND_V_MSG(attrib == INVALID_FILE_ATTRIBUTES, FAILED, "Failed to get attributes for: " + p_file);
+ BOOL ok;
+ if (p_ro) {
+ ok = SetFileAttributesW((LPCWSTR)file.utf16().get_data(), attrib | FILE_ATTRIBUTE_READONLY);
+ } else {
+ ok = SetFileAttributesW((LPCWSTR)file.utf16().get_data(), attrib & ~FILE_ATTRIBUTE_READONLY);
+ }
+ ERR_FAIL_COND_V_MSG(!ok, FAILED, "Failed to set attributes for: " + p_file);
+
+ return OK;
+}
+
void FileAccessWindows::close() {
_close();
}
diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h
index 13c881e562..73143009fc 100644
--- a/drivers/windows/file_access_windows.h
+++ b/drivers/windows/file_access_windows.h
@@ -80,8 +80,13 @@ public:
virtual bool file_exists(const String &p_name) override; ///< return true if a file exists
uint64_t _get_modified_time(const String &p_file) override;
- virtual uint32_t _get_unix_permissions(const String &p_file) override;
- virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override;
+ virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override;
+ virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override;
+
+ virtual bool _get_hidden_attribute(const String &p_file) override;
+ virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override;
+ virtual bool _get_read_only_attribute(const String &p_file) override;
+ virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override;
virtual void close() override;
diff --git a/editor/debugger/editor_debugger_inspector.cpp b/editor/debugger/editor_debugger_inspector.cpp
index 1e9b7c2c60..b2fd84d2ed 100644
--- a/editor/debugger/editor_debugger_inspector.cpp
+++ b/editor/debugger/editor_debugger_inspector.cpp
@@ -232,7 +232,7 @@ void EditorDebuggerInspector::add_stack_variable(const Array &p_array) {
PropertyHint h = PROPERTY_HINT_NONE;
String hs;
- if (var.var_type == Variant::OBJECT) {
+ if (var.var_type == Variant::OBJECT && v) {
v = Object::cast_to<EncodedObjectAsID>(v)->get_object_id();
h = PROPERTY_HINT_OBJECT_ID;
hs = "Object";
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 2efd3c031e..f207418f71 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -6928,8 +6928,7 @@ EditorNode::EditorNode() {
{
// Register importers at the beginning, so dialogs are created with the right extensions.
- Ref<ResourceImporterTexture> import_texture;
- import_texture.instantiate();
+ Ref<ResourceImporterTexture> import_texture = memnew(ResourceImporterTexture(true));
ResourceFormatImporter::get_singleton()->add_importer(import_texture);
Ref<ResourceImporterLayeredTexture> import_cubemap;
@@ -6947,8 +6946,7 @@ EditorNode::EditorNode() {
import_cubemap_array->set_mode(ResourceImporterLayeredTexture::MODE_CUBEMAP_ARRAY);
ResourceFormatImporter::get_singleton()->add_importer(import_cubemap_array);
- Ref<ResourceImporterLayeredTexture> import_3d;
- import_3d.instantiate();
+ Ref<ResourceImporterLayeredTexture> import_3d = memnew(ResourceImporterLayeredTexture(true));
import_3d->set_mode(ResourceImporterLayeredTexture::MODE_3D);
ResourceFormatImporter::get_singleton()->add_importer(import_3d);
@@ -6988,12 +6986,10 @@ EditorNode::EditorNode() {
import_shader_file.instantiate();
ResourceFormatImporter::get_singleton()->add_importer(import_shader_file);
- Ref<ResourceImporterScene> import_scene;
- import_scene.instantiate();
+ Ref<ResourceImporterScene> import_scene = memnew(ResourceImporterScene(false, true));
ResourceFormatImporter::get_singleton()->add_importer(import_scene);
- Ref<ResourceImporterScene> import_animation;
- import_animation = Ref<ResourceImporterScene>(memnew(ResourceImporterScene(true)));
+ Ref<ResourceImporterScene> import_animation = memnew(ResourceImporterScene(true, true));
ResourceFormatImporter::get_singleton()->add_importer(import_animation);
{
@@ -7856,7 +7852,6 @@ EditorNode::EditorNode() {
log = memnew(EditorLog);
Button *output_button = add_bottom_panel_item(TTR("Output"), log);
- output_button->set_theme_type_variation("BottomPanelButton");
log->set_tool_button(output_button);
center_split->connect("resized", callable_mp(this, &EditorNode::_vp_resized));
@@ -8008,8 +8003,8 @@ EditorNode::EditorNode() {
vcs_actions_menu = VersionControlEditorPlugin::get_singleton()->get_version_control_actions_panel();
vcs_actions_menu->set_name("Version Control");
vcs_actions_menu->connect("index_pressed", callable_mp(this, &EditorNode::_version_control_menu_option));
- vcs_actions_menu->add_item(TTR("Create Version Control Metadata"), RUN_VCS_METADATA);
- vcs_actions_menu->add_item(TTR("Version Control Settings"), RUN_VCS_SETTINGS);
+ vcs_actions_menu->add_item(TTR("Create Version Control Metadata..."), RUN_VCS_METADATA);
+ vcs_actions_menu->add_item(TTR("Version Control Settings..."), RUN_VCS_SETTINGS);
project_menu->add_child(vcs_actions_menu);
project_menu->set_item_submenu(project_menu->get_item_index(VCS_MENU), "Version Control");
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 7952efff97..f904ed875d 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -914,7 +914,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("icon_pressed_color", "Button", icon_pressed_color);
theme->set_color("icon_disabled_color", "Button", icon_disabled_color);
- theme->set_constant("h_separation", "Button", 2 * EDSCALE);
+ theme->set_constant("h_separation", "Button", 4 * EDSCALE);
theme->set_constant("outline_size", "Button", 0);
const float ACTION_BUTTON_EXTRA_MARGIN = 32 * EDSCALE;
@@ -1479,9 +1479,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("panel", "TabContainer", style_content_panel);
// Bottom panel.
- theme->set_type_variation("BottomPanelButton", "Button");
- // Add separation for the warning/error icon.
- theme->set_constant("h_separation", "BottomPanelButton", 6 * EDSCALE);
Ref<StyleBoxFlat> style_bottom_panel = style_content_panel->duplicate();
style_bottom_panel->set_corner_radius_all(corner_radius * EDSCALE);
theme->set_stylebox("BottomPanel", "EditorStyles", style_bottom_panel);
diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp
index 3c27864eff..46882e95cb 100644
--- a/editor/import/resource_importer_layered_texture.cpp
+++ b/editor/import/resource_importer_layered_texture.cpp
@@ -474,12 +474,19 @@ bool ResourceImporterLayeredTexture::are_import_settings_valid(const String &p_p
ResourceImporterLayeredTexture *ResourceImporterLayeredTexture::singleton = nullptr;
-ResourceImporterLayeredTexture::ResourceImporterLayeredTexture() {
- singleton = this;
+ResourceImporterLayeredTexture::ResourceImporterLayeredTexture(bool p_singleton) {
+ // This should only be set through the EditorNode.
+ if (p_singleton) {
+ singleton = this;
+ }
+
mode = MODE_CUBEMAP;
}
ResourceImporterLayeredTexture::~ResourceImporterLayeredTexture() {
+ if (singleton == this) {
+ singleton = nullptr;
+ }
}
void ResourceImporterLayeredTexture::_check_compress_ctex(const String &p_source_file, Ref<LayeredTextureImport> r_texture_import) {
diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h
index 52fd37639d..5a21651de3 100644
--- a/editor/import/resource_importer_layered_texture.h
+++ b/editor/import/resource_importer_layered_texture.h
@@ -119,7 +119,7 @@ public:
void set_mode(Mode p_mode) { mode = p_mode; }
- ResourceImporterLayeredTexture();
+ ResourceImporterLayeredTexture(bool p_singleton = false);
~ResourceImporterLayeredTexture();
};
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index b0291f3a93..2e422d8c27 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -2607,15 +2607,28 @@ void ResourceImporterScene::ResourceImporterScene::show_advanced_options(const S
SceneImportSettings::get_singleton()->open_settings(p_path, animation_importer);
}
-ResourceImporterScene::ResourceImporterScene(bool p_animation_import) {
- if (p_animation_import) {
- animation_singleton = this;
- } else {
- scene_singleton = this;
+ResourceImporterScene::ResourceImporterScene(bool p_animation_import, bool p_singleton) {
+ // This should only be set through the EditorNode.
+ if (p_singleton) {
+ if (p_animation_import) {
+ animation_singleton = this;
+ } else {
+ scene_singleton = this;
+ }
}
+
animation_importer = p_animation_import;
}
+ResourceImporterScene::~ResourceImporterScene() {
+ if (animation_singleton == this) {
+ animation_singleton = nullptr;
+ }
+ if (scene_singleton == this) {
+ scene_singleton = nullptr;
+ }
+}
+
void ResourceImporterScene::add_importer(Ref<EditorSceneFormatImporter> p_importer, bool p_first_priority) {
ERR_FAIL_COND(p_importer.is_null());
if (p_first_priority) {
diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h
index a66fd034f8..7a07a5f646 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -296,7 +296,8 @@ public:
virtual bool can_import_threaded() const override { return false; }
- ResourceImporterScene(bool p_animation_import = false);
+ ResourceImporterScene(bool p_animation_import = false, bool p_singleton = false);
+ ~ResourceImporterScene();
template <class M>
static Vector<Ref<Shape3D>> get_collision_shapes(const Ref<ImporterMesh> &p_mesh, const M &p_options, float p_applied_root_scale);
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index 114ba5653a..8eac5ec323 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -789,10 +789,12 @@ bool ResourceImporterTexture::are_import_settings_valid(const String &p_path) co
ResourceImporterTexture *ResourceImporterTexture::singleton = nullptr;
-ResourceImporterTexture::ResourceImporterTexture() {
- if (!singleton) {
+ResourceImporterTexture::ResourceImporterTexture(bool p_singleton) {
+ // This should only be set through the EditorNode.
+ if (p_singleton) {
singleton = this;
}
+
CompressedTexture2D::request_3d_callback = _texture_reimport_3d;
CompressedTexture2D::request_roughness_callback = _texture_reimport_roughness;
CompressedTexture2D::request_normal_callback = _texture_reimport_normal;
diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h
index c2bdbb6fa2..f2539a8f52 100644
--- a/editor/import/resource_importer_texture.h
+++ b/editor/import/resource_importer_texture.h
@@ -107,7 +107,7 @@ public:
virtual bool are_import_settings_valid(const String &p_path) const override;
virtual String get_import_settings_string() const override;
- ResourceImporterTexture();
+ ResourceImporterTexture(bool p_singleton = false);
~ResourceImporterTexture();
};
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 75bb6eefe8..c9c67f3d6b 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -2282,8 +2282,8 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
if (b.is_valid() && b->is_pressed() && b->get_button_index() == MouseButton::RIGHT) {
add_node_menu->clear();
- add_node_menu->add_icon_item(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), TTR("Add Node Here"), ADD_NODE);
- add_node_menu->add_icon_item(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), TTR("Instantiate Scene Here"), ADD_INSTANCE);
+ add_node_menu->add_icon_item(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), TTR("Add Node Here..."), ADD_NODE);
+ add_node_menu->add_icon_item(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), TTR("Instantiate Scene Here..."), ADD_INSTANCE);
for (Node *node : SceneTreeDock::get_singleton()->get_node_clipboard()) {
if (Object::cast_to<CanvasItem>(node)) {
add_node_menu->add_icon_item(get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons")), TTR("Paste Node(s) Here"), ADD_PASTE);
diff --git a/editor/plugins/debugger_editor_plugin.cpp b/editor/plugins/debugger_editor_plugin.cpp
index 3c9bc991d3..15829a55de 100644
--- a/editor/plugins/debugger_editor_plugin.cpp
+++ b/editor/plugins/debugger_editor_plugin.cpp
@@ -54,7 +54,6 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(PopupMenu *p_debug_menu) {
EditorDebuggerNode *debugger = memnew(EditorDebuggerNode);
Button *db = EditorNode::get_singleton()->add_bottom_panel_item(TTR("Debugger"), debugger);
- db->set_theme_type_variation("BottomPanelButton");
debugger->set_tool_button(db);
// Main editor debug menu.
diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp
index 911316822a..121b70a74f 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.cpp
+++ b/editor/plugins/tiles/tiles_editor_plugin.cpp
@@ -38,7 +38,6 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
-#include "editor/inspector_dock.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "scene/2d/tile_map.h"
@@ -326,8 +325,17 @@ void TileMapEditorPlugin::_tile_map_changed() {
}
void TileMapEditorPlugin::_update_tile_map() {
- if (tile_map && tile_map->get_tileset().is_valid()) {
- EditorNode::get_singleton()->edit_item(tile_map->get_tileset().ptr(), InspectorDock::get_inspector_singleton());
+ if (tile_map) {
+ Ref<TileSet> tile_set = tile_map->get_tileset();
+ if (tile_set.is_valid() && edited_tileset != tile_set->get_instance_id()) {
+ tile_set_plugin_singleton->edit(tile_map->get_tileset().ptr());
+ tile_set_plugin_singleton->make_visible(true);
+ edited_tileset = tile_set->get_instance_id();
+ } else if (tile_set.is_null()) {
+ tile_set_plugin_singleton->edit(nullptr);
+ tile_set_plugin_singleton->make_visible(false);
+ edited_tileset = ObjectID();
+ }
}
tile_map_changed_needs_update = false;
}
@@ -350,7 +358,9 @@ void TileMapEditorPlugin::edit(Object *p_object) {
tile_map->connect("changed", callable_mp(this, &TileMapEditorPlugin::_tile_map_changed));
if (tile_map->get_tileset().is_valid()) {
- EditorNode::get_singleton()->edit_item(tile_map->get_tileset().ptr(), InspectorDock::get_inspector_singleton());
+ tile_set_plugin_singleton->edit(tile_map->get_tileset().ptr());
+ tile_set_plugin_singleton->make_visible(true);
+ edited_tileset = tile_map->get_tileset()->get_instance_id();
}
}
}
diff --git a/editor/plugins/tiles/tiles_editor_plugin.h b/editor/plugins/tiles/tiles_editor_plugin.h
index 0bb45b746d..f8e944af81 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.h
+++ b/editor/plugins/tiles/tiles_editor_plugin.h
@@ -118,6 +118,8 @@ class TileMapEditorPlugin : public EditorPlugin {
TileMap *tile_map = nullptr;
bool tile_map_changed_needs_update = false;
+ ObjectID edited_tileset;
+
void _tile_map_changed();
void _update_tile_map();
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index e8db6ed679..3a148b7ca9 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -3771,16 +3771,16 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec
ED_SHORTCUT("scene_tree/batch_rename", TTR("Batch Rename"), KeyModifierMask::SHIFT | Key::F2);
ED_SHORTCUT_OVERRIDE("scene_tree/batch_rename", "macos", KeyModifierMask::SHIFT | Key::ENTER);
- ED_SHORTCUT("scene_tree/add_child_node", TTR("Add Child Node"), KeyModifierMask::CMD_OR_CTRL | Key::A);
- ED_SHORTCUT("scene_tree/instantiate_scene", TTR("Instantiate Child Scene"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::A);
+ ED_SHORTCUT("scene_tree/add_child_node", TTR("Add Child Node..."), KeyModifierMask::CMD_OR_CTRL | Key::A);
+ ED_SHORTCUT("scene_tree/instantiate_scene", TTR("Instantiate Child Scene..."), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::A);
ED_SHORTCUT("scene_tree/expand_collapse_all", TTR("Expand/Collapse Branch"));
ED_SHORTCUT("scene_tree/cut_node", TTR("Cut"), KeyModifierMask::CMD_OR_CTRL | Key::X);
ED_SHORTCUT("scene_tree/copy_node", TTR("Copy"), KeyModifierMask::CMD_OR_CTRL | Key::C);
ED_SHORTCUT("scene_tree/paste_node", TTR("Paste"), KeyModifierMask::CMD_OR_CTRL | Key::V);
ED_SHORTCUT("scene_tree/paste_node_as_sibling", TTR("Paste as Sibling"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::V);
- ED_SHORTCUT("scene_tree/change_node_type", TTR("Change Type"));
- ED_SHORTCUT("scene_tree/attach_script", TTR("Attach Script"));
- ED_SHORTCUT("scene_tree/extend_script", TTR("Extend Script"));
+ ED_SHORTCUT("scene_tree/change_node_type", TTR("Change Type..."));
+ ED_SHORTCUT("scene_tree/attach_script", TTR("Attach Script..."));
+ ED_SHORTCUT("scene_tree/extend_script", TTR("Extend Script..."));
ED_SHORTCUT("scene_tree/detach_script", TTR("Detach Script"));
ED_SHORTCUT("scene_tree/move_up", TTR("Move Up"), KeyModifierMask::CMD_OR_CTRL | Key::UP);
ED_SHORTCUT("scene_tree/move_down", TTR("Move Down"), KeyModifierMask::CMD_OR_CTRL | Key::DOWN);
diff --git a/platform/android/file_access_android.h b/platform/android/file_access_android.h
index 7ff5c4d117..3aa4ca98fc 100644
--- a/platform/android/file_access_android.h
+++ b/platform/android/file_access_android.h
@@ -76,8 +76,13 @@ public:
virtual bool file_exists(const String &p_path) override; // return true if a file exists
virtual uint64_t _get_modified_time(const String &p_file) override { return 0; }
- virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; }
- virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; }
+ virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
+ virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
+
+ virtual bool _get_hidden_attribute(const String &p_file) override { return false; }
+ virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; }
+ virtual bool _get_read_only_attribute(const String &p_file) override { return false; }
+ virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; }
virtual void close() override;
diff --git a/platform/android/file_access_filesystem_jandroid.h b/platform/android/file_access_filesystem_jandroid.h
index 739c8a0925..0c3f8d7259 100644
--- a/platform/android/file_access_filesystem_jandroid.h
+++ b/platform/android/file_access_filesystem_jandroid.h
@@ -91,8 +91,13 @@ public:
static void setup(jobject p_file_access_handler);
virtual uint64_t _get_modified_time(const String &p_file) override;
- virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; }
- virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; }
+ virtual BitField<FileAccess::UnixPermissionFlags> _get_unix_permissions(const String &p_file) override { return 0; }
+ virtual Error _set_unix_permissions(const String &p_file, BitField<FileAccess::UnixPermissionFlags> p_permissions) override { return FAILED; }
+
+ virtual bool _get_hidden_attribute(const String &p_file) override { return false; }
+ virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; }
+ virtual bool _get_read_only_attribute(const String &p_file) override { return false; }
+ virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; }
virtual void close() override;
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index e634f28e76..f0864f5134 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -379,7 +379,11 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) {
if (show_cursor && !previously_shown) {
WindowID window_id = get_window_at_screen_position(mouse_get_position());
- if (window_id != INVALID_WINDOW_ID) {
+ if (window_id != INVALID_WINDOW_ID && window_mouseover_id != window_id) {
+ if (window_mouseover_id != INVALID_WINDOW_ID) {
+ _send_window_event(windows[window_mouseover_id], WINDOW_EVENT_MOUSE_EXIT);
+ }
+ window_mouseover_id = window_id;
_send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER);
}
}
@@ -1449,6 +1453,11 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) {
DEBUG_LOG_X11("delete_sub_window: %lu (%u) \n", wd.x11_window, p_id);
+ if (window_mouseover_id == p_id) {
+ window_mouseover_id = INVALID_WINDOW_ID;
+ _send_window_event(windows[p_id], WINDOW_EVENT_MOUSE_EXIT);
+ }
+
window_set_rect_changed_callback(Callable(), p_id);
window_set_window_event_callback(Callable(), p_id);
window_set_input_event_callback(Callable(), p_id);
@@ -4292,7 +4301,8 @@ void DisplayServerX11::process_events() {
break;
}
- if (!mouse_mode_grab) {
+ if (!mouse_mode_grab && window_mouseover_id == window_id) {
+ window_mouseover_id = INVALID_WINDOW_ID;
_send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_EXIT);
}
@@ -4304,7 +4314,11 @@ void DisplayServerX11::process_events() {
break;
}
- if (!mouse_mode_grab) {
+ if (!mouse_mode_grab && window_mouseover_id != window_id) {
+ if (window_mouseover_id != INVALID_WINDOW_ID) {
+ _send_window_event(windows[window_mouseover_id], WINDOW_EVENT_MOUSE_EXIT);
+ }
+ window_mouseover_id = window_id;
_send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER);
}
} break;
diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h
index 74aa0b6e75..cce44a92de 100644
--- a/platform/linuxbsd/x11/display_server_x11.h
+++ b/platform/linuxbsd/x11/display_server_x11.h
@@ -225,6 +225,7 @@ class DisplayServerX11 : public DisplayServer {
List<WindowID> popup_list;
+ WindowID window_mouseover_id = INVALID_WINDOW_ID;
WindowID last_focused_window = INVALID_WINDOW_ID;
WindowID window_id_counter = MAIN_WINDOW_ID;
diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h
index e5e0e53bfb..69f6008043 100644
--- a/platform/macos/display_server_macos.h
+++ b/platform/macos/display_server_macos.h
@@ -171,6 +171,7 @@ private:
int current_layout = 0;
bool keyboard_layout_dirty = true;
+ WindowID window_mouseover_id = INVALID_WINDOW_ID;
WindowID last_focused_window = INVALID_WINDOW_ID;
WindowID window_id_counter = MAIN_WINDOW_ID;
float display_max_scale = 1.f;
@@ -240,6 +241,8 @@ public:
bool get_is_resizing() const;
void reparent_check(WindowID p_window);
WindowID _get_focused_window_or_popup() const;
+ void mouse_enter_window(WindowID p_window);
+ void mouse_exit_window(WindowID p_window);
void window_update(WindowID p_window);
void window_destroy(WindowID p_window);
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index de191827f5..e79d6acc3f 100644
--- a/platform/macos/display_server_macos.mm
+++ b/platform/macos/display_server_macos.mm
@@ -366,6 +366,25 @@ DisplayServer::WindowID DisplayServerMacOS::_get_focused_window_or_popup() const
return last_focused_window;
}
+void DisplayServerMacOS::mouse_enter_window(WindowID p_window) {
+ if (window_mouseover_id != p_window) {
+ if (window_mouseover_id != INVALID_WINDOW_ID) {
+ send_window_event(windows[window_mouseover_id], WINDOW_EVENT_MOUSE_EXIT);
+ }
+ window_mouseover_id = p_window;
+ if (p_window != INVALID_WINDOW_ID) {
+ send_window_event(windows[p_window], WINDOW_EVENT_MOUSE_ENTER);
+ }
+ }
+}
+
+void DisplayServerMacOS::mouse_exit_window(WindowID p_window) {
+ if (window_mouseover_id == p_window && p_window != INVALID_WINDOW_ID) {
+ send_window_event(windows[p_window], WINDOW_EVENT_MOUSE_EXIT);
+ }
+ window_mouseover_id = INVALID_WINDOW_ID;
+}
+
void DisplayServerMacOS::_dispatch_input_events(const Ref<InputEvent> &p_event) {
((DisplayServerMacOS *)(get_singleton()))->_dispatch_input_event(p_event);
}
@@ -2069,9 +2088,7 @@ void DisplayServerMacOS::mouse_set_mode(MouseMode p_mode) {
if (show_cursor && !previously_shown) {
window_id = get_window_at_screen_position(mouse_get_position());
- if (window_id != INVALID_WINDOW_ID) {
- send_window_event(windows[window_id], WINDOW_EVENT_MOUSE_ENTER);
- }
+ mouse_enter_window(window_id);
}
if (p_mode == MOUSE_MODE_CAPTURED) {
diff --git a/platform/macos/godot_content_view.mm b/platform/macos/godot_content_view.mm
index 3467bf90a1..231be83a03 100644
--- a/platform/macos/godot_content_view.mm
+++ b/platform/macos/godot_content_view.mm
@@ -505,9 +505,8 @@
return;
}
- DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
if (ds->mouse_get_mode() != DisplayServer::MOUSE_MODE_CAPTURED) {
- ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_MOUSE_EXIT);
+ ds->mouse_exit_window(window_id);
}
}
@@ -517,9 +516,8 @@
return;
}
- DisplayServerMacOS::WindowData &wd = ds->get_window(window_id);
if (ds->mouse_get_mode() != DisplayServer::MOUSE_MODE_CAPTURED) {
- ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_MOUSE_ENTER);
+ ds->mouse_enter_window(window_id);
}
ds->cursor_update_shape();
diff --git a/platform/macos/godot_window_delegate.mm b/platform/macos/godot_window_delegate.mm
index 1c6dbb1981..46355b4ae8 100644
--- a/platform/macos/godot_window_delegate.mm
+++ b/platform/macos/godot_window_delegate.mm
@@ -67,6 +67,7 @@
ds->window_set_transient(window_id, DisplayServerMacOS::INVALID_WINDOW_ID);
}
+ ds->mouse_exit_window(window_id);
ds->window_destroy(window_id);
}
diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp
index 07c6a8d6e4..c4be1821bd 100644
--- a/platform/windows/export/export_plugin.cpp
+++ b/platform/windows/export/export_plugin.cpp
@@ -168,10 +168,10 @@ Error EditorExportPlatformWindows::sign_shared_object(const Ref<EditorExportPres
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")) {
- _rcedit_add_data(p_preset, p_path, true);
+ _rcedit_add_data(p_preset, p_path, false);
String wrapper_path = p_path.get_basename() + ".console.exe";
if (FileAccess::exists(wrapper_path)) {
- _rcedit_add_data(p_preset, wrapper_path, false);
+ _rcedit_add_data(p_preset, wrapper_path, true);
}
}
return OK;
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index 614e9b9695..d86cc4a5f9 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -227,7 +227,6 @@ private:
void _zoom_plus();
void _update_zoom_label();
- PackedVector2Array get_connection_line(const Vector2 &p_from, const Vector2 &p_to);
void _draw_connection_line(CanvasItem *p_where, const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, const Color &p_to_color, float p_width, float p_zoom);
void _graph_node_selected(Node *p_gn);
@@ -243,8 +242,6 @@ private:
virtual void gui_input(const Ref<InputEvent> &p_ev) override;
void _top_layer_input(const Ref<InputEvent> &p_ev);
- bool is_in_input_hotzone(GraphNode *p_graph_node, int p_port, const Vector2 &p_mouse_pos, const Vector2i &p_port_size);
- bool is_in_output_hotzone(GraphNode *p_graph_node, int p_port, const Vector2 &p_mouse_pos, const Vector2i &p_port_size);
bool is_in_port_hotzone(const Vector2 &p_pos, const Vector2 &p_mouse_pos, const Vector2i &p_port_size, bool p_left);
void _top_layer_draw();
@@ -272,6 +269,9 @@ protected:
void _notification(int p_what);
+ virtual bool is_in_input_hotzone(GraphNode *p_graph_node, int p_port, const Vector2 &p_mouse_pos, const Vector2i &p_port_size);
+ virtual bool is_in_output_hotzone(GraphNode *p_graph_node, int p_port, const Vector2 &p_mouse_pos, const Vector2i &p_port_size);
+
GDVIRTUAL2RC(Vector<Vector2>, _get_connection_line, Vector2, Vector2)
GDVIRTUAL3R(bool, _is_in_input_hotzone, Object *, int, Vector2)
GDVIRTUAL3R(bool, _is_in_output_hotzone, Object *, int, Vector2)
@@ -287,6 +287,8 @@ public:
void disconnect_node(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port);
void clear_connections();
void force_connection_drag_end();
+
+ virtual PackedVector2Array get_connection_line(const Vector2 &p_from, const Vector2 &p_to);
virtual bool is_node_hover_valid(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port);
void set_connection_activity(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port, float p_activity);
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index b6a1737acb..d6b0fe797f 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -183,7 +183,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("icon_focus_color", "Button", Color(1, 1, 1, 1));
theme->set_color("icon_disabled_color", "Button", Color(1, 1, 1, 0.4));
- theme->set_constant("h_separation", "Button", Math::round(2 * scale));
+ theme->set_constant("h_separation", "Button", Math::round(4 * scale));
theme->set_constant("icon_max_width", "Button", 0);
// MenuBar
@@ -259,7 +259,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_disabled_color", "OptionButton", control_font_disabled_color);
theme->set_color("font_outline_color", "OptionButton", Color(1, 1, 1));
- theme->set_constant("h_separation", "OptionButton", Math::round(2 * scale));
+ theme->set_constant("h_separation", "OptionButton", Math::round(4 * scale));
theme->set_constant("arrow_margin", "OptionButton", Math::round(4 * scale));
theme->set_constant("outline_size", "OptionButton", 0);
theme->set_constant("modulate_arrow", "OptionButton", false);
@@ -282,7 +282,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_disabled_color", "MenuButton", Color(1, 1, 1, 0.3));
theme->set_color("font_outline_color", "MenuButton", Color(1, 1, 1));
- theme->set_constant("h_separation", "MenuButton", Math::round(3 * scale));
+ theme->set_constant("h_separation", "MenuButton", Math::round(4 * scale));
theme->set_constant("outline_size", "MenuButton", 0);
// CheckBox
@@ -788,7 +788,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("children_hl_line_width", "Tree", 1);
theme->set_constant("parent_hl_line_margin", "Tree", 0);
theme->set_constant("draw_guides", "Tree", 1);
- theme->set_constant("scroll_border", "Tree", 4);
+ theme->set_constant("scroll_border", "Tree", Math::round(4 * scale));
theme->set_constant("scroll_speed", "Tree", 12);
theme->set_constant("outline_size", "Tree", 0);
theme->set_constant("icon_max_width", "Tree", 0);
@@ -803,9 +803,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("panel", "ItemList", make_flat_stylebox(style_normal_color));
theme->set_stylebox("focus", "ItemList", focus);
- theme->set_constant("h_separation", "ItemList", 4);
- theme->set_constant("v_separation", "ItemList", 2);
- theme->set_constant("icon_margin", "ItemList", 4);
+ theme->set_constant("h_separation", "ItemList", Math::round(4 * scale));
+ theme->set_constant("v_separation", "ItemList", Math::round(2 * scale));
+ theme->set_constant("icon_margin", "ItemList", Math::round(4 * scale));
theme->set_constant("line_separation", "ItemList", Math::round(2 * scale));
theme->set_font("font", "ItemList", Ref<Font>());
@@ -1005,7 +1005,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_disabled_color", "ColorPickerButton", Color(0.9, 0.9, 0.9, 0.3));
theme->set_color("font_outline_color", "ColorPickerButton", Color(1, 1, 1));
- theme->set_constant("h_separation", "ColorPickerButton", Math::round(2 * scale));
+ theme->set_constant("h_separation", "ColorPickerButton", Math::round(4 * scale));
theme->set_constant("outline_size", "ColorPickerButton", 0);
// ColorPresetButton
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index 6430a1302d..a64ae07f05 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -2066,8 +2066,8 @@ void TorusMesh::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "inner_radius", PROPERTY_HINT_RANGE, "0.001,1000.0,0.001,or_greater,exp"), "set_inner_radius", "get_inner_radius");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "outer_radius", PROPERTY_HINT_RANGE, "0.001,1000.0,0.001,or_greater,exp"), "set_outer_radius", "get_outer_radius");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "3,128,1"), "set_rings", "get_rings");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "ring_segments", PROPERTY_HINT_RANGE, "3,64,1"), "set_ring_segments", "get_ring_segments");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "3,128,1,or_greater"), "set_rings", "get_rings");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "ring_segments", PROPERTY_HINT_RANGE, "3,64,1,or_greater"), "set_ring_segments", "get_ring_segments");
}
void TorusMesh::set_inner_radius(const float p_inner_radius) {
diff --git a/tests/core/io/test_json.h b/tests/core/io/test_json.h
index 73c7ac7a2e..bf2ed42740 100644
--- a/tests/core/io/test_json.h
+++ b/tests/core/io/test_json.h
@@ -186,20 +186,21 @@ TEST_CASE("[JSON] Parsing escape sequences") {
}
SUBCASE("Valid unicode escape sequences") {
- String json_string = "\"\\u0000\"";
+ String json_string = "\"\\u0020\"";
json.parse(json_string);
CHECK_MESSAGE(
json.get_error_line() == 0,
- vformat("Parsing valid unicode escape sequence with value `0000` as JSON should parse successfully."));
+ vformat("Parsing valid unicode escape sequence with value `0020` as JSON should parse successfully."));
String json_value = json.get_data();
CHECK_MESSAGE(
- json_value == "\0",
- vformat("Parsing valid unicode escape sequence with value `0000` as JSON should return the expected value."));
+ json_value == " ",
+ vformat("Parsing valid unicode escape sequence with value `0020` as JSON should return the expected value."));
}
SUBCASE("Invalid escape sequences") {
+ ERR_PRINT_OFF
for (char32_t i = 0; i < 128; i++) {
bool skip = false;
for (int j = 0; j < valid_escapes.size(); j++) {
@@ -228,6 +229,7 @@ TEST_CASE("[JSON] Parsing escape sequences") {
err == ERR_PARSE_ERROR,
vformat("Parsing invalid escape sequence with ASCII value `%d` as JSON should fail to parse with ERR_PARSE_ERROR.", i));
}
+ ERR_PRINT_ON
}
}
} // namespace TestJSON
diff --git a/tests/servers/rendering/test_shader_preprocessor.h b/tests/servers/rendering/test_shader_preprocessor.h
index 41a009ccf5..d65eb522e8 100644
--- a/tests/servers/rendering/test_shader_preprocessor.h
+++ b/tests/servers/rendering/test_shader_preprocessor.h
@@ -52,8 +52,7 @@ bool is_variable_char(unsigned char c) {
}
bool is_operator_char(unsigned char c) {
- static const std::string operators = "<>=+-*/";
- return operators.find(c) != std::string::npos;
+ return (c == '*') || (c == '+') || (c == '-') || (c == '/') || ((c >= '<') && (c <= '>'));
}
// Remove unnecessary spaces from a line.