Browse Source

Merge pull request #95916 from Repiteo/core/bit-field

Core: Add dedicated `BitField` template
Thaddeus Crews 3 months ago
parent
commit
addab4f001
46 changed files with 188 additions and 155 deletions
  1. 1 1
      core/input/input.h
  2. 8 0
      core/input/input_enums.h
  3. 3 3
      core/input/input_event.cpp
  4. 1 1
      core/input/input_event.h
  5. 73 0
      core/templates/bit_field.h
  6. 0 26
      core/variant/binder_common.h
  7. 0 23
      core/variant/type_info.h
  8. 5 4
      core/variant/variant.h
  9. 1 1
      drivers/d3d12/rendering_device_driver_d3d12.cpp
  10. 1 1
      drivers/metal/metal_objects.mm
  11. 2 2
      drivers/metal/rendering_device_driver_metal.mm
  12. 1 1
      drivers/vulkan/rendering_device_driver_vulkan.cpp
  13. 1 1
      editor/gui/editor_quick_open_dialog.cpp
  14. 1 1
      main/main.cpp
  15. 3 3
      modules/gdscript/gdscript_analyzer.cpp
  16. 1 1
      modules/openxr/extensions/openxr_hand_tracking_extension.cpp
  17. 1 1
      modules/openxr/openxr_interface.cpp
  18. 4 4
      platform/android/android_input_handler.cpp
  19. 2 2
      platform/android/android_input_handler.h
  20. 1 1
      platform/android/java_godot_lib_jni.cpp
  21. 1 1
      platform/linuxbsd/joypad_linux.cpp
  22. 1 1
      platform/linuxbsd/joypad_linux.h
  23. 1 1
      platform/linuxbsd/wayland/display_server_wayland.h
  24. 2 2
      platform/linuxbsd/wayland/wayland_thread.cpp
  25. 2 2
      platform/linuxbsd/wayland/wayland_thread.h
  26. 3 3
      platform/linuxbsd/x11/display_server_x11.cpp
  27. 1 1
      platform/macos/display_server_macos.mm
  28. 4 4
      platform/windows/display_server_windows.cpp
  29. 1 1
      platform/windows/joypad_windows.cpp
  30. 1 1
      scene/gui/popup_menu.h
  31. 1 1
      scene/main/node.h
  32. 1 1
      scene/main/viewport.h
  33. 3 3
      scene/resources/font.cpp
  34. 1 1
      servers/display_server.cpp
  35. 2 2
      servers/rendering/rendering_device.cpp
  36. 6 6
      servers/rendering/rendering_device.h
  37. 4 4
      servers/rendering/rendering_device_commons.h
  38. 14 14
      servers/rendering/rendering_device_driver.h
  39. 9 9
      servers/rendering/rendering_device_graph.h
  40. 1 1
      servers/rendering/storage/compositor_storage.h
  41. 1 1
      servers/xr/xr_body_tracker.h
  42. 2 2
      tests/scene/test_code_edit.h
  43. 6 6
      tests/scene/test_text_edit.h
  44. 3 3
      tests/scene/test_viewport.h
  45. 1 1
      tests/servers/test_text_server.h
  46. 6 6
      tests/test_macros.h

+ 1 - 1
core/input/input.h

@@ -85,7 +85,7 @@ public:
 	typedef void (*EventDispatchFunc)(const Ref<InputEvent> &p_event);
 	typedef void (*EventDispatchFunc)(const Ref<InputEvent> &p_event);
 
 
 private:
 private:
-	BitField<MouseButtonMask> mouse_button_mask;
+	BitField<MouseButtonMask> mouse_button_mask = MouseButtonMask::NONE;
 
 
 	RBSet<Key> key_label_pressed;
 	RBSet<Key> key_label_pressed;
 	RBSet<Key> physical_keys_pressed;
 	RBSet<Key> physical_keys_pressed;

+ 8 - 0
core/input/input_enums.h

@@ -136,3 +136,11 @@ inline MouseButtonMask mouse_button_to_mask(MouseButton button) {
 
 
 	return MouseButtonMask(1 << ((int)button - 1));
 	return MouseButtonMask(1 << ((int)button - 1));
 }
 }
+
+constexpr MouseButtonMask operator|(MouseButtonMask p_a, MouseButtonMask p_b) {
+	return static_cast<MouseButtonMask>(static_cast<int>(p_a) | static_cast<int>(p_b));
+}
+
+constexpr MouseButtonMask &operator|=(MouseButtonMask &p_a, MouseButtonMask p_b) {
+	return p_a = p_a | p_b;
+}

+ 3 - 3
core/input/input_event.cpp

