summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml18
-rw-r--r--core/image.cpp8
-rw-r--r--core/image.h2
-rw-r--r--core/os/main_loop.cpp6
-rw-r--r--core/os/main_loop.h6
-rw-r--r--core/os/os.cpp36
-rw-r--r--core/os/os.h3
-rw-r--r--doc/classes/PhysicsShapeQueryParameters2D.xml27
-rw-r--r--doc/classes/PhysicsShapeQueryParameters3D.xml27
-rw-r--r--drivers/dummy/rasterizer_dummy.h33
-rw-r--r--editor/editor_help_search.cpp19
-rw-r--r--editor/editor_node.cpp4
-rw-r--r--editor/editor_plugin_settings.cpp2
-rw-r--r--editor/editor_spin_slider.cpp4
-rw-r--r--editor/plugins/script_editor_plugin.cpp2
-rw-r--r--editor/plugins/shader_editor_plugin.cpp2
-rw-r--r--editor/plugins/shader_file_editor_plugin.cpp2
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp2
-rw-r--r--editor/scene_tree_dock.cpp19
-rw-r--r--main/main.cpp34
-rw-r--r--main/main.h1
-rw-r--r--modules/csg/csg.cpp11
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp4
-rw-r--r--modules/tga/image_loader_tga.cpp14
-rw-r--r--platform/android/java_godot_lib_jni.cpp4
-rw-r--r--platform/osx/display_server_osx.mm12
-rw-r--r--platform/windows/display_server_windows.cpp19
-rw-r--r--platform/windows/display_server_windows.h1
-rw-r--r--scene/gui/dialogs.cpp5
-rw-r--r--scene/gui/dialogs.h1
-rw-r--r--scene/gui/line_edit.cpp4
-rw-r--r--scene/gui/text_edit.cpp4
-rw-r--r--scene/main/node.cpp10
-rw-r--r--scene/main/node.h10
-rw-r--r--scene/main/scene_tree.cpp8
-rw-r--r--scene/main/viewport.cpp2
-rw-r--r--scene/main/window.cpp16
-rw-r--r--servers/physics_server_2d.cpp19
-rw-r--r--servers/physics_server_2d.h5
-rw-r--r--servers/physics_server_3d.cpp19
-rw-r--r--servers/physics_server_3d.h4
41 files changed, 282 insertions, 147 deletions
diff --git a/.travis.yml b/.travis.yml
index 9376fbcc06..2639cf9661 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -100,15 +100,15 @@ matrix:
packages:
- *linux_deps
-# - name: Javascript export template (release, emscripten latest)
-# stage: build
-# env: PLATFORM=javascript TOOLS=no TARGET=release CACHE_NAME=${PLATFORM}-emcc-latest EXTRA_ARGS="use_closure_compiler=yes"
-# os: linux
-# compiler: clang
-# addons:
-# apt:
-# packages:
-# - *linux_deps
+ - name: JavaScript export template (release, emscripten latest)
+ stage: build
+ env: PLATFORM=javascript TOOLS=no TARGET=release CACHE_NAME=${PLATFORM}-emcc-latest EXTRA_ARGS="use_closure_compiler=yes"
+ os: linux
+ compiler: clang
+ addons:
+ apt:
+ packages:
+ - *linux_deps
before_install:
- eval "${MATRIX_EVAL}"
diff --git a/core/image.cpp b/core/image.cpp
index 45f10625a9..e2b184fcde 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -30,6 +30,7 @@
#include "image.h"
+#include "core/error_macros.h"
#include "core/hash_map.h"
#include "core/io/image_loader.h"
#include "core/io/resource_loader.h"
@@ -2629,6 +2630,7 @@ void Image::fill(const Color &c) {
ImageMemLoadFunc Image::_png_mem_loader_func = nullptr;
ImageMemLoadFunc Image::_jpg_mem_loader_func = nullptr;
ImageMemLoadFunc Image::_webp_mem_loader_func = nullptr;
+ImageMemLoadFunc Image::_tga_mem_loader_func = nullptr;
void (*Image::_image_compress_bc_func)(Image *, float, Image::UsedChannels) = nullptr;
void (*Image::_image_compress_bptc_func)(Image *, float, Image::UsedChannels) = nullptr;
@@ -3058,6 +3060,7 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("load_png_from_buffer", "buffer"), &Image::load_png_from_buffer);
ClassDB::bind_method(D_METHOD("load_jpg_from_buffer", "buffer"), &Image::load_jpg_from_buffer);
ClassDB::bind_method(D_METHOD("load_webp_from_buffer", "buffer"), &Image::load_webp_from_buffer);
+ ClassDB::bind_method(D_METHOD("load_tga_from_buffer", "buffer"), &Image::load_tga_from_buffer);
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "_set_data", "_get_data");
@@ -3389,6 +3392,11 @@ Error Image::load_webp_from_buffer(const Vector<uint8_t> &p_array) {
return _load_from_buffer(p_array, _webp_mem_loader_func);
}
+Error Image::load_tga_from_buffer(const Vector<uint8_t> &p_array) {
+ ERR_FAIL_NULL_V_MSG(_tga_mem_loader_func, ERR_UNAVAILABLE, "TGA module was not installed.");
+ return _load_from_buffer(p_array, _tga_mem_loader_func);
+}
+
void Image::convert_rg_to_ra_rgba8() {
ERR_FAIL_COND(format != FORMAT_RGBA8);
ERR_FAIL_COND(!data.size());
diff --git a/core/image.h b/core/image.h
index 53c203998e..711bf5721c 100644
--- a/core/image.h
+++ b/core/image.h
@@ -135,6 +135,7 @@ public:
static ImageMemLoadFunc _png_mem_loader_func;
static ImageMemLoadFunc _jpg_mem_loader_func;
static ImageMemLoadFunc _webp_mem_loader_func;
+ static ImageMemLoadFunc _tga_mem_loader_func;
static void (*_image_compress_bc_func)(Image *, float, UsedChannels p_channels);
static void (*_image_compress_bptc_func)(Image *, float p_lossy_quality, UsedChannels p_channels);
@@ -360,6 +361,7 @@ public:
Error load_png_from_buffer(const Vector<uint8_t> &p_array);
Error load_jpg_from_buffer(const Vector<uint8_t> &p_array);
Error load_webp_from_buffer(const Vector<uint8_t> &p_array);
+ Error load_tga_from_buffer(const Vector<uint8_t> &p_array);
void convert_rg_to_ra_rgba8();
void convert_ra_rgba8_to_rg();
diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp
index dc68c2a9f9..434f6fa300 100644
--- a/core/os/main_loop.cpp
+++ b/core/os/main_loop.cpp
@@ -48,8 +48,10 @@ void MainLoop::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_WM_ABOUT);
BIND_CONSTANT(NOTIFICATION_CRASH);
BIND_CONSTANT(NOTIFICATION_OS_IME_UPDATE);
- BIND_CONSTANT(NOTIFICATION_APP_RESUMED);
- BIND_CONSTANT(NOTIFICATION_APP_PAUSED);
+ BIND_CONSTANT(NOTIFICATION_APPLICATION_RESUMED);
+ BIND_CONSTANT(NOTIFICATION_APPLICATION_PAUSED);
+ BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_IN);
+ BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_OUT);
ADD_SIGNAL(MethodInfo("on_request_permissions_result", PropertyInfo(Variant::STRING, "permission"), PropertyInfo(Variant::BOOL, "granted")));
};
diff --git a/core/os/main_loop.h b/core/os/main_loop.h
index 90790a45a1..2c34cf193c 100644
--- a/core/os/main_loop.h
+++ b/core/os/main_loop.h
@@ -52,8 +52,10 @@ public:
NOTIFICATION_WM_ABOUT = 2011,
NOTIFICATION_CRASH = 2012,
NOTIFICATION_OS_IME_UPDATE = 2013,
- NOTIFICATION_APP_RESUMED = 2014,
- NOTIFICATION_APP_PAUSED = 2015,
+ NOTIFICATION_APPLICATION_RESUMED = 2014,
+ NOTIFICATION_APPLICATION_PAUSED = 2015,
+ NOTIFICATION_APPLICATION_FOCUS_IN = 2016,
+ NOTIFICATION_APPLICATION_FOCUS_OUT = 2017,
};
virtual void init();
diff --git a/core/os/os.cpp b/core/os/os.cpp
index c842be333c..231069fcfb 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -41,6 +41,7 @@
#include <stdarg.h>
OS *OS::singleton = nullptr;
+uint64_t OS::target_ticks = 0;
OS *OS::get_singleton() {
return singleton;
@@ -468,6 +469,41 @@ void OS::close_midi_inputs() {
}
}
+void OS::add_frame_delay(bool p_can_draw) {
+ const uint32_t frame_delay = Engine::get_singleton()->get_frame_delay();
+ if (frame_delay) {
+ // Add fixed frame delay to decrease CPU/GPU usage. This doesn't take
+ // the actual frame time into account.
+ // Due to the high fluctuation of the actual sleep duration, it's not recommended
+ // to use this as a FPS limiter.
+ delay_usec(frame_delay * 1000);
+ }
+
+ // Add a dynamic frame delay to decrease CPU/GPU usage. This takes the
+ // previous frame time into account for a smoother result.
+ uint64_t dynamic_delay = 0;
+ if (is_in_low_processor_usage_mode() || !p_can_draw) {
+ dynamic_delay = get_low_processor_usage_mode_sleep_usec();
+ }
+ const int target_fps = Engine::get_singleton()->get_target_fps();
+ if (target_fps > 0 && !Engine::get_singleton()->is_editor_hint()) {
+ // Override the low processor usage mode sleep delay if the target FPS is lower.
+ dynamic_delay = MAX(dynamic_delay, (uint64_t)(1000000 / target_fps));
+ }
+
+ if (dynamic_delay > 0) {
+ target_ticks += dynamic_delay;
+ uint64_t current_ticks = get_ticks_usec();
+
+ if (current_ticks < target_ticks) {
+ delay_usec(target_ticks - current_ticks);
+ }
+
+ current_ticks = get_ticks_usec();
+ target_ticks = MIN(MAX(target_ticks, current_ticks - dynamic_delay), current_ticks + dynamic_delay);
+ }
+}
+
OS::OS() {
void *volatile stack_bottom;
diff --git a/core/os/os.h b/core/os/os.h
index 04e10518dc..f21c0d4df7 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -43,6 +43,7 @@
class OS {
static OS *singleton;
+ static uint64_t target_ticks;
String _execpath;
List<String> _cmdline;
bool _keep_screen_on = true; // set default value to true, because this had been true before godot 2.0.
@@ -212,6 +213,8 @@ public:
virtual double get_unix_time() const;
virtual void delay_usec(uint32_t p_usec) const = 0;
+ virtual void add_frame_delay(bool p_can_draw);
+
virtual uint64_t get_ticks_usec() const = 0;
uint32_t get_ticks_msec() const;
uint64_t get_splash_tick_msec() const;
diff --git a/doc/classes/PhysicsShapeQueryParameters2D.xml b/doc/classes/PhysicsShapeQueryParameters2D.xml
index 9a162dabbb..63e13954ab 100644
--- a/doc/classes/PhysicsShapeQueryParameters2D.xml
+++ b/doc/classes/PhysicsShapeQueryParameters2D.xml
@@ -9,15 +9,6 @@
<tutorials>
</tutorials>
<methods>
- <method name="set_shape">
- <return type="void">
- </return>
- <argument index="0" name="shape" type="Resource">
- </argument>
- <description>
- Sets the [Shape2D] that will be used for collision/intersection queries.
- </description>
- </method>
</methods>
<members>
<member name="collide_with_areas" type="bool" setter="set_collide_with_areas" getter="is_collide_with_areas_enabled" default="false">
@@ -38,8 +29,24 @@
<member name="motion" type="Vector2" setter="set_motion" getter="get_motion" default="Vector2( 0, 0 )">
The motion of the shape being queried for.
</member>
+ <member name="shape" type="Resource" setter="set_shape" getter="get_shape">
+ The [Shape2D] that will be used for collision/intersection queries. This stores the actual reference which avoids the shape to be released while being used for queries, so always prefer using this over [member shape_rid].
+ </member>
<member name="shape_rid" type="RID" setter="set_shape_rid" getter="get_shape_rid">
- The queried shape's [RID]. See also [method set_shape].
+ The queried shape's [RID] that will be used for collision/intersection queries. Use this over [member shape] if you want to optimize for performance using the Servers API:
+ [codeblock]
+ var shape_rid = PhysicsServer2D.circle_shape_create()
+ var radius = 64
+ PhysicsServer2D.shape_set_data(shape_rid, radius)
+
+ var params = PhysicsShapeQueryParameters2D.new()
+ params.shape_rid = shape_rid
+
+ # Execute physics queries here...
+
+ # Release the shape when done with physics queries.
+ PhysicsServer2D.free_rid(shape_rid)
+ [/codeblock]
</member>
<member name="transform" type="Transform2D" setter="set_transform" getter="get_transform" default="Transform2D( 1, 0, 0, 1, 0, 0 )">
The queried shape's transform matrix.
diff --git a/doc/classes/PhysicsShapeQueryParameters3D.xml b/doc/classes/PhysicsShapeQueryParameters3D.xml
index 6606cfbc59..f4191d4862 100644
--- a/doc/classes/PhysicsShapeQueryParameters3D.xml
+++ b/doc/classes/PhysicsShapeQueryParameters3D.xml
@@ -9,15 +9,6 @@
<tutorials>
</tutorials>
<methods>
- <method name="set_shape">
- <return type="void">
- </return>
- <argument index="0" name="shape" type="Resource">
- </argument>
- <description>
- Sets the [Shape3D] that will be used for collision/intersection queries.
- </description>
- </method>
</methods>
<members>
<member name="collide_with_areas" type="bool" setter="set_collide_with_areas" getter="is_collide_with_areas_enabled" default="false">
@@ -35,8 +26,24 @@
<member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.0">
The collision margin for the shape.
</member>
+ <member name="shape" type="Resource" setter="set_shape" getter="get_shape">
+ The [Shape3D] that will be used for collision/intersection queries. This stores the actual reference which avoids the shape to be released while being used for queries, so always prefer using this over [member shape_rid].
+ </member>
<member name="shape_rid" type="RID" setter="set_shape_rid" getter="get_shape_rid">
- The queried shape's [RID]. See also [method set_shape].
+ The queried shape's [RID] that will be used for collision/intersection queries. Use this over [member shape] if you want to optimize for performance using the Servers API:
+ [codeblock]
+ var shape_rid = PhysicsServer3D.shape_create(PhysicsServer3D.SHAPE_SPHERE)
+ var radius = 2.0
+ PhysicsServer3D.shape_set_data(shape_rid, radius)
+
+ var params = PhysicsShapeQueryParameters3D.new()
+ params.shape_rid = shape_rid
+
+ # Execute physics queries here...
+
+ # Release the shape when done with physics queries.
+ PhysicsServer3D.free_rid(shape_rid)
+ [/codeblock]
</member>
<member name="transform" type="Transform" setter="set_transform" getter="get_transform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )">
The queried shape's transform matrix.
diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h
index 7af7678f63..636a885c89 100644
--- a/drivers/dummy/rasterizer_dummy.h
+++ b/drivers/dummy/rasterizer_dummy.h
@@ -51,6 +51,14 @@ public:
int get_directional_light_shadow_size(RID p_light_intance) { return 0; }
void set_directional_shadow_count(int p_count) {}
+ /* SDFGI UPDATE */
+
+ virtual void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) {}
+ virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const { return 0; }
+ virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const { return AABB(); }
+ virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const { return 0; }
+ virtual void sdfgi_update_probes(RID p_render_buffers, RID p_environment, const RID *p_directional_light_instances, uint32_t p_directional_light_count, const RID *p_positional_light_instances, uint32_t p_positional_light_count) {}
+
/* SKY API */
RID sky_create() { return RID(); }
@@ -87,6 +95,11 @@ public:
virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) {}
virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) {}
+ virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, bool p_enhance_ssr, float p_energy, float p_normal_bias, float p_probe_bias) {}
+
+ virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) {}
+ virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) {}
+
void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) {}
void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) {}
@@ -114,6 +127,7 @@ public:
RID light_instance_create(RID p_light) { return RID(); }
void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) {}
+ virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) {}
void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) {}
void light_instance_mark_visible(RID p_light_instance) {}
@@ -137,9 +151,13 @@ public:
virtual bool gi_probe_needs_update(RID p_probe) const { return false; }
virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) {}
+ virtual void gi_probe_set_quality(RS::GIProbeQuality) {}
+
virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {}
void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) {}
virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) {}
+ virtual void render_sdfgi(RID p_render_buffers, int p_region, InstanceBase **p_cull_result, int p_cull_count) {}
+ virtual void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const RID **p_positional_light_cull_result, const uint32_t *p_positional_light_cull_count) {}
void set_scene_pass(uint64_t p_pass) {}
virtual void set_time(double p_time, double p_step) {}
@@ -148,7 +166,7 @@ public:
virtual RID render_buffers_create() { return RID(); }
virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa) {}
- virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_curve) {}
+ virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) {}
virtual bool screen_space_roughness_limiter_is_active() const { return false; }
virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) {}
@@ -158,6 +176,7 @@ public:
bool free(RID p_rid) { return true; }
virtual void update() {}
+ virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) {}
RasterizerSceneDummy() {}
~RasterizerSceneDummy() {}
@@ -576,7 +595,8 @@ public:
void light_set_negative(RID p_light, bool p_enable) {}
void light_set_cull_mask(RID p_light, uint32_t p_mask) {}
void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {}
- void light_set_use_gi(RID p_light, bool p_enabled) {}
+ void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) {}
+ void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) {}
void light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {}
@@ -595,7 +615,8 @@ public:
AABB light_get_aabb(RID p_light) const { return AABB(); }
float light_get_param(RID p_light, RS::LightParam p_param) { return 0.0; }
Color light_get_color(RID p_light) { return Color(); }
- bool light_get_use_gi(RID p_light) { return false; }
+ virtual RS::LightBakeMode light_get_bake_mode(RID p_light) { return RS::LIGHT_BAKE_DISABLED; }
+ virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) { return 0; }
uint64_t light_get_version(RID p_light) const { return 0; }
/* PROBE API */
@@ -604,9 +625,9 @@ public:
void reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) {}
void reflection_probe_set_intensity(RID p_probe, float p_intensity) {}
- void reflection_probe_set_interior_ambient(RID p_probe, const Color &p_ambient) {}
- void reflection_probe_set_interior_ambient_energy(RID p_probe, float p_energy) {}
- void reflection_probe_set_interior_ambient_probe_contribution(RID p_probe, float p_contrib) {}
+ void reflection_probe_set_ambient_mode(RID p_probe, RS::ReflectionProbeAmbientMode p_mode) {}
+ void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) {}
+ void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) {}
void reflection_probe_set_max_distance(RID p_probe, float p_distance) {}
void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {}
void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {}
diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp
index d2b9405552..4392538737 100644
--- a/editor/editor_help_search.cpp
+++ b/editor/editor_help_search.cpp
@@ -332,17 +332,10 @@ bool EditorHelpSearch::Runner::_phase_match_classes() {
if (search_flags & SEARCH_METHODS) {
for (int i = 0; i < class_doc.methods.size(); i++) {
String method_name = (search_flags & SEARCH_CASE_SENSITIVE) ? class_doc.methods[i].name : class_doc.methods[i].name.to_lower();
- String aux_term = (search_flags & SEARCH_CASE_SENSITIVE) ? term : term.to_lower();
-
- if (aux_term.begins_with(".")) {
- aux_term = aux_term.right(1);
- }
-
- if (aux_term.ends_with("(")) {
- aux_term = aux_term.left(aux_term.length() - 1).strip_edges();
- }
-
- if (aux_term.is_subsequence_of(method_name)) {
+ if (method_name.find(term) > -1 ||
+ (term.begins_with(".") && method_name.begins_with(term.right(1))) ||
+ (term.ends_with("(") && method_name.ends_with(term.left(term.length() - 1).strip_edges())) ||
+ (term.begins_with(".") && term.ends_with("(") && method_name == term.substr(1, term.length() - 2).strip_edges())) {
match.methods.push_back(const_cast<DocData::MethodDoc *>(&class_doc.methods[i]));
}
}
@@ -448,9 +441,9 @@ bool EditorHelpSearch::Runner::_phase_select_match() {
bool EditorHelpSearch::Runner::_match_string(const String &p_term, const String &p_string) const {
if (search_flags & SEARCH_CASE_SENSITIVE) {
- return p_term.is_subsequence_of(p_string);
+ return p_string.find(p_term) > -1;
} else {
- return p_term.is_subsequence_ofi(p_string);
+ return p_string.findn(p_term) > -1;
}
}
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index f2f8805aaf..8909fb2cfe 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -435,14 +435,14 @@ void EditorNode::_notification(int p_what) {
/* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */
} break;
- case NOTIFICATION_WM_FOCUS_IN: {
+ case NOTIFICATION_APPLICATION_FOCUS_IN: {
// Restore the original FPS cap after focusing back on the editor
OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/low_processor_mode_sleep_usec")));
EditorFileSystem::get_singleton()->scan_changes();
} break;
- case NOTIFICATION_WM_FOCUS_OUT: {
+ case NOTIFICATION_APPLICATION_FOCUS_OUT: {
// Set a low FPS cap to decrease CPU/GPU usage while the editor is unfocused
OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/unfocused_low_processor_mode_sleep_usec")));
} break;
diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp
index b5f1133a9e..fe49198e8f 100644
--- a/editor/editor_plugin_settings.cpp
+++ b/editor/editor_plugin_settings.cpp
@@ -39,7 +39,7 @@
#include "scene/gui/margin_container.h"
void EditorPluginSettings::_notification(int p_what) {
- if (p_what == NOTIFICATION_WM_FOCUS_IN) {
+ if (p_what == NOTIFICATION_WM_WINDOW_FOCUS_IN) {
update_plugins();
} else if (p_what == Node::NOTIFICATION_READY) {
plugin_config_dialog->connect_compat("plugin_ready", EditorNode::get_singleton(), "_on_plugin_ready");
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index 67d92c4839..d76a3d2da7 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -182,8 +182,8 @@ void EditorSpinSlider::_grabber_gui_input(const Ref<InputEvent> &p_event) {
}
void EditorSpinSlider::_notification(int p_what) {
- if (p_what == NOTIFICATION_WM_FOCUS_OUT ||
- p_what == NOTIFICATION_WM_FOCUS_IN ||
+ if (p_what == NOTIFICATION_WM_WINDOW_FOCUS_OUT ||
+ p_what == NOTIFICATION_WM_WINDOW_FOCUS_IN ||
p_what == NOTIFICATION_EXIT_TREE) {
if (grabbing_spinner) {
grabber->hide();
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 96079d5418..fd415d40da 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -1337,7 +1337,7 @@ void ScriptEditor::_notification(int p_what) {
editor->disconnect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop));
} break;
- case NOTIFICATION_WM_FOCUS_IN: {
+ case NOTIFICATION_WM_WINDOW_FOCUS_IN: {
_test_script_times_on_disk();
_update_modified_scripts_for_external_editor();
} break;
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 0c3a44e4cd..7dd0b8a238 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -338,7 +338,7 @@ void ShaderEditor::_menu_option(int p_option) {
}
void ShaderEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_WM_FOCUS_IN) {
+ if (p_what == NOTIFICATION_WM_WINDOW_FOCUS_IN) {
_check_for_external_edit();
}
}
diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp
index 0ac29f68f6..f15a801530 100644
--- a/editor/plugins/shader_file_editor_plugin.cpp
+++ b/editor/plugins/shader_file_editor_plugin.cpp
@@ -200,7 +200,7 @@ void ShaderFileEditor::_update_options() {
}
void ShaderFileEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_WM_FOCUS_IN) {
+ if (p_what == NOTIFICATION_WM_WINDOW_FOCUS_IN) {
if (is_visible_in_tree() && shader_file.is_valid()) {
_update_options();
}
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index 3a92818779..762f42abeb 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -780,7 +780,7 @@ void TextureRegionEditor::_notification(int p_what) {
_update_autoslice();
}
} break;
- case NOTIFICATION_WM_FOCUS_IN: {
+ case NOTIFICATION_WM_WINDOW_FOCUS_IN: {
// This happens when the user leaves the Editor and returns,
// they could have changed the textures, so the cache is cleared.
cache_map.clear();
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index dd42ed9760..04ac809d03 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -350,17 +350,22 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (!profile_allow_editing) {
break;
}
- String preferred = "";
- Node *current_edited_scene_root = EditorNode::get_singleton()->get_edited_scene();
+ // Prefer nodes that inherit from the current scene root.
+ Node *current_edited_scene_root = EditorNode::get_singleton()->get_edited_scene();
if (current_edited_scene_root) {
- if (ClassDB::is_parent_class(current_edited_scene_root->get_class_name(), "Node2D")) {
- preferred = "Node2D";
- } else if (ClassDB::is_parent_class(current_edited_scene_root->get_class_name(), "Node3D")) {
- preferred = "Node3D";
+ static const String preferred_types[] = { "Node2D", "Node3D", "Control" };
+
+ StringName root_class = current_edited_scene_root->get_class_name();
+
+ for (int i = 0; i < preferred_types->size(); i++) {
+ if (ClassDB::is_parent_class(root_class, preferred_types[i])) {
+ create_dialog->set_preferred_search_result_type(preferred_types[i]);
+ break;
+ }
}
}
- create_dialog->set_preferred_search_result_type(preferred);
+
create_dialog->popup_create(true);
} break;
case TOOL_INSTANCE: {
diff --git a/main/main.cpp b/main/main.cpp
index 00760b39b0..0cccccdab3 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -2115,7 +2115,6 @@ bool Main::start() {
*/
uint64_t Main::last_ticks = 0;
-uint64_t Main::target_ticks = 0;
uint32_t Main::frames = 0;
uint32_t Main::frame = 0;
bool Main::force_redraw_requested = false;
@@ -2266,38 +2265,7 @@ bool Main::iteration() {
return exit;
}
- const uint32_t frame_delay = Engine::get_singleton()->get_frame_delay();
- if (frame_delay) {
- // Add fixed frame delay to decrease CPU/GPU usage. This doesn't take
- // the actual frame time into account.
- // Due to the high fluctuation of the actual sleep duration, it's not recommended
- // to use this as a FPS limiter.
- OS::get_singleton()->delay_usec(frame_delay * 1000);
- }
-
- // Add a dynamic frame delay to decrease CPU/GPU usage. This takes the
- // previous frame time into account for a smoother result.
- uint64_t dynamic_delay = 0;
- if (OS::get_singleton()->is_in_low_processor_usage_mode() || !DisplayServer::get_singleton()->window_can_draw()) {
- dynamic_delay = OS::get_singleton()->get_low_processor_usage_mode_sleep_usec();
- }
- const int target_fps = Engine::get_singleton()->get_target_fps();
- if (target_fps > 0 && !Engine::get_singleton()->is_editor_hint()) {
- // Override the low processor usage mode sleep delay if the target FPS is lower.
- dynamic_delay = MAX(dynamic_delay, (uint64_t)(1000000 / target_fps));
- }
-
- if (dynamic_delay > 0) {
- target_ticks += dynamic_delay;
- uint64_t current_ticks = OS::get_singleton()->get_ticks_usec();
-
- if (current_ticks < target_ticks) {
- OS::get_singleton()->delay_usec(target_ticks - current_ticks);
- }
-
- current_ticks = OS::get_singleton()->get_ticks_usec();
- target_ticks = MIN(MAX(target_ticks, current_ticks - dynamic_delay), current_ticks + dynamic_delay);
- }
+ OS::get_singleton()->add_frame_delay(DisplayServer::get_singleton()->window_can_draw());
#ifdef TOOLS_ENABLED
if (auto_build_solutions) {
diff --git a/main/main.h b/main/main.h
index ab6917a65c..308128735c 100644
--- a/main/main.h
+++ b/main/main.h
@@ -38,7 +38,6 @@
class Main {
static void print_help(const char *p_binary);
static uint64_t last_ticks;
- static uint64_t target_ticks;
static uint32_t frames;
static uint32_t frame;
static bool force_redraw_requested;
diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp
index d0c9bf5d38..6c0a3a4ca3 100644
--- a/modules/csg/csg.cpp
+++ b/modules/csg/csg.cpp
@@ -523,7 +523,7 @@ void CSGBrushOperation::MeshMerge::_add_distance(List<real_t> &r_intersectionsA,
// Check if distance exists.
for (const List<real_t>::Element *E = intersections.front(); E; E = E->next()) {
- if (Math::abs(**E - p_distance) < vertex_snap) {
+ if (Math::is_equal_approx(**E, p_distance)) {
return;
}
}
@@ -1068,15 +1068,6 @@ void CSGBrushOperation::Build2DFaces::_find_edge_intersections(const Vector2 p_s
break;
}
- // Don't create degenerate triangles.
- Vector2 split_edge1[2] = { vertices[new_vertex_idx].point, edge_points[0] };
- Vector2 split_edge2[2] = { vertices[new_vertex_idx].point, edge_points[1] };
- Vector2 new_edge[2] = { vertices[new_vertex_idx].point, vertices[opposite_vertex_idx].point };
- if (are_segements_parallel(split_edge1, new_edge, vertex_snap2) &&
- are_segements_parallel(split_edge2, new_edge, vertex_snap2)) {
- break;
- }
-
// If opposite point is on the segemnt, add its index to segment indices too.
Vector2 closest_point = Geometry2D::get_closest_point_to_segment(vertices[opposite_vertex_idx].point, p_segment_points);
if ((closest_point - vertices[opposite_vertex_idx].point).length_squared() < vertex_snap2) {
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index 06b9534fce..94aa2125c2 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -1853,7 +1853,7 @@ void NativeReloadNode::_notification(int p_what) {
#ifdef TOOLS_ENABLED
switch (p_what) {
- case NOTIFICATION_WM_FOCUS_OUT: {
+ case NOTIFICATION_APPLICATION_FOCUS_OUT: {
if (unloaded) {
break;
}
@@ -1887,7 +1887,7 @@ void NativeReloadNode::_notification(int p_what) {
} break;
- case NOTIFICATION_WM_FOCUS_IN: {
+ case NOTIFICATION_APPLICATION_FOCUS_IN: {
if (!unloaded) {
break;
}
diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp
index ce889a4928..1475d24792 100644
--- a/modules/tga/image_loader_tga.cpp
+++ b/modules/tga/image_loader_tga.cpp
@@ -30,6 +30,8 @@
#include "image_loader_tga.h"
+#include "core/error_macros.h"
+#include "core/io/file_access_memory.h"
#include "core/os/os.h"
#include "core/print_string.h"
@@ -311,5 +313,17 @@ void ImageLoaderTGA::get_recognized_extensions(List<String> *p_extensions) const
p_extensions->push_back("tga");
}
+static Ref<Image> _tga_mem_loader_func(const uint8_t *p_png, int p_size) {
+ FileAccessMemory memfile;
+ Error open_memfile_error = memfile.open_custom(p_png, p_size);
+ ERR_FAIL_COND_V_MSG(open_memfile_error, Ref<Image>(), "Could not create memfile for TGA image buffer.");
+ Ref<Image> img;
+ img.instance();
+ Error load_error = ImageLoaderTGA().load_image(img, &memfile, false, 1.0f);
+ ERR_FAIL_COND_V_MSG(load_error, Ref<Image>(), "Failed to load TGA image.");
+ return img;
+}
+
ImageLoaderTGA::ImageLoaderTGA() {
+ Image::_tga_mem_loader_func = _tga_mem_loader_func;
}
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index a032ae8d2c..4610b94363 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -457,7 +457,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererResumed(JNI
return;
if (os_android->get_main_loop()) {
- os_android->get_main_loop()->notification(MainLoop::NOTIFICATION_APP_RESUMED);
+ os_android->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_RESUMED);
}
}
@@ -466,7 +466,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererPaused(JNIE
return;
if (os_android->get_main_loop()) {
- os_android->get_main_loop()->notification(MainLoop::NOTIFICATION_APP_PAUSED);
+ os_android->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_PAUSED);
}
}
}
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index 920fd24c4a..93f6e3540a 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -197,6 +197,18 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
}
+- (void)applicationDidResignActive:(NSNotification *)notification {
+ if (OS_OSX::get_singleton()->get_main_loop()) {
+ OS_OSX::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT);
+ }
+}
+
+- (void)applicationDidBecomeActive:(NSNotification *)notification {
+ if (OS_OSX::get_singleton()->get_main_loop()) {
+ OS_OSX::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN);
+ }
+}
+
- (void)globalMenuCallback:(id)sender {
if (![sender representedObject])
return;
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index f47afcc4e5..61dc156fbc 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -1790,6 +1790,12 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
// Restore mouse mode
_set_mouse_mode_impl(mouse_mode);
+ if (!app_focused) {
+ if (OS::get_singleton()->get_main_loop()) {
+ OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN);
+ }
+ app_focused = true;
+ }
break;
}
case WM_KILLFOCUS: {
@@ -1805,6 +1811,19 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
touch_state.clear();
+ bool self_steal = false;
+ HWND new_hwnd = (HWND)wParam;
+ if (IsWindow(new_hwnd)) {
+ self_steal = true;
+ }
+
+ if (!self_steal) {
+ if (OS::get_singleton()->get_main_loop()) {
+ OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT);
+ }
+ app_focused = false;
+ }
+
break;
}
case WM_ACTIVATE: // Watch For Window Activate Message
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index 995ced0809..8433bb449b 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -317,6 +317,7 @@ private:
int pressrc;
HINSTANCE hInstance; // Holds The Instance Of The Application
String rendering_driver;
+ bool app_focused = false;
struct WindowData {
HWND hWnd;
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index c6897fc684..bacc65c7bf 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -51,7 +51,9 @@ void AcceptDialog::_input_from_window(const Ref<InputEvent> &p_event) {
}
void AcceptDialog::_parent_focused() {
- _cancel_pressed();
+ if (!is_exclusive()) {
+ _cancel_pressed();
+ }
}
void AcceptDialog::_notification(int p_what) {
@@ -295,6 +297,7 @@ AcceptDialog::AcceptDialog() {
set_wrap_controls(true);
set_visible(false);
set_transient(true);
+ set_exclusive(true);
bg = memnew(Panel);
add_child(bg);
diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h
index 5d7b6272bf..81664733a3 100644
--- a/scene/gui/dialogs.h
+++ b/scene/gui/dialogs.h
@@ -44,6 +44,7 @@ class LineEdit;
class AcceptDialog : public Window {
GDCLASS(AcceptDialog, Window);
+public:
Window *parent_visible;
Panel *bg;
HBoxContainer *hbc;
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index ba55927980..251f31ce4e 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -688,12 +688,12 @@ void LineEdit::_notification(int p_what) {
update_placeholder_width();
update();
} break;
- case NOTIFICATION_WM_FOCUS_IN: {
+ case NOTIFICATION_WM_WINDOW_FOCUS_IN: {
window_has_focus = true;
draw_caret = true;
update();
} break;
- case NOTIFICATION_WM_FOCUS_OUT: {
+ case NOTIFICATION_WM_WINDOW_FOCUS_OUT: {
window_has_focus = false;
draw_caret = false;
update();
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index c7fc8dbe43..3860ce61e9 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -603,12 +603,12 @@ void TextEdit::_notification(int p_what) {
_update_wrap_at();
syntax_highlighting_cache.clear();
} break;
- case NOTIFICATION_WM_FOCUS_IN: {
+ case NOTIFICATION_WM_WINDOW_FOCUS_IN: {
window_has_focus = true;
draw_caret = true;
update();
} break;
- case NOTIFICATION_WM_FOCUS_OUT: {
+ case NOTIFICATION_WM_WINDOW_FOCUS_OUT: {
window_has_focus = false;
draw_caret = false;
update();
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 1bf828a03b..88f9730f78 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -2857,8 +2857,8 @@ void Node::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_WM_MOUSE_ENTER);
BIND_CONSTANT(NOTIFICATION_WM_MOUSE_EXIT);
- BIND_CONSTANT(NOTIFICATION_WM_FOCUS_IN);
- BIND_CONSTANT(NOTIFICATION_WM_FOCUS_OUT);
+ BIND_CONSTANT(NOTIFICATION_WM_WINDOW_FOCUS_IN);
+ BIND_CONSTANT(NOTIFICATION_WM_WINDOW_FOCUS_OUT);
BIND_CONSTANT(NOTIFICATION_WM_CLOSE_REQUEST);
BIND_CONSTANT(NOTIFICATION_WM_GO_BACK_REQUEST);
BIND_CONSTANT(NOTIFICATION_WM_SIZE_CHANGED);
@@ -2867,8 +2867,10 @@ void Node::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_WM_ABOUT);
BIND_CONSTANT(NOTIFICATION_CRASH);
BIND_CONSTANT(NOTIFICATION_OS_IME_UPDATE);
- BIND_CONSTANT(NOTIFICATION_APP_RESUMED);
- BIND_CONSTANT(NOTIFICATION_APP_PAUSED);
+ BIND_CONSTANT(NOTIFICATION_APPLICATION_RESUMED);
+ BIND_CONSTANT(NOTIFICATION_APPLICATION_PAUSED);
+ BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_IN);
+ BIND_CONSTANT(NOTIFICATION_APPLICATION_FOCUS_OUT);
BIND_ENUM_CONSTANT(PAUSE_MODE_INHERIT);
BIND_ENUM_CONSTANT(PAUSE_MODE_STOP);
diff --git a/scene/main/node.h b/scene/main/node.h
index 7595aabd9a..c3972e2d8e 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -243,8 +243,8 @@ public:
NOTIFICATION_WM_MOUSE_ENTER = 1002,
NOTIFICATION_WM_MOUSE_EXIT = 1003,
- NOTIFICATION_WM_FOCUS_IN = 1004,
- NOTIFICATION_WM_FOCUS_OUT = 1005,
+ NOTIFICATION_WM_WINDOW_FOCUS_IN = 1004,
+ NOTIFICATION_WM_WINDOW_FOCUS_OUT = 1005,
NOTIFICATION_WM_CLOSE_REQUEST = 1006,
NOTIFICATION_WM_GO_BACK_REQUEST = 1007,
NOTIFICATION_WM_SIZE_CHANGED = 1008,
@@ -255,8 +255,10 @@ public:
NOTIFICATION_WM_ABOUT = MainLoop::NOTIFICATION_WM_ABOUT,
NOTIFICATION_CRASH = MainLoop::NOTIFICATION_CRASH,
NOTIFICATION_OS_IME_UPDATE = MainLoop::NOTIFICATION_OS_IME_UPDATE,
- NOTIFICATION_APP_RESUMED = MainLoop::NOTIFICATION_APP_RESUMED,
- NOTIFICATION_APP_PAUSED = MainLoop::NOTIFICATION_APP_PAUSED
+ NOTIFICATION_APPLICATION_RESUMED = MainLoop::NOTIFICATION_APPLICATION_RESUMED,
+ NOTIFICATION_APPLICATION_PAUSED = MainLoop::NOTIFICATION_APPLICATION_PAUSED,
+ NOTIFICATION_APPLICATION_FOCUS_IN = MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN,
+ NOTIFICATION_APPLICATION_FOCUS_OUT = MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT
};
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 3c3c7533a3..a418883506 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -587,9 +587,11 @@ void SceneTree::_notification(int p_notification) {
case NOTIFICATION_OS_IME_UPDATE:
case NOTIFICATION_WM_ABOUT:
case NOTIFICATION_CRASH:
- case NOTIFICATION_APP_RESUMED:
- case NOTIFICATION_APP_PAUSED: {
- get_root()->propagate_notification(p_notification);
+ case NOTIFICATION_APPLICATION_RESUMED:
+ case NOTIFICATION_APPLICATION_PAUSED:
+ case NOTIFICATION_APPLICATION_FOCUS_IN:
+ case NOTIFICATION_APPLICATION_FOCUS_OUT: {
+ get_root()->propagate_notification(p_notification); //pass these to nodes, since they are mirrored
} break;
default:
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 606f39370b..8042f02fa6 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -815,7 +815,7 @@ void Viewport::_notification(int p_what) {
} break;
case NOTIFICATION_WM_MOUSE_EXIT:
- case NOTIFICATION_WM_FOCUS_OUT: {
+ case NOTIFICATION_WM_WINDOW_FOCUS_OUT: {
_drop_physics_mouseover();
if (gui.mouse_focus && !gui.forced_mouse_focus) {
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index a9be8a1eff..7f2160c6a5 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -316,13 +316,13 @@ void Window::_event_callback(DisplayServer::WindowEvent p_event) {
} break;
case DisplayServer::WINDOW_EVENT_FOCUS_IN: {
focused = true;
- _propagate_window_notification(this, NOTIFICATION_WM_FOCUS_IN);
+ _propagate_window_notification(this, NOTIFICATION_WM_WINDOW_FOCUS_IN);
emit_signal("focus_entered");
} break;
case DisplayServer::WINDOW_EVENT_FOCUS_OUT: {
focused = false;
- _propagate_window_notification(this, NOTIFICATION_WM_FOCUS_OUT);
+ _propagate_window_notification(this, NOTIFICATION_WM_WINDOW_FOCUS_OUT);
emit_signal("focus_exited");
} break;
case DisplayServer::WINDOW_EVENT_CLOSE_REQUEST: {
@@ -398,6 +398,18 @@ void Window::set_visible(bool p_visible) {
emit_signal(SceneStringNames::get_singleton()->visibility_changed);
RS::get_singleton()->viewport_set_active(get_viewport_rid(), visible);
+
+ //update transient exclusive
+ if (transient_parent) {
+ if (exclusive && visible) {
+ ERR_FAIL_COND_MSG(transient_parent->exclusive_child && transient_parent->exclusive_child != this, "Transient parent has another exclusive child.");
+ transient_parent->exclusive_child = this;
+ } else {
+ if (transient_parent->exclusive_child == this) {
+ transient_parent->exclusive_child = nullptr;
+ }
+ }
+ }
}
void Window::_clear_transient() {
diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp
index 080b8c61ad..19b575a259 100644
--- a/servers/physics_server_2d.cpp
+++ b/servers/physics_server_2d.cpp
@@ -132,13 +132,21 @@ PhysicsDirectBodyState2D::PhysicsDirectBodyState2D() {}
///////////////////////////////////////////////////////
-void PhysicsShapeQueryParameters2D::set_shape(const RES &p_shape) {
- ERR_FAIL_COND(p_shape.is_null());
- shape = p_shape->get_rid();
+void PhysicsShapeQueryParameters2D::set_shape(const RES &p_shape_ref) {
+ ERR_FAIL_COND(p_shape_ref.is_null());
+ shape_ref = p_shape_ref;
+ shape = p_shape_ref->get_rid();
+}
+
+RES PhysicsShapeQueryParameters2D::get_shape() const {
+ return shape_ref;
}
void PhysicsShapeQueryParameters2D::set_shape_rid(const RID &p_shape) {
- shape = p_shape;
+ if (shape != p_shape) {
+ shape_ref = RES();
+ shape = p_shape;
+ }
}
RID PhysicsShapeQueryParameters2D::get_shape_rid() const {
@@ -212,6 +220,7 @@ bool PhysicsShapeQueryParameters2D::is_collide_with_areas_enabled() const {
void PhysicsShapeQueryParameters2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shape", "shape"), &PhysicsShapeQueryParameters2D::set_shape);
+ ClassDB::bind_method(D_METHOD("get_shape"), &PhysicsShapeQueryParameters2D::get_shape);
ClassDB::bind_method(D_METHOD("set_shape_rid", "shape"), &PhysicsShapeQueryParameters2D::set_shape_rid);
ClassDB::bind_method(D_METHOD("get_shape_rid"), &PhysicsShapeQueryParameters2D::get_shape_rid);
@@ -240,7 +249,7 @@ void PhysicsShapeQueryParameters2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude", PROPERTY_HINT_NONE, itos(Variant::_RID) + ":"), "set_exclude", "get_exclude");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_margin", "get_margin");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion"), "set_motion", "get_motion");
- //ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", ""); // FIXME: Lacks a getter
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", "get_shape");
ADD_PROPERTY(PropertyInfo(Variant::_RID, "shape_rid"), "set_shape_rid", "get_shape_rid");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform"), "set_transform", "get_transform");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies"), "set_collide_with_bodies", "is_collide_with_bodies_enabled");
diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h
index 549a78aa1f..b2f2e786ee 100644
--- a/servers/physics_server_2d.h
+++ b/servers/physics_server_2d.h
@@ -98,6 +98,8 @@ class PhysicsShapeQueryResult2D;
class PhysicsShapeQueryParameters2D : public Reference {
GDCLASS(PhysicsShapeQueryParameters2D, Reference);
friend class PhysicsDirectSpaceState2D;
+
+ RES shape_ref;
RID shape;
Transform2D transform;
Vector2 motion;
@@ -112,7 +114,8 @@ protected:
static void _bind_methods();
public:
- void set_shape(const RES &p_shape);
+ void set_shape(const RES &p_shape_ref);
+ RES get_shape() const;
void set_shape_rid(const RID &p_shape);
RID get_shape_rid() const;
diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp
index 9668358710..3b361fee55 100644
--- a/servers/physics_server_3d.cpp
+++ b/servers/physics_server_3d.cpp
@@ -136,13 +136,21 @@ PhysicsDirectBodyState3D::PhysicsDirectBodyState3D() {}
///////////////////////////////////////////////////////
-void PhysicsShapeQueryParameters3D::set_shape(const RES &p_shape) {
- ERR_FAIL_COND(p_shape.is_null());
- shape = p_shape->get_rid();
+void PhysicsShapeQueryParameters3D::set_shape(const RES &p_shape_ref) {
+ ERR_FAIL_COND(p_shape_ref.is_null());
+ shape_ref = p_shape_ref;
+ shape = p_shape_ref->get_rid();
+}
+
+RES PhysicsShapeQueryParameters3D::get_shape() const {
+ return shape_ref;
}
void PhysicsShapeQueryParameters3D::set_shape_rid(const RID &p_shape) {
- shape = p_shape;
+ if (shape != p_shape) {
+ shape_ref = RES();
+ shape = p_shape;
+ }
}
RID PhysicsShapeQueryParameters3D::get_shape_rid() const {
@@ -208,6 +216,7 @@ bool PhysicsShapeQueryParameters3D::is_collide_with_areas_enabled() const {
void PhysicsShapeQueryParameters3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shape", "shape"), &PhysicsShapeQueryParameters3D::set_shape);
+ ClassDB::bind_method(D_METHOD("get_shape"), &PhysicsShapeQueryParameters3D::get_shape);
ClassDB::bind_method(D_METHOD("set_shape_rid", "shape"), &PhysicsShapeQueryParameters3D::set_shape_rid);
ClassDB::bind_method(D_METHOD("get_shape_rid"), &PhysicsShapeQueryParameters3D::get_shape_rid);
@@ -232,7 +241,7 @@ void PhysicsShapeQueryParameters3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude", PROPERTY_HINT_NONE, itos(Variant::_RID) + ":"), "set_exclude", "get_exclude");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_margin", "get_margin");
- //ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D"), "set_shape", ""); // FIXME: Lacks a getter
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape3D"), "set_shape", "get_shape");
ADD_PROPERTY(PropertyInfo(Variant::_RID, "shape_rid"), "set_shape_rid", "get_shape_rid");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "transform"), "set_transform", "get_transform");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies"), "set_collide_with_bodies", "is_collide_with_bodies_enabled");
diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h
index 2465b40d3e..1cfa4d8565 100644
--- a/servers/physics_server_3d.h
+++ b/servers/physics_server_3d.h
@@ -100,6 +100,7 @@ class PhysicsShapeQueryParameters3D : public Reference {
GDCLASS(PhysicsShapeQueryParameters3D, Reference);
friend class PhysicsDirectSpaceState3D;
+ RES shape_ref;
RID shape;
Transform transform;
float margin;
@@ -113,7 +114,8 @@ protected:
static void _bind_methods();
public:
- void set_shape(const RES &p_shape);
+ void set_shape(const RES &p_shape_ref);
+ RES get_shape() const;
void set_shape_rid(const RID &p_shape);
RID get_shape_rid() const;