diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index 7d38e86e6e..990c684577 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -113,16 +113,13 @@ jobs: with: submodules: recursive - - name: Linux dependencies for tests - if: matrix.proj-test + - name: Setup dependencies run: | - sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list - sudo apt-get install mesa-vulkan-drivers - - # TODO: Figure out somehow how to embed this one. - - name: wayland-scanner dependency - run: | - sudo apt-get install libwayland-bin + sudo apt-get update + sudo apt-get install libwayland-bin # TODO: Figure out somehow how to embed this one. + if [ "${{ matrix.proj-test }}" == "true" ]; then + sudo apt-get install mesa-vulkan-drivers + fi - name: Free disk space on runner run: | diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml index 4e7375bd18..fe1572d015 100644 --- a/.github/workflows/static_checks.yml +++ b/.github/workflows/static_checks.yml @@ -46,8 +46,8 @@ jobs: - name: Class reference schema checks run: | - sudo apt update - sudo apt install -y libxml2-utils + sudo apt-get update + sudo apt-get install libxml2-utils xmllint --quiet --noout --schema doc/class.xsd doc/classes/*.xml modules/*/doc_classes/*.xml platform/*/doc_classes/*.xml - name: Run C compiler on `gdextension_interface.h` diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index 0ac8c8cc9d..3435cb2d91 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -898,7 +898,7 @@ void InputMap::load_default() { } InputMap::InputMap() { - ERR_FAIL_COND_MSG(singleton, "Singleton in InputMap already exist."); + ERR_FAIL_COND_MSG(singleton, "Singleton in InputMap already exists."); singleton = this; } diff --git a/core/io/dir_access.cpp b/core/io/dir_access.cpp index b2cbfa13f1..bbd8be6543 100644 --- a/core/io/dir_access.cpp +++ b/core/io/dir_access.cpp @@ -492,19 +492,22 @@ Error DirAccess::_copy_dir(Ref &p_target_da, const String &p_to, int while (!n.is_empty()) { if (n != "." && n != "..") { if (p_copy_links && is_link(get_current_dir().path_join(n))) { - create_link(read_link(get_current_dir().path_join(n)), p_to + n); + Error err = p_target_da->create_link(read_link(get_current_dir().path_join(n)), p_to + n); + if (err) { + ERR_PRINT(vformat("Failed to copy symlink \"%s\".", n)); + } } else if (current_is_dir()) { dirs.push_back(n); } else { const String &rel_path = n; if (!n.is_relative_path()) { list_dir_end(); - return ERR_BUG; + ERR_FAIL_V_MSG(ERR_BUG, vformat("BUG: \"%s\" is not a relative path.", n)); } Error err = copy(get_current_dir().path_join(n), p_to + rel_path, p_chmod_flags); if (err) { list_dir_end(); - return err; + ERR_FAIL_V_MSG(err, vformat("Failed to copy file \"%s\".", n)); } } } diff --git a/core/io/ip.cpp b/core/io/ip.cpp index f203188c29..78d9a062eb 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -333,7 +333,7 @@ IP *IP::get_singleton() { IP *(*IP::_create)() = nullptr; IP *IP::create() { - ERR_FAIL_COND_V_MSG(singleton, nullptr, "IP singleton already exist."); + ERR_FAIL_COND_V_MSG(singleton, nullptr, "IP singleton already exists."); ERR_FAIL_NULL_V(_create, nullptr); return _create(); } diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h index 9de303f0e6..a28003dd88 100644 --- a/core/object/script_language_extension.h +++ b/core/object/script_language_extension.h @@ -462,7 +462,7 @@ public: r_result.description = ret.get("description", ""); r_result.is_deprecated = ret.get("is_deprecated", false); r_result.deprecated_message = ret.get("deprecated_message", ""); - r_result.is_deprecated = ret.get("is_deprecated", false); + r_result.is_experimental = ret.get("is_experimental", false); r_result.experimental_message = ret.get("experimental_message", ""); r_result.doc_type = ret.get("doc_type", ""); diff --git a/doc/classes/AStar2D.xml b/doc/classes/AStar2D.xml index 1a27ef0dca..cbb8b6dcde 100644 --- a/doc/classes/AStar2D.xml +++ b/doc/classes/AStar2D.xml @@ -245,7 +245,7 @@ Returns an array with the points that are in the path found by AStar2D between the given points. The array is ordered from the starting point to the ending point of the path. If there is no valid path to the target, and [param allow_partial_path] is [code]true[/code], returns a path to the point closest to the target that can be reached. - [b]Note:[/b] This method is not thread-safe. If called from a [Thread], it will return an empty array and will print an error message. + [b]Note:[/b] This method is not thread-safe; it can only be used from a single [Thread] at a given time. Consider using [Mutex] to ensure exclusive access to one thread to avoid race conditions. Additionally, when [param allow_partial_path] is [code]true[/code] and [param to_id] is disabled the search may take an unusually long time to finish. diff --git a/doc/classes/AStar3D.xml b/doc/classes/AStar3D.xml index fc05f97f7e..80abb34370 100644 --- a/doc/classes/AStar3D.xml +++ b/doc/classes/AStar3D.xml @@ -284,7 +284,7 @@ Returns an array with the points that are in the path found by AStar3D between the given points. The array is ordered from the starting point to the ending point of the path. If there is no valid path to the target, and [param allow_partial_path] is [code]true[/code], returns a path to the point closest to the target that can be reached. - [b]Note:[/b] This method is not thread-safe. If called from a [Thread], it will return an empty array and will print an error message. + [b]Note:[/b] This method is not thread-safe; it can only be used from a single [Thread] at a given time. Consider using [Mutex] to ensure exclusive access to one thread to avoid race conditions. Additionally, when [param allow_partial_path] is [code]true[/code] and [param to_id] is disabled the search may take an unusually long time to finish. diff --git a/doc/classes/AStarGrid2D.xml b/doc/classes/AStarGrid2D.xml index f3f3130a04..c0094178ab 100644 --- a/doc/classes/AStarGrid2D.xml +++ b/doc/classes/AStarGrid2D.xml @@ -98,7 +98,7 @@ Returns an array with the points that are in the path found by [AStarGrid2D] between the given points. The array is ordered from the starting point to the ending point of the path. If there is no valid path to the target, and [param allow_partial_path] is [code]true[/code], returns a path to the point closest to the target that can be reached. - [b]Note:[/b] This method is not thread-safe. If called from a [Thread], it will return an empty array and will print an error message. + [b]Note:[/b] This method is not thread-safe; it can only be used from a single [Thread] at a given time. Consider using [Mutex] to ensure exclusive access to one thread to avoid race conditions. Additionally, when [param allow_partial_path] is [code]true[/code] and [param to_id] is solid the search may take an unusually long time to finish. diff --git a/doc/classes/ClassDB.xml b/doc/classes/ClassDB.xml index 9c21f69b9b..f8ec708647 100644 --- a/doc/classes/ClassDB.xml +++ b/doc/classes/ClassDB.xml @@ -4,7 +4,8 @@ A class information repository. - Provides access to metadata stored for every available class. + Provides access to metadata stored for every available engine class. + [b]Note:[/b] Script-defined classes with [code]class_name[/code] are not part of [ClassDB], so they will not return reflection data such as a method or property list. However, [GDExtension]-defined classes [i]are[/i] part of [ClassDB], so they will return reflection data. @@ -200,14 +201,15 @@ - Returns the names of all the classes available. + Returns the names of all engine classes available. + [b]Note:[/b] Script-defined classes with [code]class_name[/code] are not included in this list. Use [method ProjectSettings.get_global_class_list] to get a list of script-defined classes instead. - Returns the names of all the classes that directly or indirectly inherit from [param class]. + Returns the names of all engine classes that directly or indirectly inherit from [param class]. diff --git a/doc/classes/SVGTexture.xml b/doc/classes/DPITexture.xml similarity index 69% rename from doc/classes/SVGTexture.xml rename to doc/classes/DPITexture.xml index ddbc5a6043..c7c803c164 100644 --- a/doc/classes/SVGTexture.xml +++ b/doc/classes/DPITexture.xml @@ -1,22 +1,22 @@ - + - A scalable [Texture2D] based on an SVG image. + An automatically scalable [Texture2D] based on an SVG image. - A scalable [Texture2D] based on an SVG image. [SVGTexture]s are automatically re-rasterized to match font oversampling. + An automatically scalable [Texture2D] based on an SVG image. [DPITexture]s are used to automatically re-rasterize icons and other texture based UI theme elements to match viewport scale and font oversampling. See also [member ProjectSettings.display/window/stretch/mode] ("canvas_items" mode) and [member Viewport.oversampling_override]. - + - Creates a new [SVGTexture] and initializes it by allocating and setting the SVG data from string. + Creates a new [DPITexture] and initializes it by allocating and setting the SVG data from string. @@ -48,10 +48,10 @@ - SVG texture scale. [code]1.0[/code] is the original SVG size. Higher values result in a larger image. + Texture scale. [code]1.0[/code] is the original SVG size. Higher values result in a larger image. - If set, remaps SVG texture colors according to [Color]-[Color] map. + If set, remaps texture colors according to [Color]-[Color] map. diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index aaf19feb05..281fc7d327 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -2592,10 +2592,10 @@ The display server supports initiating window drag and resize operations on demand. See [method window_start_drag] and [method window_start_resize]. - Display server supports [constant WINDOW_FLAG_EXCLUDE_FROM_CAPTURE] window flag. + Display server supports [constant WINDOW_FLAG_EXCLUDE_FROM_CAPTURE] window flag. [b]Windows, macOS[/b] - Display server supports embedding a window from another process. [b]Windows, Linux (X11)[/b] + Display server supports embedding a window from another process. [b]Windows, Linux (X11), macOS[/b] Native file selection dialog supports MIME types as filters. @@ -3123,7 +3123,7 @@ Window is excluded from screenshots taken by [method screen_get_image], [method screen_get_image_rect], and [method screen_get_pixel]. - [b]Note:[/b] This flag is implemented on macOS and Windows. + [b]Note:[/b] This flag is implemented on macOS and Windows (10, 20H1). [b]Note:[/b] Setting this flag will prevent standard screenshot methods from capturing a window image, but does [b]NOT[/b] guarantee that other apps won't be able to capture an image. It should not be used as a DRM or security measure. diff --git a/doc/classes/EditorExportPlatform.xml b/doc/classes/EditorExportPlatform.xml index 305f325e39..7376db35a1 100644 --- a/doc/classes/EditorExportPlatform.xml +++ b/doc/classes/EditorExportPlatform.xml @@ -121,7 +121,7 @@ - + Returns array of core file names that always should be exported regardless of preset config. diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index 36104c7719..2a3118eee0 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -1578,7 +1578,7 @@ The GDScript syntax highlighter text color for node reference literals (e.g. [code]$"Sprite"[/code] and [code]%"Sprite"[/code]]). - The GDScript syntax highlighter text color for [StringName] literals (e.g. [code]>"example"[/code]). + The GDScript syntax highlighter text color for [StringName] literals (e.g. [code]&"example"[/code]). The script editor's non-control flow keyword color (used for keywords like [code]var[/code], [code]func[/code], [code]extends[/code], ...). diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 2a19434429..3bc4300712 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -553,7 +553,7 @@ When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when a static inferred type uses a [Variant] as initial value, which makes the static type to also be Variant. - When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when a variable, constant, or parameter has an implicitly inferred static type. + When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when a variable, constant, or parameter has an implicitly inferred static type. In GDScript, type inference is performed by declaring a variable with [code]:=[/code] instead of [code]=[/code] and leaving out the type specifier. For example, [code]var x := 1[/code] will [i]infer[/i] the [int] type, while [code]var x: int = 1[/code] explicitly declares the variable as [int]. [b]Note:[/b] This warning is recommended [i]in addition[/i] to [member debug/gdscript/warnings/untyped_declaration] if you want to always specify the type explicitly. Having [code]INFERRED_DECLARATION[/code] warning level higher than [code]UNTYPED_DECLARATION[/code] warning level makes little sense and is not recommended. @@ -1194,7 +1194,7 @@ Maximum undo/redo history size for [TextEdit] fields. - If set to [code]true[/code] and [member display/window/stretch/mode] is set to [b]"canvas_items"[/b], font and [SVGTexture] oversampling is enabled in the main window. Use [member Viewport.oversampling] to control oversampling in other viewports and windows. + If set to [code]true[/code] and [member display/window/stretch/mode] is set to [b]"canvas_items"[/b], font and [DPITexture] oversampling is enabled in the main window. Use [member Viewport.oversampling] to control oversampling in other viewports and windows. Path to a custom [Theme] resource file to use for the project ([code].theme[/code] or generic [code].tres[/code]/[code].res[/code] extension). diff --git a/doc/classes/ResourceImporterSVG.xml b/doc/classes/ResourceImporterSVG.xml index 625fb2b917..0eb87330d2 100644 --- a/doc/classes/ResourceImporterSVG.xml +++ b/doc/classes/ResourceImporterSVG.xml @@ -1,19 +1,19 @@ - Imports an SVG file as a scalable texture for use in 2D or 3D rendering. + Imports an SVG file as an automatically scalable texture for use in UI elements and 2D rendering. - This importer imports [SVGTexture] resources. See also [ResourceImporterTexture] and [ResourceImporterImage]. + This importer imports [DPITexture] resources. See also [ResourceImporterTexture] and [ResourceImporterImage]. - SVG texture scale. [code]1.0[/code] is the original SVG size. Higher values result in a larger image. + Texture scale. [code]1.0[/code] is the original SVG size. Higher values result in a larger image. - If set, remaps SVG texture colors according to [Color]-[Color] map. + If set, remaps texture colors according to [Color]-[Color] map. If [code]true[/code], uses lossless compression for the SVG source. diff --git a/doc/classes/Sprite2D.xml b/doc/classes/Sprite2D.xml index 3d639fdf83..3bb664adb8 100644 --- a/doc/classes/Sprite2D.xml +++ b/doc/classes/Sprite2D.xml @@ -75,6 +75,7 @@ If [code]true[/code], texture is cut from a larger atlas texture. See [member region_rect]. + [b]Note:[/b] When using a custom [Shader] on a [Sprite2D], the [code]UV[/code] shader built-in will refer to the entire texture space. Use the [code]REGION_RECT[/code] built-in to get the currently visible region defined in [member region_rect] instead. See [url=$DOCS_URL/tutorials/shaders/shader_reference/canvas_item_shader.html]CanvasItem shaders[/url] for details. If [code]true[/code], the area outside of the [member region_rect] is clipped to avoid bleeding of the surrounding texture pixels. [member region_enabled] must be [code]true[/code]. diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index 5996d16588..58608a3299 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -122,11 +122,21 @@ Returns the viewport's texture. [b]Note:[/b] When trying to store the current texture (e.g. in a file), it might be completely black or outdated if used too early, especially when used in e.g. [method Node._ready]. To make sure the texture you get is correct, you can await [signal RenderingServer.frame_post_draw] signal. - [codeblock] + [codeblocks] + [gdscript] func _ready(): - await RenderingServer.frame_post_draw - $Viewport.get_texture().get_image().save_png("user://Screenshot.png") - [/codeblock] + await RenderingServer.frame_post_draw + $Viewport.get_texture().get_image().save_png("user://Screenshot.png") + [/gdscript] + [csharp] + public async override void _Ready() + { + await ToSignal(RenderingServer.Singleton, RenderingServer.SignalName.FramePostDraw); + var viewport = GetNode<Viewport>("Viewport"); + viewport.GetTexture().GetImage().SavePng("user://Screenshot.png"); + } + [/csharp] + [/codeblocks] [b]Note:[/b] When [member use_hdr_2d] is [code]true[/code] the returned texture will be an HDR image encoded in linear space. @@ -366,7 +376,7 @@ See also [member ProjectSettings.rendering/anti_aliasing/quality/msaa_3d] and [method RenderingServer.viewport_set_msaa_3d]. - If [code]true[/code] and one of the following conditions is true: [member SubViewport.size_2d_override_stretch] and [member SubViewport.size_2d_override] are set, [member Window.content_scale_factor] is set and scaling is enabled, [member oversampling_override] is set, font and [SVGTexture] oversampling is enabled. + If [code]true[/code] and one of the following conditions are true: [member SubViewport.size_2d_override_stretch] and [member SubViewport.size_2d_override] are set, [member Window.content_scale_factor] is set and scaling is enabled, [member oversampling_override] is set, font and [DPITexture] oversampling are enabled. If greater than zero, this value is used as the font oversampling factor, otherwise oversampling is equal to viewport scale. diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml index 3cfb17473d..85b502544e 100644 --- a/doc/classes/Window.xml +++ b/doc/classes/Window.xml @@ -904,7 +904,8 @@ Windows is excluded from screenshots taken by [method DisplayServer.screen_get_image], [method DisplayServer.screen_get_image_rect], and [method DisplayServer.screen_get_pixel]. - [b]Note:[/b] This flag is implemented on macOS and Windows. + [b]Note:[/b] This flag has no effect in embedded windows. + [b]Note:[/b] This flag is implemented on macOS and Windows (10, 20H1). [b]Note:[/b] Setting this flag will prevent standard screenshot methods from capturing a window image, but does [b]NOT[/b] guarantee that other apps won't be able to capture an image. It should not be used as a DRM or security measure. diff --git a/drivers/accesskit/accessibility_driver_accesskit.cpp b/drivers/accesskit/accessibility_driver_accesskit.cpp index 4051d2afa7..fd178afbbe 100644 --- a/drivers/accesskit/accessibility_driver_accesskit.cpp +++ b/drivers/accesskit/accessibility_driver_accesskit.cpp @@ -505,7 +505,7 @@ void AccessibilityDriverAccessKit::accessibility_free_element(const RID &p_id) { } void AccessibilityDriverAccessKit::accessibility_element_set_meta(const RID &p_id, const Variant &p_meta) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -519,7 +519,7 @@ Variant AccessibilityDriverAccessKit::accessibility_element_get_meta(const RID & } void AccessibilityDriverAccessKit::accessibility_update_set_focus(const RID &p_id) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); if (p_id.is_valid() && rid_owner.owns(p_id)) { focus = p_id; @@ -632,7 +632,7 @@ void AccessibilityDriverAccessKit::accessibility_set_window_focused(DisplayServe } void AccessibilityDriverAccessKit::accessibility_update_set_role(const RID &p_id, DisplayServer::AccessibilityRole p_role) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -646,7 +646,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_role(const RID &p_id } void AccessibilityDriverAccessKit::accessibility_update_set_name(const RID &p_id, const String &p_name) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -662,7 +662,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_name(const RID &p_id } void AccessibilityDriverAccessKit::accessibility_update_set_extra_info(const RID &p_id, const String &p_name_extra_info) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -678,7 +678,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_extra_info(const RID } void AccessibilityDriverAccessKit::accessibility_update_set_description(const RID &p_id, const String &p_description) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -692,7 +692,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_description(const RI } void AccessibilityDriverAccessKit::accessibility_update_set_value(const RID &p_id, const String &p_value) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -709,7 +709,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_value(const RID &p_i } void AccessibilityDriverAccessKit::accessibility_update_set_tooltip(const RID &p_id, const String &p_tooltip) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -723,7 +723,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_tooltip(const RID &p } void AccessibilityDriverAccessKit::accessibility_update_set_bounds(const RID &p_id, const Rect2 &p_rect) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -738,7 +738,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_bounds(const RID &p_ } void AccessibilityDriverAccessKit::accessibility_update_set_transform(const RID &p_id, const Transform2D &p_transform) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -749,7 +749,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_transform(const RID } void AccessibilityDriverAccessKit::accessibility_update_add_child(const RID &p_id, const RID &p_child_id) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -762,7 +762,7 @@ void AccessibilityDriverAccessKit::accessibility_update_add_child(const RID &p_i } void AccessibilityDriverAccessKit::accessibility_update_add_related_controls(const RID &p_id, const RID &p_related_id) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -775,7 +775,7 @@ void AccessibilityDriverAccessKit::accessibility_update_add_related_controls(con } void AccessibilityDriverAccessKit::accessibility_update_add_related_details(const RID &p_id, const RID &p_related_id) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -788,7 +788,7 @@ void AccessibilityDriverAccessKit::accessibility_update_add_related_details(cons } void AccessibilityDriverAccessKit::accessibility_update_add_related_described_by(const RID &p_id, const RID &p_related_id) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -801,7 +801,7 @@ void AccessibilityDriverAccessKit::accessibility_update_add_related_described_by } void AccessibilityDriverAccessKit::accessibility_update_add_related_flow_to(const RID &p_id, const RID &p_related_id) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -814,7 +814,7 @@ void AccessibilityDriverAccessKit::accessibility_update_add_related_flow_to(cons } void AccessibilityDriverAccessKit::accessibility_update_add_related_labeled_by(const RID &p_id, const RID &p_related_id) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -827,7 +827,7 @@ void AccessibilityDriverAccessKit::accessibility_update_add_related_labeled_by(c } void AccessibilityDriverAccessKit::accessibility_update_add_related_radio_group(const RID &p_id, const RID &p_related_id) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -840,7 +840,7 @@ void AccessibilityDriverAccessKit::accessibility_update_add_related_radio_group( } void AccessibilityDriverAccessKit::accessibility_update_set_active_descendant(const RID &p_id, const RID &p_other_id) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -853,7 +853,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_active_descendant(co } void AccessibilityDriverAccessKit::accessibility_update_set_next_on_line(const RID &p_id, const RID &p_other_id) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -866,7 +866,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_next_on_line(const R } void AccessibilityDriverAccessKit::accessibility_update_set_previous_on_line(const RID &p_id, const RID &p_other_id) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -879,7 +879,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_previous_on_line(con } void AccessibilityDriverAccessKit::accessibility_update_set_member_of(const RID &p_id, const RID &p_group_id) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -892,7 +892,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_member_of(const RID } void AccessibilityDriverAccessKit::accessibility_update_set_in_page_link_target(const RID &p_id, const RID &p_other_id) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -905,7 +905,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_in_page_link_target( } void AccessibilityDriverAccessKit::accessibility_update_set_error_message(const RID &p_id, const RID &p_other_id) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -918,7 +918,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_error_message(const } void AccessibilityDriverAccessKit::accessibility_update_set_live(const RID &p_id, DisplayServer::AccessibilityLiveMode p_live) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -938,7 +938,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_live(const RID &p_id } void AccessibilityDriverAccessKit::accessibility_update_add_action(const RID &p_id, DisplayServer::AccessibilityAction p_action, const Callable &p_callable) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -950,7 +950,7 @@ void AccessibilityDriverAccessKit::accessibility_update_add_action(const RID &p_ } void AccessibilityDriverAccessKit::accessibility_update_add_custom_action(const RID &p_id, int p_action_id, const String &p_action_description) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -967,7 +967,7 @@ void AccessibilityDriverAccessKit::accessibility_update_add_custom_action(const } void AccessibilityDriverAccessKit::accessibility_update_set_table_row_count(const RID &p_id, int p_count) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -977,7 +977,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_table_row_count(cons } void AccessibilityDriverAccessKit::accessibility_update_set_table_column_count(const RID &p_id, int p_count) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -987,7 +987,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_table_column_count(c } void AccessibilityDriverAccessKit::accessibility_update_set_table_row_index(const RID &p_id, int p_index) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -997,7 +997,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_table_row_index(cons } void AccessibilityDriverAccessKit::accessibility_update_set_table_column_index(const RID &p_id, int p_index) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1007,7 +1007,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_table_column_index(c } void AccessibilityDriverAccessKit::accessibility_update_set_table_cell_position(const RID &p_id, int p_row_index, int p_column_index) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1018,7 +1018,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_table_cell_position( } void AccessibilityDriverAccessKit::accessibility_update_set_table_cell_span(const RID &p_id, int p_row_span, int p_column_span) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1029,7 +1029,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_table_cell_span(cons } void AccessibilityDriverAccessKit::accessibility_update_set_list_item_count(const RID &p_id, int p_size) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1039,7 +1039,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_list_item_count(cons } void AccessibilityDriverAccessKit::accessibility_update_set_list_item_index(const RID &p_id, int p_index) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1049,7 +1049,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_list_item_index(cons } void AccessibilityDriverAccessKit::accessibility_update_set_list_item_level(const RID &p_id, int p_level) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1059,7 +1059,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_list_item_level(cons } void AccessibilityDriverAccessKit::accessibility_update_set_list_item_selected(const RID &p_id, bool p_selected) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1069,7 +1069,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_list_item_selected(c } void AccessibilityDriverAccessKit::accessibility_update_set_list_item_expanded(const RID &p_id, bool p_expanded) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1079,7 +1079,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_list_item_expanded(c } void AccessibilityDriverAccessKit::accessibility_update_set_popup_type(const RID &p_id, DisplayServer::AccessibilityPopupType p_popup) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1102,7 +1102,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_popup_type(const RID } void AccessibilityDriverAccessKit::accessibility_update_set_checked(const RID &p_id, bool p_checekd) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1116,7 +1116,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_checked(const RID &p } void AccessibilityDriverAccessKit::accessibility_update_set_num_value(const RID &p_id, double p_position) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1126,7 +1126,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_num_value(const RID } void AccessibilityDriverAccessKit::accessibility_update_set_num_range(const RID &p_id, double p_min, double p_max) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1137,7 +1137,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_num_range(const RID } void AccessibilityDriverAccessKit::accessibility_update_set_num_step(const RID &p_id, double p_step) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1147,7 +1147,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_num_step(const RID & } void AccessibilityDriverAccessKit::accessibility_update_set_num_jump(const RID &p_id, double p_jump) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1157,7 +1157,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_num_jump(const RID & } void AccessibilityDriverAccessKit::accessibility_update_set_scroll_x(const RID &p_id, double p_position) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1167,7 +1167,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_scroll_x(const RID & } void AccessibilityDriverAccessKit::accessibility_update_set_scroll_x_range(const RID &p_id, double p_min, double p_max) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1178,7 +1178,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_scroll_x_range(const } void AccessibilityDriverAccessKit::accessibility_update_set_scroll_y(const RID &p_id, double p_position) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1188,7 +1188,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_scroll_y(const RID & } void AccessibilityDriverAccessKit::accessibility_update_set_scroll_y_range(const RID &p_id, double p_min, double p_max) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1199,7 +1199,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_scroll_y_range(const } void AccessibilityDriverAccessKit::accessibility_update_set_text_decorations(const RID &p_id, bool p_underline, bool p_strikethrough, bool p_overline) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1223,7 +1223,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_text_decorations(con } void AccessibilityDriverAccessKit::accessibility_update_set_text_align(const RID &p_id, HorizontalAlignment p_align) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1246,7 +1246,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_text_align(const RID } void AccessibilityDriverAccessKit::accessibility_update_set_text_selection(const RID &p_id, const RID &p_text_start_id, int p_start_char, const RID &p_text_end_id, int p_end_char) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1293,7 +1293,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_text_selection(const } void AccessibilityDriverAccessKit::accessibility_update_set_flag(const RID &p_id, DisplayServer::AccessibilityFlags p_flag, bool p_value) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1374,7 +1374,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_flag(const RID &p_id } void AccessibilityDriverAccessKit::accessibility_update_set_classname(const RID &p_id, const String &p_classname) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1388,7 +1388,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_classname(const RID } void AccessibilityDriverAccessKit::accessibility_update_set_placeholder(const RID &p_id, const String &p_placeholder) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1402,7 +1402,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_placeholder(const RI } void AccessibilityDriverAccessKit::accessibility_update_set_language(const RID &p_id, const String &p_language) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1412,7 +1412,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_language(const RID & } void AccessibilityDriverAccessKit::accessibility_update_set_text_orientation(const RID &p_id, bool p_vertical) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1426,7 +1426,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_text_orientation(con } void AccessibilityDriverAccessKit::accessibility_update_set_list_orientation(const RID &p_id, bool p_vertical) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1440,7 +1440,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_list_orientation(con } void AccessibilityDriverAccessKit::accessibility_update_set_shortcut(const RID &p_id, const String &p_shortcut) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1454,7 +1454,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_shortcut(const RID & } void AccessibilityDriverAccessKit::accessibility_update_set_url(const RID &p_id, const String &p_url) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1468,7 +1468,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_url(const RID &p_id, } void AccessibilityDriverAccessKit::accessibility_update_set_role_description(const RID &p_id, const String &p_description) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1482,7 +1482,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_role_description(con } void AccessibilityDriverAccessKit::accessibility_update_set_state_description(const RID &p_id, const String &p_description) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1496,7 +1496,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_state_description(co } void AccessibilityDriverAccessKit::accessibility_update_set_color_value(const RID &p_id, const Color &p_color) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1506,7 +1506,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_color_value(const RI } void AccessibilityDriverAccessKit::accessibility_update_set_background_color(const RID &p_id, const Color &p_color) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); @@ -1516,7 +1516,7 @@ void AccessibilityDriverAccessKit::accessibility_update_set_background_color(con } void AccessibilityDriverAccessKit::accessibility_update_set_foreground_color(const RID &p_id, const Color &p_color) { - ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessiblinity update is only allowed inside NOTIFICATION_ACCESSIBILITY_UPDATE notification."); + ERR_FAIL_COND_MSG(!in_accessibility_update, "Accessibility updates are only allowed inside the NOTIFICATION_ACCESSIBILITY_UPDATE notification."); AccessibilityElement *ae = rid_owner.get_or_null(p_id); ERR_FAIL_NULL(ae); diff --git a/drivers/apple_embedded/display_server_apple_embedded.mm b/drivers/apple_embedded/display_server_apple_embedded.mm index 1543965733..86a97ecfd0 100644 --- a/drivers/apple_embedded/display_server_apple_embedded.mm +++ b/drivers/apple_embedded/display_server_apple_embedded.mm @@ -114,7 +114,7 @@ DisplayServerAppleEmbedded::DisplayServerAppleEmbedded(const String &p_rendering #if defined(GLES3_ENABLED) bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3"); if (fallback_to_opengl3 && rendering_driver != "opengl3") { - WARN_PRINT("Your device seem not to support MoltenVK or Metal, switching to OpenGL 3."); + WARN_PRINT("Your device does not seem to support MoltenVK or Metal, switching to OpenGL 3."); rendering_driver = "opengl3"; OS::get_singleton()->set_current_rendering_method("gl_compatibility"); OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); diff --git a/drivers/d3d12/SCsub b/drivers/d3d12/SCsub index 5957dbf70c..f026ea2abb 100644 --- a/drivers/d3d12/SCsub +++ b/drivers/d3d12/SCsub @@ -162,7 +162,9 @@ else: env.Append(CCFLAGS=["-Wno-unknown-pragmas"]) # This is needed since rendering_device_d3d12.cpp needs to include some Mesa internals. -env_d3d12_rdd.Prepend(CPPEXTPATH=mesa_private_inc_paths) +# FIXME: Should be CPPEXTPATH, but doing so introduces an include-order bug when combined with +# godot-nir-static; this necessitates warning macro wrappers. See #106376. +env_d3d12_rdd.Prepend(CPPPATH=mesa_private_inc_paths) # For the same reason as above, the defines must be the same as in the 3rd-party code itself. env_d3d12_rdd.Append(CPPDEFINES=extra_defines) diff --git a/drivers/d3d12/rendering_context_driver_d3d12.cpp b/drivers/d3d12/rendering_context_driver_d3d12.cpp index cfb5611595..bc4f8d7d63 100644 --- a/drivers/d3d12/rendering_context_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_context_driver_d3d12.cpp @@ -41,8 +41,23 @@ #include "core/version.h" #include "servers/rendering/rendering_device.h" +GODOT_GCC_WARNING_PUSH +GODOT_GCC_WARNING_IGNORE("-Wmissing-field-initializers") +GODOT_GCC_WARNING_IGNORE("-Wnon-virtual-dtor") +GODOT_GCC_WARNING_IGNORE("-Wshadow") +GODOT_GCC_WARNING_IGNORE("-Wswitch") +GODOT_CLANG_WARNING_PUSH +GODOT_CLANG_WARNING_IGNORE("-Wmissing-field-initializers") +GODOT_CLANG_WARNING_IGNORE("-Wnon-virtual-dtor") +GODOT_CLANG_WARNING_IGNORE("-Wstring-plus-int") +GODOT_CLANG_WARNING_IGNORE("-Wswitch") +GODOT_MSVC_WARNING_PUSH + #include +GODOT_GCC_WARNING_POP +GODOT_CLANG_WARNING_POP + #if !defined(_MSC_VER) #include diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp index 83ed7e1ec9..045af859de 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp @@ -42,6 +42,24 @@ #include "d3d12_godot_nir_bridge.h" #include "rendering_context_driver_d3d12.h" +GODOT_GCC_WARNING_PUSH +GODOT_GCC_WARNING_IGNORE("-Wimplicit-fallthrough") +GODOT_GCC_WARNING_IGNORE("-Wlogical-not-parentheses") +GODOT_GCC_WARNING_IGNORE("-Wmissing-field-initializers") +GODOT_GCC_WARNING_IGNORE("-Wnon-virtual-dtor") +GODOT_GCC_WARNING_IGNORE("-Wshadow") +GODOT_GCC_WARNING_IGNORE("-Wswitch") +GODOT_CLANG_WARNING_PUSH +GODOT_CLANG_WARNING_IGNORE("-Wimplicit-fallthrough") +GODOT_CLANG_WARNING_IGNORE("-Wlogical-not-parentheses") +GODOT_CLANG_WARNING_IGNORE("-Wmissing-field-initializers") +GODOT_CLANG_WARNING_IGNORE("-Wnon-virtual-dtor") +GODOT_CLANG_WARNING_IGNORE("-Wstring-plus-int") +GODOT_CLANG_WARNING_IGNORE("-Wswitch") +GODOT_MSVC_WARNING_PUSH +GODOT_MSVC_WARNING_IGNORE(4200) // "nonstandard extension used: zero-sized array in struct/union". +GODOT_MSVC_WARNING_IGNORE(4806) // "'&': unsafe operation: no value of type 'bool' promoted to type 'uint32_t' can equal the given constant". + #include #include #include @@ -49,6 +67,10 @@ extern "C" { #include } +GODOT_GCC_WARNING_POP +GODOT_CLANG_WARNING_POP +GODOT_MSVC_WARNING_POP + #if !defined(_MSC_VER) #include @@ -3696,7 +3718,7 @@ void RenderingDeviceDriverD3D12::_command_bind_uniform_set(CommandBufferID p_cmd if (unlikely(frame_heap_walkers.resources->get_free_handles() < num_resource_descs)) { if (!frames[frame_idx].desc_heaps_exhausted_reported.resources) { frames[frame_idx].desc_heaps_exhausted_reported.resources = true; - ERR_FAIL_MSG("Cannot bind uniform set because there's no enough room in current frame's RESOURCES descriptor heap.\n" + ERR_FAIL_MSG("Cannot bind uniform set because there's not enough room in the current frame's RESOURCES descriptor heap.\n" "Please increase the value of the rendering/rendering_device/d3d12/max_resource_descriptors_per_frame project setting."); } else { return; @@ -3751,7 +3773,7 @@ void RenderingDeviceDriverD3D12::_command_bind_uniform_set(CommandBufferID p_cmd if (unlikely(frame_heap_walkers.samplers->get_free_handles() < num_sampler_descs)) { if (!frames[frame_idx].desc_heaps_exhausted_reported.samplers) { frames[frame_idx].desc_heaps_exhausted_reported.samplers = true; - ERR_FAIL_MSG("Cannot bind uniform set because there's no enough room in current frame's SAMPLERS descriptors heap.\n" + ERR_FAIL_MSG("Cannot bind uniform set because there's not enough room in the current frame's SAMPLERS descriptors heap.\n" "Please increase the value of the rendering/rendering_device/d3d12/max_sampler_descriptors_per_frame project setting."); } else { return; @@ -3826,7 +3848,7 @@ void RenderingDeviceDriverD3D12::command_clear_buffer(CommandBufferID p_cmd_buff if (!frames[frame_idx].desc_heaps_exhausted_reported.resources) { frames[frame_idx].desc_heaps_exhausted_reported.resources = true; ERR_FAIL_MSG( - "Cannot clear buffer because there's no enough room in current frame's RESOURCE descriptors heap.\n" + "Cannot clear buffer because there's not enough room in the current frame's RESOURCE descriptors heap.\n" "Please increase the value of the rendering/rendering_device/d3d12/max_resource_descriptors_per_frame project setting."); } else { return; @@ -3836,7 +3858,7 @@ void RenderingDeviceDriverD3D12::command_clear_buffer(CommandBufferID p_cmd_buff if (!frames[frame_idx].desc_heaps_exhausted_reported.aux) { frames[frame_idx].desc_heaps_exhausted_reported.aux = true; ERR_FAIL_MSG( - "Cannot clear buffer because there's no enough room in current frame's AUX descriptors heap.\n" + "Cannot clear buffer because there's not enough room in the current frame's AUX descriptors heap.\n" "Please increase the value of the rendering/rendering_device/d3d12/max_misc_descriptors_per_frame project setting."); } else { return; @@ -3981,7 +4003,7 @@ void RenderingDeviceDriverD3D12::command_clear_color_texture(CommandBufferID p_c if (!frames[frame_idx].desc_heaps_exhausted_reported.rtv) { frames[frame_idx].desc_heaps_exhausted_reported.rtv = true; ERR_FAIL_MSG( - "Cannot clear texture because there's no enough room in current frame's RENDER TARGET descriptors heap.\n" + "Cannot clear texture because there's not enough room in the current frame's RENDER TARGET descriptors heap.\n" "Please increase the value of the rendering/rendering_device/d3d12/max_misc_descriptors_per_frame project setting."); } else { return; @@ -4016,7 +4038,7 @@ void RenderingDeviceDriverD3D12::command_clear_color_texture(CommandBufferID p_c if (!frames[frame_idx].desc_heaps_exhausted_reported.resources) { frames[frame_idx].desc_heaps_exhausted_reported.resources = true; ERR_FAIL_MSG( - "Cannot clear texture because there's no enough room in current frame's RESOURCE descriptors heap.\n" + "Cannot clear texture because there's not enough room in the current frame's RESOURCE descriptors heap.\n" "Please increase the value of the rendering/rendering_device/d3d12/max_resource_descriptors_per_frame project setting."); } else { return; @@ -4026,7 +4048,7 @@ void RenderingDeviceDriverD3D12::command_clear_color_texture(CommandBufferID p_c if (!frames[frame_idx].desc_heaps_exhausted_reported.aux) { frames[frame_idx].desc_heaps_exhausted_reported.aux = true; ERR_FAIL_MSG( - "Cannot clear texture because there's no enough room in current frame's AUX descriptors heap.\n" + "Cannot clear texture because there's not enough room in the current frame's AUX descriptors heap.\n" "Please increase the value of the rendering/rendering_device/d3d12/max_misc_descriptors_per_frame project setting."); } else { return; @@ -4520,7 +4542,7 @@ void RenderingDeviceDriverD3D12::command_next_render_subpass(CommandBufferID p_c if (frames[frame_idx].desc_heap_walkers.rtv.is_at_eof()) { if (!frames[frame_idx].desc_heaps_exhausted_reported.rtv) { frames[frame_idx].desc_heaps_exhausted_reported.rtv = true; - ERR_FAIL_MSG("Cannot begin subpass because there's no enough room in current frame's RENDER TARGET descriptors heap.\n" + ERR_FAIL_MSG("Cannot begin subpass because there's not enough room in the current frame's RENDER TARGET descriptors heap.\n" "Please increase the value of the rendering/rendering_device/d3d12/max_misc_descriptors_per_frame project setting."); } else { return; diff --git a/drivers/d3d12/rendering_shader_container_d3d12.cpp b/drivers/d3d12/rendering_shader_container_d3d12.cpp index df0bb2dede..17ecac38af 100644 --- a/drivers/d3d12/rendering_shader_container_d3d12.cpp +++ b/drivers/d3d12/rendering_shader_container_d3d12.cpp @@ -43,26 +43,10 @@ #define __REQUIRED_RPCNDR_H_VERSION__ 475 #endif -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Wshadow" -#pragma GCC diagnostic ignored "-Wswitch" -#pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" -#elif defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wstring-plus-int" -#pragma clang diagnostic ignored "-Wswitch" -#pragma clang diagnostic ignored "-Wmissing-field-initializers" -#pragma clang diagnostic ignored "-Wimplicit-fallthrough" -#endif - -#include "d3dx12.h" +#include #include #define D3D12MA_D3D12_HEADERS_ALREADY_INCLUDED -#include "D3D12MemAlloc.h" +#include #include @@ -71,29 +55,34 @@ #undef MemoryBarrier #endif -// No point in fighting warnings in Mesa. -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable : 4200) // "nonstandard extension used: zero-sized array in struct/union". -#pragma warning(disable : 4806) // "'&': unsafe operation: no value of type 'bool' promoted to type 'uint32_t' can equal the given constant". -#endif +GODOT_GCC_WARNING_PUSH +GODOT_GCC_WARNING_IGNORE("-Wimplicit-fallthrough") +GODOT_GCC_WARNING_IGNORE("-Wlogical-not-parentheses") +GODOT_GCC_WARNING_IGNORE("-Wmissing-field-initializers") +GODOT_GCC_WARNING_IGNORE("-Wnon-virtual-dtor") +GODOT_GCC_WARNING_IGNORE("-Wshadow") +GODOT_GCC_WARNING_IGNORE("-Wswitch") +GODOT_CLANG_WARNING_PUSH +GODOT_CLANG_WARNING_IGNORE("-Wimplicit-fallthrough") +GODOT_CLANG_WARNING_IGNORE("-Wlogical-not-parentheses") +GODOT_CLANG_WARNING_IGNORE("-Wmissing-field-initializers") +GODOT_CLANG_WARNING_IGNORE("-Wnon-virtual-dtor") +GODOT_CLANG_WARNING_IGNORE("-Wstring-plus-int") +GODOT_CLANG_WARNING_IGNORE("-Wswitch") +GODOT_MSVC_WARNING_PUSH +GODOT_MSVC_WARNING_IGNORE(4200) // "nonstandard extension used: zero-sized array in struct/union". +GODOT_MSVC_WARNING_IGNORE(4806) // "'&': unsafe operation: no value of type 'bool' promoted to type 'uint32_t' can equal the given constant". -#include "nir_spirv.h" -#include "nir_to_dxil.h" -#include "spirv_to_dxil.h" +#include +#include +#include extern "C" { -#include "dxil_spirv_nir.h" +#include } -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#elif defined(__clang__) -#pragma clang diagnostic pop -#endif - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif +GODOT_GCC_WARNING_POP +GODOT_CLANG_WARNING_POP +GODOT_MSVC_WARNING_POP static D3D12_SHADER_VISIBILITY stages_to_d3d12_visibility(uint32_t p_stages_mask) { switch (p_stages_mask) { diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index 6098600482..fcf290a8f3 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -609,7 +609,7 @@ void main() { float d = msdf_median(msdf_sample.r, msdf_sample.g, msdf_sample.b); if (outline_thickness > 0.0) { - float cr = clamp(outline_thickness, 0.0, px_range / 2.0) / px_range; + float cr = clamp(outline_thickness, 0.0, (px_range / 2.0) - 1.0) / px_range; d = min(d, msdf_sample.a); float a = clamp((d - 0.5 + cr) * px_size + 0.5, 0.0, 1.0); color.a = a * color.a; diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index 972bb4ae25..dcc3f84826 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -863,7 +863,7 @@ void MaterialData::update_textures(const HashMap &p_paramet GlobalShaderUniforms::Variable *v = material_storage->global_shader_uniforms.variables.getptr(uniform_name); if (v) { if (v->buffer_index >= 0) { - WARN_PRINT("Shader uses global parameter texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!."); + WARN_PRINT("Shader uses global parameter texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!"); } else { HashMap::Iterator E = used_global_textures.find(uniform_name); @@ -2400,7 +2400,8 @@ void MaterialStorage::material_free(RID p_rid) { // This happens when the app is being closed. for (KeyValue &E : material->params) { if (E.value.get_type() == Variant::ARRAY) { - Array(E.value).clear(); + // Clear the array for this material only (the array may be shared). + E.value = Variant(); } } diff --git a/drivers/gles3/storage/particles_storage.cpp b/drivers/gles3/storage/particles_storage.cpp index 1c97d10b82..8d7ef17f8f 100644 --- a/drivers/gles3/storage/particles_storage.cpp +++ b/drivers/gles3/storage/particles_storage.cpp @@ -1284,7 +1284,7 @@ GLuint ParticlesStorage::particles_collision_get_heightfield_framebuffer(RID p_p #ifdef DEBUG_ENABLED GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { - WARN_PRINT("Could create heightmap texture status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status)); + WARN_PRINT("Could not create heightmap texture, status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status)); } #endif GLES3::Utilities::get_singleton()->texture_allocated_data(particles_collision->heightfield_texture, size.x * size.y * 4, "Particles collision heightfield texture"); diff --git a/drivers/metal/SCsub b/drivers/metal/SCsub index f55933a2c3..b8347c7d7a 100644 --- a/drivers/metal/SCsub +++ b/drivers/metal/SCsub @@ -36,7 +36,7 @@ env_metal.drivers_sources += thirdparty_obj # Enable C++20 for the Objective-C++ Metal code, which uses C++20 concepts. if "-std=gnu++17" in env_metal["CXXFLAGS"]: env_metal["CXXFLAGS"].remove("-std=gnu++17") -env_metal.Append(CXXFLAGS=["-std=c++20"]) +env_metal.Append(CXXFLAGS=["-std=gnu++20"]) # Enable module support env_metal.Append(CCFLAGS=["-fmodules", "-fcxx-modules"]) diff --git a/drivers/sdl/joypad_sdl.cpp b/drivers/sdl/joypad_sdl.cpp index 271d66f333..79364c08eb 100644 --- a/drivers/sdl/joypad_sdl.cpp +++ b/drivers/sdl/joypad_sdl.cpp @@ -60,6 +60,19 @@ JoypadSDL::JoypadSDL() { singleton = this; } +#ifdef WINDOWS_ENABLED +extern "C" { +HWND SDL_HelperWindow; +} + +// Required for DInput joypads to work +// TODO: remove this workaround when we update to newer version of SDL +JoypadSDL::JoypadSDL(HWND p_helper_window) : + JoypadSDL() { + SDL_HelperWindow = p_helper_window; +} +#endif + JoypadSDL::~JoypadSDL() { // Process any remaining input events process_events(); @@ -90,6 +103,9 @@ Error JoypadSDL::initialize() { SDL_AddGamepadMappingsFromIO(rw, 1); } + // Make sure that we handle already connected joypads when the driver is initialized. + process_events(); + print_verbose("SDL: Init OK!"); return OK; } @@ -246,17 +262,6 @@ void JoypadSDL::process_events() { } } -#ifdef WINDOWS_ENABLED -extern "C" { -HWND SDL_HelperWindow; -} - -// Required for DInput joypads to work -void JoypadSDL::setup_sdl_helper_window(HWND p_hwnd) { - SDL_HelperWindow = p_hwnd; -} -#endif - void JoypadSDL::close_joypad(int p_pad_idx) { int sdl_instance_idx = joypads[p_pad_idx].sdl_instance_idx; diff --git a/drivers/sdl/joypad_sdl.h b/drivers/sdl/joypad_sdl.h index 7a2e668b49..7b70981ce4 100644 --- a/drivers/sdl/joypad_sdl.h +++ b/drivers/sdl/joypad_sdl.h @@ -41,15 +41,15 @@ typedef struct HWND__ *HWND; class JoypadSDL { public: JoypadSDL(); +#ifdef WINDOWS_ENABLED + JoypadSDL(HWND p_helper_window); +#endif ~JoypadSDL(); static JoypadSDL *get_singleton(); Error initialize(); void process_events(); -#ifdef WINDOWS_ENABLED - void setup_sdl_helper_window(HWND p_hwnd); -#endif private: struct Joypad { diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index a875400f67..e9a5e173d0 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -797,7 +797,7 @@ Dictionary OS_Unix::execute_with_pipe(const String &p_path, const List & Ref err_pipe; err_pipe.instantiate(); - err_pipe->open_existing(pipe_err[0], 0, p_blocking); + err_pipe->open_existing(pipe_err[0], -1, p_blocking); ProcessInfo pi; process_map_mutex.lock(); diff --git a/editor/animation/animation_blend_space_1d_editor.cpp b/editor/animation/animation_blend_space_1d_editor.cpp index 1d5754d479..20eeccd1d5 100644 --- a/editor/animation/animation_blend_space_1d_editor.cpp +++ b/editor/animation/animation_blend_space_1d_editor.cpp @@ -169,7 +169,6 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Refadd_undo_method(this, "_update_edited_point_pos"); undo_redo->commit_action(); updating = false; - _update_edited_point_pos(); } dragging_selected_attempt = false; @@ -190,11 +189,6 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref mm = p_event; - if (mm.is_valid() && !blend_space_draw->has_focus()) { - blend_space_draw->grab_focus(); - blend_space_draw->queue_redraw(); - } - if (mm.is_valid() && dragging_selected_attempt) { dragging_selected = true; drag_ofs = ((mm->get_position() - drag_from) / blend_space_draw->get_size()) * ((blend_space->get_max_space() - blend_space->get_min_space()) * Vector2(1, 0)); @@ -803,6 +797,7 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() { error_label = memnew(Label); error_label->set_focus_mode(FOCUS_ACCESSIBILITY); error_panel->add_child(error_label); + error_panel->hide(); menu = memnew(PopupMenu); add_child(menu); diff --git a/editor/animation/animation_blend_space_2d_editor.cpp b/editor/animation/animation_blend_space_2d_editor.cpp index 88ff3fdfee..f10cb0a227 100644 --- a/editor/animation/animation_blend_space_2d_editor.cpp +++ b/editor/animation/animation_blend_space_2d_editor.cpp @@ -264,7 +264,6 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Refadd_undo_method(this, "_update_edited_point_pos"); undo_redo->commit_action(); updating = false; - _update_edited_point_pos(); } } dragging_selected_attempt = false; @@ -285,11 +284,6 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref mm = p_event; - if (mm.is_valid() && !blend_space_draw->has_focus()) { - blend_space_draw->grab_focus(); - blend_space_draw->queue_redraw(); - } - if (mm.is_valid() && dragging_selected_attempt) { dragging_selected = true; if (!read_only) { @@ -1084,6 +1078,7 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() { error_label = memnew(Label); error_label->set_focus_mode(FOCUS_ACCESSIBILITY); error_panel->add_child(error_label); + error_panel->hide(); set_custom_minimum_size(Size2(0, 300 * EDSCALE)); diff --git a/editor/animation/animation_state_machine_editor.cpp b/editor/animation/animation_state_machine_editor.cpp index fb816e19d7..ca922a3e38 100644 --- a/editor/animation/animation_state_machine_editor.cpp +++ b/editor/animation/animation_state_machine_editor.cpp @@ -508,8 +508,6 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Refgrab_focus(); - String new_hovered_node_name; HoveredNodeArea new_hovered_node_area = HOVER_NODE_NONE; if (tool_select->is_pressed()) { diff --git a/editor/animation/animation_track_editor.cpp b/editor/animation/animation_track_editor.cpp index 52672c2c87..edb93f4c24 100644 --- a/editor/animation/animation_track_editor.cpp +++ b/editor/animation/animation_track_editor.cpp @@ -3165,7 +3165,7 @@ void AnimationTrackEdit::gui_input(const Ref &p_event) { } } - if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) { + if (!moving_selection && mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) { Point2 pos = mb->get_position(); if (pos.x >= timeline->get_name_limit() && pos.x <= get_size().width - timeline->get_buttons_width()) { // Can do something with menu too! show insert key. diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index ab1a63cd7b..af1ad7c347 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -2013,10 +2013,10 @@ ScriptEditorDebugger::ScriptEditorDebugger() { skip_breakpoints->connect(SceneStringName(pressed), callable_mp(this, &ScriptEditorDebugger::debug_skip_breakpoints)); ignore_error_breaks = memnew(Button); - ignore_error_breaks->set_flat(true); + ignore_error_breaks->set_theme_type_variation(SceneStringName(FlatButton)); ignore_error_breaks->set_tooltip_text(TTR("Ignore Error Breaks")); hbc->add_child(ignore_error_breaks); - ignore_error_breaks->connect("pressed", callable_mp(this, &ScriptEditorDebugger::debug_ignore_error_breaks)); + ignore_error_breaks->connect(SceneStringName(pressed), callable_mp(this, &ScriptEditorDebugger::debug_ignore_error_breaks)); hbc->add_child(memnew(VSeparator)); diff --git a/editor/doc/editor_help.cpp b/editor/doc/editor_help.cpp index fbea9c14e3..0c9aa9853f 100644 --- a/editor/doc/editor_help.cpp +++ b/editor/doc/editor_help.cpp @@ -3461,9 +3461,9 @@ EditorHelp::EditorHelp() { status_bar->set_custom_minimum_size(Size2(0, 24 * EDSCALE)); toggle_files_button = memnew(Button); + toggle_files_button->set_theme_type_variation(SceneStringName(FlatButton)); toggle_files_button->set_accessibility_name(TTRC("Scripts")); toggle_files_button->set_tooltip_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); - toggle_files_button->set_flat(true); toggle_files_button->connect(SceneStringName(pressed), callable_mp(this, &EditorHelp::_toggle_files_pressed)); status_bar->add_child(toggle_files_button); @@ -4893,7 +4893,7 @@ FindBar::FindBar() { matches_label->hide(); find_prev = memnew(Button); - find_prev->set_flat(true); + find_prev->set_theme_type_variation(SceneStringName(FlatButton)); find_prev->set_disabled(results_count < 1); find_prev->set_tooltip_text(TTR("Previous Match")); add_child(find_prev); @@ -4901,7 +4901,7 @@ FindBar::FindBar() { find_prev->connect(SceneStringName(pressed), callable_mp(this, &FindBar::search_prev)); find_next = memnew(Button); - find_next->set_flat(true); + find_next->set_theme_type_variation(SceneStringName(FlatButton)); find_next->set_disabled(results_count < 1); find_next->set_tooltip_text(TTR("Next Match")); add_child(find_next); @@ -4909,7 +4909,7 @@ FindBar::FindBar() { find_next->connect(SceneStringName(pressed), callable_mp(this, &FindBar::search_next)); hide_button = memnew(Button); - hide_button->set_flat(true); + hide_button->set_theme_type_variation(SceneStringName(FlatButton)); hide_button->set_tooltip_text(TTR("Hide")); hide_button->set_focus_mode(FOCUS_ACCESSIBILITY); hide_button->connect(SceneStringName(pressed), callable_mp(this, &FindBar::_hide_bar)); diff --git a/editor/docks/scene_tree_dock.cpp b/editor/docks/scene_tree_dock.cpp index 78e6e2ed2a..7d2058e199 100644 --- a/editor/docks/scene_tree_dock.cpp +++ b/editor/docks/scene_tree_dock.cpp @@ -2938,7 +2938,7 @@ void SceneTreeDock::_selection_changed() { node_previous_selection.reserve(editor_selection->get_selection().size()); for (const KeyValue &E : editor_selection->get_selection()) { Node *node = E.key; - node_previous_selection.push_back(node); + node_previous_selection.push_back(node->get_instance_id()); node->connect(CoreStringName(script_changed), callable_mp(this, &SceneTreeDock::_queue_update_script_button)); } _queue_update_script_button(); @@ -3378,8 +3378,11 @@ static bool _is_same_selection(const Vector &p_first, const List } void SceneTreeDock::clear_previous_node_selection() { - for (Node *node : node_previous_selection) { - node->disconnect(CoreStringName(script_changed), callable_mp(this, &SceneTreeDock::_queue_update_script_button)); + for (const ObjectID &id : node_previous_selection) { + Node *node = ObjectDB::get_instance(id); + if (node) { + node->disconnect(CoreStringName(script_changed), callable_mp(this, &SceneTreeDock::_queue_update_script_button)); + } } node_previous_selection.clear(); } diff --git a/editor/docks/scene_tree_dock.h b/editor/docks/scene_tree_dock.h index 9263b37499..47ed8ba52c 100644 --- a/editor/docks/scene_tree_dock.h +++ b/editor/docks/scene_tree_dock.h @@ -137,7 +137,7 @@ class SceneTreeDock : public VBoxContainer { EditorData *editor_data = nullptr; EditorSelection *editor_selection = nullptr; - LocalVector node_previous_selection; + LocalVector node_previous_selection; bool update_script_button_queued = false; List node_clipboard; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index aaaf06afe5..77d803e8b5 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -7411,13 +7411,13 @@ void EditorNode::_update_main_menu_type() { menu_btn_spacer = memnew(Control); menu_btn_spacer->set_custom_minimum_size(Vector2(8, 0) * EDSCALE); title_bar->add_child(menu_btn_spacer); - title_bar->move_child(menu_btn_spacer, 0); + title_bar->move_child(menu_btn_spacer, left_menu_spacer ? left_menu_spacer->get_index() + 1 : 0); #endif title_bar->add_child(main_menu_button); if (menu_btn_spacer == nullptr) { - title_bar->move_child(main_menu_button, 0); + title_bar->move_child(main_menu_button, left_menu_spacer ? left_menu_spacer->get_index() + 1 : 0); } else { - title_bar->move_child(main_menu_button, 1); + title_bar->move_child(main_menu_button, menu_btn_spacer->get_index() + 1); } memdelete_notnull(main_menu_bar); main_menu_bar = nullptr; @@ -7452,7 +7452,7 @@ void EditorNode::_update_main_menu_type() { } title_bar->add_child(main_menu_bar); - title_bar->move_child(main_menu_bar, 0); + title_bar->move_child(main_menu_bar, left_menu_spacer ? left_menu_spacer->get_index() + 1 : 0); memdelete_notnull(menu_btn_spacer); memdelete_notnull(main_menu_button); diff --git a/editor/editor_node.h b/editor/editor_node.h index 40d738e324..1c259ca806 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -453,7 +453,7 @@ private: bool immediate_dialog_confirmed = false; bool restoring_scenes = false; bool settings_overrides_changed = false; - bool unsaved_cache = true; + bool unsaved_cache = false; bool requested_first_scan = false; bool waiting_for_first_scan = true; diff --git a/editor/export/editor_export_platform.cpp b/editor/export/editor_export_platform.cpp index 2038e562e5..d9036e742a 100644 --- a/editor/export/editor_export_platform.cpp +++ b/editor/export/editor_export_platform.cpp @@ -2532,7 +2532,7 @@ void EditorExportPlatform::_bind_methods() { ClassDB::bind_method(D_METHOD("get_internal_export_files", "preset", "debug"), &EditorExportPlatform::get_internal_export_files); - ClassDB::bind_static_method("EditorExportPlatform", D_METHOD("get_forced_export_files", "preset"), &EditorExportPlatform::get_forced_export_files); + ClassDB::bind_static_method("EditorExportPlatform", D_METHOD("get_forced_export_files", "preset"), &EditorExportPlatform::get_forced_export_files, DEFVAL(Ref())); BIND_ENUM_CONSTANT(EXPORT_MESSAGE_NONE); BIND_ENUM_CONSTANT(EXPORT_MESSAGE_INFO); diff --git a/editor/file_system/editor_file_system.cpp b/editor/file_system/editor_file_system.cpp index 46c99c30ef..c306e2dc9b 100644 --- a/editor/file_system/editor_file_system.cpp +++ b/editor/file_system/editor_file_system.cpp @@ -467,7 +467,7 @@ void EditorFileSystem::_scan_filesystem() { fc.import_md5 = slices[5]; fc.import_dest_paths = slices[6].split("<*>"); } - fc.deps = split[8].strip_edges().split("<>"); + fc.deps = split[8].strip_edges().split("<>", false); file_cache[name] = fc; } @@ -1770,13 +1770,13 @@ void EditorFileSystem::_notification(int p_what) { // Set first_scan to false before the signals so the function doing_first_scan can return false // in editor_node to start the export if needed. first_scan = false; + scanning_changes = false; + done_importing = true; ResourceImporter::load_on_startup = nullptr; if (changed) { emit_signal(SNAME("filesystem_changed")); } emit_signal(SNAME("sources_changed"), sources_changed.size() > 0); - scanning_changes = false; // Changed to false here to prevent recursive triggering of scan thread. - done_importing = true; } } else if (!scanning && thread.is_started()) { set_process(false); diff --git a/editor/gui/code_editor.cpp b/editor/gui/code_editor.cpp index 84cbef6e30..fb9a425ebe 100644 --- a/editor/gui/code_editor.cpp +++ b/editor/gui/code_editor.cpp @@ -755,9 +755,9 @@ void FindReplaceBar::_bind_methods() { FindReplaceBar::FindReplaceBar() { toggle_replace_button = memnew(Button); + toggle_replace_button->set_theme_type_variation(SceneStringName(FlatButton)); add_child(toggle_replace_button); toggle_replace_button->set_accessibility_name(TTRC("Replace Mode")); - toggle_replace_button->set_flat(true); toggle_replace_button->set_focus_mode(FOCUS_ACCESSIBILITY); toggle_replace_button->connect(SceneStringName(pressed), callable_mp(this, &FindReplaceBar::_toggle_replace_pressed)); @@ -801,7 +801,7 @@ FindReplaceBar::FindReplaceBar() { matches_label->hide(); find_prev = memnew(Button); - find_prev->set_flat(true); + find_prev->set_theme_type_variation(SceneStringName(FlatButton)); find_prev->set_disabled(results_count < 1); find_prev->set_tooltip_text(TTRC("Previous Match")); hbc_button_search->add_child(find_prev); @@ -809,7 +809,7 @@ FindReplaceBar::FindReplaceBar() { find_prev->connect(SceneStringName(pressed), callable_mp(this, &FindReplaceBar::search_prev)); find_next = memnew(Button); - find_next->set_flat(true); + find_next->set_theme_type_variation(SceneStringName(FlatButton)); find_next->set_disabled(results_count < 1); find_next->set_tooltip_text(TTRC("Next Match")); hbc_button_search->add_child(find_next); @@ -854,7 +854,7 @@ FindReplaceBar::FindReplaceBar() { selection_only->connect(SceneStringName(toggled), callable_mp(this, &FindReplaceBar::_search_options_changed)); hide_button = memnew(Button); - hide_button->set_flat(true); + hide_button->set_theme_type_variation(SceneStringName(FlatButton)); hide_button->set_tooltip_text(TTRC("Hide")); hide_button->set_focus_mode(FOCUS_ACCESSIBILITY); hide_button->connect(SceneStringName(pressed), callable_mp(this, &FindReplaceBar::_hide_bar)); @@ -1920,7 +1920,7 @@ CodeTextEditor::CodeTextEditor() { error_column = 0; toggle_files_button = memnew(Button); - toggle_files_button->set_flat(true); + toggle_files_button->set_theme_type_variation(SceneStringName(FlatButton)); toggle_files_button->set_v_size_flags(SIZE_EXPAND | SIZE_SHRINK_CENTER); toggle_files_button->set_tooltip_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); toggle_files_button->connect(SceneStringName(pressed), callable_mp(this, &CodeTextEditor::_toggle_files_pressed)); @@ -1963,7 +1963,8 @@ CodeTextEditor::CodeTextEditor() { // Zoom zoom_button = memnew(MenuButton); status_bar->add_child(zoom_button); - zoom_button->set_flat(true); + zoom_button->set_flat(false); + zoom_button->set_theme_type_variation("FlatMenuButton"); zoom_button->set_v_size_flags(SIZE_EXPAND | SIZE_SHRINK_CENTER); zoom_button->set_text("100 %"); zoom_button->set_accessibility_name(TTRC("Zoom Factor")); diff --git a/editor/gui/window_wrapper.cpp b/editor/gui/window_wrapper.cpp index d647e0de52..eecbdf2acf 100644 --- a/editor/gui/window_wrapper.cpp +++ b/editor/gui/window_wrapper.cpp @@ -490,7 +490,7 @@ void ScreenSelect::pressed() { ScreenSelect::ScreenSelect() { set_button_mask(MouseButtonMask::RIGHT); - set_flat(true); + set_theme_type_variation(SceneStringName(FlatButton)); set_toggle_mode(true); set_focus_mode(FOCUS_NONE); set_action_mode(ACTION_MODE_BUTTON_PRESS); diff --git a/editor/import/3d/resource_importer_scene.cpp b/editor/import/3d/resource_importer_scene.cpp index 34bd80fb47..aa47eca792 100644 --- a/editor/import/3d/resource_importer_scene.cpp +++ b/editor/import/3d/resource_importer_scene.cpp @@ -2610,9 +2610,10 @@ Node *ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_ mesh_node->set_skeleton_path(src_mesh_node->get_skeleton_path()); mesh_node->merge_meta_from(src_mesh_node); - if (src_mesh_node->get_mesh().is_valid()) { + Ref importer_mesh = src_mesh_node->get_mesh(); + if (importer_mesh.is_valid()) { Ref mesh; - if (!src_mesh_node->get_mesh()->has_mesh()) { + if (!importer_mesh->has_mesh()) { //do mesh processing bool generate_lods = p_generate_lods; @@ -2621,7 +2622,7 @@ Node *ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_ bool bake_lightmaps = p_light_bake_mode == LIGHT_BAKE_STATIC_LIGHTMAPS; String save_to_file; - String mesh_id = src_mesh_node->get_mesh()->get_meta("import_id", src_mesh_node->get_mesh()->get_name()); + String mesh_id = importer_mesh->get_meta("import_id", importer_mesh->get_name()); if (!mesh_id.is_empty() && p_mesh_data.has(mesh_id)) { Dictionary mesh_settings = p_mesh_data[mesh_id]; @@ -2675,7 +2676,7 @@ Node *ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_ } for (int i = 0; i < post_importer_plugins.size(); i++) { - post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MESH, nullptr, src_mesh_node, src_mesh_node->get_mesh(), mesh_settings); + post_importer_plugins.write[i]->internal_process(EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MESH, nullptr, src_mesh_node, importer_mesh, mesh_settings); } } @@ -2688,7 +2689,7 @@ Node *ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_ } Vector lightmap_cache; - src_mesh_node->get_mesh()->lightmap_unwrap_cached(xf, p_lightmap_texel_size, p_src_lightmap_cache, lightmap_cache); + importer_mesh->lightmap_unwrap_cached(xf, p_lightmap_texel_size, p_src_lightmap_cache, lightmap_cache); if (!lightmap_cache.is_empty()) { if (r_lightmap_caches.is_empty()) { @@ -2713,14 +2714,14 @@ Node *ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_ if (generate_lods) { Array skin_pose_transform_array = _get_skinned_pose_transforms(src_mesh_node); - src_mesh_node->get_mesh()->generate_lods(merge_angle, skin_pose_transform_array); + importer_mesh->generate_lods(merge_angle, skin_pose_transform_array); } if (create_shadow_meshes) { - src_mesh_node->get_mesh()->create_shadow_mesh(); + importer_mesh->create_shadow_mesh(); } - src_mesh_node->get_mesh()->optimize_indices(); + importer_mesh->optimize_indices(); if (!save_to_file.is_empty()) { String save_res_path = ResourceUID::ensure_path(save_to_file); @@ -2729,7 +2730,7 @@ Node *ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_ //if somehow an existing one is useful, create existing->reset_state(); } - mesh = src_mesh_node->get_mesh()->get_mesh(existing); + mesh = importer_mesh->get_mesh(existing); Error err = ResourceSaver::save(mesh, save_res_path); //override if (err != OK) { @@ -2743,19 +2744,19 @@ Node *ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_ mesh->set_path(save_res_path, true); //takeover existing, if needed } else { - mesh = src_mesh_node->get_mesh()->get_mesh(); + mesh = importer_mesh->get_mesh(); } } else { - mesh = src_mesh_node->get_mesh()->get_mesh(); + mesh = importer_mesh->get_mesh(); } if (mesh.is_valid()) { - _copy_meta(src_mesh_node->get_mesh().ptr(), mesh.ptr()); + _copy_meta(importer_mesh.ptr(), mesh.ptr()); mesh_node->set_mesh(mesh); for (int i = 0; i < mesh->get_surface_count(); i++) { mesh_node->set_surface_override_material(i, src_mesh_node->get_surface_material(i)); } - mesh->merge_meta_from(*src_mesh_node->get_mesh()); + mesh->merge_meta_from(*importer_mesh); } } diff --git a/editor/import/resource_importer_svg.cpp b/editor/import/resource_importer_svg.cpp index 1f71ce782c..7d4515a61f 100644 --- a/editor/import/resource_importer_svg.cpp +++ b/editor/import/resource_importer_svg.cpp @@ -33,14 +33,14 @@ #include "resource_importer_svg.h" #include "core/io/file_access.h" -#include "scene/resources/svg_texture.h" +#include "scene/resources/dpi_texture.h" String ResourceImporterSVG::get_importer_name() const { return "svg"; } String ResourceImporterSVG::get_visible_name() const { - return "SVGTexture"; + return "DPITexture"; } void ResourceImporterSVG::get_recognized_extensions(List *p_extensions) const { @@ -48,11 +48,11 @@ void ResourceImporterSVG::get_recognized_extensions(List *p_extensions) } String ResourceImporterSVG::get_save_extension() const { - return "svgtex"; + return "dpitex"; } String ResourceImporterSVG::get_resource_type() const { - return "SVGTexture"; + return "DPITexture"; } bool ResourceImporterSVG::get_option_visibility(const String &p_path, const String &p_option, const HashMap &p_options) const { @@ -75,8 +75,8 @@ void ResourceImporterSVG::get_import_options(const String &p_path, List &p_options, List *r_platform_variants, List *r_gen_files, Variant *r_metadata) { - Ref svg_tex; - svg_tex.instantiate(); + Ref dpi_tex; + dpi_tex.instantiate(); String source = FileAccess::get_file_as_string(p_source_file); ERR_FAIL_COND_V_MSG(source.is_empty(), ERR_CANT_OPEN, vformat("Cannot open file from path \"%s\".", p_source_file)); @@ -85,22 +85,22 @@ Error ResourceImporterSVG::import(ResourceUID::ID p_source_id, const String &p_s double saturation = p_options["saturation"]; Dictionary color_map = p_options["color_map"]; - svg_tex->set_base_scale(base_scale); - svg_tex->set_saturation(saturation); - svg_tex->set_color_map(color_map); - svg_tex->set_source(source); + dpi_tex->set_base_scale(base_scale); + dpi_tex->set_saturation(saturation); + dpi_tex->set_color_map(color_map); + dpi_tex->set_source(source); - ERR_FAIL_COND_V_MSG(svg_tex->get_rid().is_null(), ERR_CANT_OPEN, vformat("Failed loading SVG, unsupported or invalid SVG data in \"%s\".", p_source_file)); + ERR_FAIL_COND_V_MSG(dpi_tex->get_rid().is_null(), ERR_CANT_OPEN, vformat("Failed loading SVG, unsupported or invalid SVG data in \"%s\".", p_source_file)); int flg = 0; if ((bool)p_options["compress"]) { flg |= ResourceSaver::SaverFlags::FLAG_COMPRESS; } - print_verbose("Saving to: " + p_save_path + ".svgtex"); - Error err = ResourceSaver::save(svg_tex, p_save_path + ".svgtex", flg); - ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Cannot save SVG texture to file \"%s.svgtex\".", p_save_path)); - print_verbose("Done saving to: " + p_save_path + ".svgtex"); + print_verbose("Saving to: " + p_save_path + ".dpitex"); + Error err = ResourceSaver::save(dpi_tex, p_save_path + ".dpitex", flg); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Cannot save DPI texture to file \"%s.dpitex\".", p_save_path)); + print_verbose("Done saving to: " + p_save_path + ".dpitex"); return OK; } diff --git a/editor/inspector/editor_properties.cpp b/editor/inspector/editor_properties.cpp index 21a50c8632..70d65f586e 100644 --- a/editor/inspector/editor_properties.cpp +++ b/editor/inspector/editor_properties.cpp @@ -3593,8 +3593,8 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, const Varian struct EditorPropertyRangeHint { bool or_greater = true; bool or_less = true; - double min = -99999.0; - double max = 99999.0; + double min = 0.0; + double max = 0.0; double step = 1.0; String suffix; bool exp_range = false; diff --git a/editor/inspector/editor_resource_tooltip_plugins.cpp b/editor/inspector/editor_resource_tooltip_plugins.cpp index 23704af794..f9b6bdc8d4 100644 --- a/editor/inspector/editor_resource_tooltip_plugins.cpp +++ b/editor/inspector/editor_resource_tooltip_plugins.cpp @@ -32,6 +32,8 @@ #include "editor_resource_tooltip_plugins.h" +#include "editor/editor_node.h" +#include "editor/editor_string_names.h" #include "editor/file_system/editor_file_system.h" #include "editor/inspector/editor_resource_preview.h" #include "editor/themes/editor_scale.h" @@ -74,8 +76,15 @@ VBoxContainer *EditorResourceTooltipPlugin::make_default_tooltip(const String &p { Ref f = FileAccess::open(p_resource_path, FileAccess::READ); - Label *label = memnew(Label(vformat(TTR("Size: %s"), String::humanize_size(f->get_length())))); - vb->add_child(label); + if (f.is_valid()) { + Label *label = memnew(Label(vformat(TTR("Size: %s"), String::humanize_size(f->get_length())))); + vb->add_child(label); + } else { + Label *label = memnew(Label(TTR("Invalid file or broken link."))); + label->add_theme_color_override(SceneStringName(font_color), EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), EditorStringName(Editor))); + vb->add_child(label); + return vb; + } } if (ResourceLoader::exists(p_resource_path)) { diff --git a/editor/scene/2d/polygon_2d_editor_plugin.cpp b/editor/scene/2d/polygon_2d_editor_plugin.cpp index a14e4f64e4..d2af5a75cb 100644 --- a/editor/scene/2d/polygon_2d_editor_plugin.cpp +++ b/editor/scene/2d/polygon_2d_editor_plugin.cpp @@ -576,13 +576,16 @@ void Polygon2DEditor::_canvas_input(const Ref &p_input) { return; } + const real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius"); int closest = -1; + real_t closest_dist = Math::INF; - for (int i = editing_points.size() - 1; i >= editing_points.size() - internal_vertices; i--) { + for (int i = editing_points.size() - 1; i >= editing_points.size() - internal_vertices && closest_dist >= 8; i--) { Vector2 tuv = mtx.xform(previous_polygon[i]); - if (tuv.distance_to(mb->get_position()) < 8) { + const real_t dist = tuv.distance_to(mb->get_position()); + if (dist < grab_threshold && dist < closest_dist) { closest = i; - break; + closest_dist = dist; } } @@ -627,11 +630,15 @@ void Polygon2DEditor::_canvas_input(const Ref &p_input) { } if (current_action == ACTION_EDIT_POINT) { + const real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius"); point_drag_index = -1; - for (int i = 0; i < editing_points.size(); i++) { - if (mtx.xform(editing_points[i]).distance_to(mb->get_position()) < 8) { + real_t closest_dist = Math::INF; + for (int i = editing_points.size() - 1; i >= 0 && closest_dist >= 8; i--) { + const real_t dist = mtx.xform(editing_points[i]).distance_to(mb->get_position()); + if (dist < grab_threshold && dist < closest_dist) { drag_from = mb->get_position(); point_drag_index = i; + closest_dist = dist; } } @@ -641,13 +648,16 @@ void Polygon2DEditor::_canvas_input(const Ref &p_input) { } if (current_action == ACTION_ADD_POLYGON) { + const real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius"); int closest = -1; + real_t closest_dist = Math::INF; - for (int i = editing_points.size() - 1; i >= 0; i--) { + for (int i = editing_points.size() - 1; i >= 0 && closest_dist >= 8; i--) { Vector2 tuv = mtx.xform(editing_points[i]); - if (tuv.distance_to(mb->get_position()) < 8) { + const real_t dist = tuv.distance_to(mb->get_position()); + if (dist < grab_threshold && dist < closest_dist) { closest = i; - break; + closest_dist = dist; } } diff --git a/editor/scene/3d/gizmos/physics/soft_body_3d_gizmo_plugin.cpp b/editor/scene/3d/gizmos/physics/soft_body_3d_gizmo_plugin.cpp index 6d1cad0c94..bc8d076db9 100644 --- a/editor/scene/3d/gizmos/physics/soft_body_3d_gizmo_plugin.cpp +++ b/editor/scene/3d/gizmos/physics/soft_body_3d_gizmo_plugin.cpp @@ -32,6 +32,7 @@ #include "soft_body_3d_gizmo_plugin.h" +#include "editor/editor_undo_redo_manager.h" #include "scene/3d/physics/soft_body_3d.h" SoftBody3DGizmoPlugin::SoftBody3DGizmoPlugin() { @@ -108,7 +109,15 @@ Variant SoftBody3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo void SoftBody3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel) { SoftBody3D *soft_body = Object::cast_to(p_gizmo->get_node_3d()); - soft_body->pin_point_toggle(p_id); + const bool is_pinned = soft_body->is_point_pinned(p_id); + + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(vformat(is_pinned ? TTR("Remove SoftBody3D pinned point %d") : TTR("Add SoftBody3D pinned point %d"), p_id)); + undo_redo->add_do_method(soft_body, "set_point_pinned", p_id, !is_pinned); + undo_redo->add_do_method(soft_body, "update_gizmos"); + undo_redo->add_undo_method(soft_body, "set_point_pinned", p_id, is_pinned); + undo_redo->add_undo_method(soft_body, "update_gizmos"); + undo_redo->commit_action(); } bool SoftBody3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const { diff --git a/editor/scene/3d/node_3d_editor_plugin.cpp b/editor/scene/3d/node_3d_editor_plugin.cpp index e9011a5886..3c998e0803 100644 --- a/editor/scene/3d/node_3d_editor_plugin.cpp +++ b/editor/scene/3d/node_3d_editor_plugin.cpp @@ -2434,7 +2434,7 @@ void Node3DEditorViewport::_sinput(const Ref &p_event) { _edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_handle_secondary, _edit.gizmo_initial_value, true); _edit.gizmo = Ref(); } - if (k->get_keycode() == Key::ESCAPE && !cursor.region_select) { + if (k->get_keycode() == Key::ESCAPE && !cursor.region_select && !k->is_echo()) { _clear_selected(); return; } @@ -5666,6 +5666,7 @@ void Node3DEditorViewport::finish_transform() { spatial_editor->update_transform_gizmo(); surface->queue_redraw(); set_process_input(false); + clicked = ObjectID(); } // Register a shortcut and also add it as an input action with the same events. diff --git a/editor/scene/gui/theme_editor_plugin.cpp b/editor/scene/gui/theme_editor_plugin.cpp index c857a0af57..aa41ef8392 100644 --- a/editor/scene/gui/theme_editor_plugin.cpp +++ b/editor/scene/gui/theme_editor_plugin.cpp @@ -33,6 +33,7 @@ #include "theme_editor_plugin.h" #include "editor/doc/editor_help.h" +#include "editor/docks/filesystem_dock.h" #include "editor/docks/inspector_dock.h" #include "editor/editor_node.h" #include "editor/editor_string_names.h" @@ -3712,7 +3713,7 @@ void ThemeEditor::edit(const Ref &p_theme) { } if (theme.is_valid()) { - theme_name->set_text(TTR("Theme:") + " " + theme->get_path().get_file()); + _update_theme_name(theme->get_path().get_file()); } } @@ -3751,6 +3752,23 @@ void ThemeEditor::_scene_closed(const String &p_path) { } } +void ThemeEditor::_resource_saved(const Ref &p_resource) { + if (theme.is_valid() && theme == p_resource) { + _update_theme_name(theme->get_path().get_file()); + } +} + +void ThemeEditor::_files_moved(const String &p_old_path, const String &p_new_path) { + // Theme's path may not have been updated to new path yet - need to check both old and new. + if (theme.is_valid() && (theme->get_path() == p_old_path || theme->get_path() == p_new_path)) { + _update_theme_name(p_new_path.get_file()); + } +} + +void ThemeEditor::_update_theme_name(const String &p_name) { + theme_name->set_text(TTR("Theme:") + " " + p_name); +} + void ThemeEditor::_add_preview_button_cbk() { preview_scene_dialog->popup_file_dialog(); } @@ -3881,6 +3899,8 @@ void ThemeEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_READY: { EditorNode::get_singleton()->connect("scene_closed", callable_mp(this, &ThemeEditor::_scene_closed)); + EditorNode::get_singleton()->connect("resource_saved", callable_mp(this, &ThemeEditor::_resource_saved)); + FileSystemDock::get_singleton()->connect("files_moved", callable_mp(this, &ThemeEditor::_files_moved)); } break; case NOTIFICATION_THEME_CHANGED: { diff --git a/editor/scene/gui/theme_editor_plugin.h b/editor/scene/gui/theme_editor_plugin.h index 469e13d272..866e88ff95 100644 --- a/editor/scene/gui/theme_editor_plugin.h +++ b/editor/scene/gui/theme_editor_plugin.h @@ -456,6 +456,9 @@ class ThemeEditor : public VBoxContainer { void _theme_edit_button_cbk(); void _theme_close_button_cbk(); void _scene_closed(const String &p_path); + void _resource_saved(const Ref &p_resource); + void _files_moved(const String &p_old_path, const String &p_new_path); + void _update_theme_name(const String &p_name); void _add_preview_button_cbk(); void _preview_scene_dialog_cbk(const String &p_path); diff --git a/editor/script/script_editor_plugin.cpp b/editor/script/script_editor_plugin.cpp index 333077de7a..3582674973 100644 --- a/editor/script/script_editor_plugin.cpp +++ b/editor/script/script_editor_plugin.cpp @@ -3785,8 +3785,6 @@ bool ScriptEditor::_help_tab_goto(const String &p_name, const String &p_desc) { } void ScriptEditor::update_doc(const String &p_name) { - ERR_FAIL_COND_MSG(!EditorHelp::has_doc(p_name), vformat("Can't update documentation for \"%s\".", p_name)); - for (int i = 0; i < tab_container->get_tab_count(); i++) { EditorHelp *eh = Object::cast_to(tab_container->get_tab_control(i)); if (eh && eh->get_class() == p_name) { @@ -4285,7 +4283,7 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { buttons_hbox->add_child(filename); members_overview_alphabeta_sort_button = memnew(Button); - members_overview_alphabeta_sort_button->set_flat(true); + members_overview_alphabeta_sort_button->set_theme_type_variation(SceneStringName(FlatButton)); members_overview_alphabeta_sort_button->set_tooltip_text(TTRC("Toggle alphabetical sorting of the method list.")); members_overview_alphabeta_sort_button->set_toggle_mode(true); members_overview_alphabeta_sort_button->set_pressed(EDITOR_GET("text_editor/script_list/sort_members_outline_alphabetically")); @@ -4342,6 +4340,8 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { set_process_shortcut_input(true); file_menu = memnew(MenuButton); + file_menu->set_flat(false); + file_menu->set_theme_type_variation("FlatMenuButton"); file_menu->set_text(TTRC("File")); file_menu->set_switch_on_hover(true); file_menu->set_shortcut_context(this); @@ -4410,6 +4410,8 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { file_menu->get_popup()->connect("popup_hide", callable_mp(this, &ScriptEditor::_file_menu_closed)); script_search_menu = memnew(MenuButton); + script_search_menu->set_flat(false); + script_search_menu->set_theme_type_variation("FlatMenuButton"); script_search_menu->set_text(TTRC("Search")); script_search_menu->set_switch_on_hover(true); script_search_menu->set_shortcut_context(this); @@ -4417,6 +4419,8 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { menu_hb->add_child(script_search_menu); MenuButton *debug_menu_btn = memnew(MenuButton); + debug_menu_btn->set_flat(false); + debug_menu_btn->set_theme_type_variation("FlatMenuButton"); menu_hb->add_child(debug_menu_btn); debug_menu_btn->hide(); // Handled by EditorDebuggerNode below. @@ -4443,13 +4447,13 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { menu_hb->add_spacer(); site_search = memnew(Button); + site_search->set_theme_type_variation(SceneStringName(FlatButton)); site_search->set_accessibility_name(TTRC("Site Search")); - site_search->set_flat(true); site_search->connect(SceneStringName(pressed), callable_mp(this, &ScriptEditor::_menu_option).bind(SEARCH_WEBSITE)); menu_hb->add_child(site_search); help_search = memnew(Button); - help_search->set_flat(true); + help_search->set_theme_type_variation(SceneStringName(FlatButton)); help_search->set_text(TTRC("Search Help")); help_search->connect(SceneStringName(pressed), callable_mp(this, &ScriptEditor::_menu_option).bind(SEARCH_HELP)); menu_hb->add_child(help_search); @@ -4458,14 +4462,14 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { menu_hb->add_child(memnew(VSeparator)); script_back = memnew(Button); - script_back->set_flat(true); + script_back->set_theme_type_variation(SceneStringName(FlatButton)); script_back->connect(SceneStringName(pressed), callable_mp(this, &ScriptEditor::_history_back)); menu_hb->add_child(script_back); script_back->set_disabled(true); script_back->set_tooltip_text(TTRC("Go to previous edited document.")); script_forward = memnew(Button); - script_forward->set_flat(true); + script_forward->set_theme_type_variation(SceneStringName(FlatButton)); script_forward->connect(SceneStringName(pressed), callable_mp(this, &ScriptEditor::_history_forward)); menu_hb->add_child(script_forward); script_forward->set_disabled(true); @@ -4474,7 +4478,6 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { menu_hb->add_child(memnew(VSeparator)); make_floating = memnew(ScreenSelect); - make_floating->set_flat(true); make_floating->set_tooltip_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); make_floating->connect("request_open_in_screen", callable_mp(window_wrapper, &WindowWrapper::enable_window_on_screen).bind(true)); diff --git a/editor/script/script_text_editor.cpp b/editor/script/script_text_editor.cpp index 7972da62df..d6d2aa9d37 100644 --- a/editor/script/script_text_editor.cpp +++ b/editor/script/script_text_editor.cpp @@ -2859,6 +2859,8 @@ ScriptTextEditor::ScriptTextEditor() { edit_hb = memnew(HBoxContainer); edit_menu = memnew(MenuButton); + edit_menu->set_flat(false); + edit_menu->set_theme_type_variation("FlatMenuButton"); edit_menu->set_text(TTRC("Edit")); edit_menu->set_switch_on_hover(true); edit_menu->set_shortcut_context(this); @@ -2875,11 +2877,15 @@ ScriptTextEditor::ScriptTextEditor() { set_syntax_highlighter(highlighter); search_menu = memnew(MenuButton); + search_menu->set_flat(false); + search_menu->set_theme_type_variation("FlatMenuButton"); search_menu->set_text(TTRC("Search")); search_menu->set_switch_on_hover(true); search_menu->set_shortcut_context(this); goto_menu = memnew(MenuButton); + goto_menu->set_flat(false); + goto_menu->set_theme_type_variation("FlatMenuButton"); goto_menu->set_text(TTRC("Go To")); goto_menu->set_switch_on_hover(true); goto_menu->set_shortcut_context(this); diff --git a/editor/script/text_editor.cpp b/editor/script/text_editor.cpp index 2da6c50f95..6799b8a8e4 100644 --- a/editor/script/text_editor.cpp +++ b/editor/script/text_editor.cpp @@ -628,6 +628,8 @@ TextEditor::TextEditor() { edit_hb = memnew(HBoxContainer); edit_menu = memnew(MenuButton); + edit_menu->set_flat(false); + edit_menu->set_theme_type_variation("FlatMenuButton"); edit_menu->set_shortcut_context(this); edit_hb->add_child(edit_menu); edit_menu->set_text(TTRC("Edit")); @@ -683,6 +685,8 @@ TextEditor::TextEditor() { set_syntax_highlighter(plain_highlighter); search_menu = memnew(MenuButton); + search_menu->set_flat(false); + search_menu->set_theme_type_variation("FlatMenuButton"); search_menu->set_shortcut_context(this); edit_hb->add_child(search_menu); search_menu->set_text(TTRC("Search")); @@ -698,6 +702,8 @@ TextEditor::TextEditor() { search_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/replace_in_files"), REPLACE_IN_FILES); MenuButton *goto_menu = memnew(MenuButton); + goto_menu->set_flat(false); + goto_menu->set_theme_type_variation("FlatMenuButton"); goto_menu->set_shortcut_context(this); edit_hb->add_child(goto_menu); goto_menu->set_text(TTRC("Go To")); diff --git a/editor/shader/shader_editor.h b/editor/shader/shader_editor.h index 276eae36fb..1514f14777 100644 --- a/editor/shader/shader_editor.h +++ b/editor/shader/shader_editor.h @@ -35,16 +35,19 @@ #include "scene/gui/control.h" #include "scene/resources/shader.h" +class Button; +class MenuButton; + class ShaderEditor : public Control { GDCLASS(ShaderEditor, Control); public: virtual void edit_shader(const Ref &p_shader) = 0; virtual void edit_shader_include(const Ref &p_shader_inc) {} + virtual void use_menu_bar_items(MenuButton *p_file_menu, Button *p_make_floating) = 0; virtual void apply_shaders() = 0; virtual bool is_unsaved() const = 0; virtual void save_external_data(const String &p_str = "") = 0; virtual void validate_script() = 0; - virtual Control *get_top_bar() = 0; }; diff --git a/editor/shader/shader_editor_plugin.cpp b/editor/shader/shader_editor_plugin.cpp index 93643ca98d..ff0918f254 100644 --- a/editor/shader/shader_editor_plugin.cpp +++ b/editor/shader/shader_editor_plugin.cpp @@ -192,12 +192,6 @@ void ShaderEditorPlugin::edit(Object *p_object) { cte->connect("zoomed", callable_mp(this, &ShaderEditorPlugin::_set_text_shader_zoom_factor)); cte->connect(SceneStringName(visibility_changed), callable_mp(this, &ShaderEditorPlugin::_update_shader_editor_zoom_factor).bind(cte)); } - - if (text_shader_editor->get_top_bar()) { - text_shader_editor->get_top_bar()->set_h_size_flags(Control::SIZE_EXPAND_FILL); - menu_hb->add_child(text_shader_editor->get_top_bar()); - menu_hb->move_child(text_shader_editor->get_top_bar(), 1); - } } shader_tabs->set_current_tab(shader_tabs->get_tab_count() - 1); @@ -461,29 +455,22 @@ void ShaderEditorPlugin::_make_script_list_context_menu() { void ShaderEditorPlugin::_close_shader(int p_index) { ERR_FAIL_INDEX(p_index, shader_tabs->get_tab_count()); - - Control *c = shader_tabs->get_tab_control(p_index); - VisualShaderEditor *vs_editor = Object::cast_to(c); - if (vs_editor) { - vs_editor->save_editor_layout(); + if (file_menu->get_parent() != nullptr) { file_menu->get_parent()->remove_child(file_menu); - menu_hb->add_child(file_menu); - menu_hb->move_child(file_menu, 0); - - make_floating->get_parent()->remove_child(make_floating); - menu_hb->add_child(make_floating); - } else { - memdelete(edited_shaders[p_index].shader_editor->get_top_bar()); } + if (make_floating->get_parent()) { + make_floating->get_parent()->remove_child(make_floating); + } + ShaderEditor *shader_editor = Object::cast_to(shader_tabs->get_tab_control(p_index)); + ERR_FAIL_NULL(shader_editor); - memdelete(c); + memdelete(shader_editor); edited_shaders.remove_at(p_index); _update_shader_list(); EditorUndoRedoManager::get_singleton()->clear_history(); // To prevent undo on deleted graphs. if (shader_tabs->get_tab_count() == 0) { shader_list->show(); // Make sure the panel is visible, because it can't be toggled without open shaders. - menu_spacer->show(); } else { _switch_to_editor(edited_shaders[shader_tabs->get_current_tab()].shader_editor); } @@ -797,44 +784,13 @@ void ShaderEditorPlugin::_update_shader_editor_zoom_factor(CodeTextEditor *p_sha } void ShaderEditorPlugin::_switch_to_editor(ShaderEditor *p_editor) { - Control *bar = p_editor->get_top_bar(); - - VisualShaderEditor *vs_editor = Object::cast_to(p_editor); - if (vs_editor) { + if (file_menu->get_parent() != nullptr) { file_menu->get_parent()->remove_child(file_menu); - file_menu->set_switch_on_hover(false); - bar->add_child(file_menu); - bar->move_child(file_menu, 2); // Toggle Files Panel button + separator. - + } + if (make_floating->get_parent()) { make_floating->get_parent()->remove_child(make_floating); - bar->add_child(make_floating); - } else { - if (menu_spacer->is_visible()) { - menu_spacer->hide(); - } - - // Just swapped from a visual shader editor. - if (file_menu->get_parent() != menu_hb) { - file_menu->get_parent()->remove_child(file_menu); - file_menu->set_switch_on_hover(true); - menu_hb->add_child(file_menu); - menu_hb->move_child(file_menu, 0); - - make_floating->get_parent()->remove_child(make_floating); - menu_hb->add_child(make_floating); - } - } - - for (int i = 0; i < shader_tabs->get_tab_count(); i++) { - ShaderEditor *se = Object::cast_to(shader_tabs->get_tab_control(i)); - if (se && se->get_top_bar()) { - if (se == p_editor) { - se->get_top_bar()->show(); - } else { - se->get_top_bar()->hide(); - } - } } + p_editor->use_menu_bar_items(file_menu, make_floating); } void ShaderEditorPlugin::_file_removed(const String &p_removed_file) { @@ -904,15 +860,14 @@ ShaderEditorPlugin::ShaderEditorPlugin() { files_split->set_split_offset(200 * EDSCALE); files_split->set_v_size_flags(Control::SIZE_EXPAND_FILL); - menu_hb = memnew(HBoxContainer); - main_container->add_child(menu_hb); file_menu = memnew(MenuButton); + file_menu->set_flat(false); + file_menu->set_theme_type_variation("FlatMenuButton"); file_menu->set_text(TTR("File")); file_menu->set_switch_on_hover(true); file_menu->set_shortcut_context(files_split); _setup_popup_menu(FILE, file_menu->get_popup()); file_menu->get_popup()->connect(SceneStringName(id_pressed), callable_mp(this, &ShaderEditorPlugin::_menu_item_pressed)); - menu_hb->add_child(file_menu); _set_file_specific_items_disabled(true); @@ -920,17 +875,13 @@ ShaderEditorPlugin::ShaderEditorPlugin() { add_child(context_menu); context_menu->connect(SceneStringName(id_pressed), callable_mp(this, &ShaderEditorPlugin::_menu_item_pressed)); - menu_spacer = menu_hb->add_spacer(); - make_floating = memnew(ScreenSelect); - make_floating->set_flat(true); make_floating->connect("request_open_in_screen", callable_mp(window_wrapper, &WindowWrapper::enable_window_on_screen).bind(true)); if (!make_floating->is_disabled()) { // Override default ScreenSelect tooltip if multi-window support is available. make_floating->set_tooltip_text(TTR("Make the shader editor floating.") + "\n" + TTR("Right-click to open the screen selector.")); } - menu_hb->add_child(make_floating); window_wrapper->connect("window_visibility_changed", callable_mp(this, &ShaderEditorPlugin::_window_changed)); shader_list = memnew(ItemList); @@ -963,3 +914,8 @@ ShaderEditorPlugin::ShaderEditorPlugin() { shader_create_dialog->connect("shader_created", callable_mp(this, &ShaderEditorPlugin::_shader_created)); shader_create_dialog->connect("shader_include_created", callable_mp(this, &ShaderEditorPlugin::_shader_include_created)); } + +ShaderEditorPlugin::~ShaderEditorPlugin() { + memdelete(file_menu); + memdelete(make_floating); +} diff --git a/editor/shader/shader_editor_plugin.h b/editor/shader/shader_editor_plugin.h index 2708cdd510..92df9b079f 100644 --- a/editor/shader/shader_editor_plugin.h +++ b/editor/shader/shader_editor_plugin.h @@ -85,8 +85,6 @@ class ShaderEditorPlugin : public EditorPlugin { VBoxContainer *main_container = nullptr; HSplitContainer *files_split = nullptr; - HBoxContainer *menu_hb = nullptr; - Control *menu_spacer = nullptr; ItemList *shader_list = nullptr; TabContainer *shader_tabs = nullptr; @@ -152,4 +150,5 @@ public: virtual void apply_changes() override; ShaderEditorPlugin(); + ~ShaderEditorPlugin(); }; diff --git a/editor/shader/text_shader_editor.cpp b/editor/shader/text_shader_editor.cpp index b88c075575..73c7d6b694 100644 --- a/editor/shader/text_shader_editor.cpp +++ b/editor/shader/text_shader_editor.cpp @@ -981,6 +981,13 @@ void TextShaderEditor::edit_shader_include(const Ref &p_shader_in code_editor->set_edited_shader_include(p_shader_inc); } +void TextShaderEditor::use_menu_bar_items(MenuButton *p_file_menu, Button *p_make_floating) { + p_file_menu->set_switch_on_hover(true); + menu_bar_hbox->add_child(p_file_menu); + menu_bar_hbox->move_child(p_file_menu, 0); + menu_bar_hbox->add_child(p_make_floating); +} + void TextShaderEditor::save_external_data(const String &p_str) { if (shader.is_null() && shader_inc.is_null()) { disk_changed->hide(); @@ -1029,10 +1036,6 @@ void TextShaderEditor::validate_script() { code_editor->_validate_script(); } -Control *TextShaderEditor::get_top_bar() { - return hbc; -} - bool TextShaderEditor::is_unsaved() const { return code_editor->get_text_editor()->get_saved_version() != code_editor->get_text_editor()->get_version(); } @@ -1206,9 +1209,11 @@ TextShaderEditor::TextShaderEditor() { VBoxContainer *main_container = memnew(VBoxContainer); main_container->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); - hbc = memnew(HBoxContainer); + menu_bar_hbox = memnew(HBoxContainer); edit_menu = memnew(MenuButton); + edit_menu->set_flat(false); + edit_menu->set_theme_type_variation("FlatMenuButton"); edit_menu->set_shortcut_context(this); edit_menu->set_text(TTR("Edit")); edit_menu->set_switch_on_hover(true); @@ -1237,6 +1242,8 @@ TextShaderEditor::TextShaderEditor() { edit_menu->get_popup()->connect(SceneStringName(id_pressed), callable_mp(this, &TextShaderEditor::_menu_option)); search_menu = memnew(MenuButton); + search_menu->set_flat(false); + search_menu->set_theme_type_variation("FlatMenuButton"); search_menu->set_shortcut_context(this); search_menu->set_text(TTR("Search")); search_menu->set_switch_on_hover(true); @@ -1248,6 +1255,8 @@ TextShaderEditor::TextShaderEditor() { search_menu->get_popup()->connect(SceneStringName(id_pressed), callable_mp(this, &TextShaderEditor::_menu_option)); MenuButton *goto_menu = memnew(MenuButton); + goto_menu->set_flat(false); + goto_menu->set_theme_type_variation("FlatMenuButton"); goto_menu->set_shortcut_context(this); goto_menu->set_text(TTR("Go To")); goto_menu->set_switch_on_hover(true); @@ -1263,20 +1272,21 @@ TextShaderEditor::TextShaderEditor() { bookmarks_menu->connect("index_pressed", callable_mp(this, &TextShaderEditor::_bookmark_item_pressed)); add_child(main_container); - hbc->add_child(edit_menu); - hbc->add_child(search_menu); - hbc->add_child(goto_menu); - hbc->add_spacer(); + main_container->add_child(menu_bar_hbox); + menu_bar_hbox->add_child(edit_menu); + menu_bar_hbox->add_child(search_menu); + menu_bar_hbox->add_child(goto_menu); + menu_bar_hbox->add_spacer(); site_search = memnew(Button); - site_search->set_flat(true); + site_search->set_theme_type_variation(SceneStringName(FlatButton)); site_search->connect(SceneStringName(pressed), callable_mp(this, &TextShaderEditor::_menu_option).bind(HELP_DOCS)); site_search->set_text(TTR("Online Docs")); site_search->set_tooltip_text(TTR("Open Godot online documentation.")); - hbc->add_child(site_search); - hbc->add_child(memnew(VSeparator)); + menu_bar_hbox->add_child(site_search); + menu_bar_hbox->add_child(memnew(VSeparator)); - hbc->add_theme_style_override(SceneStringName(panel), EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("ScriptEditorPanel"), EditorStringName(EditorStyles))); + menu_bar_hbox->add_theme_style_override(SceneStringName(panel), EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("ScriptEditorPanel"), EditorStringName(EditorStyles))); VSplitContainer *editor_box = memnew(VSplitContainer); main_container->add_child(editor_box); diff --git a/editor/shader/text_shader_editor.h b/editor/shader/text_shader_editor.h index 69fc52c3f0..a501c3b9e0 100644 --- a/editor/shader/text_shader_editor.h +++ b/editor/shader/text_shader_editor.h @@ -138,7 +138,7 @@ class TextShaderEditor : public ShaderEditor { EDIT_EMOJI_AND_SYMBOL, }; - HBoxContainer *hbc = nullptr; + HBoxContainer *menu_bar_hbox = nullptr; MenuButton *edit_menu = nullptr; MenuButton *search_menu = nullptr; PopupMenu *bookmarks_menu = nullptr; @@ -193,12 +193,12 @@ protected: public: virtual void edit_shader(const Ref &p_shader) override; virtual void edit_shader_include(const Ref &p_shader_inc) override; + virtual void use_menu_bar_items(MenuButton *p_file_menu, Button *p_make_floating) override; virtual void apply_shaders() override; virtual bool is_unsaved() const override; virtual void save_external_data(const String &p_str = "") override; virtual void validate_script() override; - virtual Control *get_top_bar() override; bool was_compilation_successful() const { return compilation_success; } bool get_trim_trailing_whitespace_on_save() const { return trim_trailing_whitespace_on_save; } diff --git a/editor/shader/visual_shader_editor_plugin.cpp b/editor/shader/visual_shader_editor_plugin.cpp index 85177add8c..841e588012 100644 --- a/editor/shader/visual_shader_editor_plugin.cpp +++ b/editor/shader/visual_shader_editor_plugin.cpp @@ -1562,6 +1562,13 @@ void VisualShaderEditor::edit_shader(const Ref &p_shader) { } } +void VisualShaderEditor::use_menu_bar_items(MenuButton *p_file_menu, Button *p_make_floating) { + p_file_menu->set_switch_on_hover(false); + toolbar_hflow->add_child(p_file_menu); + toolbar_hflow->move_child(p_file_menu, 2); // Toggle Files Panel button + separator. + toolbar_hflow->add_child(p_make_floating); +} + void VisualShaderEditor::apply_shaders() { // Stub. TODO: Implement apply_shaders in visual shaders for parity with text shaders. } @@ -1612,10 +1619,6 @@ VisualShader::Type VisualShaderEditor::get_current_shader_type() const { return current_type; } -Control *VisualShaderEditor::get_top_bar() { - return toolbar; -} - void VisualShaderEditor::add_plugin(const Ref &p_plugin) { if (plugins.has(p_plugin)) { return; @@ -6001,7 +6004,7 @@ void VisualShaderEditor::_varying_validate() { error += TTR("Invalid name for varying."); has_error = true; } else if (visual_shader->has_varying(varname)) { - error += TTR("Varying with that name is already exist."); + error += TTR("Varying with that name already exists."); has_error = true; } @@ -6609,7 +6612,7 @@ VisualShaderEditor::VisualShaderEditor() { toolbar_panel->set_anchors_and_offsets_preset(Control::PRESET_TOP_WIDE, PRESET_MODE_MINSIZE, 10); toolbar_panel->set_mouse_filter(Control::MOUSE_FILTER_IGNORE); - toolbar = memnew(HFlowContainer); + toolbar_hflow = memnew(HFlowContainer); { LocalVector nodes; for (int i = 0; i < graph->get_menu_hbox()->get_child_count(); i++) { @@ -6619,16 +6622,16 @@ VisualShaderEditor::VisualShaderEditor() { for (Node *node : nodes) { graph->get_menu_hbox()->remove_child(node); - toolbar->add_child(node); + toolbar_hflow->add_child(node); } graph->get_menu_hbox()->hide(); - toolbar_panel->add_child(toolbar); + toolbar_panel->add_child(toolbar_hflow); } VSeparator *vs = memnew(VSeparator); - toolbar->add_child(vs); - toolbar->move_child(vs, 0); + toolbar_hflow->add_child(vs); + toolbar_hflow->move_child(vs, 0); custom_mode_box = memnew(CheckBox); custom_mode_box->set_text(TTR("Custom")); @@ -6662,31 +6665,33 @@ VisualShaderEditor::VisualShaderEditor() { edit_type = edit_type_standard; - toolbar->add_child(custom_mode_box); - toolbar->move_child(custom_mode_box, 0); - toolbar->add_child(edit_type_standard); - toolbar->move_child(edit_type_standard, 0); - toolbar->add_child(edit_type_particles); - toolbar->move_child(edit_type_particles, 0); - toolbar->add_child(edit_type_sky); - toolbar->move_child(edit_type_sky, 0); - toolbar->add_child(edit_type_fog); - toolbar->move_child(edit_type_fog, 0); + toolbar_hflow->add_child(custom_mode_box); + toolbar_hflow->move_child(custom_mode_box, 0); + toolbar_hflow->add_child(edit_type_standard); + toolbar_hflow->move_child(edit_type_standard, 0); + toolbar_hflow->add_child(edit_type_particles); + toolbar_hflow->move_child(edit_type_particles, 0); + toolbar_hflow->add_child(edit_type_sky); + toolbar_hflow->move_child(edit_type_sky, 0); + toolbar_hflow->add_child(edit_type_fog); + toolbar_hflow->move_child(edit_type_fog, 0); add_node = memnew(Button); - add_node->set_flat(true); + add_node->set_theme_type_variation(SceneStringName(FlatButton)); add_node->set_text(TTR("Add Node...")); - toolbar->add_child(add_node); - toolbar->move_child(add_node, 0); + toolbar_hflow->add_child(add_node); + toolbar_hflow->move_child(add_node, 0); add_node->connect(SceneStringName(pressed), callable_mp(this, &VisualShaderEditor::_show_members_dialog).bind(false, VisualShaderNode::PORT_TYPE_MAX, VisualShaderNode::PORT_TYPE_MAX)); graph->connect("graph_elements_linked_to_frame_request", callable_mp(this, &VisualShaderEditor::_nodes_linked_to_frame_request)); graph->connect("frame_rect_changed", callable_mp(this, &VisualShaderEditor::_frame_rect_changed)); varying_button = memnew(MenuButton); + varying_button->set_flat(false); + varying_button->set_theme_type_variation("FlatMenuButton"); varying_button->set_text(TTR("Manage Varyings")); varying_button->set_switch_on_hover(true); - toolbar->add_child(varying_button); + toolbar_hflow->add_child(varying_button); PopupMenu *varying_menu = varying_button->get_popup(); varying_menu->add_item(TTR("Add Varying"), int(VaryingMenuOptions::ADD)); @@ -6697,7 +6702,7 @@ VisualShaderEditor::VisualShaderEditor() { code_preview_button->set_theme_type_variation(SceneStringName(FlatButton)); code_preview_button->set_toggle_mode(true); code_preview_button->set_tooltip_text(TTR("Show generated shader code.")); - toolbar->add_child(code_preview_button); + toolbar_hflow->add_child(code_preview_button); code_preview_button->connect(SceneStringName(pressed), callable_mp(this, &VisualShaderEditor::_show_preview_text)); shader_preview_button = memnew(Button); @@ -6705,34 +6710,34 @@ VisualShaderEditor::VisualShaderEditor() { shader_preview_button->set_toggle_mode(true); shader_preview_button->set_tooltip_text(TTR("Toggle shader preview.")); shader_preview_button->set_pressed(true); - toolbar->add_child(shader_preview_button); + toolbar_hflow->add_child(shader_preview_button); shader_preview_button->connect(SceneStringName(pressed), callable_mp(this, &VisualShaderEditor::_show_shader_preview)); Control *spacer = memnew(Control); spacer->set_h_size_flags(Control::SIZE_EXPAND); - toolbar->add_child(spacer); + toolbar_hflow->add_child(spacer); site_search = memnew(Button); - site_search->set_flat(true); + site_search->set_theme_type_variation(SceneStringName(FlatButton)); site_search->connect(SceneStringName(pressed), callable_mp(this, &VisualShaderEditor::_help_open)); site_search->set_text(TTR("Online Docs")); site_search->set_tooltip_text(TTR("Open Godot online documentation.")); - toolbar->add_child(site_search); - toolbar->add_child(memnew(VSeparator)); + toolbar_hflow->add_child(site_search); + toolbar_hflow->add_child(memnew(VSeparator)); VSeparator *separator = memnew(VSeparator); - toolbar->add_child(separator); - toolbar->move_child(separator, 0); + toolbar_hflow->add_child(separator); + toolbar_hflow->move_child(separator, 0); separator = memnew(VSeparator); - toolbar->add_child(separator); - toolbar->move_child(separator, 0); + toolbar_hflow->add_child(separator); + toolbar_hflow->move_child(separator, 0); toggle_files_button = memnew(Button); - toggle_files_button->set_flat(true); + toggle_files_button->set_theme_type_variation(SceneStringName(FlatButton)); toggle_files_button->connect(SceneStringName(pressed), callable_mp(this, &VisualShaderEditor::_toggle_files_pressed)); - toolbar->add_child(toggle_files_button); - toolbar->move_child(toggle_files_button, 0); + toolbar_hflow->add_child(toggle_files_button); + toolbar_hflow->move_child(toggle_files_button, 0); /////////////////////////////////////// // CODE PREVIEW @@ -7761,6 +7766,10 @@ VisualShaderEditor::VisualShaderEditor() { add_child(panning_debounce_timer); } +VisualShaderEditor::~VisualShaderEditor() { + save_editor_layout(); +} + class VisualShaderNodePluginInputEditor : public OptionButton { GDCLASS(VisualShaderNodePluginInputEditor, OptionButton); diff --git a/editor/shader/visual_shader_editor_plugin.h b/editor/shader/visual_shader_editor_plugin.h index e57d713c04..7130001d91 100644 --- a/editor/shader/visual_shader_editor_plugin.h +++ b/editor/shader/visual_shader_editor_plugin.h @@ -45,6 +45,7 @@ class ColorPicker; class CurveEditor; class GraphElement; class GraphFrame; +class HFlowContainer; class MenuButton; class PopupPanel; class RichTextLabel; @@ -222,7 +223,7 @@ class VisualShaderEditor : public ShaderEditor { MenuButton *varying_button = nullptr; Button *code_preview_button = nullptr; Button *shader_preview_button = nullptr; - Control *toolbar = nullptr; + HFlowContainer *toolbar_hflow = nullptr; int last_to_node = -1; int last_to_port = -1; @@ -652,6 +653,7 @@ protected: public: virtual void edit_shader(const Ref &p_shader) override; + virtual void use_menu_bar_items(MenuButton *p_file_menu, Button *p_make_floating) override; virtual void apply_shaders() override; virtual bool is_unsaved() const override; virtual void save_external_data(const String &p_str = "") override; @@ -662,8 +664,6 @@ public: void set_current_shader_type(VisualShader::Type p_type); VisualShader::Type get_current_shader_type() const; - virtual Control *get_top_bar() override; - void add_plugin(const Ref &p_plugin); void remove_plugin(const Ref &p_plugin); @@ -682,6 +682,7 @@ public: Ref get_visual_shader() const { return visual_shader; } VisualShaderEditor(); + ~VisualShaderEditor(); }; class VisualShaderNodePluginDefault : public VisualShaderNodePlugin { diff --git a/editor/themes/editor_icons.cpp b/editor/themes/editor_icons.cpp index 25b39014ef..bcbf79c468 100644 --- a/editor/themes/editor_icons.cpp +++ b/editor/themes/editor_icons.cpp @@ -36,8 +36,8 @@ #include "editor/themes/editor_color_map.h" #include "editor/themes/editor_icons.gen.h" #include "editor/themes/editor_scale.h" +#include "scene/resources/dpi_texture.h" #include "scene/resources/image_texture.h" -#include "scene/resources/svg_texture.h" #include "modules/svg/image_loader_svg.h" @@ -50,8 +50,8 @@ void editor_configure_icons(bool p_dark_theme) { } // See also `generate_icon()` in `scene/theme/default_theme.cpp`. -Ref editor_generate_icon(int p_index, float p_scale, float p_saturation, const Dictionary &p_convert_colors = Dictionary()) { - return SVGTexture::create_from_string(editor_icons_sources[p_index], p_scale, p_saturation, p_convert_colors); +Ref editor_generate_icon(int p_index, float p_scale, float p_saturation, const Dictionary &p_convert_colors = Dictionary()) { + return DPITexture::create_from_string(editor_icons_sources[p_index], p_scale, p_saturation, p_convert_colors); } float get_gizmo_handle_scale(const String &p_gizmo_handle_name, float p_gizmo_handle_scale) { @@ -156,14 +156,14 @@ void editor_register_icons(const Ref &p_theme, bool p_dark_theme, float p saturation = 1.0; } - Ref icon_dark = editor_generate_icon(i, get_gizmo_handle_scale(editor_icon_name, p_gizmo_handle_scale), saturation, color_conversion_map_dark); - Ref icon_light = editor_generate_icon(i, get_gizmo_handle_scale(editor_icon_name, p_gizmo_handle_scale), saturation, color_conversion_map_light); + Ref icon_dark = editor_generate_icon(i, get_gizmo_handle_scale(editor_icon_name, p_gizmo_handle_scale), saturation, color_conversion_map_dark); + Ref icon_light = editor_generate_icon(i, get_gizmo_handle_scale(editor_icon_name, p_gizmo_handle_scale), saturation, color_conversion_map_light); p_theme->set_icon(editor_icon_name + "Dark", EditorStringName(EditorIcons), icon_dark); p_theme->set_icon(editor_icon_name + "Light", EditorStringName(EditorIcons), icon_light); p_theme->set_icon(editor_icon_name, EditorStringName(EditorIcons), p_dark_theme ? icon_dark : icon_light); } else { - Ref icon; + Ref icon; if (accent_color_icons.has(editor_icon_name)) { icon = editor_generate_icon(i, get_gizmo_handle_scale(editor_icon_name, p_gizmo_handle_scale), 1.0, accent_color_map); } else { @@ -190,7 +190,7 @@ void editor_register_icons(const Ref &p_theme, bool p_dark_theme, float p const float scale = (float)p_thumb_size / 64.0 * EDSCALE; for (int i = 0; i < editor_bg_thumbs_count; i++) { const int index = editor_bg_thumbs_indices[i]; - Ref icon; + Ref icon; if (accent_color_icons.has(editor_icons_names[index])) { icon = editor_generate_icon(index, scale, 1.0, accent_color_map); @@ -213,7 +213,7 @@ void editor_register_icons(const Ref &p_theme, bool p_dark_theme, float p const float scale = (float)p_thumb_size / 32.0 * EDSCALE; for (int i = 0; i < editor_md_thumbs_count; i++) { const int index = editor_md_thumbs_indices[i]; - Ref icon; + Ref icon; if (accent_color_icons.has(editor_icons_names[index])) { icon = editor_generate_icon(index, scale, 1.0, accent_color_map); diff --git a/editor/themes/editor_theme_manager.cpp b/editor/themes/editor_theme_manager.cpp index c936b6c980..ab01241696 100644 --- a/editor/themes/editor_theme_manager.cpp +++ b/editor/themes/editor_theme_manager.cpp @@ -43,11 +43,11 @@ #include "editor/themes/editor_scale.h" #include "editor/themes/editor_theme.h" #include "scene/gui/graph_edit.h" +#include "scene/resources/dpi_texture.h" #include "scene/resources/image_texture.h" #include "scene/resources/style_box_flat.h" #include "scene/resources/style_box_line.h" #include "scene/resources/style_box_texture.h" -#include "scene/resources/svg_texture.h" #include "scene/resources/texture.h" // Theme configuration. @@ -1736,7 +1736,7 @@ void EditorThemeManager::_populate_standard_styles(const Ref &p_the p_theme->set_constant("port_h_offset", "GraphNode", 1); p_theme->set_constant("separation", "GraphNode", 1 * EDSCALE); - Ref port_icon = p_theme->get_icon(SNAME("GuiGraphNodePort"), EditorStringName(EditorIcons)); + Ref port_icon = p_theme->get_icon(SNAME("GuiGraphNodePort"), EditorStringName(EditorIcons)); // The true size is 24x24 This is necessary for sharp port icons at high zoom levels in GraphEdit (up to ~200%). port_icon->set_size_override(Size2(12, 12)); p_theme->set_icon("port", "GraphNode", port_icon); diff --git a/main/performance.cpp b/main/performance.cpp index c5c5ec8f71..1b10d336d7 100644 --- a/main/performance.cpp +++ b/main/performance.cpp @@ -531,7 +531,7 @@ void Performance::add_custom_monitor(const StringName &p_id, const Callable &p_c } void Performance::remove_custom_monitor(const StringName &p_id) { - ERR_FAIL_COND_MSG(!has_custom_monitor(p_id), "Custom monitor with id '" + String(p_id) + "' doesn't exists."); + ERR_FAIL_COND_MSG(!has_custom_monitor(p_id), "Custom monitor with id '" + String(p_id) + "' doesn't exist."); _monitor_map.erase(p_id); _monitor_modification_time = OS::get_singleton()->get_ticks_usec(); } @@ -541,7 +541,7 @@ bool Performance::has_custom_monitor(const StringName &p_id) { } Variant Performance::get_custom_monitor(const StringName &p_id) { - ERR_FAIL_COND_V_MSG(!has_custom_monitor(p_id), Variant(), "Custom monitor with id '" + String(p_id) + "' doesn't exists."); + ERR_FAIL_COND_V_MSG(!has_custom_monitor(p_id), Variant(), "Custom monitor with id '" + String(p_id) + "' doesn't exist."); bool error; String error_message; Variant return_value = _monitor_map[p_id].call(error, error_message); diff --git a/methods.py b/methods.py index 41f9aec886..e7c534877f 100644 --- a/methods.py +++ b/methods.py @@ -615,10 +615,10 @@ def CommandNoCache(env, target, sources, command, **args): return result -def Run(env, function): +def Run(env, function, comstr="$GENCOMSTR"): from SCons.Script import Action - return Action(function, "$GENCOMSTR") + return Action(function, comstr) def detect_darwin_toolchain_path(env): diff --git a/misc/extension_api_validation/4.4-stable.expected b/misc/extension_api_validation/4.4-stable.expected index c7136ebcd4..5f220c9df1 100644 --- a/misc/extension_api_validation/4.4-stable.expected +++ b/misc/extension_api_validation/4.4-stable.expected @@ -327,4 +327,4 @@ GH-108825 --------- Validate extension JSON: Error: Field 'classes/EditorExportPlatformExtension/methods/_get_option_icon/return_value': type changed value in new API, from "ImageTexture" to "Texture2D". -Return type changed to allow returning both ImageTexture and SVGTexture. Compatibility method registered. +Return type changed to allow returning both ImageTexture and DPITexture. Compatibility method registered. diff --git a/misc/scripts/install_d3d12_sdk_windows.py b/misc/scripts/install_d3d12_sdk_windows.py index 4b0ab16e31..4d3a6b8883 100755 --- a/misc/scripts/install_d3d12_sdk_windows.py +++ b/misc/scripts/install_d3d12_sdk_windows.py @@ -1,5 +1,9 @@ #!/usr/bin/env python +if __name__ != "__main__": + raise SystemExit(f'Utility script "{__file__}" should not be used as a module!') + +import argparse import os import shutil import subprocess @@ -10,6 +14,14 @@ sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "../ from misc.utility.color import Ansi, color_print +parser = argparse.ArgumentParser(description="Install D3D12 dependencies for Windows platforms.") +parser.add_argument( + "--mingw_prefix", + default=os.getenv("MINGW_PREFIX", ""), + help="Explicitly specify a path containing the MinGW bin folder.", +) +args = parser.parse_args() + # Base Godot dependencies path # If cross-compiling (no LOCALAPPDATA), we install in `bin` deps_folder = os.getenv("LOCALAPPDATA") @@ -74,10 +86,11 @@ print("Mesa NIR installed successfully.\n") # MinGW needs DLLs converted with dlltool. # We rely on finding gendef/dlltool to detect if we have MinGW. # Check existence of needed tools for generating mingw library. -gendef = shutil.which("gendef") or "" -dlltool = shutil.which("dlltool") or "" -if dlltool == "": - dlltool = shutil.which("x86_64-w64-mingw32-dlltool") or "" +pathstr = os.environ.get("PATH", "") +if args.mingw_prefix: + pathstr = os.path.join(args.mingw_prefix, "bin") + os.pathsep + pathstr +gendef = shutil.which("x86_64-w64-mingw32-gendef", path=pathstr) or shutil.which("gendef", path=pathstr) or "" +dlltool = shutil.which("x86_64-w64-mingw32-dlltool", path=pathstr) or shutil.which("dlltool", path=pathstr) or "" has_mingw = gendef != "" and dlltool != "" color_print(f"{Ansi.BOLD}[2/3] WinPixEventRuntime") @@ -107,7 +120,9 @@ if has_mingw: ) os.chdir(cwd) else: - print("MinGW wasn't found, so only MSVC support is provided for WinPixEventRuntime.") + print( + 'MinGW support requires "dlltool" and "gendef" dependencies, so only MSVC support is provided for WinPixEventRuntime. Did you forget to provide a `--mingw_prefix`?' + ) print(f"WinPixEventRuntime {pix_version} installed successfully.\n") # DirectX 12 Agility SDK diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 622bbf0200..1035758076 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -757,7 +757,12 @@ Error GDScript::reload(bool p_keep_state) { has_instances = instances.size(); } - ERR_FAIL_COND_V(!p_keep_state && has_instances, ERR_ALREADY_IN_USE); + // Check condition but reset flag before early return + if (!p_keep_state && has_instances) { + reloading = false; // Reset flag before returning + + ERR_FAIL_V_MSG(ERR_ALREADY_IN_USE, "Cannot reload script while instances exist."); + } String basedir = path; diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 92316d3ceb..03ae20c5a7 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -1989,16 +1989,18 @@ void GDScriptAnalyzer::resolve_function_body(GDScriptParser::FunctionNode *p_fun } p_function->resolved_body = true; - if (p_function->is_abstract) { - // Abstract functions don't have a body. - if (!p_function->body->statements.is_empty()) { - push_error(R"(Abstract function cannot have a body.)", p_function->body); + if (p_function->body->statements.is_empty()) { + // Non-abstract functions must have a body. + if (p_function->source_lambda != nullptr) { + push_error(R"(A lambda function must have a ":" followed by a body.)", p_function); + } else if (!p_function->is_abstract) { + push_error(R"(A function must either have a ":" followed by a body, or be marked as "@abstract".)", p_function); } return; } else { - // Non-abstract functions must have a body. - if (p_function->body->statements.is_empty()) { - push_error(R"(A function must either have a ":" followed by a body, or be marked as "@abstract".)", p_function); + // Abstract functions must not have a body. + if (p_function->is_abstract) { + push_error(R"(An abstract function cannot have a body.)", p_function->body); return; } } diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 46b69b7f7c..e9fa8b9a59 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -1787,7 +1787,7 @@ GDScriptParser::AnnotationNode *GDScriptParser::parse_annotation(uint32_t p_vali } argument_index++; - } while (match(GDScriptTokenizer::Token::COMMA) && !is_at_end()); + } while (match(GDScriptTokenizer::Token::COMMA)); pop_multiline(); consume(GDScriptTokenizer::Token::PARENTHESIS_CLOSE, R"*(Expected ")" after annotation arguments.)*"); diff --git a/modules/gdscript/tests/README.md b/modules/gdscript/tests/README.md index 4dc706f8d1..fef0190954 100644 --- a/modules/gdscript/tests/README.md +++ b/modules/gdscript/tests/README.md @@ -13,7 +13,7 @@ The `script/completion` folder contains test for the GDScript autocompletion. Each test case consists of at least one `.gd` file, which contains the code, and one `.cfg` file, which contains expected results and configuration. Inside of the GDScript file the character `âž¡` represents the cursor position, at which autocompletion is invoked. -The script files won't be parsable GDScript since it contains an invalid char and and often the code is not complete during autocompletion. To allow for a valid base when used with a scene, the +The script files won't be parsable GDScript since it contains an invalid char and often the code is not complete during autocompletion. To allow for a valid base when used with a scene, the runner will remove the line which contains `âž¡`. Therefore the scripts need to be valid if this line is removed, otherwise the test might behave in unexpected ways. This may for example require adding an additional `pass` statement. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/abstract_methods.gd b/modules/gdscript/tests/scripts/analyzer/errors/abstract_methods.gd index e50cf6d27f..3bc9b295dc 100644 --- a/modules/gdscript/tests/scripts/analyzer/errors/abstract_methods.gd +++ b/modules/gdscript/tests/scripts/analyzer/errors/abstract_methods.gd @@ -37,5 +37,8 @@ class Test4 extends AbstractClass: @abstract @abstract class DuplicateAbstract: pass +func holding_some_invalid_lambda(invalid_default_arg = func():): + var some_invalid_lambda = (func():) + func test(): pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/abstract_methods.out b/modules/gdscript/tests/scripts/analyzer/errors/abstract_methods.out index 4145012d08..e637570438 100644 --- a/modules/gdscript/tests/scripts/analyzer/errors/abstract_methods.out +++ b/modules/gdscript/tests/scripts/analyzer/errors/abstract_methods.out @@ -2,10 +2,12 @@ GDTEST_ANALYZER_ERROR >> ERROR at line 37: "@abstract" annotation can only be used once per class. >> ERROR at line 28: "@abstract" annotation can only be used once per function. >> ERROR at line 35: "@abstract" annotation cannot be applied to static functions. +>> ERROR at line 40: A lambda function must have a ":" followed by a body. +>> ERROR at line 41: A lambda function must have a ":" followed by a body. >> ERROR at line 11: Class "Test1" is not abstract but contains abstract methods. Mark the class as "@abstract" or remove "@abstract" from all methods in this class. >> ERROR at line 14: Class "Test2" must implement "AbstractClass.some_func()" and other inherited abstract methods or be marked as "@abstract". >> ERROR at line 17: Class "Test3" must implement "AbstractClassAgain.some_func()" and other inherited abstract methods or be marked as "@abstract". >> ERROR at line 22: Cannot call the parent class' abstract function "some_func()" because it hasn't been defined. >> ERROR at line 25: Cannot call the parent class' abstract function "some_func()" because it hasn't been defined. ->> ERROR at line 32: Abstract function cannot have a body. +>> ERROR at line 32: An abstract function cannot have a body. >> ERROR at line 35: A function must either have a ":" followed by a body, or be marked as "@abstract". diff --git a/modules/gltf/editor/editor_scene_importer_blend.cpp b/modules/gltf/editor/editor_scene_importer_blend.cpp index e88c6b2922..32ce2c7b76 100644 --- a/modules/gltf/editor/editor_scene_importer_blend.cpp +++ b/modules/gltf/editor/editor_scene_importer_blend.cpp @@ -148,6 +148,7 @@ Node *EditorSceneFormatImporterBlend::import_scene(const String &p_path, uint32_ parameters_map["export_keep_originals"] = unpack_original_images; parameters_map["export_format"] = "GLTF_SEPARATE"; parameters_map["export_yup"] = true; + parameters_map["export_import_convert_lighting_mode"] = "COMPAT"; if (p_options.has(SNAME("blender/nodes/custom_properties")) && p_options[SNAME("blender/nodes/custom_properties")]) { parameters_map["export_extras"] = true; diff --git a/modules/gltf/extensions/gltf_light.cpp b/modules/gltf/extensions/gltf_light.cpp index 5fb2f2df3f..a2baf30e6d 100644 --- a/modules/gltf/extensions/gltf_light.cpp +++ b/modules/gltf/extensions/gltf_light.cpp @@ -184,6 +184,7 @@ Light3D *GLTFLight::to_node() const { return nullptr; } light->set_color(color.linear_to_srgb()); + light->set_param(Light3D::PARAM_ATTENUATION, 2.0); return light; } diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 53f40d6ed9..a0878239ac 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -1505,7 +1505,8 @@ Error GLTFDocument::_decode_buffer_view(Ref p_state, double *p_dst, c } double d = 0; - + // 3.11. Implementations MUST use following equations to decode real floating-point value f from a normalized integer c and vise-versa. + // https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#animations switch (p_component_type) { case GLTFAccessor::COMPONENT_TYPE_NONE: { ERR_FAIL_V_MSG(ERR_INVALID_DATA, "glTF: Failed to decode buffer view, component type not set."); @@ -1513,7 +1514,7 @@ Error GLTFDocument::_decode_buffer_view(Ref p_state, double *p_dst, c case GLTFAccessor::COMPONENT_TYPE_SIGNED_BYTE: { int8_t b = int8_t(*src); if (p_normalized) { - d = (double(b) / 128.0); + d = MAX(double(b) / 127.0, -1.0); } else { d = double(b); } @@ -1529,7 +1530,7 @@ Error GLTFDocument::_decode_buffer_view(Ref p_state, double *p_dst, c case GLTFAccessor::COMPONENT_TYPE_SIGNED_SHORT: { int16_t s = *(int16_t *)src; if (p_normalized) { - d = (double(s) / 32768.0); + d = MAX(double(s) / 32767.0, -1.0); } else { d = double(s); } @@ -1630,7 +1631,7 @@ Vector GLTFDocument::_decode_accessor(Ref p_state, const GLTF case GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT: { if (a->accessor_type == GLTFAccessor::TYPE_MAT3) { skip_every = 6; - skip_bytes = 4; + skip_bytes = 2; element_size = 16; //override for this case } } break; @@ -1726,7 +1727,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_ints(Ref p_state, int64_t size = p_state->buffers[0].size(); const GLTFAccessor::GLTFAccessorType accessor_type = GLTFAccessor::TYPE_SCALAR; GLTFAccessor::GLTFComponentType component_type; - if (max_index > 65535 || p_for_vertex) { + if (max_index > 65534 || p_for_vertex) { component_type = GLTFAccessor::COMPONENT_TYPE_UNSIGNED_INT; } else { component_type = GLTFAccessor::COMPONENT_TYPE_UNSIGNED_SHORT; @@ -2276,7 +2277,7 @@ GLTFAccessorIndex GLTFDocument::_encode_sparse_accessor_as_vec3(Ref p } sparse_accessor->max = type_max; sparse_accessor->min = type_min; - int64_t sparse_accessor_index_stride = max_changed_index > 65535 ? 4 : 2; + int64_t sparse_accessor_index_stride = max_changed_index > 65534 ? 4 : 2; int64_t sparse_accessor_storage_size = changed_indices.size() * (sparse_accessor_index_stride + element_count * sizeof(float)); int64_t conventional_storage_size = p_attribs.size() * element_count * sizeof(float); @@ -3053,7 +3054,7 @@ Error GLTFDocument::_serialize_meshes(Ref p_state) { } } { - const Array &a = array[Mesh::ARRAY_WEIGHTS]; + const PackedRealArray &a = array[Mesh::ARRAY_WEIGHTS]; const Vector &vertex_array = array[Mesh::ARRAY_VERTEX]; if ((a.size() / JOINT_GROUP_SIZE) == vertex_array.size()) { int32_t vertex_count = vertex_array.size(); @@ -3342,13 +3343,14 @@ Error GLTFDocument::_parse_meshes(Ref p_state) { Vector indices_vec4_mapping; if (mesh_prim.has("indices")) { indices = _decode_accessor_as_ints(p_state, mesh_prim["indices"], false); - const int is = indices.size(); + const int index_count = indices.size(); if (primitive == Mesh::PRIMITIVE_TRIANGLES) { + ERR_FAIL_COND_V_MSG(index_count % 3 != 0, ERR_PARSE_ERROR, "glTF import: Mesh " + itos(i) + " surface " + itos(j) + " in file " + p_state->filename + " is invalid. Indexed triangle meshes MUST have an index array with a size that is a multiple of 3, but got " + itos(index_count) + " indices."); // Swap around indices, convert ccw to cw for front face. int *w = indices.ptrw(); - for (int k = 0; k < is; k += 3) { + for (int k = 0; k < index_count; k += 3) { SWAP(w[k + 1], w[k + 2]); } } @@ -3357,7 +3359,7 @@ Error GLTFDocument::_parse_meshes(Ref p_state) { Vector used_indices; used_indices.resize_initialized(orig_vertex_num); bool *used_w = used_indices.ptrw(); - for (int idx_i = 0; idx_i < is; idx_i++) { + for (int idx_i = 0; idx_i < index_count; idx_i++) { ERR_FAIL_INDEX_V(indices_w[idx_i], orig_vertex_num, ERR_INVALID_DATA); used_w[indices_w[idx_i]] = true; } @@ -3476,6 +3478,9 @@ Error GLTFDocument::_parse_meshes(Ref p_state) { } array[Mesh::ARRAY_BONES] = joints; } + // glTF stores weights as a VEC4 array or multiple VEC4 arrays, but Godot's + // ArrayMesh uses a flat array of either 4 or 8 floats per vertex. + // Therefore, decode up to two glTF VEC4 arrays as float arrays. if (a.has("WEIGHTS_0") && !a.has("WEIGHTS_1")) { Vector weights = _decode_accessor_as_floats(p_state, a["WEIGHTS_0"], true, indices_vec4_mapping); ERR_FAIL_COND_V(weights.size() != 4 * vertex_num, ERR_INVALID_DATA); @@ -3558,11 +3563,12 @@ Error GLTFDocument::_parse_meshes(Ref p_state) { // Generate indices because they need to be swapped for CW/CCW. const Vector &vertices = array[Mesh::ARRAY_VERTEX]; ERR_FAIL_COND_V(vertices.is_empty(), ERR_PARSE_ERROR); - const int vs = vertices.size(); - indices.resize(vs); + const int vertex_count = vertices.size(); + ERR_FAIL_COND_V_MSG(vertex_count % 3 != 0, ERR_PARSE_ERROR, "glTF import: Mesh " + itos(i) + " surface " + itos(j) + " in file " + p_state->filename + " is invalid. Non-indexed triangle meshes MUST have a vertex array with a size that is a multiple of 3, but got " + itos(vertex_count) + " vertices."); + indices.resize(vertex_count); { int *w = indices.ptrw(); - for (int k = 0; k < vs; k += 3) { + for (int k = 0; k < vertex_count; k += 3) { w[k] = k; w[k + 1] = k + 2; w[k + 2] = k + 1; @@ -7784,9 +7790,12 @@ bool GLTFDocument::_convert_animation_node_track(Ref p_state, GLTFAni while (true) { Vector3 scale; Error err = p_godot_animation->try_scale_track_interpolate(p_godot_anim_track_index, time, &scale); - ERR_CONTINUE(err != OK); - p_gltf_node_track.scale_track.values.push_back(scale); - p_gltf_node_track.scale_track.times.push_back(time); + if (err == OK) { + p_gltf_node_track.scale_track.values.push_back(scale); + p_gltf_node_track.scale_track.times.push_back(time); + } else { + ERR_PRINT(vformat("Error interpolating animation %s scale track %d at time %f", p_godot_animation->get_name(), p_godot_anim_track_index, time)); + } if (last) { break; } @@ -7819,9 +7828,12 @@ bool GLTFDocument::_convert_animation_node_track(Ref p_state, GLTFAni while (true) { Vector3 scale; Error err = p_godot_animation->try_position_track_interpolate(p_godot_anim_track_index, time, &scale); - ERR_CONTINUE(err != OK); - p_gltf_node_track.position_track.values.push_back(scale); - p_gltf_node_track.position_track.times.push_back(time); + if (err == OK) { + p_gltf_node_track.position_track.values.push_back(scale); + p_gltf_node_track.position_track.times.push_back(time); + } else { + ERR_PRINT(vformat("Error interpolating animation %s position track %d at time %f", p_godot_animation->get_name(), p_godot_anim_track_index, time)); + } if (last) { break; } @@ -7854,9 +7866,12 @@ bool GLTFDocument::_convert_animation_node_track(Ref p_state, GLTFAni while (true) { Quaternion rotation; Error err = p_godot_animation->try_rotation_track_interpolate(p_godot_anim_track_index, time, &rotation); - ERR_CONTINUE(err != OK); - p_gltf_node_track.rotation_track.values.push_back(rotation); - p_gltf_node_track.rotation_track.times.push_back(time); + if (err == OK) { + p_gltf_node_track.rotation_track.values.push_back(rotation); + p_gltf_node_track.rotation_track.times.push_back(time); + } else { + ERR_PRINT(vformat("Error interpolating animation %s value rotation track %d at time %f", p_godot_animation->get_name(), p_godot_anim_track_index, time)); + } if (last) { break; } @@ -7896,9 +7911,12 @@ bool GLTFDocument::_convert_animation_node_track(Ref p_state, GLTFAni while (true) { Vector3 position; Error err = p_godot_animation->try_position_track_interpolate(p_godot_anim_track_index, time, &position); - ERR_CONTINUE(err != OK); - p_gltf_node_track.position_track.values.push_back(position); - p_gltf_node_track.position_track.times.push_back(time); + if (err == OK) { + p_gltf_node_track.position_track.values.push_back(position); + p_gltf_node_track.position_track.times.push_back(time); + } else { + ERR_PRINT(vformat("Error interpolating animation %s value position track %d at time %f", p_godot_animation->get_name(), p_godot_anim_track_index, time)); + } if (last) { break; } @@ -7929,9 +7947,12 @@ bool GLTFDocument::_convert_animation_node_track(Ref p_state, GLTFAni while (true) { Quaternion rotation; Error err = p_godot_animation->try_rotation_track_interpolate(p_godot_anim_track_index, time, &rotation); - ERR_CONTINUE(err != OK); - p_gltf_node_track.rotation_track.values.push_back(rotation); - p_gltf_node_track.rotation_track.times.push_back(time); + if (err == OK) { + p_gltf_node_track.rotation_track.values.push_back(rotation); + p_gltf_node_track.rotation_track.times.push_back(time); + } else { + ERR_PRINT(vformat("Error interpolating animation %s value rotation track %d at time %f", p_godot_animation->get_name(), p_godot_anim_track_index, time)); + } if (last) { break; } @@ -7972,9 +7993,12 @@ bool GLTFDocument::_convert_animation_node_track(Ref p_state, GLTFAni while (true) { Vector3 scale; Error err = p_godot_animation->try_scale_track_interpolate(p_godot_anim_track_index, time, &scale); - ERR_CONTINUE(err != OK); - p_gltf_node_track.scale_track.values.push_back(scale); - p_gltf_node_track.scale_track.times.push_back(time); + if (err == OK) { + p_gltf_node_track.scale_track.values.push_back(scale); + p_gltf_node_track.scale_track.times.push_back(time); + } else { + ERR_PRINT(vformat("Error interpolating animation %s scale track %d at time %f", p_godot_animation->get_name(), p_godot_anim_track_index, time)); + } if (last) { break; } @@ -8017,17 +8041,22 @@ bool GLTFDocument::_convert_animation_node_track(Ref p_state, GLTFAni Quaternion rotation; Vector3 scale; Error err = p_godot_animation->try_position_track_interpolate(p_godot_anim_track_index, time, &position); - ERR_CONTINUE(err != OK); - err = p_godot_animation->try_rotation_track_interpolate(p_godot_anim_track_index, time, &rotation); - ERR_CONTINUE(err != OK); - err = p_godot_animation->try_scale_track_interpolate(p_godot_anim_track_index, time, &scale); - ERR_CONTINUE(err != OK); - p_gltf_node_track.position_track.values.push_back(position); - p_gltf_node_track.position_track.times.push_back(time); - p_gltf_node_track.rotation_track.values.push_back(rotation); - p_gltf_node_track.rotation_track.times.push_back(time); - p_gltf_node_track.scale_track.values.push_back(scale); - p_gltf_node_track.scale_track.times.push_back(time); + if (err == OK) { + err = p_godot_animation->try_rotation_track_interpolate(p_godot_anim_track_index, time, &rotation); + if (err == OK) { + err = p_godot_animation->try_scale_track_interpolate(p_godot_anim_track_index, time, &scale); + } + } + if (err == OK) { + p_gltf_node_track.position_track.values.push_back(position); + p_gltf_node_track.position_track.times.push_back(time); + p_gltf_node_track.rotation_track.values.push_back(rotation); + p_gltf_node_track.rotation_track.times.push_back(time); + p_gltf_node_track.scale_track.values.push_back(scale); + p_gltf_node_track.scale_track.times.push_back(time); + } else { + ERR_PRINT(vformat("Error interpolating animation %s transform track %d at time %f", p_godot_animation->get_name(), p_godot_anim_track_index, time)); + } if (last) { break; } diff --git a/modules/jolt_physics/objects/jolt_soft_body_3d.cpp b/modules/jolt_physics/objects/jolt_soft_body_3d.cpp index 00e0f421bd..8490184ff0 100644 --- a/modules/jolt_physics/objects/jolt_soft_body_3d.cpp +++ b/modules/jolt_physics/objects/jolt_soft_body_3d.cpp @@ -159,6 +159,9 @@ bool JoltSoftBody3D::_ref_shared_data() { const int mesh_index_count = mesh_indices.size(); mesh_to_physics.resize(mesh_vertex_count); + for (int &index : mesh_to_physics) { + index = -1; + } physics_vertices.reserve(mesh_vertex_count); vertex_to_physics.reserve(mesh_vertex_count); @@ -411,7 +414,8 @@ void JoltSoftBody3D::apply_vertex_impulse(int p_index, const Vector3 &p_impulse) ERR_FAIL_NULL(shared); ERR_FAIL_INDEX(p_index, (int)shared->mesh_to_physics.size()); - const size_t physics_index = (size_t)shared->mesh_to_physics[p_index]; + const int physics_index = shared->mesh_to_physics[p_index]; + ERR_FAIL_COND_MSG(physics_index < 0, vformat("Soft body vertex %d was not used by a face and has been omitted for '%s'. No impulse can be applied.", p_index, to_string())); ERR_FAIL_COND_MSG(pinned_vertices.has(physics_index), vformat("Failed to apply impulse to point at index %d for '%s'. Point was found to be pinned.", static_cast(physics_index), to_string())); JPH::SoftBodyMotionProperties &motion_properties = static_cast(*jolt_body->GetMotionPropertiesUnchecked()); @@ -674,12 +678,13 @@ void JoltSoftBody3D::update_rendering_server(PhysicsServer3DRenderingServerHandl for (int i = 0; i < mesh_vertex_count; ++i) { const int physics_index = shared->mesh_to_physics[i]; + if (physics_index >= 0) { + const Vector3 vertex = to_godot(physics_vertices[(size_t)physics_index].mPosition); + const Vector3 normal = normals[(uint32_t)physics_index]; - const Vector3 vertex = to_godot(physics_vertices[(size_t)physics_index].mPosition); - const Vector3 normal = normals[(uint32_t)physics_index]; - - p_rendering_server_handler->set_vertex(i, vertex); - p_rendering_server_handler->set_normal(i, normal); + p_rendering_server_handler->set_vertex(i, vertex); + p_rendering_server_handler->set_normal(i, normal); + } } p_rendering_server_handler->set_aabb(get_bounds()); @@ -690,7 +695,8 @@ Vector3 JoltSoftBody3D::get_vertex_position(int p_index) { ERR_FAIL_NULL_V(shared, Vector3()); ERR_FAIL_INDEX_V(p_index, (int)shared->mesh_to_physics.size(), Vector3()); - const size_t physics_index = (size_t)shared->mesh_to_physics[p_index]; + const int physics_index = shared->mesh_to_physics[p_index]; + ERR_FAIL_COND_V_MSG(physics_index < 0, Vector3(), vformat("Soft body vertex %d was not used by a face and has been omitted for '%s'. Position cannot be returned.", p_index, to_string())); const JPH::SoftBodyMotionProperties &motion_properties = static_cast(*jolt_body->GetMotionPropertiesUnchecked()); const JPH::Array &physics_vertices = motion_properties.GetVertices(); @@ -704,7 +710,8 @@ void JoltSoftBody3D::set_vertex_position(int p_index, const Vector3 &p_position) ERR_FAIL_NULL(shared); ERR_FAIL_INDEX(p_index, (int)shared->mesh_to_physics.size()); - const size_t physics_index = (size_t)shared->mesh_to_physics[p_index]; + const int physics_index = shared->mesh_to_physics[p_index]; + ERR_FAIL_COND_MSG(physics_index < 0, vformat("Soft body vertex %d was not used by a face and has been omitted for '%s'. Position cannot be set.", p_index, to_string())); JPH::SoftBodyMotionProperties &motion_properties = static_cast(*jolt_body->GetMotionPropertiesUnchecked()); JPH::Array &physics_vertices = motion_properties.GetVertices(); diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index e444a4b0a6..e30b6cf5ee 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -1129,7 +1129,7 @@ void CSharpLanguage::release_binding_gchandle_thread_safe(GCHandleIntPtr p_gchan } CSharpLanguage::CSharpLanguage() { - ERR_FAIL_COND_MSG(singleton, "C# singleton already exist."); + ERR_FAIL_COND_MSG(singleton, "C# singleton already exists."); singleton = this; } diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/KeywordClassNameAndNamespaceTest.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/KeywordClassNameAndNamespaceTest.cs new file mode 100644 index 0000000000..2cb24f03c3 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/KeywordClassNameAndNamespaceTest.cs @@ -0,0 +1,15 @@ +using Xunit; + +namespace Godot.SourceGenerators.Tests; + +public class KeywordClassAndNamespaceTest +{ + [Fact] + public async void GenerateScriptMethodsTest() + { + await CSharpSourceGeneratorVerifier.Verify( + "KeywordClassNameAndNamespace.cs", + "namespace.class_ScriptMethods.generated.cs" + ); + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/namespace.class_ScriptMethods.generated.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/namespace.class_ScriptMethods.generated.cs new file mode 100644 index 0000000000..fd5ac59440 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/GeneratedSources/namespace.class_ScriptMethods.generated.cs @@ -0,0 +1,17 @@ +using Godot; +using Godot.NativeInterop; + +namespace @namespace { + +partial class @class +{ +#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword + /// + /// Cached StringNames for the methods contained in this class, for fast lookup. + /// + public new class MethodName : global::Godot.GodotObject.MethodName { + } +#pragma warning restore CS0109 +} + +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/KeywordClassNameAndNamespace.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/KeywordClassNameAndNamespace.cs new file mode 100644 index 0000000000..97ac64c237 --- /dev/null +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators.Tests/TestData/Sources/KeywordClassNameAndNamespace.cs @@ -0,0 +1,8 @@ +using Godot; + +namespace @namespace +{ + partial class @class : GodotObject + { + } +} diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs index a717212f5c..2157a560b7 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs @@ -181,13 +181,6 @@ namespace Godot.SourceGenerators }; } - public static string NameWithTypeParameters(this INamedTypeSymbol symbol) - { - return symbol.IsGenericType && symbol.TypeParameters.Length > 0 ? - string.Concat(symbol.Name, "<", string.Join(", ", symbol.TypeParameters), ">") : - symbol.Name; - } - private static SymbolDisplayFormat FullyQualifiedFormatOmitGlobal { get; } = SymbolDisplayFormat.FullyQualifiedFormat .WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted); @@ -268,6 +261,8 @@ namespace Godot.SourceGenerators public static string SanitizeQualifiedNameForUniqueHint(this string qualifiedName) => qualifiedName + // AddSource() doesn't support @ prefix + .Replace("@", "") // AddSource() doesn't support angle brackets .Replace("<", "(Of ") .Replace(">", ")"); diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs index 89c5c8e912..cd0671e0ea 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs @@ -114,13 +114,13 @@ namespace Godot.SourceGenerators source.Append("partial "); source.Append(containingType.GetDeclarationKeyword()); source.Append(" "); - source.Append(containingType.NameWithTypeParameters()); + source.Append(containingType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); } } source.Append("partial class "); - source.Append(symbol.NameWithTypeParameters()); + source.Append(symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); var members = symbol.GetMembers(); diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs index 59cf9946c9..ec6094637d 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPathAttributeGenerator.cs @@ -138,7 +138,7 @@ namespace Godot.SourceGenerators source.Append(attributes); source.Append("\npartial class "); - source.Append(symbol.NameWithTypeParameters()); + source.Append(symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n}\n"); if (hasNamespace) diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs index 07a2849d97..34e8fc7714 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs @@ -103,13 +103,13 @@ namespace Godot.SourceGenerators source.Append("partial "); source.Append(containingType.GetDeclarationKeyword()); source.Append(" "); - source.Append(containingType.NameWithTypeParameters()); + source.Append(containingType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); } } source.Append("partial class "); - source.Append(symbol.NameWithTypeParameters()); + source.Append(symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); var members = symbol.GetMembers(); diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs index 480f15495d..d12336a1cd 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs @@ -100,13 +100,13 @@ namespace Godot.SourceGenerators source.Append("partial "); source.Append(containingType.GetDeclarationKeyword()); source.Append(" "); - source.Append(containingType.NameWithTypeParameters()); + source.Append(containingType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); } } source.Append("partial class "); - source.Append(symbol.NameWithTypeParameters()); + source.Append(symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); var exportedMembers = new List(); diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs index 937da76335..57e24ec25e 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs @@ -101,13 +101,13 @@ namespace Godot.SourceGenerators source.Append("partial "); source.Append(containingType.GetDeclarationKeyword()); source.Append(" "); - source.Append(containingType.NameWithTypeParameters()); + source.Append(containingType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); } } source.Append("partial class "); - source.Append(symbol.NameWithTypeParameters()); + source.Append(symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); var members = symbol.GetMembers(); diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs index 527a3d88d8..8b623ab0f5 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs @@ -106,13 +106,13 @@ namespace Godot.SourceGenerators source.Append("partial "); source.Append(containingType.GetDeclarationKeyword()); source.Append(" "); - source.Append(containingType.NameWithTypeParameters()); + source.Append(containingType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); } } source.Append("partial class "); - source.Append(symbol.NameWithTypeParameters()); + source.Append(symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); var members = symbol.GetMembers(); diff --git a/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/ExtensionMethods.cs b/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/ExtensionMethods.cs index 3fc27a29d8..a7e3f57c3c 100644 --- a/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/ExtensionMethods.cs +++ b/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/ExtensionMethods.cs @@ -94,13 +94,6 @@ internal static class ExtensionMethods }; } - public static string NameWithTypeParameters(this INamedTypeSymbol symbol) - { - return symbol.IsGenericType && symbol.TypeParameters.Length > 0 ? - string.Concat(symbol.Name, "<", string.Join(", ", symbol.TypeParameters), ">") : - symbol.Name; - } - private static SymbolDisplayFormat FullyQualifiedFormatOmitGlobal { get; } = SymbolDisplayFormat.FullyQualifiedFormat .WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted); @@ -123,6 +116,8 @@ internal static class ExtensionMethods public static string SanitizeQualifiedNameForUniqueHint(this string qualifiedName) => qualifiedName + // AddSource() doesn't support @ prefix + .Replace("@", "") // AddSource() doesn't support angle brackets .Replace("<", "(Of ") .Replace(">", ")"); diff --git a/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/UnmanagedCallbacksGenerator.cs b/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/UnmanagedCallbacksGenerator.cs index 80d6160f3d..53197bf895 100644 --- a/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/UnmanagedCallbacksGenerator.cs +++ b/modules/mono/glue/GodotSharp/Godot.SourceGenerators.Internal/UnmanagedCallbacksGenerator.cs @@ -140,7 +140,7 @@ using Godot.NativeInterop; source.Append("partial "); source.Append(containingType.GetDeclarationKeyword()); source.Append(" "); - source.Append(containingType.NameWithTypeParameters()); + source.Append(containingType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); } } @@ -319,7 +319,7 @@ using Godot.NativeInterop; source.Append("partial "); source.Append(containingType.GetDeclarationKeyword()); source.Append(" "); - source.Append(containingType.NameWithTypeParameters()); + source.Append(containingType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); source.Append("\n{\n"); } } diff --git a/modules/openxr/action_map/openxr_action_map.cpp b/modules/openxr/action_map/openxr_action_map.cpp index 311b2856c3..a7f613bea8 100644 --- a/modules/openxr/action_map/openxr_action_map.cpp +++ b/modules/openxr/action_map/openxr_action_map.cpp @@ -476,7 +476,7 @@ void OpenXRActionMap::create_default_action_sets() { profile->add_new_binding(trigger, "/user/hand/left/input/trigger/value,/user/hand/right/input/trigger/value"); profile->add_new_binding(trigger_click, "/user/hand/left/input/trigger/click,/user/hand/right/input/trigger/click"); profile->add_new_binding(trigger_touch, "/user/hand/left/input/trigger/touch,/user/hand/right/input/trigger/touch"); - profile->add_new_binding(grip, "/user/hand/left/input/squeeze/click,/user/hand/right/input/squeeze/click"); + profile->add_new_binding(grip, "/user/hand/left/input/squeeze/value,/user/hand/right/input/squeeze/value"); profile->add_new_binding(grip_click, "/user/hand/left/input/squeeze/click,/user/hand/right/input/squeeze/click"); // primary on our Focus 3 controller is our thumbstick. profile->add_new_binding(primary, "/user/hand/left/input/thumbstick,/user/hand/right/input/thumbstick"); diff --git a/modules/openxr/extensions/openxr_htc_controller_extension.cpp b/modules/openxr/extensions/openxr_htc_controller_extension.cpp index b9f51e2729..bf14c10b03 100644 --- a/modules/openxr/extensions/openxr_htc_controller_extension.cpp +++ b/modules/openxr/extensions/openxr_htc_controller_extension.cpp @@ -110,6 +110,7 @@ void OpenXRHTCControllerExtension::on_register_metadata() { openxr_metadata->register_io_path(profile_path, "Trigger click", user_path, user_path + "/input/trigger/click", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Trigger touch", user_path, user_path + "/input/trigger/touch", "", OpenXRAction::OPENXR_ACTION_BOOL); + openxr_metadata->register_io_path(profile_path, "Squeeze", user_path, user_path + "/input/squeeze/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); openxr_metadata->register_io_path(profile_path, "Squeeze click", user_path, user_path + "/input/squeeze/click", "", OpenXRAction::OPENXR_ACTION_BOOL); openxr_metadata->register_io_path(profile_path, "Squeeze touch", user_path, user_path + "/input/squeeze/touch", "", OpenXRAction::OPENXR_ACTION_BOOL); diff --git a/modules/openxr/extensions/openxr_render_model_extension.cpp b/modules/openxr/extensions/openxr_render_model_extension.cpp index c650673ff7..bb1c735381 100644 --- a/modules/openxr/extensions/openxr_render_model_extension.cpp +++ b/modules/openxr/extensions/openxr_render_model_extension.cpp @@ -347,29 +347,20 @@ RID OpenXRRenderModelExtension::render_model_create(XrRenderModelIdEXT p_render_ RenderModel render_model; render_model.xr_render_model_id = p_render_model_id; - // Start with the extensions that are supported in our base (see GLTFDocument::_parse_gltf_extensions). - Vector supported_gltf_extensions = { - "KHR_lights_punctual", - "KHR_materials_pbrSpecularGlossiness", - "KHR_texture_transform", - "KHR_materials_unlit", - "KHR_materials_emissive_strength", - }; - - // Now find anything we support through plugins, which is a bit of a pain as they are converted to Strings - // and we need to convert them back. - Vector char_extensions; // Just for temp storage of our c-strings. - Vector> gltf_document_extensions = GLTFDocument::get_all_gltf_document_extensions(); - for (Ref &gltf_document_extension : gltf_document_extensions) { - Vector supported_extensions = gltf_document_extension->get_supported_extensions(); - for (const String &extension : supported_extensions) { - char_extensions.push_back(extension.utf8()); - } + // Get a list of supported glTF extensions. + const HashSet supported_gltf_extensions_hash_set = GLTFDocument::get_supported_gltf_extensions_hashset(); + Vector supported_gltf_extensions_char_string; // Just for temp storage of our c-strings. + supported_gltf_extensions_char_string.resize(supported_gltf_extensions_hash_set.size()); + int64_t supported_gltf_extension_index = 0; + for (const String &ext : supported_gltf_extensions_hash_set) { + supported_gltf_extensions_char_string.set(supported_gltf_extension_index, ext.utf8()); + supported_gltf_extension_index++; } - - // Now we can add them to our supported extensions list. - for (const CharString &cs : char_extensions) { - supported_gltf_extensions.push_back(cs.get_data()); + // Now we can convert them to the `const char *` format. + Vector supported_gltf_extensions; + supported_gltf_extensions.resize(supported_gltf_extensions_char_string.size()); + for (int64_t i = 0; i < supported_gltf_extensions_char_string.size(); i++) { + supported_gltf_extensions.write[i] = supported_gltf_extensions_char_string[i].get_data(); } XrRenderModelCreateInfoEXT create_info = { diff --git a/modules/openxr/extensions/platform/openxr_metal_extension.mm b/modules/openxr/extensions/platform/openxr_metal_extension.mm index 826f3587c5..342a722835 100644 --- a/modules/openxr/extensions/platform/openxr_metal_extension.mm +++ b/modules/openxr/extensions/platform/openxr_metal_extension.mm @@ -157,7 +157,7 @@ bool OpenXRMetalExtension::get_swapchain_image_data(XrSwapchain p_swapchain, int uint32_t swapchain_length; XrResult result = xrEnumerateSwapchainImages(p_swapchain, 0, &swapchain_length, nullptr); if (XR_FAILED(result)) { - print_line("OpenXR: Failed to get swapchaim image count [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); + print_line("OpenXR: Failed to get swapchain image count [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); return false; } @@ -171,7 +171,7 @@ bool OpenXRMetalExtension::get_swapchain_image_data(XrSwapchain p_swapchain, int result = xrEnumerateSwapchainImages(p_swapchain, swapchain_length, &swapchain_length, (XrSwapchainImageBaseHeader *)images.ptr()); if (XR_FAILED(result)) { - print_line("OpenXR: Failed to get swapchaim images [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); + print_line("OpenXR: Failed to get swapchain images [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); return false; } diff --git a/modules/openxr/extensions/platform/openxr_opengl_extension.cpp b/modules/openxr/extensions/platform/openxr_opengl_extension.cpp index d8de70d565..51d447d29a 100644 --- a/modules/openxr/extensions/platform/openxr_opengl_extension.cpp +++ b/modules/openxr/extensions/platform/openxr_opengl_extension.cpp @@ -230,7 +230,7 @@ bool OpenXROpenGLExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in uint32_t swapchain_length; XrResult result = xrEnumerateSwapchainImages(p_swapchain, 0, &swapchain_length, nullptr); if (XR_FAILED(result)) { - print_line("OpenXR: Failed to get swapchaim image count [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); + print_line("OpenXR: Failed to get swapchain image count [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); return false; } @@ -254,7 +254,7 @@ bool OpenXROpenGLExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in result = xrEnumerateSwapchainImages(p_swapchain, swapchain_length, &swapchain_length, (XrSwapchainImageBaseHeader *)images.ptr()); if (XR_FAILED(result)) { - print_line("OpenXR: Failed to get swapchaim images [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); + print_line("OpenXR: Failed to get swapchain images [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); return false; } diff --git a/modules/openxr/extensions/platform/openxr_vulkan_extension.cpp b/modules/openxr/extensions/platform/openxr_vulkan_extension.cpp index b9f76481a1..fdfdbcd479 100644 --- a/modules/openxr/extensions/platform/openxr_vulkan_extension.cpp +++ b/modules/openxr/extensions/platform/openxr_vulkan_extension.cpp @@ -73,7 +73,7 @@ bool OpenXRVulkanExtension::check_graphics_api_support(XrVersion p_desired_versi XrResult result = xrGetVulkanGraphicsRequirements2KHR(OpenXRAPI::get_singleton()->get_instance(), OpenXRAPI::get_singleton()->get_system_id(), &vulkan_requirements); if (XR_FAILED(result)) { - print_line("OpenXR: Failed to get vulkan graphics requirements [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); + print_line("OpenXR: Failed to get Vulkan graphics requirements [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); return false; } @@ -127,7 +127,7 @@ bool OpenXRVulkanExtension::create_vulkan_instance(const VkInstanceCreateInfo *p VkResult vk_result = VK_SUCCESS; XrResult result = xrCreateVulkanInstanceKHR(OpenXRAPI::get_singleton()->get_instance(), &xr_vulkan_instance_info, &vulkan_instance, &vk_result); if (XR_FAILED(result)) { - print_line("OpenXR: Failed to create vulkan instance [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); + print_line("OpenXR: Failed to create Vulkan instance [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); return false; } @@ -161,7 +161,7 @@ bool OpenXRVulkanExtension::get_physical_device(VkPhysicalDevice *r_device) { XrResult result = xrGetVulkanGraphicsDevice2KHR(OpenXRAPI::get_singleton()->get_instance(), &get_info, &vulkan_physical_device); if (XR_FAILED(result)) { - print_line("OpenXR: Failed to obtain vulkan physical device [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); + print_line("OpenXR: Failed to obtain Vulkan physical device [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); return false; } @@ -187,12 +187,12 @@ bool OpenXRVulkanExtension::create_vulkan_device(const VkDeviceCreateInfo *p_dev VkResult vk_result = VK_SUCCESS; XrResult result = xrCreateVulkanDeviceKHR(OpenXRAPI::get_singleton()->get_instance(), &create_info, &vulkan_device, &vk_result); if (XR_FAILED(result)) { - print_line("OpenXR: Failed to create vulkan device [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); + print_line("OpenXR: Failed to create Vulkan device [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); return false; } if (vk_result != VK_SUCCESS) { - print_line("OpenXR: Failed to create vulkan device [vulkan error", vk_result, "]"); + print_line("OpenXR: Failed to create Vulkan device [Vulkan error", vk_result, "]"); } *r_device = vulkan_device; @@ -253,7 +253,7 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in uint32_t swapchain_length; XrResult result = xrEnumerateSwapchainImages(p_swapchain, 0, &swapchain_length, nullptr); if (XR_FAILED(result)) { - print_line("OpenXR: Failed to get swapchaim image count [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); + print_line("OpenXR: Failed to get swapchain image count [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); return false; } @@ -281,7 +281,7 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in result = xrEnumerateSwapchainImages(p_swapchain, swapchain_length, &swapchain_length, (XrSwapchainImageBaseHeader *)images.ptr()); if (XR_FAILED(result)) { - print_line("OpenXR: Failed to get swapchaim images [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); + print_line("OpenXR: Failed to get swapchain images [", OpenXRAPI::get_singleton()->get_error_string(result), "]"); return false; } diff --git a/modules/openxr/scene/openxr_composition_layer.cpp b/modules/openxr/scene/openxr_composition_layer.cpp index e210dc6400..1eb4ee5f8a 100644 --- a/modules/openxr/scene/openxr_composition_layer.cpp +++ b/modules/openxr/scene/openxr_composition_layer.cpp @@ -247,7 +247,7 @@ void OpenXRCompositionLayer::_clear_composition_layer_provider() { void OpenXRCompositionLayer::_on_openxr_session_begun() { openxr_session_running = true; - if (is_natively_supported() && is_visible() && is_inside_tree()) { + if (_should_register()) { _setup_composition_layer_provider(); } if (!fallback && _should_use_fallback_node()) { @@ -267,6 +267,10 @@ void OpenXRCompositionLayer::update_fallback_mesh() { should_update_fallback_mesh = true; } +bool OpenXRCompositionLayer::_should_register() { + return !registered && openxr_session_running && is_inside_tree() && is_visible() && is_natively_supported(); +} + XrPosef OpenXRCompositionLayer::get_openxr_pose() { Transform3D reference_frame = XRServer::get_singleton()->get_reference_frame(); Transform3D transform = reference_frame.inverse() * get_transform(); @@ -300,7 +304,7 @@ void OpenXRCompositionLayer::set_layer_viewport(SubViewport *p_viewport) { } layer_viewport = p_viewport; - if (!registered && is_natively_supported() && openxr_session_running && is_inside_tree() && is_visible()) { + if (_should_register()) { _setup_composition_layer_provider(); } @@ -330,8 +334,13 @@ void OpenXRCompositionLayer::set_use_android_surface(bool p_use_android_surface) use_android_surface = p_use_android_surface; if (use_android_surface) { + // It's possible that the layer provider is unregistered here (if previously invisible) set_layer_viewport(nullptr); openxr_layer_provider->set_use_android_surface(true, android_surface_size); + // ...and it may not be set up above because of viewport = null, android surface is false, so set it up again: + if (_should_register()) { + _setup_composition_layer_provider(); + } } else { openxr_layer_provider->set_use_android_surface(false, Size2i()); } diff --git a/modules/openxr/scene/openxr_composition_layer.h b/modules/openxr/scene/openxr_composition_layer.h index b1343b6af3..5975a50b1c 100644 --- a/modules/openxr/scene/openxr_composition_layer.h +++ b/modules/openxr/scene/openxr_composition_layer.h @@ -122,6 +122,8 @@ protected: virtual void _on_openxr_session_begun(); virtual void _on_openxr_session_stopping(); + bool _should_register(); + virtual Ref _create_fallback_mesh() = 0; void update_fallback_mesh(); diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 1a22126f13..60b52ae3d9 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -5718,10 +5718,25 @@ RID TextServerAdvanced::_find_sys_font_for_text(const RID &p_fdef, const String } } + bool fb_use_msdf = key.msdf; + if (fb_use_msdf) { + FontAdvanced *fd = _get_font_data(sysf.rid); + if (fd) { + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, 16); + FontForSizeAdvanced *ffsd = nullptr; + if (_ensure_cache_for_size(fd, size, ffsd)) { + if (ffsd && (FT_HAS_COLOR(ffsd->face) || !FT_IS_SCALABLE(ffsd->face))) { + fb_use_msdf = false; + } + } + } + } + _font_set_antialiasing(sysf.rid, key.antialiasing); _font_set_disable_embedded_bitmaps(sysf.rid, key.disable_embedded_bitmaps); _font_set_generate_mipmaps(sysf.rid, key.mipmaps); - _font_set_multichannel_signed_distance_field(sysf.rid, key.msdf); + _font_set_multichannel_signed_distance_field(sysf.rid, fb_use_msdf); _font_set_msdf_pixel_range(sysf.rid, key.msdf_range); _font_set_msdf_size(sysf.rid, key.msdf_source_size); _font_set_fixed_size(sysf.rid, key.fixed_size); diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 9435d88ceb..e5a3f8cf16 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -4469,10 +4469,25 @@ RID TextServerFallback::_find_sys_font_for_text(const RID &p_fdef, const String } } + bool fb_use_msdf = key.msdf; + if (fb_use_msdf) { + FontFallback *fd = _get_font_data(sysf.rid); + if (fd) { + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, 16); + FontForSizeFallback *ffsd = nullptr; + if (_ensure_cache_for_size(fd, size, ffsd)) { + if (ffsd && (FT_HAS_COLOR(ffsd->face) || !FT_IS_SCALABLE(ffsd->face))) { + fb_use_msdf = false; + } + } + } + } + _font_set_antialiasing(sysf.rid, key.antialiasing); _font_set_disable_embedded_bitmaps(sysf.rid, key.disable_embedded_bitmaps); _font_set_generate_mipmaps(sysf.rid, key.mipmaps); - _font_set_multichannel_signed_distance_field(sysf.rid, key.msdf); + _font_set_multichannel_signed_distance_field(sysf.rid, fb_use_msdf); _font_set_msdf_pixel_range(sysf.rid, key.msdf_range); _font_set_msdf_size(sysf.rid, key.msdf_source_size); _font_set_fixed_size(sysf.rid, key.fixed_size); diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index 4d83535e8b..a887800f8d 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -737,7 +737,7 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis #if defined(GLES3_ENABLED) bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3"); if (fallback_to_opengl3 && rendering_driver != "opengl3") { - WARN_PRINT("Your device seem not to support Vulkan, switching to OpenGL 3."); + WARN_PRINT("Your device does not seem to support Vulkan, switching to OpenGL 3."); rendering_driver = "opengl3"; OS::get_singleton()->set_current_rendering_method("gl_compatibility"); OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java index a52b75e5cd..72b2257962 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java @@ -227,7 +227,12 @@ public class GodotIO { } if (topView != null) { - int insetTypes = WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout(); + int insetTypes; + if (godot.isInImmersiveMode()) { + insetTypes = WindowInsetsCompat.Type.displayCutout(); + } else { + insetTypes = WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout(); + } if (topView.getRootWindowInsets() != null) { WindowInsetsCompat insetsCompat = WindowInsetsCompat.toWindowInsetsCompat(topView.getRootWindowInsets(), topView); diff --git a/platform/linuxbsd/freedesktop_at_spi_monitor.cpp b/platform/linuxbsd/freedesktop_at_spi_monitor.cpp index eeb68bae2d..98ef94088e 100644 --- a/platform/linuxbsd/freedesktop_at_spi_monitor.cpp +++ b/platform/linuxbsd/freedesktop_at_spi_monitor.cpp @@ -63,7 +63,8 @@ void FreeDesktopAtSPIMonitor::monitor_thread_func(void *p_userdata) { } static const char *iface = "org.a11y.Status"; - static const char *member = "IsEnabled"; + static const char *member_ac = "IsEnabled"; + static const char *member_sr = "ScreenReaderEnabled"; while (!mon->exit_thread.is_set()) { DBusMessage *message = dbus_message_new_method_call(BUS_OBJECT_NAME, BUS_OBJECT_PATH, BUS_INTERFACE_PROPERTIES, "Get"); @@ -71,12 +72,56 @@ void FreeDesktopAtSPIMonitor::monitor_thread_func(void *p_userdata) { dbus_message_append_args( message, DBUS_TYPE_STRING, &iface, - DBUS_TYPE_STRING, &member, + DBUS_TYPE_STRING, &member_ac, DBUS_TYPE_INVALID); DBusMessage *reply = dbus_connection_send_with_reply_and_block(bus, message, 50, &error); dbus_message_unref(message); + if (!dbus_error_is_set(&error)) { + DBusMessageIter iter, iter_variant, iter_struct; + dbus_bool_t result; + dbus_message_iter_init(reply, &iter); + dbus_message_iter_recurse(&iter, &iter_variant); + switch (dbus_message_iter_get_arg_type(&iter_variant)) { + case DBUS_TYPE_STRUCT: { + dbus_message_iter_recurse(&iter_variant, &iter_struct); + if (dbus_message_iter_get_arg_type(&iter_struct) == DBUS_TYPE_BOOLEAN) { + dbus_message_iter_get_basic(&iter_struct, &result); + if (result) { + mon->ac_enabled.set(); + } else { + mon->ac_enabled.clear(); + } + } + } break; + case DBUS_TYPE_BOOLEAN: { + dbus_message_iter_get_basic(&iter_variant, &result); + if (result) { + mon->ac_enabled.set(); + } else { + mon->ac_enabled.clear(); + } + } break; + default: + break; + } + dbus_message_unref(reply); + } else { + dbus_error_free(&error); + } + + message = dbus_message_new_method_call(BUS_OBJECT_NAME, BUS_OBJECT_PATH, BUS_INTERFACE_PROPERTIES, "Get"); + + dbus_message_append_args( + message, + DBUS_TYPE_STRING, &iface, + DBUS_TYPE_STRING, &member_sr, + DBUS_TYPE_INVALID); + + reply = dbus_connection_send_with_reply_and_block(bus, message, 50, &error); + dbus_message_unref(message); + if (!dbus_error_is_set(&error)) { DBusMessageIter iter, iter_variant, iter_struct; dbus_bool_t result; @@ -117,31 +162,6 @@ void FreeDesktopAtSPIMonitor::monitor_thread_func(void *p_userdata) { } FreeDesktopAtSPIMonitor::FreeDesktopAtSPIMonitor() { -#ifdef SOWRAP_ENABLED -#ifdef DEBUG_ENABLED - int dylibloader_verbose = 1; -#else - int dylibloader_verbose = 0; -#endif - if (initialize_dbus(dylibloader_verbose) != 0) { - print_verbose("AT-SPI2: Failed to load DBus library!"); - supported.clear(); - return; - } -#endif - bool ver_ok = false; - int version_major = 0; - int version_minor = 0; - int version_rev = 0; - dbus_get_version(&version_major, &version_minor, &version_rev); - ver_ok = (version_major == 1 && version_minor >= 10) || (version_major > 1); // 1.10.0 - print_verbose(vformat("AT-SPI2: DBus %d.%d.%d detected.", version_major, version_minor, version_rev)); - if (!ver_ok) { - print_verbose("AT-SPI2: Unsupported DBus library version!"); - supported.clear(); - return; - } - supported.set(); sr_enabled.clear(); exit_thread.clear(); diff --git a/platform/linuxbsd/freedesktop_at_spi_monitor.h b/platform/linuxbsd/freedesktop_at_spi_monitor.h index 1e3af26cc7..98c8ad3c16 100644 --- a/platform/linuxbsd/freedesktop_at_spi_monitor.h +++ b/platform/linuxbsd/freedesktop_at_spi_monitor.h @@ -42,6 +42,7 @@ private: Thread thread; SafeFlag exit_thread; + SafeFlag ac_enabled; SafeFlag sr_enabled; SafeFlag supported; @@ -52,7 +53,7 @@ public: ~FreeDesktopAtSPIMonitor(); bool is_supported() { return supported.is_set(); } - bool is_active() { return sr_enabled.is_set(); } + bool is_active() { return sr_enabled.is_set() && ac_enabled.is_set(); } }; #endif // DBUS_ENABLED diff --git a/platform/linuxbsd/freedesktop_portal_desktop.cpp b/platform/linuxbsd/freedesktop_portal_desktop.cpp index d0df62c636..3a9d3dbd39 100644 --- a/platform/linuxbsd/freedesktop_portal_desktop.cpp +++ b/platform/linuxbsd/freedesktop_portal_desktop.cpp @@ -967,33 +967,6 @@ void FreeDesktopPortalDesktop::_system_theme_changed_callback() { } FreeDesktopPortalDesktop::FreeDesktopPortalDesktop() { -#ifdef SOWRAP_ENABLED -#ifdef DEBUG_ENABLED - int dylibloader_verbose = 1; -#else - int dylibloader_verbose = 0; -#endif - unsupported = (initialize_dbus(dylibloader_verbose) != 0); -#else - unsupported = false; -#endif - - if (unsupported) { - return; - } - - bool ver_ok = false; - int version_major = 0; - int version_minor = 0; - int version_rev = 0; - dbus_get_version(&version_major, &version_minor, &version_rev); - ver_ok = (version_major == 1 && version_minor >= 10) || (version_major > 1); // 1.10.0 - print_verbose(vformat("PortalDesktop: DBus %d.%d.%d detected.", version_major, version_minor, version_rev)); - if (!ver_ok) { - print_verbose("PortalDesktop: Unsupported DBus library version!"); - unsupported = true; - } - DBusError err; dbus_error_init(&err); monitor_connection = dbus_bus_get(DBUS_BUS_SESSION, &err); diff --git a/platform/linuxbsd/freedesktop_screensaver.cpp b/platform/linuxbsd/freedesktop_screensaver.cpp index 7bb6b77ee8..28c3e6f32d 100644 --- a/platform/linuxbsd/freedesktop_screensaver.cpp +++ b/platform/linuxbsd/freedesktop_screensaver.cpp @@ -133,32 +133,6 @@ void FreeDesktopScreenSaver::uninhibit() { } FreeDesktopScreenSaver::FreeDesktopScreenSaver() { -#ifdef SOWRAP_ENABLED -#ifdef DEBUG_ENABLED - int dylibloader_verbose = 1; -#else - int dylibloader_verbose = 0; -#endif - unsupported = (initialize_dbus(dylibloader_verbose) != 0); -#else - unsupported = false; -#endif - - if (unsupported) { - return; - } - - bool ver_ok = false; - int version_major = 0; - int version_minor = 0; - int version_rev = 0; - dbus_get_version(&version_major, &version_minor, &version_rev); - ver_ok = (version_major == 1 && version_minor >= 10) || (version_major > 1); // 1.10.0 - print_verbose(vformat("ScreenSaver: DBus %d.%d.%d detected.", version_major, version_minor, version_rev)); - if (!ver_ok) { - print_verbose("ScreenSaver:: Unsupported DBus library version!"); - unsupported = true; - } } #endif // DBUS_ENABLED diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index 0d8911854b..8f9a554edc 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -58,6 +58,14 @@ #include "drivers/accesskit/accessibility_driver_accesskit.h" #endif +#ifdef DBUS_ENABLED +#ifdef SOWRAP_ENABLED +#include "dbus-so_wrap.h" +#else +#include +#endif +#endif + #define WAYLAND_MAX_FRAME_TIME_US (1'000'000) String DisplayServerWayland::_get_app_id_from_context(Context p_context) { @@ -313,14 +321,19 @@ bool DisplayServerWayland::is_dark_mode() const { } Color DisplayServerWayland::get_accent_color() const { + if (!portal_desktop) { + return Color(); + } return portal_desktop->get_appearance_accent_color(); } void DisplayServerWayland::set_system_theme_change_callback(const Callable &p_callable) { + ERR_FAIL_COND(!portal_desktop); portal_desktop->set_system_theme_change_callback(p_callable); } Error DisplayServerWayland::file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector &p_filters, const Callable &p_callback, WindowID p_window_id) { + ERR_FAIL_COND_V(!portal_desktop, ERR_UNAVAILABLE); MutexLock mutex_lock(wayland_thread.mutex); WindowID window_id = p_window_id; @@ -335,6 +348,7 @@ Error DisplayServerWayland::file_dialog_show(const String &p_title, const String } Error DisplayServerWayland::file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector &p_filters, const TypedArray &p_options, const Callable &p_callback, WindowID p_window_id) { + ERR_FAIL_COND_V(!portal_desktop, ERR_UNAVAILABLE); MutexLock mutex_lock(wayland_thread.mutex); WindowID window_id = p_window_id; @@ -1323,6 +1337,9 @@ void DisplayServerWayland::window_set_ime_position(const Point2i &p_pos, Display int DisplayServerWayland::accessibility_should_increase_contrast() const { #ifdef DBUS_ENABLED + if (!portal_desktop) { + return -1; + } return portal_desktop->get_high_contrast(); #endif return -1; @@ -1330,7 +1347,7 @@ int DisplayServerWayland::accessibility_should_increase_contrast() const { int DisplayServerWayland::accessibility_screen_reader_active() const { #ifdef DBUS_ENABLED - if (atspi_monitor->is_supported()) { + if (atspi_monitor && atspi_monitor->is_supported()) { return atspi_monitor->is_active(); } #endif @@ -1546,6 +1563,10 @@ Key DisplayServerWayland::keyboard_get_keycode_from_physical(Key p_keycode) cons bool DisplayServerWayland::color_picker(const Callable &p_callback) { #ifdef DBUS_ENABLED + if (!portal_desktop) { + return false; + } + MutexLock mutex_lock(wayland_thread.mutex); WindowID window_id = MAIN_WINDOW_ID; // TODO: Use window IDs for multiwindow support. WaylandThread::WindowState *ws = wayland_thread.wl_surface_get_window_state(wayland_thread.window_get_wl_surface(window_id)); @@ -2114,9 +2135,31 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win #endif // RD_ENABLED #ifdef DBUS_ENABLED - portal_desktop = memnew(FreeDesktopPortalDesktop); - atspi_monitor = memnew(FreeDesktopAtSPIMonitor); - screensaver = memnew(FreeDesktopScreenSaver); + bool dbus_ok = true; +#ifdef SOWRAP_ENABLED + if (initialize_dbus(dylibloader_verbose) != 0) { + print_verbose("Failed to load DBus library!"); + dbus_ok = false; + } +#endif + if (dbus_ok) { + bool ver_ok = false; + int version_major = 0; + int version_minor = 0; + int version_rev = 0; + dbus_get_version(&version_major, &version_minor, &version_rev); + ver_ok = (version_major == 1 && version_minor >= 10) || (version_major > 1); // 1.10.0 + print_verbose(vformat("DBus %d.%d.%d detected.", version_major, version_minor, version_rev)); + if (!ver_ok) { + print_verbose("Unsupported DBus library version!"); + dbus_ok = false; + } + } + if (dbus_ok) { + screensaver = memnew(FreeDesktopScreenSaver); + portal_desktop = memnew(FreeDesktopPortalDesktop); + atspi_monitor = memnew(FreeDesktopAtSPIMonitor); + } #endif // DBUS_ENABLED screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on")); @@ -2180,9 +2223,13 @@ DisplayServerWayland::~DisplayServerWayland() { #ifdef DBUS_ENABLED if (portal_desktop) { memdelete(portal_desktop); - memdelete(atspi_monitor); + } + if (screensaver) { memdelete(screensaver); } + if (atspi_monitor) { + memdelete(atspi_monitor); + } #endif } diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index 15d17bfe4e..82ea56614b 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -59,6 +59,14 @@ #include "drivers/accesskit/accessibility_driver_accesskit.h" #endif +#ifdef DBUS_ENABLED +#ifdef SOWRAP_ENABLED +#include "dbus-so_wrap.h" +#else +#include +#endif +#endif + #include #include #include @@ -440,14 +448,19 @@ bool DisplayServerX11::is_dark_mode() const { } Color DisplayServerX11::get_accent_color() const { + if (!portal_desktop) { + return Color(); + } return portal_desktop->get_appearance_accent_color(); } void DisplayServerX11::set_system_theme_change_callback(const Callable &p_callable) { + ERR_FAIL_COND(!portal_desktop); portal_desktop->set_system_theme_change_callback(p_callable); } Error DisplayServerX11::file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector &p_filters, const Callable &p_callback, WindowID p_window_id) { + ERR_FAIL_COND_V(!portal_desktop, ERR_UNAVAILABLE); WindowID window_id = p_window_id; if (!windows.has(window_id) || windows[window_id].is_popup) { @@ -459,6 +472,7 @@ Error DisplayServerX11::file_dialog_show(const String &p_title, const String &p_ } Error DisplayServerX11::file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector &p_filters, const TypedArray &p_options, const Callable &p_callback, WindowID p_window_id) { + ERR_FAIL_COND_V(!portal_desktop, ERR_UNAVAILABLE); WindowID window_id = p_window_id; if (!windows.has(window_id) || windows[window_id].is_popup) { @@ -1847,13 +1861,15 @@ void DisplayServerX11::screen_set_keep_on(bool p_enable) { return; } - if (p_enable) { - screensaver->inhibit(); - } else { - screensaver->uninhibit(); - } + if (screensaver) { + if (p_enable) { + screensaver->inhibit(); + } else { + screensaver->uninhibit(); + } - keep_screen_on = p_enable; + keep_screen_on = p_enable; + } } bool DisplayServerX11::screen_is_kept_on() const { @@ -3422,6 +3438,9 @@ void DisplayServerX11::window_set_ime_position(const Point2i &p_pos, WindowID p_ int DisplayServerX11::accessibility_should_increase_contrast() const { #ifdef DBUS_ENABLED + if (!portal_desktop) { + return -1; + } return portal_desktop->get_high_contrast(); #endif return -1; @@ -3429,7 +3448,7 @@ int DisplayServerX11::accessibility_should_increase_contrast() const { int DisplayServerX11::accessibility_screen_reader_active() const { #ifdef DBUS_ENABLED - if (atspi_monitor->is_supported()) { + if (atspi_monitor && atspi_monitor->is_supported()) { return atspi_monitor->is_active(); } #endif @@ -3694,6 +3713,9 @@ Key DisplayServerX11::keyboard_get_label_from_physical(Key p_keycode) const { bool DisplayServerX11::color_picker(const Callable &p_callback) { #ifdef DBUS_ENABLED + if (!portal_desktop) { + return false; + } WindowID window_id = last_focused_window; if (!windows.has(window_id)) { @@ -7349,12 +7371,35 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode _update_real_mouse_position(windows[MAIN_WINDOW_ID]); #ifdef DBUS_ENABLED - screensaver = memnew(FreeDesktopScreenSaver); + bool dbus_ok = true; +#ifdef SOWRAP_ENABLED + if (initialize_dbus(dylibloader_verbose) != 0) { + print_verbose("Failed to load DBus library!"); + dbus_ok = false; + } +#endif + if (dbus_ok) { + bool ver_ok = false; + int version_major = 0; + int version_minor = 0; + int version_rev = 0; + dbus_get_version(&version_major, &version_minor, &version_rev); + ver_ok = (version_major == 1 && version_minor >= 10) || (version_major > 1); // 1.10.0 + print_verbose(vformat("DBus %d.%d.%d detected.", version_major, version_minor, version_rev)); + if (!ver_ok) { + print_verbose("Unsupported DBus library version!"); + dbus_ok = false; + } + } + if (dbus_ok) { + screensaver = memnew(FreeDesktopScreenSaver); + portal_desktop = memnew(FreeDesktopPortalDesktop); + atspi_monitor = memnew(FreeDesktopAtSPIMonitor); + } +#endif // DBUS_ENABLED + screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on")); - portal_desktop = memnew(FreeDesktopPortalDesktop); - atspi_monitor = memnew(FreeDesktopAtSPIMonitor); -#endif // DBUS_ENABLED XSetErrorHandler(&default_window_error_handler); r_error = OK; @@ -7486,9 +7531,15 @@ DisplayServerX11::~DisplayServerX11() { #endif #ifdef DBUS_ENABLED - memdelete(screensaver); - memdelete(portal_desktop); - memdelete(atspi_monitor); + if (screensaver) { + memdelete(screensaver); + } + if (portal_desktop) { + memdelete(portal_desktop); + } + if (atspi_monitor) { + memdelete(atspi_monitor); + } #endif } diff --git a/platform/macos/display_server_embedded.mm b/platform/macos/display_server_embedded.mm index d4544597d5..5e1b94894c 100644 --- a/platform/macos/display_server_embedded.mm +++ b/platform/macos/display_server_embedded.mm @@ -99,7 +99,7 @@ DisplayServerEmbedded::DisplayServerEmbedded(const String &p_rendering_driver, W #if defined(GLES3_ENABLED) bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3"); if (fallback_to_opengl3 && rendering_driver != "opengl3") { - WARN_PRINT("Your device seem not to support MoltenVK or Metal, switching to OpenGL 3."); + WARN_PRINT("Your device does not seem to support MoltenVK or Metal, switching to OpenGL 3."); rendering_driver = "opengl3"; OS::get_singleton()->set_current_rendering_method("gl_compatibility"); OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); @@ -324,6 +324,7 @@ bool DisplayServerEmbedded::mouse_is_mode_override_enabled() const { void DisplayServerEmbedded::warp_mouse(const Point2i &p_position) { _THREAD_SAFE_METHOD_ + Input::get_singleton()->set_mouse_position(p_position); EngineDebugger::get_singleton()->send_message("game_view:warp_mouse", { p_position }); } @@ -480,7 +481,7 @@ bool DisplayServerEmbedded::has_feature(Feature p_feature) const { case FEATURE_CUSTOM_CURSOR_SHAPE: // case FEATURE_HIDPI: // case FEATURE_ICON: - case FEATURE_MOUSE: + // case FEATURE_MOUSE: case FEATURE_MOUSE_WARP: // case FEATURE_NATIVE_DIALOG: // case FEATURE_NATIVE_ICON: diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index edde1d7272..1fb0c594d7 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -3880,7 +3880,7 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM #if defined(GLES3_ENABLED) bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3"); if (fallback_to_opengl3 && rendering_driver != "opengl3") { - WARN_PRINT("Your device seem not to support MoltenVK or Metal, switching to OpenGL 3."); + WARN_PRINT("Your device does not seem to support MoltenVK or Metal, switching to OpenGL 3."); rendering_driver = "opengl3"; OS::get_singleton()->set_current_rendering_method("gl_compatibility"); OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); diff --git a/platform/macos/editor/embedded_process_macos.h b/platform/macos/editor/embedded_process_macos.h index 77ed21d217..50b4e37cfb 100644 --- a/platform/macos/editor/embedded_process_macos.h +++ b/platform/macos/editor/embedded_process_macos.h @@ -42,6 +42,7 @@ class LayerHost final : public Control { ScriptEditorDebugger *script_debugger = nullptr; EmbeddedProcessMacOS *process = nullptr; + bool window_focused = true; struct CustomCursor { Ref image; diff --git a/platform/macos/editor/embedded_process_macos.mm b/platform/macos/editor/embedded_process_macos.mm index ea01c08875..ee1354bfc4 100644 --- a/platform/macos/editor/embedded_process_macos.mm +++ b/platform/macos/editor/embedded_process_macos.mm @@ -254,6 +254,10 @@ void LayerHost::_notification(int p_what) { // Restore embedded process mouse mode. ds->mouse_set_mode(process->get_mouse_mode()); } + if (!window_focused && script_debugger) { + script_debugger->send_message("embed:win_event", { DisplayServer::WINDOW_EVENT_FOCUS_IN }); + window_focused = true; + } } break; case NOTIFICATION_MOUSE_EXIT: { DisplayServer *ds = DisplayServer::get_singleton(); @@ -270,6 +274,10 @@ void LayerHost::_notification(int p_what) { if (ds->mouse_get_mode() != DisplayServer::MOUSE_MODE_VISIBLE) { ds->mouse_set_mode(DisplayServer::MOUSE_MODE_VISIBLE); } + if (window_focused && script_debugger) { + script_debugger->send_message("embed:win_event", { DisplayServer::WINDOW_EVENT_FOCUS_OUT }); + window_focused = false; + } } break; case MainLoop::NOTIFICATION_OS_IME_UPDATE: { if (script_debugger && has_focus()) { @@ -287,6 +295,28 @@ void LayerHost::_notification(int p_what) { } } } break; + case NOTIFICATION_WM_WINDOW_FOCUS_IN: { + if (!window_focused && script_debugger) { + script_debugger->send_message("embed:win_event", { DisplayServer::WINDOW_EVENT_FOCUS_IN }); + window_focused = true; + } + } break; + case NOTIFICATION_WM_WINDOW_FOCUS_OUT: { + if (window_focused && script_debugger) { + script_debugger->send_message("embed:win_event", { DisplayServer::WINDOW_EVENT_FOCUS_OUT }); + window_focused = false; + } + } break; + case NOTIFICATION_APPLICATION_FOCUS_IN: { + if (script_debugger) { + script_debugger->send_message("embed:notification", { NOTIFICATION_APPLICATION_FOCUS_IN }); + } + } break; + case NOTIFICATION_APPLICATION_FOCUS_OUT: { + if (script_debugger) { + script_debugger->send_message("embed:notification", { NOTIFICATION_APPLICATION_FOCUS_OUT }); + } + } break; } } diff --git a/platform/macos/embedded_debugger.h b/platform/macos/embedded_debugger.h index 2c502628c8..f0e785f618 100644 --- a/platform/macos/embedded_debugger.h +++ b/platform/macos/embedded_debugger.h @@ -62,6 +62,7 @@ private: Error _msg_mouse_set_mode(const Array &p_args); Error _msg_event(const Array &p_args); Error _msg_win_event(const Array &p_args); + Error _msg_notification(const Array &p_args); Error _msg_ime_update(const Array &p_args); Error _msg_joy_add(const Array &p_args); Error _msg_joy_del(const Array &p_args); diff --git a/platform/macos/embedded_debugger.mm b/platform/macos/embedded_debugger.mm index b472bf983c..135c7d31fb 100644 --- a/platform/macos/embedded_debugger.mm +++ b/platform/macos/embedded_debugger.mm @@ -75,6 +75,7 @@ void EmbeddedDebugger::_init_parse_message_handlers() { parse_message_handlers["mouse_set_mode"] = &EmbeddedDebugger::_msg_mouse_set_mode; parse_message_handlers["event"] = &EmbeddedDebugger::_msg_event; parse_message_handlers["win_event"] = &EmbeddedDebugger::_msg_win_event; + parse_message_handlers["notification"] = &EmbeddedDebugger::_msg_notification; parse_message_handlers["ime_update"] = &EmbeddedDebugger::_msg_ime_update; parse_message_handlers["joy_add"] = &EmbeddedDebugger::_msg_joy_add; parse_message_handlers["joy_del"] = &EmbeddedDebugger::_msg_joy_del; @@ -153,6 +154,15 @@ Error EmbeddedDebugger::_msg_ime_update(const Array &p_args) { return OK; } +Error EmbeddedDebugger::_msg_notification(const Array &p_args) { + ERR_FAIL_COND_V_MSG(p_args.size() != 1, ERR_INVALID_PARAMETER, "Invalid number of arguments for 'notification' message."); + int notification = p_args[0]; + if (OS::get_singleton()->get_main_loop()) { + OS::get_singleton()->get_main_loop()->notification(notification); + } + return OK; +} + Error EmbeddedDebugger::_msg_joy_add(const Array &p_args) { ERR_FAIL_COND_V_MSG(p_args.size() != 2, ERR_INVALID_PARAMETER, "Invalid number of arguments for 'joy_add' message."); int idx = p_args[0]; diff --git a/platform/web/api/api.cpp b/platform/web/api/api.cpp index 5a0334be22..04601f9d0c 100644 --- a/platform/web/api/api.cpp +++ b/platform/web/api/api.cpp @@ -56,7 +56,7 @@ JavaScriptBridge *JavaScriptBridge::get_singleton() { } JavaScriptBridge::JavaScriptBridge() { - ERR_FAIL_COND_MSG(singleton != nullptr, "JavaScriptBridge singleton already exist."); + ERR_FAIL_COND_MSG(singleton != nullptr, "JavaScriptBridge singleton already exists."); singleton = this; } diff --git a/platform/web/js/libs/audio.position.worklet.js b/platform/web/js/libs/audio.position.worklet.js index 0fa0ee1552..4e70de1bc9 100644 --- a/platform/web/js/libs/audio.position.worklet.js +++ b/platform/web/js/libs/audio.position.worklet.js @@ -31,22 +31,28 @@ /**************************************************************************/ class GodotPositionReportingProcessor extends AudioWorkletProcessor { + static get parameterDescriptors() { + return [ + { + name: 'reset', + defaultValue: 0, + minValue: 0, + maxValue: 1, + automationRate: 'k-rate', + }, + ]; + } + constructor(...args) { super(...args); this.position = 0; - - this.port.onmessage = (event) => { - switch (event?.data?.type) { - case 'reset': - this.position = 0; - break; - default: - // Do nothing. - } - }; } - process(inputs, _outputs, _parameters) { + process(inputs, _outputs, parameters) { + if (parameters['reset'][0] > 0) { + this.position = 0; + } + if (inputs.length > 0) { const input = inputs[0]; if (input.length > 0) { diff --git a/platform/web/js/libs/library_godot_audio.js b/platform/web/js/libs/library_godot_audio.js index 46d77611c7..99937e4c5a 100644 --- a/platform/web/js/libs/library_godot_audio.js +++ b/platform/web/js/libs/library_godot_audio.js @@ -645,6 +645,7 @@ class SampleNode { 'godot-position-reporting-processor' ); } + this._playbackPosition = this.offset; this._positionWorklet.port.onmessage = (event) => { switch (event.data['type']) { case 'position': @@ -654,7 +655,11 @@ class SampleNode { // Do nothing. } }; - this._positionWorklet.port.postMessage('reset'); + + const resetParameter = this._positionWorklet.parameters.get('reset'); + resetParameter.setValueAtTime(1, GodotAudio.ctx.currentTime); + resetParameter.setValueAtTime(0, GodotAudio.ctx.currentTime + 1); + return this._positionWorklet; } diff --git a/platform/web/js/libs/library_godot_input.js b/platform/web/js/libs/library_godot_input.js index 94a57130a2..e9a06d3b93 100644 --- a/platform/web/js/libs/library_godot_input.js +++ b/platform/web/js/libs/library_godot_input.js @@ -506,10 +506,6 @@ const GodotInput = { const func = GodotRuntime.get_func(callback); const canvas = GodotConfig.canvas; function move_cb(evt) { - if (evt.pointerType == 'touch') { - return; - } - const rect = canvas.getBoundingClientRect(); const pos = GodotInput.computePosition(evt, rect); // Scale movement @@ -541,10 +537,6 @@ const GodotInput = { const func = GodotRuntime.get_func(callback); const canvas = GodotConfig.canvas; function button_cb(p_pressed, evt) { - if (evt.pointerType == 'touch') { - return; - } - const rect = canvas.getBoundingClientRect(); const pos = GodotInput.computePosition(evt, rect); const modifiers = GodotInput.getModifiers(evt); @@ -557,8 +549,8 @@ const GodotInput = { evt.preventDefault(); } } - GodotEventListeners.add(canvas, 'pointerdown', button_cb.bind(null, 1), false); - GodotEventListeners.add(window, 'pointerup', button_cb.bind(null, 0), false); + GodotEventListeners.add(canvas, 'mousedown', button_cb.bind(null, 1), false); + GodotEventListeners.add(window, 'mouseup', button_cb.bind(null, 0), false); }, /* diff --git a/platform/windows/SCsub b/platform/windows/SCsub index 3582a99647..ee7f43e955 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -74,11 +74,7 @@ env.add_source_files(sources, common_win) sources += res_obj if env["accesskit"] and not env.msvc: - env["BUILDERS"]["DEF"].emitter = redirect_emitter - def_file = "uiautomationcore." + env["arch"] + ".def" - def_target = "libuiautomationcore." + env["arch"] + ".a" - def_obj = env.DEF(def_target, def_file) - sources += def_obj + sources += env.DEFLIB("uiautomationcore") prog = env.add_program("#bin/redot", sources, PROGSUFFIX=env["PROGSUFFIX"]) arrange_program_clean(prog) diff --git a/platform/windows/detect.py b/platform/windows/detect.py index e1fb38ebc6..0f7f48633f 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -237,46 +237,6 @@ def get_flags(): } -def build_def_file(target, source, env: "SConsEnvironment"): - arch_aliases = { - "x86_32": "i386", - "x86_64": "i386:x86-64", - "arm32": "arm", - "arm64": "arm64", - } - - cmdbase = "dlltool -m " + arch_aliases[env["arch"]] - if env["arch"] == "x86_32": - cmdbase += " -k" - else: - cmdbase += " --no-leading-underscore" - - mingw_bin_prefix = get_mingw_bin_prefix(env["mingw_prefix"], env["arch"]) - - for x in range(len(source)): - ok = True - # Try prefixed executable (MinGW on Linux). - cmd = mingw_bin_prefix + cmdbase + " -d " + str(source[x]) + " -l " + str(target[x]) - try: - out = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE).communicate() - if len(out[1]): - ok = False - except Exception: - ok = False - - # Try generic executable (MSYS2). - if not ok: - cmd = cmdbase + " -d " + str(source[x]) + " -l " + str(target[x]) - try: - out = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE).communicate() - if len(out[1]): - return -1 - except Exception: - return -1 - - return 0 - - def configure_msvc(env: "SConsEnvironment"): """Configure env to work with MSVC""" @@ -919,7 +879,35 @@ def configure_mingw(env: "SConsEnvironment"): env.Append(CPPDEFINES=["MINGW_ENABLED", ("MINGW_HAS_SECURE_API", 1)]) # dlltool - env.Append(BUILDERS={"DEF": env.Builder(action=build_def_file, suffix=".a", src_suffix=".def")}) + env["DEF"] = get_detected(env, "dlltool") + env["DEFCOM"] = "$DEF $DEFFLAGS -d $SOURCE -l $TARGET" + env["DEFCOMSTR"] = "$CXXCOMSTR" + env["DEFPREFIX"] = "$LIBPREFIX" + env["DEFSUFFIX"] = ".${__env__['arch']}$LIBSUFFIX" + env["DEFSRCSUFFIX"] = ".${__env__['arch']}.def" + DEF_ALIASES = { + "x86_32": "i386", + "x86_64": "i386:x86-64", + "arm32": "arm", + "arm64": "arm64", + } + env.Append(DEFFLAGS=["-m", DEF_ALIASES[env["arch"]]]) + if env["arch"] == "x86_32": + env.Append(DEFFLAGS=["-k"]) + else: + env.Append(DEFFLAGS=["--no-leading-underscore"]) + + env.Append( + BUILDERS={ + "DEFLIB": env.Builder( + action=env.Run("$DEFCOM", "$DEFCOMSTR"), + prefix="$DEFPREFIX", + suffix="$DEFSUFFIX", + src_suffix="$DEFSRCSUFFIX", + emitter=methods.redirect_emitter, + ) + } + ) def configure(env: "SConsEnvironment"): diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 517ea5de10..75d337737e 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -151,8 +151,9 @@ bool DisplayServerWindows::has_feature(Feature p_feature) const { case FEATURE_STATUS_INDICATOR: case FEATURE_WINDOW_EMBEDDING: case FEATURE_WINDOW_DRAG: - case FEATURE_SCREEN_EXCLUDE_FROM_CAPTURE: return true; + case FEATURE_SCREEN_EXCLUDE_FROM_CAPTURE: + return (os_ver.dwBuildNumber >= 19041); // Fully supported on Windows 10 Vibranium R1 (2004)+ only, captured as black rect on older versions. case FEATURE_EMOJI_AND_SYMBOL_PICKER: return (os_ver.dwBuildNumber >= 17134); // Windows 10 Redstone 4 (1803)+ only. #ifdef ACCESSKIT_ENABLED @@ -2470,6 +2471,21 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window) } } + if ((wd.maximized || wd.was_maximized_pre_fs) && wd.borderless && p_mode != WINDOW_MODE_MINIMIZED && p_mode != WINDOW_MODE_FULLSCREEN && p_mode != WINDOW_MODE_EXCLUSIVE_FULLSCREEN) { + RECT rect; + if (wd.pre_fs_valid) { + rect = wd.pre_fs_rect; + } else { + rect.left = 0; + rect.right = wd.width; + rect.top = 0; + rect.bottom = wd.height; + } + + ShowWindow(wd.hWnd, SW_RESTORE); + MoveWindow(wd.hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE); + } + if (p_mode == WINDOW_MODE_WINDOWED) { ShowWindow(wd.hWnd, SW_NORMAL); wd.maximized = false; @@ -2483,6 +2499,11 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window) } if (p_mode == WINDOW_MODE_MAXIMIZED && wd.borderless) { + if (!was_fullscreen && !(wd.maximized && wd.borderless)) { + // Save non-fullscreen rect before entering fullscreen. + GetWindowRect(wd.hWnd, &wd.pre_fs_rect); + wd.pre_fs_valid = true; + } ShowWindow(wd.hWnd, SW_NORMAL); wd.maximized = true; wd.minimized = false; @@ -2516,7 +2537,7 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window) // Save previous maximized stare. wd.was_maximized_pre_fs = wd.maximized; - if (!was_fullscreen) { + if (!was_fullscreen && !(wd.maximized && wd.borderless)) { // Save non-fullscreen rect before entering fullscreen. GetWindowRect(wd.hWnd, &wd.pre_fs_rect); wd.pre_fs_valid = true; @@ -7189,10 +7210,8 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win } #ifdef SDL_ENABLED - joypad_sdl = memnew(JoypadSDL()); - if (joypad_sdl->initialize() == OK) { - joypad_sdl->setup_sdl_helper_window(windows[MAIN_WINDOW_ID].hWnd); - } else { + joypad_sdl = memnew(JoypadSDL(windows[MAIN_WINDOW_ID].hWnd)); + if (joypad_sdl->initialize() != OK) { ERR_PRINT("Couldn't initialize SDL joypad input driver."); memdelete(joypad_sdl); joypad_sdl = nullptr; diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 5e2e2e9770..028780e6b9 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -641,7 +641,7 @@ String OS_Windows::get_version_alias() const { } else { windows_string += "Unknown"; } - // Windows versions older than 7 cannot run Godot. + // Windows versions older than 10 cannot run Godot. return vformat("%s (build %d)", windows_string, (int64_t)fow.dwBuildNumber); } diff --git a/scene/2d/tile_map_layer.cpp b/scene/2d/tile_map_layer.cpp index 5e0ede6abc..762a8d86f8 100644 --- a/scene/2d/tile_map_layer.cpp +++ b/scene/2d/tile_map_layer.cpp @@ -74,6 +74,9 @@ void TileMapLayer::_debug_update(bool p_force_cleanup) { if (debug_quadrant->canvas_item.is_valid()) { rs->free(debug_quadrant->canvas_item); } + if (debug_quadrant->physics_mesh.is_valid()) { + rs->free(debug_quadrant->physics_mesh); + } } debug_quadrant_map.clear(); _debug_was_cleaned_up = true; @@ -840,6 +843,7 @@ void TileMapLayer::_physics_update(bool p_force_cleanup) { physics_body_key.angular_velocity = angular_velocity; physics_body_key.one_way_collision = tile_data->is_collision_polygon_one_way(tile_set_physics_layer, polygon_index); physics_body_key.one_way_collision_margin = tile_data->get_collision_polygon_one_way_margin(tile_set_physics_layer, polygon_index); + physics_body_key.y_origin = map_to_local(cell_data.coords).y; if (!physics_quadrant->bodies.has(physics_body_key)) { RID body = ps->body_create(); diff --git a/scene/2d/tile_map_layer.h b/scene/2d/tile_map_layer.h index a58482a2de..83d5820402 100644 --- a/scene/2d/tile_map_layer.h +++ b/scene/2d/tile_map_layer.h @@ -245,14 +245,20 @@ public: int physics_layer = 0; Vector2 linear_velocity; real_t angular_velocity = 0.0; + bool one_way_collision = false; real_t one_way_collision_margin = 0.0; + int64_t y_origin = 0; // This is only used if one_way_collision is on, to avoid merging polygons vertically in that case. + bool operator<(const PhysicsBodyKey &p_other) const { if (physics_layer == p_other.physics_layer) { if (linear_velocity == p_other.linear_velocity) { if (angular_velocity == p_other.angular_velocity) { if (one_way_collision == p_other.one_way_collision) { + if (one_way_collision && y_origin != p_other.y_origin) { + return y_origin < p_other.y_origin; + } return one_way_collision_margin < p_other.one_way_collision_margin; } return one_way_collision < p_other.one_way_collision; @@ -272,7 +278,8 @@ public: linear_velocity == p_other.linear_velocity && angular_velocity == p_other.angular_velocity && one_way_collision == p_other.one_way_collision && - one_way_collision_margin == p_other.one_way_collision_margin; + one_way_collision_margin == p_other.one_way_collision_margin && + (!one_way_collision || y_origin == p_other.y_origin); } }; @@ -282,6 +289,9 @@ public: h = hash_murmur3_one_real(p_hash.linear_velocity.x); h = hash_murmur3_one_real(p_hash.linear_velocity.y, h); h = hash_murmur3_one_real(p_hash.angular_velocity, h); + if (p_hash.one_way_collision) { + h = hash_murmur3_one_32(p_hash.y_origin, h); + } return h; } }; diff --git a/scene/3d/modifier_bone_target_3d.cpp b/scene/3d/modifier_bone_target_3d.cpp index f56067b279..5ea866ad80 100644 --- a/scene/3d/modifier_bone_target_3d.cpp +++ b/scene/3d/modifier_bone_target_3d.cpp @@ -74,6 +74,19 @@ void ModifierBoneTarget3D::_validate_property(PropertyInfo &p_property) const { if (p_property.name == "influence") { p_property.usage = PROPERTY_USAGE_READ_ONLY; } + if (!Engine::get_singleton()->is_editor_hint()) { + return; + } + if (p_property.name == "bone_name") { + Skeleton3D *skeleton = get_skeleton(); + if (skeleton) { + p_property.hint = PROPERTY_HINT_ENUM; + p_property.hint_string = skeleton->get_concatenated_bone_names(); + } else { + p_property.hint = PROPERTY_HINT_NONE; + p_property.hint_string = ""; + } + } } void ModifierBoneTarget3D::_bind_methods() { diff --git a/scene/3d/physics/soft_body_3d.cpp b/scene/3d/physics/soft_body_3d.cpp index 1777ff02e6..60b077e1b7 100644 --- a/scene/3d/physics/soft_body_3d.cpp +++ b/scene/3d/physics/soft_body_3d.cpp @@ -706,10 +706,6 @@ void SoftBody3D::apply_central_force(const Vector3 &p_force) { PhysicsServer3D::get_singleton()->soft_body_apply_central_force(physics_rid, p_force); } -void SoftBody3D::pin_point_toggle(int p_point_index) { - pin_point(p_point_index, !(-1 != _has_pinned_point(p_point_index))); -} - void SoftBody3D::pin_point(int p_point_index, bool pin, const NodePath &p_spatial_attachment_path, int p_insert_at) { ERR_FAIL_COND_MSG(p_insert_at < -1 || p_insert_at >= pinned_points.size(), "Invalid index for pin point insertion position."); _pin_point_on_physics_server(p_point_index, pin); diff --git a/scene/3d/physics/soft_body_3d.h b/scene/3d/physics/soft_body_3d.h index 31e5dee657..99cc66c9d9 100644 --- a/scene/3d/physics/soft_body_3d.h +++ b/scene/3d/physics/soft_body_3d.h @@ -184,7 +184,6 @@ public: Vector3 get_point_transform(int p_point_index); - void pin_point_toggle(int p_point_index); void pin_point(int p_point_index, bool pin, const NodePath &p_spatial_attachment_path = NodePath(), int p_insert_at = -1); bool is_point_pinned(int p_point_index) const; diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 8e3028ad7e..1e2411b7bd 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -297,7 +297,7 @@ void Skeleton3D::_notification(int p_what) { #if !defined(DISABLE_DEPRECATED) && !defined(PHYSICS_3D_DISABLED) setup_simulator(); #endif // _DISABLE_DEPRECATED && PHYSICS_3D_DISABLED - update_flags = UPDATE_FLAG_POSE; + update_flags |= UPDATE_FLAG_POSE; _notification(NOTIFICATION_UPDATE_SKELETON); } break; #ifdef TOOLS_ENABLED @@ -931,7 +931,7 @@ void Skeleton3D::_make_dirty() { return; } dirty = true; - _update_deferred(); + _update_deferred(modifiers.is_empty() ? UPDATE_FLAG_POSE : (UpdateFlag)(UPDATE_FLAG_POSE | UPDATE_FLAG_MODIFIER)); } void Skeleton3D::_update_deferred(UpdateFlag p_update_flag) { diff --git a/scene/gui/color_mode.h b/scene/gui/color_mode.h index 7dfd885276..2550220848 100644 --- a/scene/gui/color_mode.h +++ b/scene/gui/color_mode.h @@ -117,7 +117,7 @@ public: float slider_max[3] = { 1, 1, 1 }; Ref rgb_texture[3]; - virtual String get_name() const override { return "Linear"; } + virtual String get_name() const override { return ETR("Linear"); } virtual float get_slider_step() const override { return 1.0 / 255.0; } virtual String get_slider_label(int idx) const override; diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 135ff73f9e..80773e26d8 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -2580,6 +2580,7 @@ void ColorPickerButton::_update_picker() { picker->connect("color_changed", callable_mp(this, &ColorPickerButton::_color_changed)); popup->connect("about_to_popup", callable_mp(this, &ColorPickerButton::_about_to_popup)); popup->connect("popup_hide", callable_mp(this, &ColorPickerButton::_modal_closed)); + popup->connect("tree_exiting", callable_mp(this, &ColorPickerButton::_modal_closed)); picker->connect(SceneStringName(minimum_size_changed), callable_mp((Window *)popup, &Window::reset_size)); picker->set_pick_color(color); picker->set_edit_alpha(edit_alpha); diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 048c44420a..a77a4b71bb 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -2145,7 +2145,7 @@ FileDialog::FileDialog() { favorite_button = memnew(Button); favorite_button->set_theme_type_variation(SceneStringName(FlatButton)); - favorite_button->set_tooltip_text(TTRC("(Un)favorite current folder.")); + favorite_button->set_tooltip_text(ETR("(Un)favorite current folder.")); top_toolbar->add_child(favorite_button); favorite_button->connect(SceneStringName(pressed), callable_mp(this, &FileDialog::_favorite_pressed)); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index f3e5bd7f3c..d481510067 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -505,7 +505,7 @@ void LineEdit::gui_input(const Ref &p_event) { last_dblclk_pos = b->get_position(); PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid); for (int i = 0; i < words.size(); i = i + 2) { - if ((words[i] < caret_column && words[i + 1] > caret_column) || (i == words.size() - 2 && caret_column == words[i + 1])) { + if (words[i] <= caret_column && words[i + 1] >= caret_column) { selection.enabled = true; selection.begin = words[i]; selection.end = words[i + 1]; @@ -599,10 +599,10 @@ void LineEdit::gui_input(const Ref &p_event) { PackedInt32Array words = TS->shaped_text_get_word_breaks(text_rid); for (int i = 0; i < words.size(); i = i + 2) { - if ((words[i] < selection.begin && words[i + 1] > selection.begin) || (i == words.size() - 2 && selection.begin == words[i + 1])) { + if (words[i] <= selection.begin && words[i + 1] >= selection.begin) { selection.begin = words[i]; } - if ((words[i] < selection.end && words[i + 1] > selection.end) || (i == words.size() - 2 && selection.end == words[i + 1])) { + if (words[i] <= selection.end && words[i + 1] >= selection.end) { selection.end = words[i + 1]; selection.enabled = true; break; diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index b34f0e2cb0..19f5f2534f 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -396,6 +396,7 @@ void OptionButton::add_separator(const String &p_text) { void OptionButton::clear() { popup->clear(); set_text(""); + set_button_icon(Ref()); current = NONE_SELECTED; _refresh_size_cache(); } @@ -412,7 +413,7 @@ void OptionButton::_select(int p_which, bool p_emit) { current = NONE_SELECTED; set_text(""); - set_button_icon(nullptr); + set_button_icon(Ref()); } else { ERR_FAIL_INDEX(p_which, popup->get_item_count()); diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index cfb39ba926..7f0c5780bf 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -40,7 +40,7 @@ #include "scene/theme/theme_db.h" void Popup::_input_from_window(const Ref &p_event) { - if ((ac_popup || get_flag(FLAG_POPUP)) && p_event->is_action_pressed(SNAME("ui_cancel"), false, true)) { + if (get_flag(FLAG_POPUP) && p_event->is_action_pressed(SNAME("ui_cancel"), false, true)) { hide_reason = HIDE_REASON_CANCELED; // ESC pressed, mark as canceled unconditionally. _close_pressed(); } @@ -80,6 +80,8 @@ void Popup::_notification(int p_what) { if (!is_in_edited_scene_root()) { if (is_visible()) { _initialize_visible_parents(); + popped_up = true; + hide_reason = HIDE_REASON_NONE; } else { _deinitialize_visible_parents(); if (hide_reason == HIDE_REASON_NONE) { @@ -91,15 +93,6 @@ void Popup::_notification(int p_what) { } } break; - case NOTIFICATION_WM_WINDOW_FOCUS_IN: { - if (!is_in_edited_scene_root()) { - if (has_focus()) { - popped_up = true; - hide_reason = HIDE_REASON_NONE; - } - } - } break; - case NOTIFICATION_UNPARENTED: case NOTIFICATION_EXIT_TREE: { if (!is_in_edited_scene_root()) { @@ -117,7 +110,7 @@ void Popup::_notification(int p_what) { } break; case NOTIFICATION_APPLICATION_FOCUS_OUT: { - if (!is_in_edited_scene_root() && (get_flag(FLAG_POPUP) || ac_popup)) { + if (!is_in_edited_scene_root() && get_flag(FLAG_POPUP)) { if (hide_reason == HIDE_REASON_NONE) { hide_reason = HIDE_REASON_UNFOCUSED; } @@ -128,7 +121,7 @@ void Popup::_notification(int p_what) { } void Popup::_parent_focused() { - if (popped_up && (get_flag(FLAG_POPUP) || ac_popup)) { + if (popped_up && get_flag(FLAG_POPUP)) { if (hide_reason == HIDE_REASON_NONE) { hide_reason = HIDE_REASON_UNFOCUSED; } diff --git a/scene/gui/popup.h b/scene/gui/popup.h index d1840fe0b2..481a654067 100644 --- a/scene/gui/popup.h +++ b/scene/gui/popup.h @@ -42,7 +42,6 @@ class Popup : public Window { GDCLASS(Popup, Window); LocalVector visible_parents; - bool ac_popup = false; bool popped_up = false; public: @@ -62,7 +61,6 @@ protected: void _close_pressed(); virtual Rect2i _popup_adjust_rect() const override; virtual void _input_from_window(const Ref &p_event) override; - void set_ac_popup() { ac_popup = true; } void _notification(int p_what); void _validate_property(PropertyInfo &p_property) const; diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 57cc1b8b40..9f10cb5a94 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -967,7 +967,7 @@ void PopupMenu::_draw_items() { } else { item_ofs.x = display_width - theme_cache.panel_style->get_margin(SIDE_RIGHT) - items[i].accel_text_buf->get_size().x - theme_cache.item_end_padding; } - Vector2 text_pos = item_ofs + Point2(0, Math::floor((h - items[i].text_buf->get_size().y) / 2.0)); + Vector2 text_pos = item_ofs + Point2(0, Math::floor((h - items[i].accel_text_buf->get_size().y) / 2.0)); if (theme_cache.font_outline_size > 0 && theme_cache.font_outline_color.a > 0) { items[i].accel_text_buf->draw_outline(ci, text_pos, theme_cache.font_outline_size, theme_cache.font_outline_color); } @@ -3211,13 +3211,8 @@ void PopupMenu::popup(const Rect2i &p_bounds) { _native_popup(p_bounds != Rect2i() ? p_bounds : Rect2i(get_position(), Size2i())); } else { if (is_inside_tree()) { - bool ac = get_tree()->is_accessibility_enabled(); - // Note: Native popup menus need keyboard focus to work with screen reader. - set_flag(FLAG_POPUP, !ac); - set_flag(FLAG_NO_FOCUS, !is_embedded() && !ac); - if (ac) { - set_ac_popup(); - } + set_flag(FLAG_POPUP, true); + set_flag(FLAG_NO_FOCUS, !is_embedded()); } moved = Vector2(); @@ -3255,13 +3250,8 @@ void PopupMenu::set_visible(bool p_visible) { } } else { if (is_inside_tree()) { - bool ac = get_tree()->is_accessibility_enabled(); - // Note: Native popup menus need keyboard focus to work with screen reader. - set_flag(FLAG_POPUP, !ac); - set_flag(FLAG_NO_FOCUS, !is_embedded() && !ac); - if (ac) { - set_ac_popup(); - } + set_flag(FLAG_POPUP, true); + set_flag(FLAG_NO_FOCUS, !is_embedded()); } Popup::set_visible(p_visible); diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp index b36a515d49..9ccec62757 100644 --- a/scene/gui/range.cpp +++ b/scene/gui/range.cpp @@ -35,22 +35,39 @@ #include "thirdparty/misc/r128.h" double Range::_snapped_r128(double p_value, double p_step) { - if (p_step != 0) { - // All these lines are the equivalent of: p_value = Math::floor(p_value / p_step + 0.5) * p_step; - // Convert to String to force rounding to a decimal value (not a binary one). - String step_str = String::num(p_step); - String value_str = String::num(p_value); - R128 step_r128; - R128 value_r128; - const R128 half_r128 = R128(0.5); - r128FromString(&step_r128, step_str.ascii().get_data(), nullptr); - r128FromString(&value_r128, value_str.ascii().get_data(), nullptr); - r128Div(&value_r128, &value_r128, &step_r128); - r128Add(&value_r128, &value_r128, &half_r128); - r128Floor(&value_r128, &value_r128); - r128Mul(&value_r128, &value_r128, &step_r128); - p_value = value_r128; + if (p_step == 0.0) { + return p_value; } + if (p_value > (1e18 * p_step) || p_value < -(1e18 * p_step)) { + // If the value goes outside of the range R128 supports, fallback to normal snapping. + return Math::snapped(p_value, p_step); + } + // Rescale values to better utilize R128's range before snapping. + // R128 is fixed-precision with 64 bits after the decimal point, but double already uses 53 of those, + // so a step size finer than 2^-11 will lose precision, and in practice even 1e-3 can be problematic. + // By rescaling the value and step, we can shift precision into the higher bits (effectively turning R128 into a makeshift float). + const int decimals = 14 - Math::floor(std::log10(MAX(Math::abs(p_value), p_step))); + const double scale = Math::pow(10.0, decimals); + p_value *= scale; + p_step *= scale; + // All these lines are the equivalent of: p_value = Math::floor(p_value / p_step + 0.5) * p_step; + // Convert to String to force rounding to a decimal value (not a binary one). + String step_str = String::num(p_step); + String value_str = String::num(p_value); + R128 step_r128; + R128 value_r128; + const R128 half_r128 = R128(0.5); + r128FromString(&step_r128, step_str.ascii().get_data(), nullptr); + r128FromString(&value_r128, value_str.ascii().get_data(), nullptr); + r128Div(&value_r128, &value_r128, &step_r128); + r128Add(&value_r128, &value_r128, &half_r128); + r128Floor(&value_r128, &value_r128); + r128Mul(&value_r128, &value_r128, &step_r128); + if (scale != 1.0) { + const R128 scale_r128 = R128(scale); + r128Div(&value_r128, &value_r128, &scale_r128); + } + p_value = (double)value_r128; return p_value; } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 6b31bc0254..a830568f06 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -595,10 +595,11 @@ float RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref String second = tx.substr(remaining_characters, -1); l.text_buf->add_string(first, font, font_size, lang, it->rid); l.text_buf->add_string(second, font, font_size, lang, it->rid); + } else { + l.text_buf->add_string(tx, font, font_size, lang, it->rid); } remaining_characters -= tx.length(); - l.text_buf->add_string(tx, font, font_size, lang, it->rid); txt += tx; l.char_count += tx.length(); } break; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index c7027340fa..ace4a78d4e 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -314,7 +314,7 @@ void TextEdit::Text::invalidate_cache(int p_line, bool p_text_changed) { float width_ratio = info["width_ratio"]; String left_string = text_with_ime.substr(from, start - from); text_line.data_buf->add_string(left_string, font, font_size, language); - text_line.data_buf->add_object(info, Vector2(font_height * width_ratio, font_height), INLINE_ALIGNMENT_TOP, 0); + text_line.data_buf->add_object(info, Vector2(font_height * width_ratio, font_height), INLINE_ALIGNMENT_CENTER, 0); from = start; } } @@ -331,7 +331,7 @@ void TextEdit::Text::invalidate_cache(int p_line, bool p_text_changed) { } Dictionary info = key; float width_ratio = info["width_ratio"]; - text_line.data_buf->resize_object(info, Vector2(font_height * width_ratio, font_height), INLINE_ALIGNMENT_TOP, 0); + text_line.data_buf->resize_object(info, Vector2(font_height * width_ratio, font_height), INLINE_ALIGNMENT_CENTER, 0); } } } diff --git a/scene/main/node.cpp b/scene/main/node.cpp index e195589eab..02c8886809 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -70,7 +70,7 @@ void Node::_notification(int p_notification) { for (int i = 0; i < get_child_count(); i++) { Node *child_node = get_child(i); Window *child_wnd = Object::cast_to(child_node); - if (child_wnd && !child_wnd->is_embedded()) { + if (child_wnd && !(child_wnd->is_visible() && (child_wnd->is_embedded() || child_wnd->is_popup()))) { continue; } if (child_node->is_part_of_edited_scene()) { @@ -2111,6 +2111,14 @@ Window *Node::get_window() const { return nullptr; } +Window *Node::get_non_popup_window() const { + Window *w = get_window(); + while (w && w->is_popup()) { + w = w->get_parent_visible_window(); + } + return w; +} + Window *Node::get_last_exclusive_window() const { Window *w = get_window(); while (w && w->get_exclusive_child()) { @@ -3756,8 +3764,9 @@ RID Node::get_accessibility_element() const { return RID(); } if (unlikely(data.accessibility_element.is_null())) { - if (get_window() && get_window()->get_window_id() != DisplayServer::INVALID_WINDOW_ID) { - data.accessibility_element = DisplayServer::get_singleton()->accessibility_create_element(get_window()->get_window_id(), DisplayServer::ROLE_CONTAINER); + Window *w = get_non_popup_window(); + if (w && w->get_window_id() != DisplayServer::INVALID_WINDOW_ID && get_window()->is_visible()) { + data.accessibility_element = DisplayServer::get_singleton()->accessibility_create_element(w->get_window_id(), DisplayServer::ROLE_CONTAINER); } } return data.accessibility_element; diff --git a/scene/main/node.h b/scene/main/node.h index d350199b0a..e9103a3101 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -506,6 +506,7 @@ public: Node *find_parent(const String &p_pattern) const; Window *get_window() const; + Window *get_non_popup_window() const; Window *get_last_exclusive_window() const; _FORCE_INLINE_ SceneTree *get_tree() const { diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index e1c944ffba..3837f0cbdb 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -248,10 +248,10 @@ void SceneTree::_process_accessibility_changes(DisplayServer::WindowID p_window_ Vector processed; for (const ObjectID &id : accessibility_change_queue) { Node *node = Object::cast_to(ObjectDB::get_instance(id)); - if (!node || !node->get_window()) { + if (!node || !node->get_non_popup_window() || !node->get_window()->is_visible()) { processed.push_back(id); continue; // Invalid node, remove from list and skip. - } else if (node->get_window()->get_window_id() != p_window_id) { + } else if (node->get_non_popup_window()->get_window_id() != p_window_id) { continue; // Another window, skip. } node->notification(Node::NOTIFICATION_ACCESSIBILITY_UPDATE); @@ -269,6 +269,15 @@ void SceneTree::_process_accessibility_changes(DisplayServer::WindowID p_window_ w_this = w_focus; } + // Popups have no native window focus, but have focused element. + DisplayServer::WindowID popup_id = DisplayServer::get_singleton()->window_get_active_popup(); + if (popup_id != DisplayServer::INVALID_WINDOW_ID) { + Window *popup_w = Window::get_from_id(popup_id); + if (popup_w && w_this->is_ancestor_of(popup_w)) { + w_this = popup_w; + } + } + RID new_focus_element; Control *n_focus = w_this->gui_get_focus_owner(); if (n_focus && !n_focus->is_part_of_edited_scene()) { diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 650fb5ff0c..fede9c094e 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -45,8 +45,8 @@ #include "scene/gui/subviewport_container.h" #include "scene/main/canvas_layer.h" #include "scene/main/window.h" +#include "scene/resources/dpi_texture.h" #include "scene/resources/mesh.h" -#include "scene/resources/svg_texture.h" #include "scene/resources/text_line.h" #include "scene/resources/world_2d.h" #include "servers/audio_server.h" @@ -1097,8 +1097,8 @@ bool Viewport::_set_size(const Size2i &p_size, const Size2 &p_size_2d_override, TS->reference_oversampling_level(new_font_oversampling); TS->unreference_oversampling_level(font_oversampling); - SVGTexture::reference_scaling_level(new_font_oversampling); - SVGTexture::unreference_scaling_level(font_oversampling); + DPITexture::reference_scaling_level(new_font_oversampling); + DPITexture::unreference_scaling_level(font_oversampling); } size = new_size; diff --git a/scene/main/window.cpp b/scene/main/window.cpp index d36939ce90..706aef4651 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -572,6 +572,10 @@ bool Window::get_flag(Flags p_flag) const { return flags[p_flag]; } +bool Window::is_popup() const { + return get_flag(Window::FLAG_POPUP) || get_flag(Window::FLAG_NO_FOCUS); +} + bool Window::is_maximize_allowed() const { ERR_READ_THREAD_GUARD_V(false); if (window_id != DisplayServer::INVALID_WINDOW_ID) { @@ -682,11 +686,6 @@ void Window::_make_window() { } } - if (get_tree() && get_tree()->is_accessibility_supported()) { - get_tree()->_accessibility_force_update(); - _accessibility_notify_enter(this); - } - _update_window_callbacks(); RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_VISIBLE); @@ -718,10 +717,6 @@ void Window::_clear_window() { _update_from_window(); - if (get_tree() && get_tree()->is_accessibility_supported()) { - _accessibility_notify_exit(this); - } - DisplayServer::get_singleton()->delete_sub_window(window_id); window_id = DisplayServer::INVALID_WINDOW_ID; @@ -888,7 +883,7 @@ void Window::_accessibility_notify_enter(Node *p_node) { if (p_node != this) { const Window *window = Object::cast_to(p_node); - if (window && !window->is_embedded()) { + if (window) { return; } } @@ -903,7 +898,7 @@ void Window::_accessibility_notify_exit(Node *p_node) { if (p_node != this) { const Window *window = Object::cast_to(p_node); - if (window && !window->is_embedded()) { + if (window) { return; } } @@ -952,23 +947,35 @@ void Window::set_visible(bool p_visible) { } } embedder->_sub_window_register(this); - embedder->queue_accessibility_update(); RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE); } else { embedder->_sub_window_remove(this); - embedder->queue_accessibility_update(); embedder = nullptr; RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED); } _update_window_size(); } - if (!visible) { + if (visible) { + if (get_tree() && get_tree()->is_accessibility_supported()) { + get_tree()->_accessibility_force_update(); + _accessibility_notify_enter(this); + } + } else { + if (get_tree() && get_tree()->is_accessibility_supported()) { + _accessibility_notify_exit(this); + } focused = false; if (focused_window == this) { focused_window = nullptr; } } + if (get_parent()) { + get_parent()->queue_accessibility_update(); + } + if (embedder) { + embedder->queue_accessibility_update(); + } notification(NOTIFICATION_VISIBILITY_CHANGED); emit_signal(SceneStringName(visibility_changed)); @@ -1373,10 +1380,10 @@ Viewport *Window::get_embedder() const { } RID Window::get_accessibility_element() const { - if (is_part_of_edited_scene()) { + if (!visible || is_part_of_edited_scene()) { return RID(); } - if (get_embedder()) { + if (get_embedder() || is_popup()) { return Node::get_accessibility_element(); } else if (window_id != DisplayServer::INVALID_WINDOW_ID) { return DisplayServer::get_singleton()->accessibility_get_window_root(window_id); @@ -1417,11 +1424,18 @@ void Window::_notification(int p_what) { DisplayServer::get_singleton()->accessibility_update_add_action(ae, DisplayServer::AccessibilityAction::ACTION_FOCUS, callable_mp(this, &Window::_accessibility_action_grab_focus)); DisplayServer::get_singleton()->accessibility_update_set_flag(ae, DisplayServer::AccessibilityFlags::FLAG_HIDDEN, !visible); - if (get_embedder()) { + if (get_embedder() || is_popup()) { Control *parent_ctrl = Object::cast_to(get_parent()); Transform2D parent_tr = parent_ctrl ? parent_ctrl->get_global_transform() : Transform2D(); Transform2D tr; - tr.set_origin(position); + if (window_id == DisplayServer::INVALID_WINDOW_ID) { + tr.set_origin(position); + } else { + Window *np = get_non_popup_window(); + if (np) { + tr.set_origin(get_position() - np->get_position()); + } + } DisplayServer::get_singleton()->accessibility_update_set_transform(ae, parent_tr.affine_inverse() * tr); DisplayServer::get_singleton()->accessibility_update_set_bounds(ae, Rect2(Point2(), size)); @@ -1542,9 +1556,19 @@ void Window::_notification(int p_what) { _make_transient(); } if (visible) { + if (window_id != DisplayServer::MAIN_WINDOW_ID && get_tree() && get_tree()->is_accessibility_supported()) { + get_tree()->_accessibility_force_update(); + _accessibility_notify_enter(this); + } notification(NOTIFICATION_VISIBILITY_CHANGED); emit_signal(SceneStringName(visibility_changed)); RS::get_singleton()->viewport_set_active(get_viewport_rid(), true); + if (get_parent()) { + get_parent()->queue_accessibility_update(); + } + if (embedder) { + embedder->queue_accessibility_update(); + } } // Emits NOTIFICATION_THEME_CHANGED internally. @@ -1586,6 +1610,18 @@ void Window::_notification(int p_what) { set_theme_context(nullptr, false); + if (visible && window_id != DisplayServer::MAIN_WINDOW_ID) { + if (get_tree() && get_tree()->is_accessibility_supported()) { + _accessibility_notify_exit(this); + if (get_parent()) { + get_parent()->queue_accessibility_update(); + } + if (embedder) { + embedder->queue_accessibility_update(); + } + } + } + accessibility_title_element = RID(); accessibility_announcement_element = RID(); @@ -1818,6 +1854,14 @@ Viewport *Window::get_parent_viewport() const { } } +Window *Window::get_non_popup_window() const { + Window *w = const_cast(this); + while (w && w->is_popup()) { + w = w->get_parent_visible_window(); + } + return w; +} + Window *Window::get_parent_visible_window() const { ERR_READ_THREAD_GUARD_V(nullptr); Viewport *vp = get_parent_viewport(); diff --git a/scene/main/window.h b/scene/main/window.h index 16d8b82c3a..16c8fd7f3e 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -334,6 +334,8 @@ public: void set_flag(Flags p_flag, bool p_enabled); bool get_flag(Flags p_flag) const; + bool is_popup() const; + bool is_maximize_allowed() const; void request_attention(); @@ -401,6 +403,7 @@ public: Window *get_exclusive_child() const { return exclusive_child; } HashSet get_transient_children() const { return transient_children; } Window *get_parent_visible_window() const; + Window *get_non_popup_window() const; Viewport *get_parent_viewport() const; virtual void popup(const Rect2i &p_screen_rect = Rect2i()); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 04de5736b7..f82fc802bc 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -137,6 +137,7 @@ #if !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) #include "scene/resources/navigation_mesh.h" #endif // !defined(NAVIGATION_2D_DISABLED) || !defined(NAVIGATION_3D_DISABLED) +#include "scene/resources/dpi_texture.h" #include "scene/resources/packed_scene.h" #include "scene/resources/particle_process_material.h" #include "scene/resources/placeholder_textures.h" @@ -150,7 +151,6 @@ #include "scene/resources/style_box_line.h" #include "scene/resources/style_box_texture.h" #include "scene/resources/surface_tool.h" -#include "scene/resources/svg_texture.h" #include "scene/resources/syntax_highlighter.h" #include "scene/resources/text_line.h" #include "scene/resources/text_paragraph.h" @@ -1059,7 +1059,7 @@ void register_scene_types() { GDREGISTER_CLASS(PlaceholderTexture2DArray); GDREGISTER_CLASS(PlaceholderCubemap); GDREGISTER_CLASS(PlaceholderCubemapArray); - GDREGISTER_CLASS(SVGTexture); + GDREGISTER_CLASS(DPITexture); #ifndef DISABLE_DEPRECATED GDREGISTER_CLASS(AnimatedTexture); #endif diff --git a/scene/resources/3d/importer_mesh.cpp b/scene/resources/3d/importer_mesh.cpp index 82ef0d94ff..f9efa783a9 100644 --- a/scene/resources/3d/importer_mesh.cpp +++ b/scene/resources/3d/importer_mesh.cpp @@ -324,6 +324,7 @@ void ImporterMesh::generate_lods(float p_normal_merge_angle, Array p_bone_transf if (index_count == 0) { continue; //no lods if no indices } + ERR_FAIL_COND_MSG(index_count % 3 != 0, "ImporterMesh::generate_lods: Indexed triangle meshes MUST have an index array with a size that is a multiple of 3, but got " + itos(index_count) + " indices. Cannot generate LODs for this invalid mesh."); const Vector3 *vertices_ptr = vertices.ptr(); const int *indices_ptr = indices.ptr(); diff --git a/scene/resources/audio_stream_wav.cpp b/scene/resources/audio_stream_wav.cpp index 8a04852775..73a661c414 100644 --- a/scene/resources/audio_stream_wav.cpp +++ b/scene/resources/audio_stream_wav.cpp @@ -1155,22 +1155,35 @@ Ref AudioStreamWAV::load_from_buffer(const Vector &p_st if (!tag_map.is_empty()) { // Used to make the metadata tags more unified across different AudioStreams. // See https://www.recordingblogs.com/wiki/list-chunk-of-a-wave-file + // https://wiki.hydrogenaudio.org/index.php?title=Tag_Mapping#Mapping_Tables HashMap tag_id_remaps; tag_id_remaps.reserve(15); tag_id_remaps["IARL"] = "location"; tag_id_remaps["IART"] = "artist"; tag_id_remaps["ICMS"] = "organization"; - tag_id_remaps["ICMT"] = "comments"; + tag_id_remaps["ICMT"] = "comment"; + tag_id_remaps["ICNT"] = "releasecountry"; tag_id_remaps["ICOP"] = "copyright"; tag_id_remaps["ICRD"] = "date"; + tag_id_remaps["IENC"] = "encodedby"; + tag_id_remaps["IENG"] = "engineer"; + tag_id_remaps["IFRM"] = "tracktotal"; tag_id_remaps["IGNR"] = "genre"; tag_id_remaps["IKEY"] = "keywords"; - tag_id_remaps["IMED"] = "medium"; + tag_id_remaps["ILNG"] = "language"; + tag_id_remaps["IMED"] = "media"; + tag_id_remaps["IMUS"] = "composer"; tag_id_remaps["INAM"] = "title"; tag_id_remaps["IPRD"] = "album"; + tag_id_remaps["IPRO"] = "producer"; + tag_id_remaps["IPRT"] = "tracknumber"; tag_id_remaps["ISBJ"] = "description"; - tag_id_remaps["ISFT"] = "software"; + tag_id_remaps["ISFT"] = "encoder"; + tag_id_remaps["ISRF"] = "media"; + tag_id_remaps["ITCH"] = "encodedby"; tag_id_remaps["ITRK"] = "tracknumber"; + tag_id_remaps["IWRI"] = "author"; + tag_id_remaps["TLEN"] = "length"; Dictionary tag_dictionary; for (const KeyValue &E : tag_map) { HashMap::ConstIterator remap = tag_id_remaps.find(E.key); diff --git a/scene/resources/svg_texture.cpp b/scene/resources/dpi_texture.cpp similarity index 78% rename from scene/resources/svg_texture.cpp rename to scene/resources/dpi_texture.cpp index b503da824f..c4f6e710cc 100644 --- a/scene/resources/svg_texture.cpp +++ b/scene/resources/dpi_texture.cpp @@ -1,5 +1,5 @@ /**************************************************************************/ -/* svg_texture.cpp */ +/* dpi_texture.cpp */ /**************************************************************************/ /* This file is part of: */ /* REDOT ENGINE */ @@ -30,7 +30,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#include "svg_texture.h" +#include "dpi_texture.h" #include "core/io/image_loader.h" #include "scene/main/canvas_item.h" @@ -43,10 +43,10 @@ #include "modules/svg/image_loader_svg.h" #endif -Mutex SVGTexture::mutex; -HashMap SVGTexture::scaling_levels; +Mutex DPITexture::mutex; +HashMap DPITexture::scaling_levels; -void SVGTexture::reference_scaling_level(double p_scale) { +void DPITexture::reference_scaling_level(double p_scale) { uint32_t oversampling = CLAMP(p_scale, 0.1, 100.0) * 64; if (oversampling == 64) { return; @@ -63,7 +63,7 @@ void SVGTexture::reference_scaling_level(double p_scale) { } } -void SVGTexture::unreference_scaling_level(double p_scale) { +void DPITexture::unreference_scaling_level(double p_scale) { uint32_t oversampling = CLAMP(p_scale, 0.1, 100.0) * 64; if (oversampling == 64) { return; @@ -75,7 +75,7 @@ void SVGTexture::unreference_scaling_level(double p_scale) { if (sl) { sl->refcount--; if (sl->refcount == 0) { - for (SVGTexture *tx : sl->textures) { + for (DPITexture *tx : sl->textures) { tx->_remove_scale(scale); } sl->textures.clear(); @@ -84,17 +84,17 @@ void SVGTexture::unreference_scaling_level(double p_scale) { } } -Ref SVGTexture::create_from_string(const String &p_source, float p_scale, float p_saturation, const Dictionary &p_color_map) { - Ref svg_texture; - svg_texture.instantiate(); - svg_texture->set_source(p_source); - svg_texture->set_base_scale(p_scale); - svg_texture->set_saturation(p_saturation); - svg_texture->set_color_map(p_color_map); - return svg_texture; +Ref DPITexture::create_from_string(const String &p_source, float p_scale, float p_saturation, const Dictionary &p_color_map) { + Ref dpi_texture; + dpi_texture.instantiate(); + dpi_texture->set_source(p_source); + dpi_texture->set_base_scale(p_scale); + dpi_texture->set_saturation(p_saturation); + dpi_texture->set_color_map(p_color_map); + return dpi_texture; } -void SVGTexture::set_source(const String &p_source) { +void DPITexture::set_source(const String &p_source) { if (source == p_source) { return; } @@ -102,11 +102,11 @@ void SVGTexture::set_source(const String &p_source) { _update_texture(); } -String SVGTexture::get_source() const { +String DPITexture::get_source() const { return source; } -void SVGTexture::set_base_scale(float p_scale) { +void DPITexture::set_base_scale(float p_scale) { if (base_scale == p_scale) { return; } @@ -116,11 +116,11 @@ void SVGTexture::set_base_scale(float p_scale) { _update_texture(); } -float SVGTexture::get_base_scale() const { +float DPITexture::get_base_scale() const { return base_scale; } -void SVGTexture::set_saturation(float p_saturation) { +void DPITexture::set_saturation(float p_saturation) { if (saturation == p_saturation) { return; } @@ -129,11 +129,11 @@ void SVGTexture::set_saturation(float p_saturation) { _update_texture(); } -float SVGTexture::get_saturation() const { +float DPITexture::get_saturation() const { return saturation; } -void SVGTexture::set_color_map(const Dictionary &p_color_map) { +void DPITexture::set_color_map(const Dictionary &p_color_map) { if (color_map == p_color_map) { return; } @@ -145,11 +145,11 @@ void SVGTexture::set_color_map(const Dictionary &p_color_map) { _update_texture(); } -Dictionary SVGTexture::get_color_map() const { +Dictionary DPITexture::get_color_map() const { return color_map; } -void SVGTexture::_remove_scale(double p_scale) { +void DPITexture::_remove_scale(double p_scale) { if (Math::is_equal_approx(p_scale, 1.0)) { return; } @@ -163,7 +163,7 @@ void SVGTexture::_remove_scale(double p_scale) { } } -RID SVGTexture::_ensure_scale(double p_scale) const { +RID DPITexture::_ensure_scale(double p_scale) const { uint32_t oversampling = CLAMP(p_scale, 0.1, 100.0) * 64; if (oversampling == 64) { if (base_texture.is_null()) { @@ -181,14 +181,14 @@ RID SVGTexture::_ensure_scale(double p_scale) const { MutexLock lock(mutex); ScalingLevel *sl = scaling_levels.getptr(scale); ERR_FAIL_NULL_V_MSG(sl, RID(), "Invalid scaling level"); - sl->textures.insert(const_cast(this)); + sl->textures.insert(const_cast(this)); RID new_rid = _load_at_scale(scale, false); texture_cache[scale] = new_rid; return new_rid; } -RID SVGTexture::_load_at_scale(double p_scale, bool p_set_size) const { +RID DPITexture::_load_at_scale(double p_scale, bool p_set_size) const { Ref img; img.instantiate(); #ifdef MODULE_SVG_ENABLED @@ -229,7 +229,7 @@ RID SVGTexture::_load_at_scale(double p_scale, bool p_set_size) const { return rid; } -void SVGTexture::_clear() { +void DPITexture::_clear() { for (KeyValue &tx : texture_cache) { if (tx.value.is_valid()) { RenderingServer::get_singleton()->free(tx.value); @@ -243,12 +243,12 @@ void SVGTexture::_clear() { alpha_cache.unref(); } -void SVGTexture::_update_texture() { +void DPITexture::_update_texture() { _clear(); emit_changed(); } -Ref SVGTexture::get_image() const { +Ref DPITexture::get_image() const { RID rid = _ensure_scale(1.0); if (rid.is_valid()) { return RenderingServer::get_singleton()->texture_2d_get(rid); @@ -257,25 +257,25 @@ Ref SVGTexture::get_image() const { } } -int SVGTexture::get_width() const { +int DPITexture::get_width() const { _ensure_scale(1.0); return size.x; } -int SVGTexture::get_height() const { +int DPITexture::get_height() const { _ensure_scale(1.0); return size.y; } -RID SVGTexture::get_rid() const { +RID DPITexture::get_rid() const { return _ensure_scale(1.0); } -bool SVGTexture::has_alpha() const { +bool DPITexture::has_alpha() const { return true; } -RID SVGTexture::get_scaled_rid() const { +RID DPITexture::get_scaled_rid() const { double scale = 1.0; CanvasItem *ci = CanvasItem::get_current_item_drawn(); if (ci) { @@ -287,19 +287,19 @@ RID SVGTexture::get_scaled_rid() const { return _ensure_scale(scale); } -void SVGTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const { +void DPITexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const { RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, size), get_scaled_rid(), false, p_modulate, p_transpose); } -void SVGTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const { +void DPITexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const { RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, get_scaled_rid(), p_tile, p_modulate, p_transpose); } -void SVGTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) const { +void DPITexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) const { RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_scaled_rid(), p_src_rect, p_modulate, p_transpose, p_clip_uv); } -bool SVGTexture::is_pixel_opaque(int p_x, int p_y) const { +bool DPITexture::is_pixel_opaque(int p_x, int p_y) const { if (alpha_cache.is_null()) { Ref img = get_image(); if (img.is_valid()) { @@ -327,7 +327,7 @@ bool SVGTexture::is_pixel_opaque(int p_x, int p_y) const { return true; } -void SVGTexture::set_size_override(const Size2i &p_size) { +void DPITexture::set_size_override(const Size2i &p_size) { if (size_override == p_size) { return; } @@ -354,19 +354,19 @@ void SVGTexture::set_size_override(const Size2i &p_size) { emit_changed(); } -void SVGTexture::_bind_methods() { - ClassDB::bind_static_method("SVGTexture", D_METHOD("create_from_string", "source", "scale", "saturation", "color_map"), &SVGTexture::create_from_string, DEFVAL(1.0), DEFVAL(1.0), DEFVAL(Dictionary())); +void DPITexture::_bind_methods() { + ClassDB::bind_static_method("DPITexture", D_METHOD("create_from_string", "source", "scale", "saturation", "color_map"), &DPITexture::create_from_string, DEFVAL(1.0), DEFVAL(1.0), DEFVAL(Dictionary())); - ClassDB::bind_method(D_METHOD("set_source", "source"), &SVGTexture::set_source); - ClassDB::bind_method(D_METHOD("get_source"), &SVGTexture::get_source); - ClassDB::bind_method(D_METHOD("set_base_scale", "base_scale"), &SVGTexture::set_base_scale); - ClassDB::bind_method(D_METHOD("get_base_scale"), &SVGTexture::get_base_scale); - ClassDB::bind_method(D_METHOD("set_saturation", "saturation"), &SVGTexture::set_saturation); - ClassDB::bind_method(D_METHOD("get_saturation"), &SVGTexture::get_saturation); - ClassDB::bind_method(D_METHOD("set_color_map", "color_map"), &SVGTexture::set_color_map); - ClassDB::bind_method(D_METHOD("get_color_map"), &SVGTexture::get_color_map); - ClassDB::bind_method(D_METHOD("set_size_override", "size"), &SVGTexture::set_size_override); - ClassDB::bind_method(D_METHOD("get_scaled_rid"), &SVGTexture::get_scaled_rid); + ClassDB::bind_method(D_METHOD("set_source", "source"), &DPITexture::set_source); + ClassDB::bind_method(D_METHOD("get_source"), &DPITexture::get_source); + ClassDB::bind_method(D_METHOD("set_base_scale", "base_scale"), &DPITexture::set_base_scale); + ClassDB::bind_method(D_METHOD("get_base_scale"), &DPITexture::get_base_scale); + ClassDB::bind_method(D_METHOD("set_saturation", "saturation"), &DPITexture::set_saturation); + ClassDB::bind_method(D_METHOD("get_saturation"), &DPITexture::get_saturation); + ClassDB::bind_method(D_METHOD("set_color_map", "color_map"), &DPITexture::set_color_map); + ClassDB::bind_method(D_METHOD("get_color_map"), &DPITexture::get_color_map); + ClassDB::bind_method(D_METHOD("set_size_override", "size"), &DPITexture::set_size_override); + ClassDB::bind_method(D_METHOD("get_scaled_rid"), &DPITexture::get_scaled_rid); ADD_PROPERTY(PropertyInfo(Variant::STRING, "_source", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_STORAGE), "set_source", "get_source"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "base_scale", PROPERTY_HINT_RANGE, "0.01,10.0,0.01"), "set_base_scale", "get_base_scale"); @@ -374,7 +374,7 @@ void SVGTexture::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "color_map", PROPERTY_HINT_DICTIONARY_TYPE, "Color;Color"), "set_color_map", "get_color_map"); } -SVGTexture::~SVGTexture() { +DPITexture::~DPITexture() { _clear(); MutexLock lock(mutex); diff --git a/scene/resources/svg_texture.h b/scene/resources/dpi_texture.h similarity index 94% rename from scene/resources/svg_texture.h rename to scene/resources/dpi_texture.h index 8a26bfb427..724f1f1a5a 100644 --- a/scene/resources/svg_texture.h +++ b/scene/resources/dpi_texture.h @@ -1,5 +1,5 @@ /**************************************************************************/ -/* svg_texture.h */ +/* dpi_texture.h */ /**************************************************************************/ /* This file is part of: */ /* REDOT ENGINE */ @@ -37,9 +37,9 @@ class BitMap; -class SVGTexture : public Texture2D { - GDCLASS(SVGTexture, Texture2D); - RES_BASE_EXTENSION("svgtex"); +class DPITexture : public Texture2D { + GDCLASS(DPITexture, Texture2D); + RES_BASE_EXTENSION("dpitex"); String source; float base_scale = 1.0; @@ -48,7 +48,7 @@ class SVGTexture : public Texture2D { Size2 size_override; struct ScalingLevel { - HashSet textures; + HashSet textures; int32_t refcount = 1; }; static Mutex mutex; @@ -71,7 +71,7 @@ protected: static void _bind_methods(); public: - static Ref create_from_string(const String &p_source, float p_scale = 1.0, float p_saturation = 1.0, const Dictionary &p_color_map = Dictionary()); + static Ref create_from_string(const String &p_source, float p_scale = 1.0, float p_saturation = 1.0, const Dictionary &p_color_map = Dictionary()); void set_source(const String &p_source); String get_source() const; @@ -104,5 +104,5 @@ public: static void reference_scaling_level(double p_scale); static void unreference_scaling_level(double p_scale); - ~SVGTexture(); + ~DPITexture(); }; diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 62c2a5cb7a..64e7205450 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -66,6 +66,7 @@ Ref Material::get_next_pass() const { void Material::set_render_priority(int p_priority) { ERR_FAIL_COND(p_priority < RENDER_PRIORITY_MIN); ERR_FAIL_COND(p_priority > RENDER_PRIORITY_MAX); + render_priority = p_priority; if (material.is_valid()) { @@ -1640,7 +1641,7 @@ void fragment() {)"; float px_size = max(0.5 * dot(msdf_size, dest_size), 1.0); float d = msdf_median(albedo_tex.r, albedo_tex.g, albedo_tex.b); if (msdf_outline_size > 0.0) { - float cr = clamp(msdf_outline_size, 0.0, msdf_pixel_range / 2.0) / msdf_pixel_range; + float cr = clamp(msdf_outline_size, 0.0, (msdf_pixel_range / 2.0) - 1.0) / msdf_pixel_range; d = min(d, albedo_tex.a); albedo_tex.a = clamp((d - 0.5 + cr) * px_size + 0.5, 0.0, 1.0); } else { @@ -3222,6 +3223,11 @@ void BaseMaterial3D::set_stencil_mode(StencilMode p_stencil_mode) { return; } + if (p_stencil_mode == StencilMode::STENCIL_MODE_OUTLINE || p_stencil_mode == StencilMode::STENCIL_MODE_XRAY) { + ERR_FAIL_COND_EDMSG(get_render_priority() >= RENDER_PRIORITY_MAX, + vformat("Cannot use stencil mode Outline or Xray, when render priority is RENDER_PRIORITY_MAX(%d).", RENDER_PRIORITY_MAX)); + } + stencil_mode = p_stencil_mode; _prepare_stencil_effect(); _queue_shader_change(); diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 8ec0cc89e8..01fe9b45f4 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -349,7 +349,24 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const { node->get_script_instance()->get_property_state(old_state); } - node->set(snames[nprops[j].name], props[nprops[j].value], &valid); +#ifdef TOOLS_ENABLED + const Ref