@@ -230,7 +230,7 @@ void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModif
 }
 }
 
 
 BitField<KeyModifierMask> InputEventWithModifiers::get_modifiers_mask() const {
 BitField<KeyModifierMask> InputEventWithModifiers::get_modifiers_mask() const {
-	BitField<KeyModifierMask> mask;
+	BitField<KeyModifierMask> mask = {};
 	if (is_ctrl_pressed()) {
 	if (is_ctrl_pressed()) {
 		mask.set_flag(KeyModifierMask::CTRL);
 		mask.set_flag(KeyModifierMask::CTRL);
 	}
 	}
@@ -385,11 +385,11 @@ bool InputEventKey::is_echo() const {
 }
 }
 
 
 Key InputEventKey::get_keycode_with_modifiers() const {
 Key InputEventKey::get_keycode_with_modifiers() const {
-	return keycode | (int64_t)get_modifiers_mask();
+	return keycode | get_modifiers_mask();
 }
 }
 
 
 Key InputEventKey::get_physical_keycode_with_modifiers() const {
 Key InputEventKey::get_physical_keycode_with_modifiers() const {
-	return physical_keycode | (int64_t)get_modifiers_mask();
+	return physical_keycode | get_modifiers_mask();
 }
 }
 
 
 Key InputEventKey::get_key_label_with_modifiers() const {
 Key InputEventKey::get_key_label_with_modifiers() const {

+ 1 - 1
core/input/input_event.h

@@ -208,7 +208,7 @@ public:
 class InputEventMouse : public InputEventWithModifiers {
 class InputEventMouse : public InputEventWithModifiers {
 	GDCLASS(InputEventMouse, InputEventWithModifiers);
 	GDCLASS(InputEventMouse, InputEventWithModifiers);
 
 
-	BitField<MouseButtonMask> button_mask;
+	BitField<MouseButtonMask> button_mask = MouseButtonMask::NONE;
 
 
 	Vector2 pos;
 	Vector2 pos;
 	Vector2 global_pos;
 	Vector2 global_pos;

+ 73 - 0
core/templates/bit_field.h

@@ -0,0 +1,73 @@
+/**************************************************************************/
+/*  bit_field.h                                                           */
+/**************************************************************************/
+/*                         This file is part of:                          */
+/*                             GODOT ENGINE                               */
+/*                        https://godotengine.org                         */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */
+/*                                                                        */
+/* Permission is hereby granted, free of charge, to any person obtaining  */
+/* a copy of this software and associated documentation files (the        */
+/* "Software"), to deal in the Software without restriction, including    */
+/* without limitation the rights to use, copy, modify, merge, publish,    */
+/* distribute, sublicense, and/or sell copies of the Software, and to     */
+/* permit persons to whom the Software is furnished to do so, subject to  */
+/* the following conditions:                                              */
+/*                                                                        */
+/* The above copyright notice and this permission notice shall be         */
+/* included in all copies or substantial portions of the Software.        */
+/*                                                                        */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */
+/**************************************************************************/
+
+#pragma once
+
+#include "core/typedefs.h"
+
+#include <type_traits>
+
+// TODO: Replace `typename` with enum concept once C++20 concepts/constraints are allowed.
+
+template <typename T>
+class BitField {
+	static_assert(std::is_enum_v<T>);
+	uint64_t value;
+
+public:
+	_ALWAYS_INLINE_ constexpr void set_flag(BitField p_flag) { value |= p_flag.value; }
+	_ALWAYS_INLINE_ constexpr bool has_flag(BitField p_flag) const { return value & p_flag.value; }
+	_ALWAYS_INLINE_ constexpr bool is_empty() const { return value == 0; }
+	_ALWAYS_INLINE_ constexpr void clear_flag(BitField p_flag) { value &= ~p_flag.value; }
+	_ALWAYS_INLINE_ constexpr void clear() { value = 0; }
+
+	[[nodiscard]] _ALWAYS_INLINE_ constexpr BitField get_combined(BitField p_other) const { return BitField(value | p_other.value); }
+	[[nodiscard]] _ALWAYS_INLINE_ constexpr BitField get_shared(BitField p_other) const { return BitField(value & p_other.value); }
+	[[nodiscard]] _ALWAYS_INLINE_ constexpr BitField get_different(BitField p_other) const { return BitField(value ^ p_other.value); }
+
+	_ALWAYS_INLINE_ constexpr BitField() = default;
+	_ALWAYS_INLINE_ constexpr BitField(T p_value) :
+			value(static_cast<uint64_t>(p_value)) {}
+	_ALWAYS_INLINE_ constexpr operator T() const { return static_cast<T>(value); }
+
+	// TODO: Unify as single constructor once C++20 `explicit` conditionals are allowed.
+
+	template <typename V, std::enable_if_t<std::is_arithmetic_v<V> && std::is_convertible_v<T, int>, int> = 0>
+	_ALWAYS_INLINE_ constexpr BitField(V p_value) :
+			value(static_cast<uint64_t>(p_value)) {}
+	template <typename V, std::enable_if_t<std::is_arithmetic_v<V> && !std::is_convertible_v<T, int>, int> = 0>
+	_ALWAYS_INLINE_ constexpr explicit BitField(V p_value) :
+			value(static_cast<uint64_t>(p_value)) {}
+	template <typename V, std::enable_if_t<std::is_arithmetic_v<V>, int> = 0>
+	_ALWAYS_INLINE_ constexpr explicit operator V() const { return static_cast<V>(value); }
+};
+
+// Implicitly zero-constructible as a trivially-constructible type.
+static_assert(is_zero_constructible_v<BitField<Error>>);

+ 0 - 26
core/variant/binder_common.h

@@ -123,32 +123,6 @@ VARIANT_ENUM_CAST(Key);
 VARIANT_BITFIELD_CAST(KeyModifierMask);
 VARIANT_BITFIELD_CAST(KeyModifierMask);
 VARIANT_ENUM_CAST(KeyLocation);
 VARIANT_ENUM_CAST(KeyLocation);
 
 
-static inline Key &operator|=(Key &a, BitField<KeyModifierMask> b) {
-	a = static_cast<Key>(static_cast<int>(a) | static_cast<int>(b.operator int64_t()));
-	return a;
-}
-
-static inline Key &operator&=(Key &a, BitField<KeyModifierMask> b) {
-	a = static_cast<Key>(static_cast<int>(a) & static_cast<int>(b.operator int64_t()));
-	return a;
-}
-
-static inline Key operator|(Key a, BitField<KeyModifierMask> b) {
-	return (Key)((int)a | (int)b.operator int64_t());
-}
-
-static inline Key operator&(Key a, BitField<KeyModifierMask> b) {
-	return (Key)((int)a & (int)b.operator int64_t());
-}
-
-static inline Key operator+(BitField<KeyModifierMask> a, Key b) {
-	return (Key)((int)a.operator int64_t() + (int)b);
-}
-
-static inline Key operator|(BitField<KeyModifierMask> a, Key b) {
-	return (Key)((int)a.operator int64_t() | (int)b);
-}
-
 template <>
 template <>
 struct VariantCaster<char32_t> {
 struct VariantCaster<char32_t> {
 	static _FORCE_INLINE_ char32_t cast(const Variant &p_variant) {
 	static _FORCE_INLINE_ char32_t cast(const Variant &p_variant) {

+ 0 - 23
core/variant/type_info.h

@@ -209,29 +209,6 @@ inline StringName __constant_get_enum_name(T param, const String &p_constant) {
 	return GetTypeInfo<T>::get_class_info().class_name;
 	return GetTypeInfo<T>::get_class_info().class_name;
 }
 }
 
 
-template <typename T>
-class BitField {
-	int64_t value = 0;
-
-public:
-	_FORCE_INLINE_ BitField<T> &set_flag(T p_flag) {
-		value |= (int64_t)p_flag;
-		return *this;
-	}
-	_FORCE_INLINE_ bool has_flag(T p_flag) const { return value & (int64_t)p_flag; }
-	_FORCE_INLINE_ bool is_empty() const { return value == 0; }
-	_FORCE_INLINE_ void clear_flag(T p_flag) { value &= ~(int64_t)p_flag; }
-	_FORCE_INLINE_ void clear() { value = 0; }
-	_FORCE_INLINE_ constexpr BitField() = default;
-	_FORCE_INLINE_ constexpr BitField(int64_t p_value) { value = p_value; }
-	_FORCE_INLINE_ constexpr BitField(T p_value) { value = (int64_t)p_value; }
-	_FORCE_INLINE_ operator int64_t() const { return value; }
-	_FORCE_INLINE_ BitField<T> operator^(const BitField<T> &p_b) const { return BitField<T>(value ^ p_b.value); }
-};
-
-template <typename T>
-struct is_zero_constructible<BitField<T>> : std::true_type {};
-
 #define MAKE_BITFIELD_TYPE_INFO(m_enum)                                                                                                          \
 #define MAKE_BITFIELD_TYPE_INFO(m_enum)                                                                                                          \
 	template <>                                                                                                                                  \
 	template <>                                                                                                                                  \
 	struct GetTypeInfo<m_enum> {                                                                                                                 \
 	struct GetTypeInfo<m_enum> {                                                                                                                 \

+ 5 - 4
core/variant/variant.h

@@ -54,6 +54,7 @@
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
 #include "core/string/node_path.h"
 #include "core/string/node_path.h"
 #include "core/string/ustring.h"
 #include "core/string/ustring.h"
+#include "core/templates/bit_field.h"
 #include "core/templates/list.h"
 #include "core/templates/list.h"
 #include "core/templates/paged_allocator.h"
 #include "core/templates/paged_allocator.h"
 #include "core/templates/rid.h"
 #include "core/templates/rid.h"
@@ -485,8 +486,8 @@ public:
 
 
 	template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
 	template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
 	_FORCE_INLINE_ operator T() const { return static_cast<T>(operator int64_t()); }
 	_FORCE_INLINE_ operator T() const { return static_cast<T>(operator int64_t()); }
-	template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
-	_FORCE_INLINE_ operator BitField<T>() const { return static_cast<T>(operator int64_t()); }
+	template <typename T>
+	_FORCE_INLINE_ operator BitField<T>() const { return static_cast<T>(operator uint64_t()); }
 
 
 	Object *get_validated_object() const;
 	Object *get_validated_object() const;
 	Object *get_validated_object_with_check(bool &r_previously_freed) const;
 	Object *get_validated_object_with_check(bool &r_previously_freed) const;
@@ -554,9 +555,9 @@ public:
 	template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
 	template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
 	_FORCE_INLINE_ Variant(T p_enum) :
 	_FORCE_INLINE_ Variant(T p_enum) :
 			Variant(static_cast<int64_t>(p_enum)) {}
 			Variant(static_cast<int64_t>(p_enum)) {}
-	template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
+	template <typename T>
 	_FORCE_INLINE_ Variant(BitField<T> p_bitfield) :
 	_FORCE_INLINE_ Variant(BitField<T> p_bitfield) :
-			Variant(static_cast<int64_t>(p_bitfield)) {}
+			Variant(static_cast<uint64_t>(p_bitfield)) {}
 
 
 	// If this changes the table in variant_op must be updated
 	// If this changes the table in variant_op must be updated
 	enum Operator {
 	enum Operator {

+ 1 - 1
drivers/d3d12/rendering_device_driver_d3d12.cpp

@@ -3058,7 +3058,7 @@ Vector<uint8_t> RenderingDeviceDriverD3D12::shader_compile_binary_from_spirv(Vec
 
 
 	// Translate SPIR-V shaders to DXIL, and collect shader info from the new representation.
 	// Translate SPIR-V shaders to DXIL, and collect shader info from the new representation.
 	HashMap<ShaderStage, Vector<uint8_t>> dxil_blobs;
 	HashMap<ShaderStage, Vector<uint8_t>> dxil_blobs;
-	BitField<ShaderStage> stages_processed;
+	BitField<ShaderStage> stages_processed = {};
 	{
 	{
 		HashMap<int, nir_shader *> stages_nir_shaders;
 		HashMap<int, nir_shader *> stages_nir_shaders;
 
 

+ 1 - 1
drivers/metal/metal_objects.mm

@@ -612,7 +612,7 @@ void MDCommandBuffer::_render_clear_render_area() {
 	bool shouldClearStencil = (ds_index != RDD::AttachmentReference::UNUSED && pass.attachments[ds_index].shouldClear(subpass, true));
 	bool shouldClearStencil = (ds_index != RDD::AttachmentReference::UNUSED && pass.attachments[ds_index].shouldClear(subpass, true));
 	if (shouldClearDepth || shouldClearStencil) {
 	if (shouldClearDepth || shouldClearStencil) {
 		MDAttachment const &attachment = pass.attachments[ds_index];
 		MDAttachment const &attachment = pass.attachments[ds_index];
-		BitField<RDD::TextureAspectBits> bits;
+		BitField<RDD::TextureAspectBits> bits = {};
 		if (shouldClearDepth && attachment.type & MDAttachmentType::Depth) {
 		if (shouldClearDepth && attachment.type & MDAttachmentType::Depth) {
 			bits.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT);
 			bits.set_flag(RDD::TEXTURE_ASPECT_DEPTH_BIT);
 		}
 		}

+ 2 - 2
drivers/metal/rendering_device_driver_metal.mm

@@ -2524,7 +2524,7 @@ RDD::ShaderID RenderingDeviceDriverMetal::shader_create_from_bytecode(const Vect
 			su.writable = uniform.writable;
 			su.writable = uniform.writable;
 			su.length = uniform.length;
 			su.length = uniform.length;
 			su.binding = uniform.binding;
 			su.binding = uniform.binding;
-			su.stages = uniform.stages;
+			su.stages = (ShaderStage)(uint8_t)uniform.stages;
 			uset.write[i] = su;
 			uset.write[i] = su;
 
 
 			UniformInfo ui;
 			UniformInfo ui;
@@ -2590,7 +2590,7 @@ RDD::ShaderID RenderingDeviceDriverMetal::shader_create_from_bytecode(const Vect
 		sc.type = c.type;
 		sc.type = c.type;
 		sc.constant_id = c.constant_id;
 		sc.constant_id = c.constant_id;
 		sc.int_value = c.int_value;
 		sc.int_value = c.int_value;
-		sc.stages = c.stages;
+		sc.stages = (ShaderStage)(uint8_t)c.stages;
 		r_shader_desc.specialization_constants.write[i] = sc;
 		r_shader_desc.specialization_constants.write[i] = sc;
 	}
 	}
 
 

+ 1 - 1
drivers/vulkan/rendering_device_driver_vulkan.cpp

@@ -2593,7 +2593,7 @@ RDD::CommandQueueFamilyID RenderingDeviceDriverVulkan::command_queue_family_get(
 		// Preferring a queue with less bits will get us closer to getting a queue that performs better for our requirements.
 		// Preferring a queue with less bits will get us closer to getting a queue that performs better for our requirements.
 		// For example, dedicated compute and transfer queues are usually indicated as such.
 		// For example, dedicated compute and transfer queues are usually indicated as such.
 		const VkQueueFlags option_queue_flags = queue_family_properties[i].queueFlags;
 		const VkQueueFlags option_queue_flags = queue_family_properties[i].queueFlags;
-		const bool includes_all_bits = (option_queue_flags & p_cmd_queue_family_bits) == p_cmd_queue_family_bits;
+		const bool includes_all_bits = p_cmd_queue_family_bits.get_shared(option_queue_flags) == p_cmd_queue_family_bits;
 		const bool prefer_less_bits = option_queue_flags < picked_queue_flags;
 		const bool prefer_less_bits = option_queue_flags < picked_queue_flags;
 		if (includes_all_bits && prefer_less_bits) {
 		if (includes_all_bits && prefer_less_bits) {
 			picked_family_index = i;
 			picked_family_index = i;

+ 1 - 1
editor/gui/editor_quick_open_dialog.cpp

@@ -606,7 +606,7 @@ void QuickOpenResultContainer::handle_search_box_input(const Ref<InputEvent> &p_
 			case Key::RIGHT: {
 			case Key::RIGHT: {
 				if (content_display_mode == QuickOpenDisplayMode::GRID) {
 				if (content_display_mode == QuickOpenDisplayMode::GRID) {
 					// Maybe strip off the shift modifier to allow non-selecting navigation by character?
 					// Maybe strip off the shift modifier to allow non-selecting navigation by character?
-					if (key_event->get_modifiers_mask() == 0) {
+					if (key_event->get_modifiers_mask().is_empty()) {
 						move_selection = true;
 						move_selection = true;
 					}
 					}
 				}
 				}

+ 1 - 1
main/main.cpp

@@ -3799,7 +3799,7 @@ int Main::start() {
 #ifdef TOOLS_ENABLED
 #ifdef TOOLS_ENABLED
 	String doc_tool_path;
 	String doc_tool_path;
 	bool doc_tool_implicit_cwd = false;
 	bool doc_tool_implicit_cwd = false;
-	BitField<DocTools::GenerateFlags> gen_flags;
+	BitField<DocTools::GenerateFlags> gen_flags = {};
 	String _export_preset;
 	String _export_preset;
 	Vector<String> patches;
 	Vector<String> patches;
 	bool export_debug = false;
 	bool export_debug = false;

+ 3 - 3
modules/gdscript/gdscript_analyzer.cpp

@@ -1803,7 +1803,7 @@ void GDScriptAnalyzer::resolve_function_signature(GDScriptParser::FunctionNode *
 		GDScriptParser::DataType parent_return_type;
 		GDScriptParser::DataType parent_return_type;
 		List<GDScriptParser::DataType> parameters_types;
 		List<GDScriptParser::DataType> parameters_types;
 		int default_par_count = 0;
 		int default_par_count = 0;
-		BitField<MethodFlags> method_flags;
+		BitField<MethodFlags> method_flags = {};
 		StringName native_base;
 		StringName native_base;
 		if (!p_is_lambda && get_function_signature(p_function, false, base_type, function_name, parent_return_type, parameters_types, default_par_count, method_flags, &native_base)) {
 		if (!p_is_lambda && get_function_signature(p_function, false, base_type, function_name, parent_return_type, parameters_types, default_par_count, method_flags, &native_base)) {
 			bool valid = p_function->is_static == method_flags.has_flag(METHOD_FLAG_STATIC);
 			bool valid = p_function->is_static == method_flags.has_flag(METHOD_FLAG_STATIC);
@@ -2276,7 +2276,7 @@ void GDScriptAnalyzer::resolve_for(GDScriptParser::ForNode *p_for) {
 			GDScriptParser::DataType return_type;
 			GDScriptParser::DataType return_type;
 			List<GDScriptParser::DataType> par_types;
 			List<GDScriptParser::DataType> par_types;
 			int default_arg_count = 0;
 			int default_arg_count = 0;
-			BitField<MethodFlags> method_flags;
+			BitField<MethodFlags> method_flags = {};
 			if (get_function_signature(p_for->list, false, list_type, CoreStringName(_iter_get), return_type, par_types, default_arg_count, method_flags)) {
 			if (get_function_signature(p_for->list, false, list_type, CoreStringName(_iter_get), return_type, par_types, default_arg_count, method_flags)) {
 				variable_type = return_type;
 				variable_type = return_type;
 				variable_type.type_source = list_type.type_source;
 				variable_type.type_source = list_type.type_source;
@@ -3567,7 +3567,7 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a
 	}
 	}
 
 
 	int default_arg_count = 0;
 	int default_arg_count = 0;
-	BitField<MethodFlags> method_flags;
+	BitField<MethodFlags> method_flags = {};
 	GDScriptParser::DataType return_type;
 	GDScriptParser::DataType return_type;
 	List<GDScriptParser::DataType> par_types;
 	List<GDScriptParser::DataType> par_types;
 
 

+ 1 - 1
modules/openxr/extensions/openxr_hand_tracking_extension.cpp

@@ -263,7 +263,7 @@ void OpenXRHandTrackingExtension::on_process() {
 					Transform3D transform;
 					Transform3D transform;
 					Vector3 linear_velocity;
 					Vector3 linear_velocity;
 					Vector3 angular_velocity;
 					Vector3 angular_velocity;
-					BitField<XRHandTracker::HandJointFlags> flags;
+					BitField<XRHandTracker::HandJointFlags> flags = {};
 
 
 					if (location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT) {
 					if (location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT) {
 						if (pose.orientation.x != 0 || pose.orientation.y != 0 || pose.orientation.z != 0 || pose.orientation.w != 0) {
 						if (pose.orientation.x != 0 || pose.orientation.y != 0 || pose.orientation.z != 0 || pose.orientation.w != 0) {

+ 1 - 1
modules/openxr/openxr_interface.cpp

@@ -1466,7 +1466,7 @@ OpenXRInterface::HandTrackedSource OpenXRInterface::get_hand_tracking_source(con
 }
 }
 
 
 BitField<OpenXRInterface::HandJointFlags> OpenXRInterface::get_hand_joint_flags(Hand p_hand, HandJoints p_joint) const {
 BitField<OpenXRInterface::HandJointFlags> OpenXRInterface::get_hand_joint_flags(Hand p_hand, HandJoints p_joint) const {
-	BitField<OpenXRInterface::HandJointFlags> bits;
+	BitField<OpenXRInterface::HandJointFlags> bits = HAND_JOINT_NONE;
 
 
 	OpenXRHandTrackingExtension *hand_tracking_ext = OpenXRHandTrackingExtension::get_singleton();
 	OpenXRHandTrackingExtension *hand_tracking_ext = OpenXRHandTrackingExtension::get_singleton();
 	if (hand_tracking_ext && hand_tracking_ext->get_active()) {
 	if (hand_tracking_ext && hand_tracking_ext->get_active()) {

+ 4 - 4
platform/android/android_input_handler.cpp

@@ -283,7 +283,7 @@ void AndroidInputHandler::_parse_mouse_event_info(BitField<MouseButtonMask> even
 	}
 	}
 	ev->set_pressed(p_pressed);
 	ev->set_pressed(p_pressed);
 	ev->set_canceled(p_canceled);
 	ev->set_canceled(p_canceled);
-	BitField<MouseButtonMask> changed_button_mask = BitField<MouseButtonMask>(buttons_state.operator int64_t() ^ event_buttons_mask.operator int64_t());
+	BitField<MouseButtonMask> changed_button_mask = buttons_state.get_different(event_buttons_mask);
 
 
 	buttons_state = event_buttons_mask;
 	buttons_state = event_buttons_mask;
 
 
@@ -395,7 +395,7 @@ void AndroidInputHandler::_wheel_button_click(BitField<MouseButtonMask> event_bu
 	Ref<InputEventMouseButton> evd = ev->duplicate();
 	Ref<InputEventMouseButton> evd = ev->duplicate();
 	_set_key_modifier_state(evd, Key::NONE);
 	_set_key_modifier_state(evd, Key::NONE);
 	evd->set_button_index(wheel_button);
 	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_button_mask(event_buttons_mask.get_different(mouse_button_to_mask(wheel_button)));
 	evd->set_factor(factor);
 	evd->set_factor(factor);
 	Input::get_singleton()->parse_input_event(evd);
 	Input::get_singleton()->parse_input_event(evd);
 	Ref<InputEventMouseButton> evdd = evd->duplicate();
 	Ref<InputEventMouseButton> evdd = evd->duplicate();
@@ -423,7 +423,7 @@ void AndroidInputHandler::process_pan(Point2 p_pos, Vector2 p_delta) {
 }
 }
 
 
 MouseButton AndroidInputHandler::_button_index_from_mask(BitField<MouseButtonMask> button_mask) {
 MouseButton AndroidInputHandler::_button_index_from_mask(BitField<MouseButtonMask> button_mask) {
-	switch (MouseButtonMask(button_mask.operator int64_t())) {
+	switch (button_mask) {
 		case MouseButtonMask::LEFT:
 		case MouseButtonMask::LEFT:
 			return MouseButton::LEFT;
 			return MouseButton::LEFT;
 		case MouseButtonMask::RIGHT:
 		case MouseButtonMask::RIGHT:
@@ -440,7 +440,7 @@ MouseButton AndroidInputHandler::_button_index_from_mask(BitField<MouseButtonMas
 }
 }
 
 
 BitField<MouseButtonMask> AndroidInputHandler::_android_button_mask_to_godot_button_mask(int android_button_mask) {
 BitField<MouseButtonMask> AndroidInputHandler::_android_button_mask_to_godot_button_mask(int android_button_mask) {
-	BitField<MouseButtonMask> godot_button_mask;
+	BitField<MouseButtonMask> godot_button_mask = MouseButtonMask::NONE;
 	if (android_button_mask & AMOTION_EVENT_BUTTON_PRIMARY) {
 	if (android_button_mask & AMOTION_EVENT_BUTTON_PRIMARY) {
 		godot_button_mask.set_flag(MouseButtonMask::LEFT);
 		godot_button_mask.set_flag(MouseButtonMask::LEFT);
 	}
 	}

+ 2 - 2
platform/android/android_input_handler.h

@@ -62,7 +62,7 @@ public:
 		int index = 0; // Can be either JoyAxis or JoyButton.
 		int index = 0; // Can be either JoyAxis or JoyButton.
 		bool pressed = false;
 		bool pressed = false;
 		float value = 0;
 		float value = 0;
-		BitField<HatMask> hat;
+		BitField<HatMask> hat = HatMask::CENTER;
 	};
 	};
 
 
 private:
 private:
@@ -71,7 +71,7 @@ private:
 	bool control_mem = false;
 	bool control_mem = false;
 	bool meta_mem = false;
 	bool meta_mem = false;
 
 
-	BitField<MouseButtonMask> buttons_state;
+	BitField<MouseButtonMask> buttons_state = MouseButtonMask::NONE;
 
 
 	Vector<TouchPos> touch;
 	Vector<TouchPos> touch;
 	MouseEventInfo mouse_event_info;
 	MouseEventInfo mouse_event_info;

+ 1 - 1
platform/android/java_godot_lib_jni.cpp

@@ -398,7 +398,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, j
 	AndroidInputHandler::JoypadEvent jevent;
 	AndroidInputHandler::JoypadEvent jevent;
 	jevent.device = p_device;
 	jevent.device = p_device;
 	jevent.type = AndroidInputHandler::JOY_EVENT_HAT;
 	jevent.type = AndroidInputHandler::JOY_EVENT_HAT;
-	BitField<HatMask> hat;
+	BitField<HatMask> hat = HatMask::CENTER;
 	if (p_hat_x != 0) {
 	if (p_hat_x != 0) {
 		if (p_hat_x < 0) {
 		if (p_hat_x < 0) {
 			hat.set_flag(HatMask::LEFT);
 			hat.set_flag(HatMask::LEFT);

+ 1 - 1
platform/linuxbsd/joypad_linux.cpp

@@ -73,7 +73,7 @@ JoypadLinux::Joypad::~Joypad() {
 }
 }
 
 
 void JoypadLinux::Joypad::reset() {
 void JoypadLinux::Joypad::reset() {
-	dpad = 0;
+	dpad.clear();
 	fd = -1;
 	fd = -1;
 	for (int i = 0; i < MAX_ABS; i++) {
 	for (int i = 0; i < MAX_ABS; i++) {
 		abs_map[i] = -1;
 		abs_map[i] = -1;

+ 1 - 1
platform/linuxbsd/joypad_linux.h

@@ -62,7 +62,7 @@ private:
 		float curr_axis[MAX_ABS];
 		float curr_axis[MAX_ABS];
 		int key_map[MAX_KEY];
 		int key_map[MAX_KEY];
 		int abs_map[MAX_ABS];
 		int abs_map[MAX_ABS];
-		BitField<HatMask> dpad;
+		BitField<HatMask> dpad = HatMask::CENTER;
 		int fd = -1;
 		int fd = -1;
 
 
 		String devpath;
 		String devpath;

+ 1 - 1
platform/linuxbsd/wayland/display_server_wayland.h

@@ -144,7 +144,7 @@ class DisplayServerWayland : public DisplayServer {
 	// are the "take all input thx" windows while the `popup_stack` variable keeps
 	// are the "take all input thx" windows while the `popup_stack` variable keeps
 	// track of all the generic floating window concept.
 	// track of all the generic floating window concept.
 	List<WindowID> popup_menu_list;
 	List<WindowID> popup_menu_list;
-	BitField<MouseButtonMask> last_mouse_monitor_mask;
+	BitField<MouseButtonMask> last_mouse_monitor_mask = MouseButtonMask::NONE;
 
 
 	String ime_text;
 	String ime_text;
 	Vector2i ime_selection;
 	Vector2i ime_selection;

+ 2 - 2
platform/linuxbsd/wayland/wayland_thread.cpp

@@ -1779,7 +1779,7 @@ void WaylandThread::_wl_pointer_on_frame(void *data, struct wl_pointer *wl_point
 	}
 	}
 
 
 	if (old_pd.pressed_button_mask != pd.pressed_button_mask) {
 	if (old_pd.pressed_button_mask != pd.pressed_button_mask) {
-		BitField<MouseButtonMask> pressed_mask_delta = old_pd.pressed_button_mask ^ pd.pressed_button_mask;
+		BitField<MouseButtonMask> pressed_mask_delta = old_pd.pressed_button_mask.get_different(pd.pressed_button_mask);
 
 
 		const MouseButton buttons_to_test[] = {
 		const MouseButton buttons_to_test[] = {
 			MouseButton::LEFT,
 			MouseButton::LEFT,
@@ -2746,7 +2746,7 @@ void WaylandThread::_wp_tablet_tool_on_frame(void *data, struct zwp_tablet_tool_
 	if (old_td.pressed_button_mask != td.pressed_button_mask) {
 	if (old_td.pressed_button_mask != td.pressed_button_mask) {
 		td.button_time = time;
 		td.button_time = time;
 
 
-		BitField<MouseButtonMask> pressed_mask_delta = BitField<MouseButtonMask>((int64_t)old_td.pressed_button_mask ^ (int64_t)td.pressed_button_mask);
+		BitField<MouseButtonMask> pressed_mask_delta = old_td.pressed_button_mask.get_different(td.pressed_button_mask);
 
 
 		for (MouseButton test_button : { MouseButton::LEFT, MouseButton::RIGHT }) {
 		for (MouseButton test_button : { MouseButton::LEFT, MouseButton::RIGHT }) {
 			MouseButtonMask test_button_mask = mouse_button_to_mask(test_button);
 			MouseButtonMask test_button_mask = mouse_button_to_mask(test_button);

+ 2 - 2
platform/linuxbsd/wayland/wayland_thread.h

@@ -341,7 +341,7 @@ public:
 		Vector2 relative_motion;
 		Vector2 relative_motion;
 		uint32_t relative_motion_time = 0;
 		uint32_t relative_motion_time = 0;
 
 
-		BitField<MouseButtonMask> pressed_button_mask;
+		BitField<MouseButtonMask> pressed_button_mask = MouseButtonMask::NONE;
 
 
 		MouseButton last_button_pressed = MouseButton::NONE;
 		MouseButton last_button_pressed = MouseButton::NONE;
 		Point2 last_pressed_position;
 		Point2 last_pressed_position;
@@ -371,7 +371,7 @@ public:
 		Vector2 tilt;
 		Vector2 tilt;
 		uint32_t pressure = 0;
 		uint32_t pressure = 0;
 
 
-		BitField<MouseButtonMask> pressed_button_mask;
+		BitField<MouseButtonMask> pressed_button_mask = MouseButtonMask::NONE;
 
 
 		MouseButton last_button_pressed = MouseButton::NONE;
 		MouseButton last_button_pressed = MouseButton::NONE;
 		Point2 last_pressed_position;
 		Point2 last_pressed_position;

+ 3 - 3
platform/linuxbsd/x11/display_server_x11.cpp

@@ -622,7 +622,7 @@ BitField<MouseButtonMask> DisplayServerX11::mouse_get_button_state() const {
 		int root_x, root_y, win_x, win_y;
 		int root_x, root_y, win_x, win_y;
 		unsigned int mask;
 		unsigned int mask;
 		if (XQueryPointer(x11_display, XRootWindow(x11_display, i), &root, &child, &root_x, &root_y, &win_x, &win_y, &mask)) {
 		if (XQueryPointer(x11_display, XRootWindow(x11_display, i), &root, &child, &root_x, &root_y, &win_x, &win_y, &mask)) {
-			BitField<MouseButtonMask> last_button_state = 0;
+			BitField<MouseButtonMask> last_button_state = MouseButtonMask::NONE;
 
 
 			if (mask & Button1Mask) {
 			if (mask & Button1Mask) {
 				last_button_state.set_flag(MouseButtonMask::LEFT);
 				last_button_state.set_flag(MouseButtonMask::LEFT);
@@ -643,7 +643,7 @@ BitField<MouseButtonMask> DisplayServerX11::mouse_get_button_state() const {
 			return last_button_state;
 			return last_button_state;
 		}
 		}
 	}
 	}
-	return 0;
+	return MouseButtonMask::NONE;
 }
 }
 
 
 void DisplayServerX11::clipboard_set(const String &p_text) {
 void DisplayServerX11::clipboard_set(const String &p_text) {
@@ -5318,7 +5318,7 @@ void DisplayServerX11::process_events() {
 					pos = Point2i(windows[focused_window_id].size.width / 2, windows[focused_window_id].size.height / 2);
 					pos = Point2i(windows[focused_window_id].size.width / 2, windows[focused_window_id].size.height / 2);
 				}
 				}
 
 
-				BitField<MouseButtonMask> last_button_state = 0;
+				BitField<MouseButtonMask> last_button_state = MouseButtonMask::NONE;
 				if (event.xmotion.state & Button1Mask) {
 				if (event.xmotion.state & Button1Mask) {
 					last_button_state.set_flag(MouseButtonMask::LEFT);
 					last_button_state.set_flag(MouseButtonMask::LEFT);
 				}
 				}

+ 1 - 1
platform/macos/display_server_macos.mm

@@ -1614,7 +1614,7 @@ Point2i DisplayServerMacOS::mouse_get_position() const {
 }
 }
 
 
 BitField<MouseButtonMask> DisplayServerMacOS::mouse_get_button_state() const {
 BitField<MouseButtonMask> DisplayServerMacOS::mouse_get_button_state() const {
-	BitField<MouseButtonMask> last_button_state = 0;
+	BitField<MouseButtonMask> last_button_state = MouseButtonMask::NONE;
 
 
 	NSUInteger buttons = [NSEvent pressedMouseButtons];
 	NSUInteger buttons = [NSEvent pressedMouseButtons];
 	if (buttons & (1 << 0)) {
 	if (buttons & (1 << 0)) {

+ 4 - 4
platform/windows/display_server_windows.cpp

@@ -922,7 +922,7 @@ Point2i DisplayServerWindows::mouse_get_position() const {
 }
 }
 
 
 BitField<MouseButtonMask> DisplayServerWindows::mouse_get_button_state() const {
 BitField<MouseButtonMask> DisplayServerWindows::mouse_get_button_state() const {
-	BitField<MouseButtonMask> last_button_state = 0;
+	BitField<MouseButtonMask> last_button_state = MouseButtonMask::NONE;
 
 
 	if (GetKeyState(VK_LBUTTON) & (1 << 15)) {
 	if (GetKeyState(VK_LBUTTON) & (1 << 15)) {
 		last_button_state.set_flag(MouseButtonMask::LEFT);
 		last_button_state.set_flag(MouseButtonMask::LEFT);
@@ -4526,7 +4526,7 @@ void DisplayServerWindows::popup_close(WindowID p_window) {
 }
 }
 
 
 BitField<DisplayServerWindows::WinKeyModifierMask> DisplayServerWindows::_get_mods() const {
 BitField<DisplayServerWindows::WinKeyModifierMask> DisplayServerWindows::_get_mods() const {
-	BitField<WinKeyModifierMask> mask;
+	BitField<WinKeyModifierMask> mask = {};
 	static unsigned char keyboard_state[256];
 	static unsigned char keyboard_state[256];
 	if (GetKeyboardState((PBYTE)&keyboard_state)) {
 	if (GetKeyboardState((PBYTE)&keyboard_state)) {
 		if ((keyboard_state[VK_LSHIFT] & 0x80) || (keyboard_state[VK_RSHIFT] & 0x80)) {
 		if ((keyboard_state[VK_LSHIFT] & 0x80) || (keyboard_state[VK_RSHIFT] & 0x80)) {
@@ -5136,7 +5136,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
 			mb.instantiate();
 			mb.instantiate();
 			mb->set_window_id(window_id);
 			mb->set_window_id(window_id);
 
 
-			BitField<MouseButtonMask> last_button_state = 0;
+			BitField<MouseButtonMask> last_button_state = MouseButtonMask::NONE;
 			if (IS_POINTER_FIRSTBUTTON_WPARAM(wParam)) {
 			if (IS_POINTER_FIRSTBUTTON_WPARAM(wParam)) {
 				last_button_state.set_flag(MouseButtonMask::LEFT);
 				last_button_state.set_flag(MouseButtonMask::LEFT);
 				mb->set_button_index(MouseButton::LEFT);
 				mb->set_button_index(MouseButton::LEFT);
@@ -5302,7 +5302,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
 			mm->set_alt_pressed(mods.has_flag(WinKeyModifierMask::ALT));
 			mm->set_alt_pressed(mods.has_flag(WinKeyModifierMask::ALT));
 			mm->set_meta_pressed(mods.has_flag(WinKeyModifierMask::META));
 			mm->set_meta_pressed(mods.has_flag(WinKeyModifierMask::META));
 
 
-			BitField<MouseButtonMask> last_button_state = 0;
+			BitField<MouseButtonMask> last_button_state = MouseButtonMask::NONE;
 			if (IS_POINTER_FIRSTBUTTON_WPARAM(wParam)) {
 			if (IS_POINTER_FIRSTBUTTON_WPARAM(wParam)) {
 				last_button_state.set_flag(MouseButtonMask::LEFT);
 				last_button_state.set_flag(MouseButtonMask::LEFT);
 			}
 			}

+ 1 - 1
platform/windows/joypad_windows.cpp

@@ -479,7 +479,7 @@ void JoypadWindows::process_joypads() {
 }
 }
 
 
 void JoypadWindows::post_hat(int p_device, DWORD p_dpad) {
 void JoypadWindows::post_hat(int p_device, DWORD p_dpad) {
-	BitField<HatMask> dpad_val;
+	BitField<HatMask> dpad_val = HatMask::CENTER;
 
 
 	// Should be -1 when centered, but according to docs:
 	// Should be -1 when centered, but according to docs:
 	// "Some drivers report the centered position of the POV indicator as 65,535. Determine whether the indicator is centered as follows:
 	// "Some drivers report the centered position of the POV indicator as 65,535. Determine whether the indicator is centered as follows:

+ 1 - 1
scene/gui/popup_menu.h

@@ -122,7 +122,7 @@ class PopupMenu : public Popup {
 	Timer *submenu_timer = nullptr;
 	Timer *submenu_timer = nullptr;
 	List<Rect2> autohide_areas;
 	List<Rect2> autohide_areas;
 	mutable Vector<Item> items;
 	mutable Vector<Item> items;
-	BitField<MouseButtonMask> initial_button_mask;
+	BitField<MouseButtonMask> initial_button_mask = MouseButtonMask::NONE;
 	bool during_grabbed_click = false;
 	bool during_grabbed_click = false;
 	bool is_scrolling = false;
 	bool is_scrolling = false;
 	int mouse_over = -1;
 	int mouse_over = -1;

+ 1 - 1
scene/main/node.h

@@ -204,7 +204,7 @@ private:
 		ProcessThreadGroup process_thread_group = PROCESS_THREAD_GROUP_INHERIT;
 		ProcessThreadGroup process_thread_group = PROCESS_THREAD_GROUP_INHERIT;
 		Node *process_thread_group_owner = nullptr;
 		Node *process_thread_group_owner = nullptr;
 		int process_thread_group_order = 0;
 		int process_thread_group_order = 0;
-		BitField<ProcessThreadMessages> process_thread_messages;
+		BitField<ProcessThreadMessages> process_thread_messages = {};
 		void *process_group = nullptr; // to avoid cyclic dependency
 		void *process_group = nullptr; // to avoid cyclic dependency
 
 
 		int multiplayer_authority = 1; // Server by default.
 		int multiplayer_authority = 1; // Server by default.

+ 1 - 1
scene/main/viewport.h

@@ -367,7 +367,7 @@ private:
 		HashMap<int, ObjectID> touch_focus;
 		HashMap<int, ObjectID> touch_focus;
 		Control *mouse_focus = nullptr;
 		Control *mouse_focus = nullptr;
 		Control *mouse_click_grabber = nullptr;
 		Control *mouse_click_grabber = nullptr;
-		BitField<MouseButtonMask> mouse_focus_mask;
+		BitField<MouseButtonMask> mouse_focus_mask = MouseButtonMask::NONE;
 		Control *key_focus = nullptr;
 		Control *key_focus = nullptr;
 		Control *mouse_over = nullptr;
 		Control *mouse_over = nullptr;
 		LocalVector<Control *> mouse_over_hierarchy;
 		LocalVector<Control *> mouse_over_hierarchy;

+ 3 - 3
scene/resources/font.cpp

@@ -298,7 +298,7 @@ void Font::set_cache_capacity(int p_single_line, int p_multi_line) {
 
 
 Size2 Font::get_string_size(const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
 Size2 Font::get_string_size(const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
 	bool fill = (p_alignment == HORIZONTAL_ALIGNMENT_FILL);
 	bool fill = (p_alignment == HORIZONTAL_ALIGNMENT_FILL);
-	ShapedTextKey key = ShapedTextKey(p_text, p_font_size, fill ? p_width : 0.0, fill ? p_jst_flags : TextServer::JUSTIFICATION_NONE, TextServer::BREAK_NONE, p_direction, p_orientation);
+	ShapedTextKey key = ShapedTextKey(p_text, p_font_size, fill ? p_width : 0.0, fill ? p_jst_flags : BitField(TextServer::JUSTIFICATION_NONE), TextServer::BREAK_NONE, p_direction, p_orientation);
 
 
 	Ref<TextLine> buffer;
 	Ref<TextLine> buffer;
 	if (cache.has(key)) {
 	if (cache.has(key)) {
@@ -347,7 +347,7 @@ Size2 Font::get_multiline_string_size(const String &p_text, HorizontalAlignment
 
 
 void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
 void Font::draw_string(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
 	bool fill = (p_alignment == HORIZONTAL_ALIGNMENT_FILL);
 	bool fill = (p_alignment == HORIZONTAL_ALIGNMENT_FILL);
-	ShapedTextKey key = ShapedTextKey(p_text, p_font_size, fill ? p_width : 0.0, fill ? p_jst_flags : TextServer::JUSTIFICATION_NONE, TextServer::BREAK_NONE, p_direction, p_orientation);
+	ShapedTextKey key = ShapedTextKey(p_text, p_font_size, fill ? p_width : 0.0, fill ? p_jst_flags : BitField(TextServer::JUSTIFICATION_NONE), TextServer::BREAK_NONE, p_direction, p_orientation);
 
 
 	Ref<TextLine> buffer;
 	Ref<TextLine> buffer;
 	if (cache.has(key)) {
 	if (cache.has(key)) {
@@ -410,7 +410,7 @@ void Font::draw_multiline_string(RID p_canvas_item, const Point2 &p_pos, const S
 
 
 void Font::draw_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
 void Font::draw_string_outline(RID p_canvas_item, const Point2 &p_pos, const String &p_text, HorizontalAlignment p_alignment, float p_width, int p_font_size, int p_size, const Color &p_modulate, BitField<TextServer::JustificationFlag> p_jst_flags, TextServer::Direction p_direction, TextServer::Orientation p_orientation) const {
 	bool fill = (p_alignment == HORIZONTAL_ALIGNMENT_FILL);
 	bool fill = (p_alignment == HORIZONTAL_ALIGNMENT_FILL);
-	ShapedTextKey key = ShapedTextKey(p_text, p_font_size, fill ? p_width : 0.0, fill ? p_jst_flags : TextServer::JUSTIFICATION_NONE, TextServer::BREAK_NONE, p_direction, p_orientation);
+	ShapedTextKey key = ShapedTextKey(p_text, p_font_size, fill ? p_width : 0.0, fill ? p_jst_flags : BitField(TextServer::JUSTIFICATION_NONE), TextServer::BREAK_NONE, p_direction, p_orientation);
 
 
 	Ref<TextLine> buffer;
 	Ref<TextLine> buffer;
 	if (cache.has(key)) {
 	if (cache.has(key)) {

+ 1 - 1
servers/display_server.cpp

@@ -528,7 +528,7 @@ Point2i DisplayServer::mouse_get_position() const {
 }
 }
 
 
 BitField<MouseButtonMask> DisplayServer::mouse_get_button_state() const {
 BitField<MouseButtonMask> DisplayServer::mouse_get_button_state() const {
-	ERR_FAIL_V_MSG(0, "Mouse is not supported by this display server.");
+	ERR_FAIL_V_MSG(MouseButtonMask::NONE, "Mouse is not supported by this display server.");
 }
 }
 
 
 void DisplayServer::clipboard_set(const String &p_text) {
 void DisplayServer::clipboard_set(const String &p_text) {

+ 2 - 2
servers/rendering/rendering_device.cpp

@@ -4407,7 +4407,7 @@ RenderingDevice::DrawListID RenderingDevice::draw_list_begin(RID p_framebuffer,
 	thread_local LocalVector<RDD::RenderPassClearValue> clear_values;
 	thread_local LocalVector<RDD::RenderPassClearValue> clear_values;
 	thread_local LocalVector<RDG::ResourceTracker *> resource_trackers;
 	thread_local LocalVector<RDG::ResourceTracker *> resource_trackers;
 	thread_local LocalVector<RDG::ResourceUsage> resource_usages;
 	thread_local LocalVector<RDG::ResourceUsage> resource_usages;
-	BitField<RDD::PipelineStageBits> stages;
+	BitField<RDD::PipelineStageBits> stages = {};
 	operations.resize(framebuffer->texture_ids.size());
 	operations.resize(framebuffer->texture_ids.size());
 	clear_values.resize(framebuffer->texture_ids.size());
 	clear_values.resize(framebuffer->texture_ids.size());
 	resource_trackers.clear();
 	resource_trackers.clear();
@@ -6694,7 +6694,7 @@ Error RenderingDevice::initialize(RenderingContextDriver *p_context, DisplayServ
 	// Pick the main queue family. It is worth noting we explicitly do not request the transfer bit, as apparently the specification defines
 	// Pick the main queue family. It is worth noting we explicitly do not request the transfer bit, as apparently the specification defines
 	// that the existence of either the graphics or compute bit implies that the queue can also do transfer operations, but it is optional
 	// that the existence of either the graphics or compute bit implies that the queue can also do transfer operations, but it is optional
 	// to indicate whether it supports them or not with the dedicated transfer bit if either is set.
 	// to indicate whether it supports them or not with the dedicated transfer bit if either is set.
-	BitField<RDD::CommandQueueFamilyBits> main_queue_bits;
+	BitField<RDD::CommandQueueFamilyBits> main_queue_bits = {};
 	main_queue_bits.set_flag(RDD::COMMAND_QUEUE_FAMILY_GRAPHICS_BIT);
 	main_queue_bits.set_flag(RDD::COMMAND_QUEUE_FAMILY_GRAPHICS_BIT);
 	main_queue_bits.set_flag(RDD::COMMAND_QUEUE_FAMILY_COMPUTE_BIT);
 	main_queue_bits.set_flag(RDD::COMMAND_QUEUE_FAMILY_COMPUTE_BIT);
 
 

+ 6 - 6
servers/rendering/rendering_device.h

@@ -170,7 +170,7 @@ private:
 		int current = 0;
 		int current = 0;
 		uint32_t block_size = 0;
 		uint32_t block_size = 0;
 		uint64_t max_size = 0;
 		uint64_t max_size = 0;
-		BitField<RDD::BufferUsageBits> usage_bits;
+		BitField<RDD::BufferUsageBits> usage_bits = {};
 		bool used = false;
 		bool used = false;
 	};
 	};
 
 
@@ -184,7 +184,7 @@ private:
 	struct Buffer {
 	struct Buffer {
 		RDD::BufferID driver_id;
 		RDD::BufferID driver_id;
 		uint32_t size = 0;
 		uint32_t size = 0;
-		BitField<RDD::BufferUsageBits> usage;
+		BitField<RDD::BufferUsageBits> usage = {};
 		RDG::ResourceTracker *draw_tracker = nullptr;
 		RDG::ResourceTracker *draw_tracker = nullptr;
 		int32_t transfer_worker_index = -1;
 		int32_t transfer_worker_index = -1;
 		uint64_t transfer_worker_operation = 0;
 		uint64_t transfer_worker_operation = 0;
@@ -315,8 +315,8 @@ public:
 		bool is_discardable = false;
 		bool is_discardable = false;
 		bool has_initial_data = false;
 		bool has_initial_data = false;
 
 
-		BitField<RDD::TextureAspectBits> read_aspect_flags;
-		BitField<RDD::TextureAspectBits> barrier_aspect_flags;
+		BitField<RDD::TextureAspectBits> read_aspect_flags = {};
+		BitField<RDD::TextureAspectBits> barrier_aspect_flags = {};
 		bool bound = false; // Bound to framebuffer.
 		bool bound = false; // Bound to framebuffer.
 		RID owner;
 		RID owner;
 
 
@@ -872,7 +872,7 @@ private:
 		String name; // Used for debug.
 		String name; // Used for debug.
 		RDD::ShaderID driver_id;
 		RDD::ShaderID driver_id;
 		uint32_t layout_hash = 0;
 		uint32_t layout_hash = 0;
-		BitField<RDD::PipelineStageBits> stage_bits;
+		BitField<RDD::PipelineStageBits> stage_bits = {};
 		Vector<uint32_t> set_formats;
 		Vector<uint32_t> set_formats;
 	};
 	};
 
 
@@ -1149,7 +1149,7 @@ private:
 		uint32_t shader_layout_hash = 0;
 		uint32_t shader_layout_hash = 0;
 		Vector<uint32_t> set_formats;
 		Vector<uint32_t> set_formats;
 		RDD::PipelineID driver_id;
 		RDD::PipelineID driver_id;
-		BitField<RDD::PipelineStageBits> stage_bits;
+		BitField<RDD::PipelineStageBits> stage_bits = {};
 		uint32_t push_constant_size = 0;
 		uint32_t push_constant_size = 0;
 	};
 	};
 
 

+ 4 - 4
servers/rendering/rendering_device_commons.h

@@ -962,7 +962,7 @@ public:
 		UniformType type = UniformType::UNIFORM_TYPE_MAX;
 		UniformType type = UniformType::UNIFORM_TYPE_MAX;
 		bool writable = false;
 		bool writable = false;
 		uint32_t binding = 0;
 		uint32_t binding = 0;
-		BitField<ShaderStage> stages;
+		BitField<ShaderStage> stages = {};
 		uint32_t length = 0; // Size of arrays (in total elements), or ubos (in bytes * total elements).
 		uint32_t length = 0; // Size of arrays (in total elements), or ubos (in bytes * total elements).
 
 
 		bool operator!=(const ShaderUniform &p_other) const {
 		bool operator!=(const ShaderUniform &p_other) const {
@@ -990,7 +990,7 @@ public:
 	};
 	};
 
 
 	struct ShaderSpecializationConstant : public PipelineSpecializationConstant {
 	struct ShaderSpecializationConstant : public PipelineSpecializationConstant {
-		BitField<ShaderStage> stages;
+		BitField<ShaderStage> stages = {};
 
 
 		bool operator<(const ShaderSpecializationConstant &p_other) const { return constant_id < p_other.constant_id; }
 		bool operator<(const ShaderSpecializationConstant &p_other) const { return constant_id < p_other.constant_id; }
 	};
 	};
@@ -1009,7 +1009,7 @@ public:
 
 
 protected:
 protected:
 	struct ShaderReflection : public ShaderDescription {
 	struct ShaderReflection : public ShaderDescription {
-		BitField<ShaderStage> stages;
-		BitField<ShaderStage> push_constant_stages;
+		BitField<ShaderStage> stages = {};
+		BitField<ShaderStage> push_constant_stages = {};
 	};
 	};
 };
 };

+ 14 - 14
servers/rendering/rendering_device_driver.h

@@ -267,14 +267,14 @@ public:
 	};
 	};
 
 
 	struct TextureSubresourceLayers {
 	struct TextureSubresourceLayers {
-		BitField<TextureAspectBits> aspect;
+		BitField<TextureAspectBits> aspect = {};
 		uint32_t mipmap = 0;
 		uint32_t mipmap = 0;
 		uint32_t base_layer = 0;
 		uint32_t base_layer = 0;
 		uint32_t layer_count = 0;
 		uint32_t layer_count = 0;
 	};
 	};
 
 
 	struct TextureSubresourceRange {
 	struct TextureSubresourceRange {
-		BitField<TextureAspectBits> aspect;
+		BitField<TextureAspectBits> aspect = {};
 		uint32_t base_mipmap = 0;
 		uint32_t base_mipmap = 0;
 		uint32_t mipmap_count = 0;
 		uint32_t mipmap_count = 0;
 		uint32_t base_layer = 0;
 		uint32_t base_layer = 0;
@@ -370,22 +370,22 @@ public:
 	};
 	};
 
 
 	struct MemoryBarrier {
 	struct MemoryBarrier {
-		BitField<BarrierAccessBits> src_access;
-		BitField<BarrierAccessBits> dst_access;
+		BitField<BarrierAccessBits> src_access = {};
+		BitField<BarrierAccessBits> dst_access = {};
 	};
 	};
 
 
 	struct BufferBarrier {
 	struct BufferBarrier {
 		BufferID buffer;
 		BufferID buffer;
-		BitField<BarrierAccessBits> src_access;
-		BitField<BarrierAccessBits> dst_access;
+		BitField<BarrierAccessBits> src_access = {};
+		BitField<BarrierAccessBits> dst_access = {};
 		uint64_t offset = 0;
 		uint64_t offset = 0;
 		uint64_t size = 0;
 		uint64_t size = 0;
 	};
 	};
 
 
 	struct TextureBarrier {
 	struct TextureBarrier {
 		TextureID texture;
 		TextureID texture;
-		BitField<BarrierAccessBits> src_access;
-		BitField<BarrierAccessBits> dst_access;
+		BitField<BarrierAccessBits> src_access = {};
+		BitField<BarrierAccessBits> dst_access = {};
 		TextureLayout prev_layout = TEXTURE_LAYOUT_UNDEFINED;
 		TextureLayout prev_layout = TEXTURE_LAYOUT_UNDEFINED;
 		TextureLayout next_layout = TEXTURE_LAYOUT_UNDEFINED;
 		TextureLayout next_layout = TEXTURE_LAYOUT_UNDEFINED;
 		TextureSubresourceRange subresources;
 		TextureSubresourceRange subresources;
@@ -628,7 +628,7 @@ public:
 		static const uint32_t UNUSED = 0xffffffff;
 		static const uint32_t UNUSED = 0xffffffff;
 		uint32_t attachment = UNUSED;
 		uint32_t attachment = UNUSED;
 		TextureLayout layout = TEXTURE_LAYOUT_UNDEFINED;
 		TextureLayout layout = TEXTURE_LAYOUT_UNDEFINED;
-		BitField<TextureAspectBits> aspect;
+		BitField<TextureAspectBits> aspect = {};
 	};
 	};
 
 
 	struct Subpass {
 	struct Subpass {
@@ -644,10 +644,10 @@ public:
 	struct SubpassDependency {
 	struct SubpassDependency {
 		uint32_t src_subpass = 0xffffffff;
 		uint32_t src_subpass = 0xffffffff;
 		uint32_t dst_subpass = 0xffffffff;
 		uint32_t dst_subpass = 0xffffffff;
-		BitField<PipelineStageBits> src_stages;
-		BitField<PipelineStageBits> dst_stages;
-		BitField<BarrierAccessBits> src_access;
-		BitField<BarrierAccessBits> dst_access;
+		BitField<PipelineStageBits> src_stages = {};
+		BitField<PipelineStageBits> dst_stages = {};
+		BitField<BarrierAccessBits> src_access = {};
+		BitField<BarrierAccessBits> dst_access = {};
 	};
 	};
 
 
 	virtual RenderPassID render_pass_create(VectorView<Attachment> p_attachments, VectorView<Subpass> p_subpasses, VectorView<SubpassDependency> p_subpass_dependencies, uint32_t p_view_count, AttachmentReference p_fragment_density_map_attachment) = 0;
 	virtual RenderPassID render_pass_create(VectorView<Attachment> p_attachments, VectorView<Subpass> p_subpasses, VectorView<SubpassDependency> p_subpass_dependencies, uint32_t p_view_count, AttachmentReference p_fragment_density_map_attachment) = 0;
@@ -666,7 +666,7 @@ public:
 	};
 	};
 
 
 	struct AttachmentClear {
 	struct AttachmentClear {
-		BitField<TextureAspectBits> aspect;
+		BitField<TextureAspectBits> aspect = {};
 		uint32_t color_attachment = 0xffffffff;
 		uint32_t color_attachment = 0xffffffff;
 		RenderPassClearValue value;
 		RenderPassClearValue value;
 	};
 	};

+ 9 - 9
servers/rendering/rendering_device_graph.h

@@ -114,9 +114,9 @@ public:
 		int32_t buffer_barrier_count = 0;
 		int32_t buffer_barrier_count = 0;
 #endif
 #endif
 		int32_t label_index = -1;
 		int32_t label_index = -1;
-		BitField<RDD::PipelineStageBits> previous_stages;
-		BitField<RDD::PipelineStageBits> next_stages;
-		BitField<RDD::PipelineStageBits> self_stages;
+		BitField<RDD::PipelineStageBits> previous_stages = {};
+		BitField<RDD::PipelineStageBits> next_stages = {};
+		BitField<RDD::PipelineStageBits> self_stages = {};
 	};
 	};
 
 
 	struct RecordedBufferCopy {
 	struct RecordedBufferCopy {
@@ -156,8 +156,8 @@ public:
 	struct ResourceTracker {
 	struct ResourceTracker {
 		uint32_t reference_count = 0;
 		uint32_t reference_count = 0;
 		int64_t command_frame = -1;
 		int64_t command_frame = -1;
-		BitField<RDD::PipelineStageBits> previous_frame_stages;
-		BitField<RDD::PipelineStageBits> current_frame_stages;
+		BitField<RDD::PipelineStageBits> previous_frame_stages = {};
+		BitField<RDD::PipelineStageBits> current_frame_stages = {};
 		int32_t read_full_command_list_index = -1;
 		int32_t read_full_command_list_index = -1;
 		int32_t read_slice_command_list_index = -1;
 		int32_t read_slice_command_list_index = -1;
 		int32_t write_command_or_list_index = -1;
 		int32_t write_command_or_list_index = -1;
@@ -166,7 +166,7 @@ public:
 		int32_t compute_list_index = -1;
 		int32_t compute_list_index = -1;
 		ResourceUsage compute_list_usage = RESOURCE_USAGE_NONE;
 		ResourceUsage compute_list_usage = RESOURCE_USAGE_NONE;
 		ResourceUsage usage = RESOURCE_USAGE_NONE;
 		ResourceUsage usage = RESOURCE_USAGE_NONE;
-		BitField<RDD::BarrierAccessBits> usage_access;
+		BitField<RDD::BarrierAccessBits> usage_access = {};
 		RDD::BufferID buffer_driver_id;
 		RDD::BufferID buffer_driver_id;
 		RDD::TextureID texture_driver_id;
 		RDD::TextureID texture_driver_id;
 		RDD::TextureSubresourceRange texture_subresources;
 		RDD::TextureSubresourceRange texture_subresources;
@@ -241,7 +241,7 @@ private:
 		LocalVector<uint8_t> data;
 		LocalVector<uint8_t> data;
 		LocalVector<ResourceTracker *> command_trackers;
 		LocalVector<ResourceTracker *> command_trackers;
 		LocalVector<ResourceUsage> command_tracker_usages;
 		LocalVector<ResourceUsage> command_tracker_usages;
-		BitField<RDD::PipelineStageBits> stages;
+		BitField<RDD::PipelineStageBits> stages = {};
 		int32_t index = 0;
 		int32_t index = 0;
 
 
 		void clear() {
 		void clear() {
@@ -660,8 +660,8 @@ private:
 	};
 	};
 
 
 	struct BarrierGroup {
 	struct BarrierGroup {
-		BitField<RDD::PipelineStageBits> src_stages;
-		BitField<RDD::PipelineStageBits> dst_stages;
+		BitField<RDD::PipelineStageBits> src_stages = {};
+		BitField<RDD::PipelineStageBits> dst_stages = {};
 		RDD::MemoryBarrier memory_barrier;
 		RDD::MemoryBarrier memory_barrier;
 		LocalVector<RDD::TextureBarrier> normalization_barriers;
 		LocalVector<RDD::TextureBarrier> normalization_barriers;
 		LocalVector<RDD::TextureBarrier> transition_barriers;
 		LocalVector<RDD::TextureBarrier> transition_barriers;

+ 1 - 1
servers/rendering/storage/compositor_storage.h

@@ -44,7 +44,7 @@ private:
 		RS::CompositorEffectCallbackType callback_type;
 		RS::CompositorEffectCallbackType callback_type;
 		Callable callback;
 		Callable callback;
 
 
-		BitField<RS::CompositorEffectFlags> flags;
+		BitField<RS::CompositorEffectFlags> flags = {};
 	};
 	};
 
 
 	mutable RID_Owner<CompositorEffect, true> compositor_effects_owner;
 	mutable RID_Owner<CompositorEffect, true> compositor_effects_owner;

+ 1 - 1
servers/xr/xr_body_tracker.h

@@ -161,7 +161,7 @@ protected:
 
 
 private:
 private:
 	bool has_tracking_data = false;
 	bool has_tracking_data = false;
-	BitField<BodyFlags> body_flags;
+	BitField<BodyFlags> body_flags = {};
 
 
 	BitField<JointFlags> joint_flags[JOINT_MAX];
 	BitField<JointFlags> joint_flags[JOINT_MAX];
 	Transform3D joint_transforms[JOINT_MAX];
 	Transform3D joint_transforms[JOINT_MAX];

+ 2 - 2
tests/scene/test_code_edit.h

@@ -4148,10 +4148,10 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
 
 
 			Point2 caret_pos = code_edit->get_caret_draw_pos();
 			Point2 caret_pos = code_edit->get_caret_draw_pos();
 			caret_pos.y += code_edit->get_line_height();
 			caret_pos.y += code_edit->get_line_height();
-			SEND_GUI_MOUSE_BUTTON_EVENT(caret_pos, MouseButton::WHEEL_DOWN, 0, Key::NONE);
+			SEND_GUI_MOUSE_BUTTON_EVENT(caret_pos, MouseButton::WHEEL_DOWN, MouseButtonMask::NONE, Key::NONE);
 			CHECK(code_edit->get_code_completion_selected_index() == 1);
 			CHECK(code_edit->get_code_completion_selected_index() == 1);
 
 
-			SEND_GUI_MOUSE_BUTTON_EVENT(caret_pos, MouseButton::WHEEL_UP, 0, Key::NONE);
+			SEND_GUI_MOUSE_BUTTON_EVENT(caret_pos, MouseButton::WHEEL_UP, MouseButtonMask::NONE, Key::NONE);
 			CHECK(code_edit->get_code_completion_selected_index() == 0);
 			CHECK(code_edit->get_code_completion_selected_index() == 0);
 
 
 			/* Single click selects. */
 			/* Single click selects. */

+ 6 - 6
tests/scene/test_text_edit.h

@@ -7727,28 +7727,28 @@ TEST_CASE("[SceneTree][TextEdit] viewport") {
 
 
 	// Scroll.
 	// Scroll.
 	int v_scroll = text_edit->get_v_scroll();
 	int v_scroll = text_edit->get_v_scroll();
-	SEND_GUI_MOUSE_BUTTON_EVENT(Point2i(10, 10), MouseButton::WHEEL_DOWN, 0, Key::NONE);
+	SEND_GUI_MOUSE_BUTTON_EVENT(Point2i(10, 10), MouseButton::WHEEL_DOWN, MouseButtonMask::NONE, Key::NONE);
 	CHECK(text_edit->get_v_scroll() > v_scroll);
 	CHECK(text_edit->get_v_scroll() > v_scroll);
-	SEND_GUI_MOUSE_BUTTON_EVENT(Point2i(10, 10), MouseButton::WHEEL_UP, 0, Key::NONE);
+	SEND_GUI_MOUSE_BUTTON_EVENT(Point2i(10, 10), MouseButton::WHEEL_UP, MouseButtonMask::NONE, Key::NONE);
 	CHECK(text_edit->get_v_scroll() == v_scroll);
 	CHECK(text_edit->get_v_scroll() == v_scroll);
 
 
 	// smooth scroll speed.
 	// smooth scroll speed.
 	text_edit->set_smooth_scroll_enabled(true);
 	text_edit->set_smooth_scroll_enabled(true);
 
 
 	v_scroll = text_edit->get_v_scroll();
 	v_scroll = text_edit->get_v_scroll();
-	SEND_GUI_MOUSE_BUTTON_EVENT(Point2i(10, 10), MouseButton::WHEEL_DOWN, 0, Key::NONE);
+	SEND_GUI_MOUSE_BUTTON_EVENT(Point2i(10, 10), MouseButton::WHEEL_DOWN, MouseButtonMask::NONE, Key::NONE);
 	text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
 	text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
 	CHECK(text_edit->get_v_scroll() >= v_scroll);
 	CHECK(text_edit->get_v_scroll() >= v_scroll);
-	SEND_GUI_MOUSE_BUTTON_EVENT(Point2i(10, 10), MouseButton::WHEEL_UP, 0, Key::NONE);
+	SEND_GUI_MOUSE_BUTTON_EVENT(Point2i(10, 10), MouseButton::WHEEL_UP, MouseButtonMask::NONE, Key::NONE);
 	text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
 	text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
 	CHECK(text_edit->get_v_scroll() == v_scroll);
 	CHECK(text_edit->get_v_scroll() == v_scroll);
 
 
 	v_scroll = text_edit->get_v_scroll();
 	v_scroll = text_edit->get_v_scroll();
 	text_edit->set_v_scroll_speed(10000);
 	text_edit->set_v_scroll_speed(10000);
-	SEND_GUI_MOUSE_BUTTON_EVENT(Point2i(10, 10), MouseButton::WHEEL_DOWN, 0, Key::NONE);
+	SEND_GUI_MOUSE_BUTTON_EVENT(Point2i(10, 10), MouseButton::WHEEL_DOWN, MouseButtonMask::NONE, Key::NONE);
 	text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
 	text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
 	CHECK(text_edit->get_v_scroll() >= v_scroll);
 	CHECK(text_edit->get_v_scroll() >= v_scroll);
-	SEND_GUI_MOUSE_BUTTON_EVENT(Point2i(10, 10), MouseButton::WHEEL_UP, 0, Key::NONE);
+	SEND_GUI_MOUSE_BUTTON_EVENT(Point2i(10, 10), MouseButton::WHEEL_UP, MouseButtonMask::NONE, Key::NONE);
 	text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
 	text_edit->notification(TextEdit::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
 	CHECK(text_edit->get_v_scroll() == v_scroll);
 	CHECK(text_edit->get_v_scroll() == v_scroll);
 
 

+ 3 - 3
tests/scene/test_viewport.h

@@ -347,7 +347,7 @@ TEST_CASE("[SceneTree][Viewport] Controls and InputEvent handling") {
 				SEND_GUI_MOUSE_BUTTON_EVENT(on_a, MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
 				SEND_GUI_MOUSE_BUTTON_EVENT(on_a, MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
 				CHECK(node_a->has_focus());
 				CHECK(node_a->has_focus());
 
 
-				SEND_GUI_MOUSE_BUTTON_EVENT(on_b, MouseButton::RIGHT, (int)MouseButtonMask::LEFT | (int)MouseButtonMask::RIGHT, Key::NONE);
+				SEND_GUI_MOUSE_BUTTON_EVENT(on_b, MouseButton::RIGHT, MouseButtonMask::LEFT | MouseButtonMask::RIGHT, Key::NONE);
 				CHECK(node_a->has_focus());
 				CHECK(node_a->has_focus());
 
 
 				SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(on_b, MouseButton::RIGHT, MouseButtonMask::LEFT, Key::NONE);
 				SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(on_b, MouseButton::RIGHT, MouseButtonMask::LEFT, Key::NONE);
@@ -362,12 +362,12 @@ TEST_CASE("[SceneTree][Viewport] Controls and InputEvent handling") {
 				SEND_GUI_MOUSE_BUTTON_EVENT(on_background, MouseButton::RIGHT, MouseButtonMask::RIGHT, Key::NONE);
 				SEND_GUI_MOUSE_BUTTON_EVENT(on_background, MouseButton::RIGHT, MouseButtonMask::RIGHT, Key::NONE);
 				CHECK_FALSE(root->gui_get_focus_owner());
 				CHECK_FALSE(root->gui_get_focus_owner());
 
 
-				SEND_GUI_MOUSE_BUTTON_EVENT(on_a, MouseButton::LEFT, (int)MouseButtonMask::LEFT | (int)MouseButtonMask::RIGHT, Key::NONE);
+				SEND_GUI_MOUSE_BUTTON_EVENT(on_a, MouseButton::LEFT, MouseButtonMask::LEFT | MouseButtonMask::RIGHT, Key::NONE);
 				CHECK(node_a->has_focus());
 				CHECK(node_a->has_focus());
 				SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(on_a, MouseButton::LEFT, MouseButtonMask::RIGHT, Key::NONE);
 				SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(on_a, MouseButton::LEFT, MouseButtonMask::RIGHT, Key::NONE);
 				CHECK(node_a->has_focus());
 				CHECK(node_a->has_focus());
 
 
-				SEND_GUI_MOUSE_BUTTON_EVENT(on_b, MouseButton::LEFT, (int)MouseButtonMask::LEFT | (int)MouseButtonMask::RIGHT, Key::NONE);
+				SEND_GUI_MOUSE_BUTTON_EVENT(on_b, MouseButton::LEFT, MouseButtonMask::LEFT | MouseButtonMask::RIGHT, Key::NONE);
 				CHECK(node_b->has_focus());
 				CHECK(node_b->has_focus());
 
 
 				SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(on_d, MouseButton::LEFT, MouseButtonMask::RIGHT, Key::NONE);
 				SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(on_d, MouseButton::LEFT, MouseButtonMask::RIGHT, Key::NONE);

+ 1 - 1
tests/servers/test_text_server.h

@@ -517,7 +517,7 @@ TEST_SUITE("[TextServer]") {
 					struct TestCase {
 					struct TestCase {
 						String text;
 						String text;
 						PackedInt32Array breaks;
 						PackedInt32Array breaks;
-						BitField<TextServer::LineBreakFlag> flags;
+						BitField<TextServer::LineBreakFlag> flags = TextServer::BREAK_NONE;
 					};
 					};
 					TestCase cases[] = {
 					TestCase cases[] = {
 						{ U"test \rtest", { 0, 4, 6, 10 }, TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_TRIM_START_EDGE_SPACES | TextServer::BREAK_TRIM_END_EDGE_SPACES },
 						{ U"test \rtest", { 0, 4, 6, 10 }, TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_TRIM_START_EDGE_SPACES | TextServer::BREAK_TRIM_END_EDGE_SPACES },

+ 6 - 6
tests/test_macros.h

@@ -211,12 +211,12 @@ int register_test_command(String p_command, TestFunc p_function);
 		MessageQueue::get_singleton()->flush();                                          \
 		MessageQueue::get_singleton()->flush();                                          \
 	}
 	}
 
 
-#define SEND_GUI_DOUBLE_CLICK(m_screen_pos, m_modifiers)                          \
-	{                                                                             \
-		_CREATE_GUI_MOUSE_EVENT(m_screen_pos, MouseButton::LEFT, 0, m_modifiers); \
-		event->set_double_click(true);                                            \
-		_SEND_DISPLAYSERVER_EVENT(event);                                         \
-		MessageQueue::get_singleton()->flush();                                   \
+#define SEND_GUI_DOUBLE_CLICK(m_screen_pos, m_modifiers)                                              \
+	{                                                                                                 \
+		_CREATE_GUI_MOUSE_EVENT(m_screen_pos, MouseButton::LEFT, MouseButtonMask::NONE, m_modifiers); \
+		event->set_double_click(true);                                                                \
+		_SEND_DISPLAYSERVER_EVENT(event);                                                             \
+		MessageQueue::get_singleton()->flush();                                                       \
 	}
 	}
 
 
 // We toggle _print_error_enabled to prevent display server not supported warnings.
 // We toggle _print_error_enabled to prevent display server not supported warnings.