diff options
24 files changed, 254 insertions, 299 deletions
diff --git a/doc/classes/NavigationServer3D.xml b/doc/classes/NavigationServer3D.xml index 16b850866a..1feb363999 100644 --- a/doc/classes/NavigationServer3D.xml +++ b/doc/classes/NavigationServer3D.xml @@ -422,15 +422,6 @@ Sets the map up direction. </description> </method> - <method name="process"> - <return type="void" /> - <param index="0" name="delta_time" type="float" /> - <description> - Process the collision avoidance agents. - The result of this process is needed by the physics server, so this must be called in the main thread. - [b]Note:[/b] This function is not thread safe. - </description> - </method> <method name="query_path" qualifiers="const"> <return type="void" /> <param index="0" name="parameters" type="NavigationPathQueryParameters3D" /> diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index 49bb65b64d..5985af53fc 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -373,7 +373,7 @@ <return type="void" /> <param index="0" name="data" type="Variant" /> <description> - Adds a [code][meta][/code] tag to the tag stack. Similar to the BBCode [code][url=something]{text}[/url][/code], but supports non-[String] metadata types. + Adds a meta tag to the tag stack. Similar to the BBCode [code][url=something]{text}[/url][/code], but supports non-[String] metadata types. </description> </method> <method name="push_mono"> @@ -625,60 +625,6 @@ <constant name="LIST_DOTS" value="3" enum="ListType"> Each list item has a filled circle marker. </constant> - <constant name="ITEM_FRAME" value="0" enum="ItemType"> - </constant> - <constant name="ITEM_TEXT" value="1" enum="ItemType"> - </constant> - <constant name="ITEM_IMAGE" value="2" enum="ItemType"> - </constant> - <constant name="ITEM_NEWLINE" value="3" enum="ItemType"> - </constant> - <constant name="ITEM_FONT" value="4" enum="ItemType"> - </constant> - <constant name="ITEM_FONT_SIZE" value="5" enum="ItemType"> - </constant> - <constant name="ITEM_FONT_FEATURES" value="6" enum="ItemType"> - </constant> - <constant name="ITEM_COLOR" value="7" enum="ItemType"> - </constant> - <constant name="ITEM_OUTLINE_SIZE" value="8" enum="ItemType"> - </constant> - <constant name="ITEM_OUTLINE_COLOR" value="9" enum="ItemType"> - </constant> - <constant name="ITEM_UNDERLINE" value="10" enum="ItemType"> - </constant> - <constant name="ITEM_STRIKETHROUGH" value="11" enum="ItemType"> - </constant> - <constant name="ITEM_PARAGRAPH" value="12" enum="ItemType"> - </constant> - <constant name="ITEM_INDENT" value="13" enum="ItemType"> - </constant> - <constant name="ITEM_LIST" value="14" enum="ItemType"> - </constant> - <constant name="ITEM_TABLE" value="15" enum="ItemType"> - </constant> - <constant name="ITEM_FADE" value="16" enum="ItemType"> - </constant> - <constant name="ITEM_SHAKE" value="17" enum="ItemType"> - </constant> - <constant name="ITEM_WAVE" value="18" enum="ItemType"> - </constant> - <constant name="ITEM_TORNADO" value="19" enum="ItemType"> - </constant> - <constant name="ITEM_RAINBOW" value="20" enum="ItemType"> - </constant> - <constant name="ITEM_BGCOLOR" value="21" enum="ItemType"> - </constant> - <constant name="ITEM_FGCOLOR" value="22" enum="ItemType"> - </constant> - <constant name="ITEM_META" value="23" enum="ItemType"> - </constant> - <constant name="ITEM_HINT" value="24" enum="ItemType"> - </constant> - <constant name="ITEM_DROPCAP" value="25" enum="ItemType"> - </constant> - <constant name="ITEM_CUSTOMFX" value="26" enum="ItemType"> - </constant> <constant name="MENU_COPY" value="0" enum="MenuItems"> Copies the selected text. </constant> diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 2e3e6263ed..600aa908cc 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -306,6 +306,15 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display glReadBuffer(GL_COLOR_ATTACHMENT0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); + + if (p_screen_rect.position != Vector2()) { + // Viewport doesn't cover entire window so clear window to black before blitting. + Size2i win_size = DisplayServer::get_singleton()->window_get_size(); + glViewport(0, 0, win_size.width, win_size.height); + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + } + Vector2i screen_rect_end = p_screen_rect.get_end(); glBlitFramebuffer(0, 0, rt->size.x, rt->size.y, p_screen_rect.position.x, flip_y ? screen_rect_end.y : p_screen_rect.position.y, screen_rect_end.x, flip_y ? p_screen_rect.position.y : screen_rect_end.y, diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp index 2895aa9710..be4a070213 100644 --- a/editor/animation_track_editor_plugins.cpp +++ b/editor/animation_track_editor_plugins.cpp @@ -847,9 +847,14 @@ bool AnimationTrackEditTypeAudio::is_key_selectable_by_distance() const { void AnimationTrackEditTypeAudio::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) { Ref<AudioStream> stream = get_animation()->audio_track_get_key_stream(get_track(), p_index); - if (!stream.is_valid()) { - AnimationTrackEdit::draw_key(p_index, p_pixels_sec, p_x, p_selected, p_clip_left, p_clip_right); + AnimationTrackEdit::draw_key(p_index, p_pixels_sec, p_x, p_selected, p_clip_left, p_clip_right); // Draw diamond. + return; + } + + float len = stream->get_length(); + if (len == 0) { + AnimationTrackEdit::draw_key(p_index, p_pixels_sec, p_x, p_selected, p_clip_left, p_clip_right); // Draw diamond. return; } @@ -871,16 +876,10 @@ void AnimationTrackEditTypeAudio::draw_key(int p_index, float p_pixels_sec, int int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); float fh = int(font->get_height(font_size) * 1.5); - float len = stream->get_length(); - Ref<AudioStreamPreview> preview = AudioStreamPreviewGenerator::get_singleton()->generate_preview(stream); float preview_len = preview->get_length(); - if (len == 0) { - len = preview_len; - } - int pixel_total_len = len * p_pixels_sec; len -= end_ofs; @@ -1044,16 +1043,13 @@ void AnimationTrackEditTypeAudio::gui_input(const Ref<InputEvent> &p_event) { continue; } - float start_ofs = get_animation()->audio_track_get_key_start_offset(get_track(), i); - float end_ofs = get_animation()->audio_track_get_key_end_offset(get_track(), i); float len = stream->get_length(); - if (len == 0) { - Ref<AudioStreamPreview> preview = AudioStreamPreviewGenerator::get_singleton()->generate_preview(stream); - float preview_len = preview->get_length(); - len = preview_len; + continue; } + float start_ofs = get_animation()->audio_track_get_key_start_offset(get_track(), i); + float end_ofs = get_animation()->audio_track_get_key_end_offset(get_track(), i); len -= end_ofs; len -= start_ofs; diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index dd84f3b9e1..23e32dcbd8 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -384,9 +384,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { if (score > 0 && score >= best_score) { best = locale; best_score = score; - if (score == 10) { - break; // Exact match, skip the rest. - } } } if (best_score == 0) { diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index de0dacece3..8d09249125 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -4278,11 +4278,15 @@ Variant GDScriptAnalyzer::make_variable_default_value(GDScriptParser::VariableNo } } else { GDScriptParser::DataType datatype = p_variable->get_datatype(); - if (datatype.is_hard_type() && datatype.kind == GDScriptParser::DataType::BUILTIN && datatype.builtin_type != Variant::OBJECT) { - if (datatype.builtin_type == Variant::ARRAY && datatype.has_container_element_type()) { - result = make_array_from_element_datatype(datatype.get_container_element_type()); - } else { - VariantInternal::initialize(&result, datatype.builtin_type); + if (datatype.is_hard_type()) { + if (datatype.kind == GDScriptParser::DataType::BUILTIN && datatype.builtin_type != Variant::OBJECT) { + if (datatype.builtin_type == Variant::ARRAY && datatype.has_container_element_type()) { + result = make_array_from_element_datatype(datatype.get_container_element_type()); + } else { + VariantInternal::initialize(&result, datatype.builtin_type); + } + } else if (datatype.kind == GDScriptParser::DataType::ENUM) { + result = 0; } } } diff --git a/modules/gltf/editor/editor_scene_importer_blend.cpp b/modules/gltf/editor/editor_scene_importer_blend.cpp index 520f33261a..7dcdc8e7cf 100644 --- a/modules/gltf/editor/editor_scene_importer_blend.cpp +++ b/modules/gltf/editor/editor_scene_importer_blend.cpp @@ -214,7 +214,14 @@ Node *EditorSceneFormatImporterBlend::import_scene(const String &p_path, uint32_ } return nullptr; } + +#ifndef DISABLE_DEPRECATED + bool trimming = p_options.has("animation/trimming") ? (bool)p_options["animation/trimming"] : false; + bool remove_immutable = p_options.has("animation/remove_immutable_tracks") ? (bool)p_options["animation/remove_immutable_tracks"] : true; + return gltf->generate_scene(state, (float)p_options["animation/fps"], trimming, remove_immutable); +#else return gltf->generate_scene(state, (float)p_options["animation/fps"], (bool)p_options["animation/trimming"], (bool)p_options["animation/remove_immutable_tracks"]); +#endif } Variant EditorSceneFormatImporterBlend::get_option_visibility(const String &p_path, bool p_for_animation, const String &p_option, diff --git a/modules/gltf/editor/editor_scene_importer_fbx.cpp b/modules/gltf/editor/editor_scene_importer_fbx.cpp index d829630032..f8f458fcc7 100644 --- a/modules/gltf/editor/editor_scene_importer_fbx.cpp +++ b/modules/gltf/editor/editor_scene_importer_fbx.cpp @@ -100,7 +100,14 @@ Node *EditorSceneFormatImporterFBX::import_scene(const String &p_path, uint32_t } return nullptr; } + +#ifndef DISABLE_DEPRECATED + bool trimming = p_options.has("animation/trimming") ? (bool)p_options["animation/trimming"] : false; + bool remove_immutable = p_options.has("animation/remove_immutable_tracks") ? (bool)p_options["animation/remove_immutable_tracks"] : true; + return gltf->generate_scene(state, (float)p_options["animation/fps"], trimming, remove_immutable); +#else return gltf->generate_scene(state, (float)p_options["animation/fps"], (bool)p_options["animation/trimming"], (bool)p_options["animation/remove_immutable_tracks"]); +#endif } Variant EditorSceneFormatImporterFBX::get_option_visibility(const String &p_path, bool p_for_animation, diff --git a/modules/gltf/editor/editor_scene_importer_gltf.cpp b/modules/gltf/editor/editor_scene_importer_gltf.cpp index 012a144d52..5339275439 100644 --- a/modules/gltf/editor/editor_scene_importer_gltf.cpp +++ b/modules/gltf/editor/editor_scene_importer_gltf.cpp @@ -47,15 +47,15 @@ void EditorSceneFormatImporterGLTF::get_extensions(List<String> *r_extensions) c Node *EditorSceneFormatImporterGLTF::import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, List<String> *r_missing_deps, Error *r_err) { - Ref<GLTFDocument> doc; - doc.instantiate(); + Ref<GLTFDocument> gltf; + gltf.instantiate(); Ref<GLTFState> state; state.instantiate(); if (p_options.has("gltf/embedded_image_handling")) { int32_t enum_option = p_options["gltf/embedded_image_handling"]; state->set_handle_binary_image(enum_option); } - Error err = doc->append_from_file(p_path, state, p_flags); + Error err = gltf->append_from_file(p_path, state, p_flags); if (err != OK) { if (r_err) { *r_err = err; @@ -67,21 +67,11 @@ Node *EditorSceneFormatImporterGLTF::import_scene(const String &p_path, uint32_t } #ifndef DISABLE_DEPRECATED - if (p_options.has("animation/trimming")) { - if (p_options.has("animation/remove_immutable_tracks")) { - return doc->generate_scene(state, (float)p_options["animation/fps"], (bool)p_options["animation/trimming"], (bool)p_options["animation/remove_immutable_tracks"]); - } else { - return doc->generate_scene(state, (float)p_options["animation/fps"], (bool)p_options["animation/trimming"], true); - } - } else { - if (p_options.has("animation/remove_immutable_tracks")) { - return doc->generate_scene(state, (float)p_options["animation/fps"], false, (bool)p_options["animation/remove_immutable_tracks"]); - } else { - return doc->generate_scene(state, (float)p_options["animation/fps"], false, true); - } - } + bool trimming = p_options.has("animation/trimming") ? (bool)p_options["animation/trimming"] : false; + bool remove_immutable = p_options.has("animation/remove_immutable_tracks") ? (bool)p_options["animation/remove_immutable_tracks"] : true; + return gltf->generate_scene(state, (float)p_options["animation/fps"], trimming, remove_immutable); #else - return doc->generate_scene(state, (float)p_options["animation/fps"], (bool)p_options["animation/trimming"], (bool)p_options["animation/remove_immutable_tracks"]); + return gltf->generate_scene(state, (float)p_options["animation/fps"], (bool)p_options["animation/trimming"], (bool)p_options["animation/remove_immutable_tracks"]); #endif } diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 028028a103..e3ba290eb2 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -3285,7 +3285,6 @@ Error GLTFDocument::_parse_images(Ref<GLTFState> p_state, const String &p_base_p tex.instantiate(); tex->set_name(img->get_name()); tex->set_keep_compressed_buffer(true); - p_state->source_images.push_back(img); tex->create_from_image(img, PortableCompressedTexture2D::COMPRESSION_MODE_BASIS_UNIVERSAL); p_state->images.push_back(tex); p_state->source_images.push_back(img); diff --git a/platform/android/android_input_handler.cpp b/platform/android/android_input_handler.cpp index 6d34e28182..63045237e9 100644 --- a/platform/android/android_input_handler.cpp +++ b/platform/android/android_input_handler.cpp @@ -49,11 +49,19 @@ void AndroidInputHandler::process_joy_event(AndroidInputHandler::JoypadEvent p_e } } -void AndroidInputHandler::_set_key_modifier_state(Ref<InputEventWithModifiers> ev) { - ev->set_shift_pressed(shift_mem); - ev->set_alt_pressed(alt_mem); - ev->set_meta_pressed(meta_mem); - ev->set_ctrl_pressed(control_mem); +void AndroidInputHandler::_set_key_modifier_state(Ref<InputEventWithModifiers> ev, Key p_keycode) { + if (p_keycode != Key::SHIFT) { + ev->set_shift_pressed(shift_mem); + } + if (p_keycode != Key::ALT) { + ev->set_alt_pressed(alt_mem); + } + if (p_keycode != Key::META) { + ev->set_meta_pressed(meta_mem); + } + if (p_keycode != Key::CTRL) { + ev->set_ctrl_pressed(control_mem); + } } void AndroidInputHandler::process_key_event(int p_physical_keycode, int p_unicode, int p_key_label, bool p_pressed) { @@ -118,7 +126,7 @@ void AndroidInputHandler::process_key_event(int p_physical_keycode, int p_unicod ev->set_unicode(fix_unicode(unicode)); ev->set_pressed(p_pressed); - _set_key_modifier_state(ev); + _set_key_modifier_state(ev, keycode); if (p_physical_keycode == AKEYCODE_BACK) { if (DisplayServerAndroid *dsa = Object::cast_to<DisplayServerAndroid>(DisplayServer::get_singleton())) { @@ -260,7 +268,7 @@ void AndroidInputHandler::_parse_mouse_event_info(BitField<MouseButtonMask> even Ref<InputEventMouseButton> ev; ev.instantiate(); - _set_key_modifier_state(ev); + _set_key_modifier_state(ev, Key::NONE); if (p_source_mouse_relative) { ev->set_position(hover_prev_pos); ev->set_global_position(hover_prev_pos); @@ -294,7 +302,7 @@ void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_an // https://developer.android.com/reference/android/view/MotionEvent.html#ACTION_HOVER_ENTER Ref<InputEventMouseMotion> ev; ev.instantiate(); - _set_key_modifier_state(ev); + _set_key_modifier_state(ev, Key::NONE); ev->set_position(p_event_pos); ev->set_global_position(p_event_pos); ev->set_relative(p_event_pos - hover_prev_pos); @@ -329,7 +337,7 @@ void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_an Ref<InputEventMouseMotion> ev; ev.instantiate(); - _set_key_modifier_state(ev); + _set_key_modifier_state(ev, Key::NONE); if (p_source_mouse_relative) { ev->set_position(hover_prev_pos); ev->set_global_position(hover_prev_pos); @@ -348,7 +356,7 @@ void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_an case AMOTION_EVENT_ACTION_SCROLL: { Ref<InputEventMouseButton> ev; ev.instantiate(); - _set_key_modifier_state(ev); + _set_key_modifier_state(ev, Key::NONE); if (p_source_mouse_relative) { ev->set_position(hover_prev_pos); ev->set_global_position(hover_prev_pos); @@ -375,7 +383,7 @@ void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_an void AndroidInputHandler::_wheel_button_click(BitField<MouseButtonMask> event_buttons_mask, const Ref<InputEventMouseButton> &ev, MouseButton wheel_button, float factor) { Ref<InputEventMouseButton> evd = ev->duplicate(); - _set_key_modifier_state(evd); + _set_key_modifier_state(evd, Key::NONE); evd->set_button_index(wheel_button); evd->set_button_mask(BitField<MouseButtonMask>(event_buttons_mask.operator int64_t() ^ int64_t(mouse_button_to_mask(wheel_button)))); evd->set_factor(factor); @@ -389,7 +397,7 @@ void AndroidInputHandler::_wheel_button_click(BitField<MouseButtonMask> event_bu void AndroidInputHandler::process_magnify(Point2 p_pos, float p_factor) { Ref<InputEventMagnifyGesture> magnify_event; magnify_event.instantiate(); - _set_key_modifier_state(magnify_event); + _set_key_modifier_state(magnify_event, Key::NONE); magnify_event->set_position(p_pos); magnify_event->set_factor(p_factor); Input::get_singleton()->parse_input_event(magnify_event); @@ -398,7 +406,7 @@ void AndroidInputHandler::process_magnify(Point2 p_pos, float p_factor) { void AndroidInputHandler::process_pan(Point2 p_pos, Vector2 p_delta) { Ref<InputEventPanGesture> pan_event; pan_event.instantiate(); - _set_key_modifier_state(pan_event); + _set_key_modifier_state(pan_event, Key::NONE); pan_event->set_position(p_pos); pan_event->set_delta(p_delta); Input::get_singleton()->parse_input_event(pan_event); diff --git a/platform/android/android_input_handler.h b/platform/android/android_input_handler.h index a56b6aa6c4..2badd32636 100644 --- a/platform/android/android_input_handler.h +++ b/platform/android/android_input_handler.h @@ -76,7 +76,7 @@ private: MouseEventInfo mouse_event_info; Point2 hover_prev_pos; // needed to calculate the relative position on hover events - void _set_key_modifier_state(Ref<InputEventWithModifiers> ev); + void _set_key_modifier_state(Ref<InputEventWithModifiers> ev, Key p_keycode); static MouseButton _button_index_from_mask(BitField<MouseButtonMask> button_mask); static BitField<MouseButtonMask> _android_button_mask_to_godot_button_mask(int android_button_mask); diff --git a/platform/web/display_server_web.cpp b/platform/web/display_server_web.cpp index d71fd60543..e89a79834b 100644 --- a/platform/web/display_server_web.cpp +++ b/platform/web/display_server_web.cpp @@ -108,11 +108,19 @@ void DisplayServerWeb::request_quit_callback() { // Keys -void DisplayServerWeb::dom2godot_mod(Ref<InputEventWithModifiers> ev, int p_mod) { - ev->set_shift_pressed(p_mod & 1); - ev->set_alt_pressed(p_mod & 2); - ev->set_ctrl_pressed(p_mod & 4); - ev->set_meta_pressed(p_mod & 8); +void DisplayServerWeb::dom2godot_mod(Ref<InputEventWithModifiers> ev, int p_mod, Key p_keycode) { + if (p_keycode != Key::SHIFT) { + ev->set_shift_pressed(p_mod & 1); + } + if (p_keycode != Key::ALT) { + ev->set_alt_pressed(p_mod & 2); + } + if (p_keycode != Key::CTRL) { + ev->set_ctrl_pressed(p_mod & 4); + } + if (p_keycode != Key::META) { + ev->set_meta_pressed(p_mod & 8); + } } void DisplayServerWeb::key_callback(int p_pressed, int p_repeat, int p_modifiers) { @@ -138,7 +146,7 @@ void DisplayServerWeb::key_callback(int p_pressed, int p_repeat, int p_modifiers ev->set_key_label(fix_key_label(c, keycode)); ev->set_unicode(fix_unicode(c)); ev->set_pressed(p_pressed); - dom2godot_mod(ev, p_modifiers); + dom2godot_mod(ev, p_modifiers, fix_keycode(c, keycode)); Input::get_singleton()->parse_input_event(ev); @@ -157,7 +165,7 @@ int DisplayServerWeb::mouse_button_callback(int p_pressed, int p_button, double ev->set_position(pos); ev->set_global_position(pos); ev->set_pressed(p_pressed); - dom2godot_mod(ev, p_modifiers); + dom2godot_mod(ev, p_modifiers, Key::NONE); switch (p_button) { case DOM_BUTTON_LEFT: @@ -235,7 +243,7 @@ void DisplayServerWeb::mouse_move_callback(double p_x, double p_y, double p_rel_ Point2 pos(p_x, p_y); Ref<InputEventMouseMotion> ev; ev.instantiate(); - dom2godot_mod(ev, p_modifiers); + dom2godot_mod(ev, p_modifiers, Key::NONE); ev->set_button_mask(input_mask); ev->set_position(pos); diff --git a/platform/web/display_server_web.h b/platform/web/display_server_web.h index 6d76af4e56..2e50a6bbc8 100644 --- a/platform/web/display_server_web.h +++ b/platform/web/display_server_web.h @@ -81,7 +81,7 @@ private: bool swap_cancel_ok = false; // utilities - static void dom2godot_mod(Ref<InputEventWithModifiers> ev, int p_mod); + static void dom2godot_mod(Ref<InputEventWithModifiers> ev, int p_mod, Key p_keycode); static const char *godot2dom_cursor(DisplayServer::CursorShape p_shape); // events diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index fe7d91dc18..1cfc9c9f47 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -3668,10 +3668,18 @@ void DisplayServerWindows::_process_key_events() { } k->set_window_id(ke.window_id); - k->set_shift_pressed(ke.shift); - k->set_alt_pressed(ke.alt); - k->set_ctrl_pressed(ke.control); - k->set_meta_pressed(ke.meta); + if (keycode != Key::SHIFT) { + k->set_shift_pressed(ke.shift); + } + if (keycode != Key::ALT) { + k->set_alt_pressed(ke.alt); + } + if (keycode != Key::CTRL) { + k->set_ctrl_pressed(ke.control); + } + if (keycode != Key::META) { + k->set_meta_pressed(ke.meta); + } k->set_pressed(true); k->set_keycode(keycode); k->set_physical_keycode(physical_keycode); @@ -3693,11 +3701,6 @@ void DisplayServerWindows::_process_key_events() { k.instantiate(); k->set_window_id(ke.window_id); - k->set_shift_pressed(ke.shift); - k->set_alt_pressed(ke.alt); - k->set_ctrl_pressed(ke.control); - k->set_meta_pressed(ke.meta); - k->set_pressed(ke.uMsg == WM_KEYDOWN); Key keycode = KeyMappingWindows::get_keysym(ke.wParam); @@ -3719,6 +3722,18 @@ void DisplayServerWindows::_process_key_events() { } } + if (keycode != Key::SHIFT) { + k->set_shift_pressed(ke.shift); + } + if (keycode != Key::ALT) { + k->set_alt_pressed(ke.alt); + } + if (keycode != Key::CTRL) { + k->set_ctrl_pressed(ke.control); + } + if (keycode != Key::META) { + k->set_meta_pressed(ke.meta); + } k->set_keycode(keycode); k->set_physical_keycode(physical_keycode); k->set_key_label(key_label); diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index b084cb5bea..e2f7ec860c 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -2856,7 +2856,7 @@ void CodeEdit::_filter_code_completion_candidates_impl() { const int caret_line = get_caret_line(); const int caret_column = get_caret_column(); const String line = get_line(caret_line); - ERR_FAIL_INDEX_MSG(caret_column - 1, line.length(), "Caret column exceeds line length."); + ERR_FAIL_INDEX_MSG(caret_column, line.length() + 1, "Caret column exceeds line length."); if (caret_column > 0 && line[caret_column - 1] == '(' && !code_completion_forced) { cancel_code_completion(); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index c0ef71ee4f..45218773fe 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -86,9 +86,7 @@ int Label::get_line_height(int p_line) const { } } -void Label::_shape() { - bool font_was_dirty = font_dirty; - +bool Label::_shape() { Ref<StyleBox> style = theme_cache.normal_style; int width = (get_size().width - style->get_minimum_size().width); @@ -103,7 +101,7 @@ void Label::_shape() { } const Ref<Font> &font = (settings.is_valid() && settings->get_font().is_valid()) ? settings->get_font() : theme_cache.font; int font_size = settings.is_valid() ? settings->get_font_size() : theme_cache.font_size; - ERR_FAIL_COND(font.is_null()); + ERR_FAIL_COND_V(font.is_null(), true); String txt = (uppercase) ? TS->string_to_upper(xl_text, language) : xl_text; if (visible_chars >= 0 && visible_chars_behavior == TextServer::VC_CHARS_BEFORE_SHAPING) { txt = txt.substr(0, visible_chars); @@ -123,6 +121,7 @@ void Label::_shape() { dirty = false; font_dirty = false; lines_dirty = true; + // Note for future maintainers: forgetting stable width here (e.g., setting it to -1) may fix still undiscovered bugs. } if (lines_dirty) { @@ -135,129 +134,136 @@ void Label::_shape() { Size2i prev_minsize = minsize; minsize = Size2(); + bool can_process_lines = false; if (xl_text.length() == 0) { + can_process_lines = true; lines_dirty = false; - return; - } - - // Don't compute minimum size until width is stable (two shape requests in a row with the same width.) - // This avoids situations in which the initial width is very narrow and the label would break text - // into many very short lines, causing a very tall label that can leave a deformed container. - bool width_stabilized = get_size().width == stable_width; - stable_width = get_size().width; + } else { + // With autowrap on, we won't compute the minimum size until width is stable (two shape requests in a + // row with the same width.) This avoids situations in which the initial width is very narrow and the label + // would break text into many very short lines, causing a very tall label that can leave a deformed container. + + can_process_lines = get_size().width == stable_width || autowrap_mode == TextServer::AUTOWRAP_OFF; + stable_width = get_size().width; + + if (can_process_lines) { + if (lines_dirty) { + BitField<TextServer::LineBreakFlag> autowrap_flags = TextServer::BREAK_MANDATORY; + switch (autowrap_mode) { + case TextServer::AUTOWRAP_WORD_SMART: + autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_ADAPTIVE | TextServer::BREAK_MANDATORY; + break; + case TextServer::AUTOWRAP_WORD: + autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_MANDATORY; + break; + case TextServer::AUTOWRAP_ARBITRARY: + autowrap_flags = TextServer::BREAK_GRAPHEME_BOUND | TextServer::BREAK_MANDATORY; + break; + case TextServer::AUTOWRAP_OFF: + break; + } + autowrap_flags = autowrap_flags | TextServer::BREAK_TRIM_EDGE_SPACES; - // With autowrap off, there's still a point in shaping before width is stable: to contribute a min width. - if (lines_dirty && (width_stabilized || autowrap_mode == TextServer::AUTOWRAP_OFF)) { - BitField<TextServer::LineBreakFlag> autowrap_flags = TextServer::BREAK_MANDATORY; - switch (autowrap_mode) { - case TextServer::AUTOWRAP_WORD_SMART: - autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_ADAPTIVE | TextServer::BREAK_MANDATORY; - break; - case TextServer::AUTOWRAP_WORD: - autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_MANDATORY; - break; - case TextServer::AUTOWRAP_ARBITRARY: - autowrap_flags = TextServer::BREAK_GRAPHEME_BOUND | TextServer::BREAK_MANDATORY; - break; - case TextServer::AUTOWRAP_OFF: - break; - } - autowrap_flags = autowrap_flags | TextServer::BREAK_TRIM_EDGE_SPACES; + PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(text_rid, width, 0, autowrap_flags); + for (int i = 0; i < line_breaks.size(); i = i + 2) { + RID line = TS->shaped_text_substr(text_rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]); + lines_rid.push_back(line); + } + } - PackedInt32Array line_breaks = TS->shaped_text_get_line_breaks(text_rid, width, 0, autowrap_flags); - for (int i = 0; i < line_breaks.size(); i = i + 2) { - RID line = TS->shaped_text_substr(text_rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]); - lines_rid.push_back(line); - } - } + if (autowrap_mode == TextServer::AUTOWRAP_OFF) { + for (int i = 0; i < lines_rid.size(); i++) { + if (minsize.width < TS->shaped_text_get_size(lines_rid[i]).x) { + minsize.width = TS->shaped_text_get_size(lines_rid[i]).x; + } + } - if (autowrap_mode == TextServer::AUTOWRAP_OFF) { - for (int i = 0; i < lines_rid.size(); i++) { - if (minsize.width < TS->shaped_text_get_size(lines_rid[i]).x) { - minsize.width = TS->shaped_text_get_size(lines_rid[i]).x; + // With autowrap off, by now we already know the width the label will take. + width = (minsize.width - style->get_minimum_size().width); } - } - // With autowrap off, by now we already know the width the label will take. - width = (minsize.width - style->get_minimum_size().width); - width_stabilized = true; - } - - if (lines_dirty && width_stabilized) { - BitField<TextServer::TextOverrunFlag> overrun_flags = TextServer::OVERRUN_NO_TRIM; - switch (overrun_behavior) { - case TextServer::OVERRUN_TRIM_WORD_ELLIPSIS: - overrun_flags.set_flag(TextServer::OVERRUN_TRIM); - overrun_flags.set_flag(TextServer::OVERRUN_TRIM_WORD_ONLY); - overrun_flags.set_flag(TextServer::OVERRUN_ADD_ELLIPSIS); - break; - case TextServer::OVERRUN_TRIM_ELLIPSIS: - overrun_flags.set_flag(TextServer::OVERRUN_TRIM); - overrun_flags.set_flag(TextServer::OVERRUN_ADD_ELLIPSIS); - break; - case TextServer::OVERRUN_TRIM_WORD: - overrun_flags.set_flag(TextServer::OVERRUN_TRIM); - overrun_flags.set_flag(TextServer::OVERRUN_TRIM_WORD_ONLY); - break; - case TextServer::OVERRUN_TRIM_CHAR: - overrun_flags.set_flag(TextServer::OVERRUN_TRIM); - break; - case TextServer::OVERRUN_NO_TRIMMING: - break; - } + if (lines_dirty) { + BitField<TextServer::TextOverrunFlag> overrun_flags = TextServer::OVERRUN_NO_TRIM; + switch (overrun_behavior) { + case TextServer::OVERRUN_TRIM_WORD_ELLIPSIS: + overrun_flags.set_flag(TextServer::OVERRUN_TRIM); + overrun_flags.set_flag(TextServer::OVERRUN_TRIM_WORD_ONLY); + overrun_flags.set_flag(TextServer::OVERRUN_ADD_ELLIPSIS); + break; + case TextServer::OVERRUN_TRIM_ELLIPSIS: + overrun_flags.set_flag(TextServer::OVERRUN_TRIM); + overrun_flags.set_flag(TextServer::OVERRUN_ADD_ELLIPSIS); + break; + case TextServer::OVERRUN_TRIM_WORD: + overrun_flags.set_flag(TextServer::OVERRUN_TRIM); + overrun_flags.set_flag(TextServer::OVERRUN_TRIM_WORD_ONLY); + break; + case TextServer::OVERRUN_TRIM_CHAR: + overrun_flags.set_flag(TextServer::OVERRUN_TRIM); + break; + case TextServer::OVERRUN_NO_TRIMMING: + break; + } - // Fill after min_size calculation. + // Fill after min_size calculation. - int visible_lines = lines_rid.size(); - if (max_lines_visible >= 0 && visible_lines > max_lines_visible) { - visible_lines = max_lines_visible; - } - if (autowrap_mode != TextServer::AUTOWRAP_OFF) { - bool lines_hidden = visible_lines > 0 && visible_lines < lines_rid.size(); - if (lines_hidden) { - overrun_flags.set_flag(TextServer::OVERRUN_ENFORCE_ELLIPSIS); - } - if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL) { - for (int i = 0; i < lines_rid.size(); i++) { - if (i < visible_lines - 1 || lines_rid.size() == 1) { - TS->shaped_text_fit_to_width(lines_rid[i], width); - } else if (i == (visible_lines - 1)) { + int visible_lines = lines_rid.size(); + if (max_lines_visible >= 0 && visible_lines > max_lines_visible) { + visible_lines = max_lines_visible; + } + if (autowrap_mode != TextServer::AUTOWRAP_OFF) { + bool lines_hidden = visible_lines > 0 && visible_lines < lines_rid.size(); + if (lines_hidden) { + overrun_flags.set_flag(TextServer::OVERRUN_ENFORCE_ELLIPSIS); + } + if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL) { + for (int i = 0; i < lines_rid.size(); i++) { + if (i < visible_lines - 1 || lines_rid.size() == 1) { + TS->shaped_text_fit_to_width(lines_rid[i], width); + } else if (i == (visible_lines - 1)) { + TS->shaped_text_overrun_trim_to_width(lines_rid[visible_lines - 1], width, overrun_flags); + } + } + } else if (lines_hidden) { TS->shaped_text_overrun_trim_to_width(lines_rid[visible_lines - 1], width, overrun_flags); } - } - } else if (lines_hidden) { - TS->shaped_text_overrun_trim_to_width(lines_rid[visible_lines - 1], width, overrun_flags); - } - } else { - // Autowrap disabled. - for (int i = 0; i < lines_rid.size(); i++) { - if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL) { - TS->shaped_text_fit_to_width(lines_rid[i], width); - overrun_flags.set_flag(TextServer::OVERRUN_JUSTIFICATION_AWARE); - TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags); - TS->shaped_text_fit_to_width(lines_rid[i], width, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_CONSTRAIN_ELLIPSIS); } else { - TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags); + // Autowrap disabled. + for (int i = 0; i < lines_rid.size(); i++) { + if (horizontal_alignment == HORIZONTAL_ALIGNMENT_FILL) { + TS->shaped_text_fit_to_width(lines_rid[i], width); + overrun_flags.set_flag(TextServer::OVERRUN_JUSTIFICATION_AWARE); + TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags); + TS->shaped_text_fit_to_width(lines_rid[i], width, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_CONSTRAIN_ELLIPSIS); + } else { + TS->shaped_text_overrun_trim_to_width(lines_rid[i], width, overrun_flags); + } + } + } + + int last_line = MIN(lines_rid.size(), visible_lines + lines_skipped); + int line_spacing = settings.is_valid() ? settings->get_line_spacing() : theme_cache.line_spacing; + for (int64_t i = lines_skipped; i < last_line; i++) { + minsize.height += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing; } - } - } - int last_line = MIN(lines_rid.size(), visible_lines + lines_skipped); - int line_spacing = settings.is_valid() ? settings->get_line_spacing() : theme_cache.line_spacing; - for (int64_t i = lines_skipped; i < last_line; i++) { - minsize.height += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing; + lines_dirty = false; + } + } else { + callable_mp(this, &Label::_shape).call_deferred(); } + } - lines_dirty = false; + if (draw_pending) { + queue_redraw(); + draw_pending = false; } - if (minsize != prev_minsize || font_was_dirty) { + if (minsize != prev_minsize) { update_minimum_size(); } - if (!width_stabilized) { - callable_mp(this, &Label::_shape).call_deferred(); - } + return can_process_lines; } inline void draw_glyph(const Glyph &p_gl, const RID &p_canvas, const Color &p_font_color, const Vector2 &p_ofs) { @@ -367,10 +373,9 @@ void Label::_notification(int p_what) { } if (dirty || font_dirty || lines_dirty) { - _shape(); - if (lines_dirty) { + if (!_shape()) { // There will be another pass. - queue_redraw(); + draw_pending = true; break; } } @@ -396,7 +401,7 @@ void Label::_notification(int p_what) { style->draw(ci, Rect2(Point2(0, 0), get_size())); float total_h = 0.0; - int visible_lines = 0; + int lines_visible = 0; // Get number of lines to fit to the height. for (int64_t i = lines_skipped; i < lines_rid.size(); i++) { @@ -404,14 +409,14 @@ void Label::_notification(int p_what) { if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) { break; } - visible_lines++; + lines_visible++; } - if (max_lines_visible >= 0 && visible_lines > max_lines_visible) { - visible_lines = max_lines_visible; + if (max_lines_visible >= 0 && lines_visible > max_lines_visible) { + lines_visible = max_lines_visible; } - int last_line = MIN(lines_rid.size(), visible_lines + lines_skipped); + int last_line = MIN(lines_rid.size(), lines_visible + lines_skipped); bool trim_chars = (visible_chars >= 0) && (visible_chars_behavior == TextServer::VC_CHARS_AFTER_SHAPING); bool trim_glyphs_ltr = (visible_chars >= 0) && ((visible_chars_behavior == TextServer::VC_GLYPHS_LTR) || ((visible_chars_behavior == TextServer::VC_GLYPHS_AUTO) && !rtl_layout)); bool trim_glyphs_rtl = (visible_chars >= 0) && ((visible_chars_behavior == TextServer::VC_GLYPHS_RTL) || ((visible_chars_behavior == TextServer::VC_GLYPHS_AUTO) && rtl_layout)); @@ -428,7 +433,7 @@ void Label::_notification(int p_what) { total_h += style->get_margin(SIDE_TOP) + style->get_margin(SIDE_BOTTOM); int vbegin = 0, vsep = 0; - if (visible_lines > 0) { + if (lines_visible > 0) { switch (vertical_alignment) { case VERTICAL_ALIGNMENT_TOP: { // Nothing. @@ -445,8 +450,8 @@ void Label::_notification(int p_what) { } break; case VERTICAL_ALIGNMENT_FILL: { vbegin = 0; - if (visible_lines > 1) { - vsep = (size.y - (total_h - line_spacing)) / (visible_lines - 1); + if (lines_visible > 1) { + vsep = (size.y - (total_h - line_spacing)) / (lines_visible - 1); } else { vsep = 0; } @@ -615,6 +620,8 @@ void Label::_notification(int p_what) { } ofs.y += TS->shaped_text_get_descent(lines_rid[i]) + vsep + line_spacing; } + + draw_pending = false; } break; case NOTIFICATION_THEME_CHANGED: { @@ -666,25 +673,25 @@ int Label::get_line_count() const { int Label::get_visible_line_count() const { Ref<StyleBox> style = theme_cache.normal_style; int line_spacing = settings.is_valid() ? settings->get_line_spacing() : theme_cache.line_spacing; - int visible_lines = 0; + int lines_visible = 0; float total_h = 0.0; for (int64_t i = lines_skipped; i < lines_rid.size(); i++) { total_h += TS->shaped_text_get_size(lines_rid[i]).y + line_spacing; if (total_h > (get_size().height - style->get_minimum_size().height + line_spacing)) { break; } - visible_lines++; + lines_visible++; } - if (visible_lines > lines_rid.size()) { - visible_lines = lines_rid.size(); + if (lines_visible > lines_rid.size()) { + lines_visible = lines_rid.size(); } - if (max_lines_visible >= 0 && visible_lines > max_lines_visible) { - visible_lines = max_lines_visible; + if (max_lines_visible >= 0 && lines_visible > max_lines_visible) { + lines_visible = max_lines_visible; } - return visible_lines; + return lines_visible; } void Label::set_horizontal_alignment(HorizontalAlignment p_alignment) { @@ -969,7 +976,7 @@ void Label::_bind_methods() { ClassDB::bind_method(D_METHOD("get_visible_ratio"), &Label::get_visible_ratio); ClassDB::bind_method(D_METHOD("set_lines_skipped", "lines_skipped"), &Label::set_lines_skipped); ClassDB::bind_method(D_METHOD("get_lines_skipped"), &Label::get_lines_skipped); - ClassDB::bind_method(D_METHOD("set_max_lines_visible", "visible_lines"), &Label::set_max_lines_visible); + ClassDB::bind_method(D_METHOD("set_max_lines_visible", "lines_visible"), &Label::set_max_lines_visible); ClassDB::bind_method(D_METHOD("get_max_lines_visible"), &Label::get_max_lines_visible); ClassDB::bind_method(D_METHOD("set_structured_text_bidi_override", "parser"), &Label::set_structured_text_bidi_override); ClassDB::bind_method(D_METHOD("get_structured_text_bidi_override"), &Label::get_structured_text_bidi_override); diff --git a/scene/gui/label.h b/scene/gui/label.h index 448cb245eb..36b85f7af8 100644 --- a/scene/gui/label.h +++ b/scene/gui/label.h @@ -50,7 +50,6 @@ private: bool uppercase = false; bool lines_dirty = true; - bool dirty = true; bool font_dirty = true; RID text_rid; @@ -66,6 +65,7 @@ private: float visible_ratio = 1.0; int lines_skipped = 0; int max_lines_visible = -1; + bool draw_pending = false; Ref<LabelSettings> settings; @@ -83,7 +83,7 @@ private: int font_shadow_outline_size; } theme_cache; - void _shape(); + bool _shape(); void _invalidate(); protected: diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index f9c9906efa..2c1c44322a 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -5520,34 +5520,6 @@ void RichTextLabel::_bind_methods() { BIND_ENUM_CONSTANT(LIST_ROMAN); BIND_ENUM_CONSTANT(LIST_DOTS); - BIND_ENUM_CONSTANT(ITEM_FRAME); - BIND_ENUM_CONSTANT(ITEM_TEXT); - BIND_ENUM_CONSTANT(ITEM_IMAGE); - BIND_ENUM_CONSTANT(ITEM_NEWLINE); - BIND_ENUM_CONSTANT(ITEM_FONT); - BIND_ENUM_CONSTANT(ITEM_FONT_SIZE); - BIND_ENUM_CONSTANT(ITEM_FONT_FEATURES); - BIND_ENUM_CONSTANT(ITEM_COLOR); - BIND_ENUM_CONSTANT(ITEM_OUTLINE_SIZE); - BIND_ENUM_CONSTANT(ITEM_OUTLINE_COLOR); - BIND_ENUM_CONSTANT(ITEM_UNDERLINE); - BIND_ENUM_CONSTANT(ITEM_STRIKETHROUGH); - BIND_ENUM_CONSTANT(ITEM_PARAGRAPH); - BIND_ENUM_CONSTANT(ITEM_INDENT); - BIND_ENUM_CONSTANT(ITEM_LIST); - BIND_ENUM_CONSTANT(ITEM_TABLE); - BIND_ENUM_CONSTANT(ITEM_FADE); - BIND_ENUM_CONSTANT(ITEM_SHAKE); - BIND_ENUM_CONSTANT(ITEM_WAVE); - BIND_ENUM_CONSTANT(ITEM_TORNADO); - BIND_ENUM_CONSTANT(ITEM_RAINBOW); - BIND_ENUM_CONSTANT(ITEM_BGCOLOR); - BIND_ENUM_CONSTANT(ITEM_FGCOLOR); - BIND_ENUM_CONSTANT(ITEM_META); - BIND_ENUM_CONSTANT(ITEM_HINT); - BIND_ENUM_CONSTANT(ITEM_DROPCAP); - BIND_ENUM_CONSTANT(ITEM_CUSTOMFX); - BIND_ENUM_CONSTANT(MENU_COPY); BIND_ENUM_CONSTANT(MENU_SELECT_ALL); BIND_ENUM_CONSTANT(MENU_MAX); diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index b01fccf14c..1dae8b75ca 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -740,7 +740,6 @@ public: }; VARIANT_ENUM_CAST(RichTextLabel::ListType); -VARIANT_ENUM_CAST(RichTextLabel::ItemType); VARIANT_ENUM_CAST(RichTextLabel::MenuItems); #endif // RICH_TEXT_LABEL_H diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp index eca6cb3eef..5e378a0321 100644 --- a/scene/gui/tab_bar.cpp +++ b/scene/gui/tab_bar.cpp @@ -342,6 +342,8 @@ void TabBar::_notification(int p_what) { _shape(i); } + queue_redraw(); + [[fallthrough]]; } case NOTIFICATION_RESIZED: { diff --git a/scene/main/window.cpp b/scene/main/window.cpp index 6fbf6ccb81..b79a9ba444 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -984,17 +984,13 @@ void Window::_update_viewport_size() { Size2 margin; Size2 offset; - //black bars and margin + if (content_scale_aspect != CONTENT_SCALE_ASPECT_EXPAND && screen_size.x < video_mode.x) { margin.x = Math::round((video_mode.x - screen_size.x) / 2.0); - //RenderingServer::get_singleton()->black_bars_set_margins(margin.x, 0, margin.x, 0); offset.x = Math::round(margin.x * viewport_size.y / screen_size.y); } else if (content_scale_aspect != CONTENT_SCALE_ASPECT_EXPAND && screen_size.y < video_mode.y) { margin.y = Math::round((video_mode.y - screen_size.y) / 2.0); - //RenderingServer::get_singleton()->black_bars_set_margins(0, margin.y, 0, margin.y); offset.y = Math::round(margin.y * viewport_size.x / screen_size.x); - } else { - //RenderingServer::get_singleton()->black_bars_set_margins(0, 0, 0, 0); } switch (content_scale_mode) { diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index cf9baa2907..a7b53244e2 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -526,6 +526,9 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { vc = indices.size(); ir = indices.ptrw(); has_indices = true; + } else { + // Ensure there are enough vertices to construct at least one triangle. + ERR_FAIL_COND_V(vertices.size() % 3 != 0, Ref<ArrayMesh>()); } HashMap<Vector3, Vector3> normal_accum; diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp index 02460bdb18..fbe97b9acb 100644 --- a/servers/navigation_server_3d.cpp +++ b/servers/navigation_server_3d.cpp @@ -115,7 +115,6 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("free_rid", "rid"), &NavigationServer3D::free); ClassDB::bind_method(D_METHOD("set_active", "active"), &NavigationServer3D::set_active); - ClassDB::bind_method(D_METHOD("process", "delta_time"), &NavigationServer3D::process); ADD_SIGNAL(MethodInfo("map_changed", PropertyInfo(Variant::RID, "map"))); |