summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp2
-rw-r--r--editor/editor_node.cpp24
-rw-r--r--editor/editor_node.h2
-rw-r--r--modules/squish/config.py2
-rw-r--r--modules/squish/image_compress_squish.cpp4
-rw-r--r--modules/squish/image_compress_squish.h2
-rw-r--r--modules/squish/register_types.cpp7
-rw-r--r--modules/squish/register_types.h2
-rw-r--r--platform/javascript/audio_driver_javascript.cpp104
-rw-r--r--platform/javascript/audio_driver_javascript.h7
-rw-r--r--platform/javascript/detect.py1
-rw-r--r--scene/gui/text_edit.cpp5
-rw-r--r--scene/main/viewport.cpp109
-rw-r--r--scene/main/viewport.h4
14 files changed, 209 insertions, 66 deletions
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 235c799a55..2b038fcc0e 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -7673,7 +7673,7 @@ void RasterizerStorageGLES3::initialize() {
config.etc2_supported = true;
config.hdr_supported = false;
config.s3tc_supported = config.extensions.has("GL_EXT_texture_compression_dxt1") || config.extensions.has("GL_EXT_texture_compression_s3tc") || config.extensions.has("WEBGL_compressed_texture_s3tc");
- config.rgtc_supported = config.extensions.has("GL_EXT_texture_compression_rgtc") || config.extensions.has("GL_ARB_texture_compression_rgtc");
+ config.rgtc_supported = config.extensions.has("GL_EXT_texture_compression_rgtc") || config.extensions.has("GL_ARB_texture_compression_rgtc") || config.extensions.has("EXT_texture_compression_rgtc");
#endif
config.pvrtc_supported = config.extensions.has("GL_IMG_texture_compression_pvrtc");
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 157dd4d66f..d009ed61b5 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -3249,17 +3249,31 @@ Ref<Texture> EditorNode::get_class_icon(const String &p_class, const String &p_f
void EditorNode::progress_add_task(const String &p_task, const String &p_label, int p_steps, bool p_can_cancel) {
- singleton->progress_dialog->add_task(p_task, p_label, p_steps, p_can_cancel);
+ if (singleton->disable_progress_dialog) {
+ print_line(p_task + ": begin: " + p_label + " steps: " + itos(p_steps));
+ } else {
+ singleton->progress_dialog->add_task(p_task, p_label, p_steps, p_can_cancel);
+ }
}
bool EditorNode::progress_task_step(const String &p_task, const String &p_state, int p_step, bool p_force_refresh) {
- return singleton->progress_dialog->task_step(p_task, p_state, p_step, p_force_refresh);
+ if (singleton->disable_progress_dialog) {
+ print_line("\t" + p_task + ": step " + itos(p_step) + ": " + p_state);
+ return false;
+ } else {
+
+ return singleton->progress_dialog->task_step(p_task, p_state, p_step, p_force_refresh);
+ }
}
void EditorNode::progress_end_task(const String &p_task) {
- singleton->progress_dialog->end_task(p_task);
+ if (singleton->disable_progress_dialog) {
+ print_line(p_task + ": end");
+ } else {
+ singleton->progress_dialog->end_task(p_task);
+ }
}
void EditorNode::progress_add_task_bg(const String &p_task, const String &p_label, int p_steps) {
@@ -3341,7 +3355,7 @@ Error EditorNode::export_preset(const String &p_preset, const String &p_path, bo
export_defer.path = p_path;
export_defer.debug = p_debug;
export_defer.password = p_password;
-
+ disable_progress_dialog = true;
return OK;
}
@@ -4731,7 +4745,7 @@ EditorNode::EditorNode() {
_initializing_addons = false;
docks_visible = true;
restoring_scenes = false;
-
+ disable_progress_dialog = false;
scene_distraction = false;
script_distraction = false;
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 3fa762c20b..4d89d1f956 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -525,6 +525,8 @@ private:
} export_defer;
+ bool disable_progress_dialog;
+
static EditorNode *singleton;
static Vector<EditorNodeInitCallback> _init_callbacks;
diff --git a/modules/squish/config.py b/modules/squish/config.py
index 098f1eafa9..1c8cd12a2d 100644
--- a/modules/squish/config.py
+++ b/modules/squish/config.py
@@ -1,5 +1,5 @@
def can_build(env, platform):
- return env['tools']
+ return True
def configure(env):
pass
diff --git a/modules/squish/image_compress_squish.cpp b/modules/squish/image_compress_squish.cpp
index a08ac7bd28..4161a0f6ae 100644
--- a/modules/squish/image_compress_squish.cpp
+++ b/modules/squish/image_compress_squish.cpp
@@ -30,8 +30,6 @@
#include "image_compress_squish.h"
-#include "core/print_string.h"
-
#include <squish.h>
void image_decompress_squish(Image *p_image) {
@@ -76,6 +74,7 @@ void image_decompress_squish(Image *p_image) {
p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data);
}
+#ifdef TOOLS_ENABLED
void image_compress_squish(Image *p_image, float p_lossy_quality, Image::CompressSource p_source) {
if (p_image->get_format() >= Image::FORMAT_DXT1)
@@ -204,3 +203,4 @@ void image_compress_squish(Image *p_image, float p_lossy_quality, Image::Compres
p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data);
}
}
+#endif
diff --git a/modules/squish/image_compress_squish.h b/modules/squish/image_compress_squish.h
index dfebdc955f..dd53f2787a 100644
--- a/modules/squish/image_compress_squish.h
+++ b/modules/squish/image_compress_squish.h
@@ -33,7 +33,9 @@
#include "core/image.h"
+#ifdef TOOLS_ENABLED
void image_compress_squish(Image *p_image, float p_lossy_quality, Image::CompressSource p_source);
+#endif
void image_decompress_squish(Image *p_image);
#endif // IMAGE_COMPRESS_SQUISH_H
diff --git a/modules/squish/register_types.cpp b/modules/squish/register_types.cpp
index d4ed676cce..9a5bb47f19 100644
--- a/modules/squish/register_types.cpp
+++ b/modules/squish/register_types.cpp
@@ -29,17 +29,14 @@
/*************************************************************************/
#include "register_types.h"
-
-#ifdef TOOLS_ENABLED
-
#include "image_compress_squish.h"
void register_squish_types() {
+#ifdef TOOLS_ENABLED
Image::set_compress_bc_func(image_compress_squish);
+#endif
Image::_image_decompress_bc = image_decompress_squish;
}
void unregister_squish_types() {}
-
-#endif
diff --git a/modules/squish/register_types.h b/modules/squish/register_types.h
index 00f5c345c4..9dbd69c46b 100644
--- a/modules/squish/register_types.h
+++ b/modules/squish/register_types.h
@@ -28,7 +28,5 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef TOOLS_ENABLED
void register_squish_types();
void unregister_squish_types();
-#endif
diff --git a/platform/javascript/audio_driver_javascript.cpp b/platform/javascript/audio_driver_javascript.cpp
index 7a6613bb32..a5b627b8dc 100644
--- a/platform/javascript/audio_driver_javascript.cpp
+++ b/platform/javascript/audio_driver_javascript.cpp
@@ -44,6 +44,11 @@ extern "C" EMSCRIPTEN_KEEPALIVE void audio_driver_js_mix() {
AudioDriverJavaScript::singleton->mix_to_js();
}
+extern "C" EMSCRIPTEN_KEEPALIVE void audio_driver_process_capture(float sample) {
+
+ AudioDriverJavaScript::singleton->process_capture(sample);
+}
+
void AudioDriverJavaScript::mix_to_js() {
int channel_count = get_total_channels_by_speaker_mode(get_speaker_mode());
@@ -51,31 +56,39 @@ void AudioDriverJavaScript::mix_to_js() {
int32_t *stream_buffer = reinterpret_cast<int32_t *>(internal_buffer);
audio_server_process(sample_count, stream_buffer);
for (int i = 0; i < sample_count * channel_count; i++) {
- internal_buffer[i] = float(stream_buffer[i] >> 16) / 32768.0;
+ internal_buffer[i] = float(stream_buffer[i] >> 16) / 32768.f;
}
}
+void AudioDriverJavaScript::process_capture(float sample) {
+
+ int32_t sample32 = int32_t(sample * 32768.f) * (1U << 16);
+ input_buffer_write(sample32);
+}
+
Error AudioDriverJavaScript::init() {
/* clang-format off */
EM_ASM({
_audioDriver_audioContext = new (window.AudioContext || window.webkitAudioContext);
+ _audioDriver_audioInput = null;
+ _audioDriver_inputStream = null;
_audioDriver_scriptNode = null;
});
/* clang-format on */
int channel_count = get_total_channels_by_speaker_mode(get_speaker_mode());
/* clang-format off */
- int buffer_length = EM_ASM_INT({
+ buffer_length = EM_ASM_INT({
var CHANNEL_COUNT = $0;
var channelCount = _audioDriver_audioContext.destination.channelCount;
try {
// Try letting the browser recommend a buffer length.
- _audioDriver_scriptNode = _audioDriver_audioContext.createScriptProcessor(0, 0, channelCount);
+ _audioDriver_scriptNode = _audioDriver_audioContext.createScriptProcessor(0, 2, channelCount);
} catch (e) {
// ...otherwise, default to 4096.
- _audioDriver_scriptNode = _audioDriver_audioContext.createScriptProcessor(4096, 0, channelCount);
+ _audioDriver_scriptNode = _audioDriver_audioContext.createScriptProcessor(4096, 2, channelCount);
}
_audioDriver_scriptNode.connect(_audioDriver_audioContext.destination);
@@ -91,6 +104,7 @@ Error AudioDriverJavaScript::init() {
memdelete_arr(internal_buffer);
internal_buffer = memnew_arr(float, buffer_length *channel_count);
}
+
return internal_buffer ? OK : ERR_OUT_OF_MEMORY;
}
@@ -101,11 +115,13 @@ void AudioDriverJavaScript::start() {
var INTERNAL_BUFFER_PTR = $0;
var audioDriverMixFunction = cwrap('audio_driver_js_mix');
+ var audioDriverProcessCapture = cwrap('audio_driver_process_capture', null, ['number']);
_audioDriver_scriptNode.onaudioprocess = function(audioProcessingEvent) {
audioDriverMixFunction();
- // The output buffer contains the samples that will be modified and played.
+
+ var input = audioProcessingEvent.inputBuffer;
var output = audioProcessingEvent.outputBuffer;
- var input = HEAPF32.subarray(
+ var internalBuffer = HEAPF32.subarray(
INTERNAL_BUFFER_PTR / HEAPF32.BYTES_PER_ELEMENT,
INTERNAL_BUFFER_PTR / HEAPF32.BYTES_PER_ELEMENT + output.length * output.numberOfChannels);
@@ -113,8 +129,16 @@ void AudioDriverJavaScript::start() {
var outputData = output.getChannelData(channel);
// Loop through samples.
for (var sample = 0; sample < outputData.length; sample++) {
- // Set output equal to input.
- outputData[sample] = input[sample * output.numberOfChannels + channel];
+ outputData[sample] = internalBuffer[sample * output.numberOfChannels + channel];
+ }
+ }
+
+ if (_audioDriver_audioInput) {
+ var inputDataL = input.getChannelData(0);
+ var inputDataR = input.getChannelData(1);
+ for (var i = 0; i < inputDataL.length; i++) {
+ audioDriverProcessCapture(inputDataL[i]);
+ audioDriverProcessCapture(inputDataR[i]);
}
}
};
@@ -152,14 +176,74 @@ void AudioDriverJavaScript::finish() {
/* clang-format off */
EM_ASM({
_audioDriver_audioContext = null;
+ _audioDriver_audioInput = null;
_audioDriver_scriptNode = null;
});
/* clang-format on */
- memdelete_arr(internal_buffer);
- internal_buffer = NULL;
+
+ if (internal_buffer) {
+ memdelete_arr(internal_buffer);
+ internal_buffer = NULL;
+ }
+}
+
+Error AudioDriverJavaScript::capture_start() {
+
+ input_buffer_init(buffer_length);
+
+ /* clang-format off */
+ EM_ASM({
+ function gotMediaInput(stream) {
+ _audioDriver_inputStream = stream;
+ _audioDriver_audioInput = _audioDriver_audioContext.createMediaStreamSource(stream);
+ _audioDriver_audioInput.connect(_audioDriver_scriptNode);
+ }
+
+ function gotMediaInputError(e) {
+ console.log(e);
+ }
+
+ if (navigator.mediaDevices.getUserMedia) {
+ navigator.mediaDevices.getUserMedia({"audio": true}).then(gotMediaInput, gotMediaInputError);
+ } else {
+ if (!navigator.getUserMedia)
+ navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
+ navigator.getUserMedia({"audio": true}, gotMediaInput, gotMediaInputError);
+ }
+ });
+ /* clang-format on */
+
+ return OK;
+}
+
+Error AudioDriverJavaScript::capture_stop() {
+
+ /* clang-format off */
+ EM_ASM({
+ if (_audioDriver_inputStream) {
+ const tracks = _audioDriver_inputStream.getTracks();
+ for (var i = 0; i < tracks.length; i++) {
+ tracks[i].stop();
+ }
+ _audioDriver_inputStream = null;
+ }
+
+ if (_audioDriver_audioInput) {
+ _audioDriver_audioInput.disconnect();
+ _audioDriver_audioInput = null;
+ }
+
+ });
+ /* clang-format on */
+
+ input_buffer.clear();
+
+ return OK;
}
AudioDriverJavaScript::AudioDriverJavaScript() {
+ internal_buffer = NULL;
+
singleton = this;
}
diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h
index a65a8ec29f..c8aeb0b446 100644
--- a/platform/javascript/audio_driver_javascript.h
+++ b/platform/javascript/audio_driver_javascript.h
@@ -37,8 +37,12 @@ class AudioDriverJavaScript : public AudioDriver {
float *internal_buffer;
+ int buffer_length;
+
public:
void mix_to_js();
+ void process_capture(float sample);
+
static AudioDriverJavaScript *singleton;
virtual const char *get_name() const;
@@ -51,6 +55,9 @@ public:
virtual void unlock();
virtual void finish();
+ virtual Error capture_start();
+ virtual Error capture_stop();
+
AudioDriverJavaScript();
};
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index cf85c3df7f..22b5f1f87a 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -122,6 +122,7 @@ def configure(env):
## Link flags
env.Append(LINKFLAGS=['-s', 'BINARYEN=1'])
+ env.Append(LINKFLAGS=['-s', 'BINARYEN_TRAP_MODE=\'clamp\''])
# Allow increasing memory buffer size during runtime. This is efficient
# when using WebAssembly (in comparison to asm.js) and works well for
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 5fe6fcdfac..51d707c28f 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -5758,6 +5758,7 @@ void TextEdit::_update_completion_candidates() {
completion_base = s;
Vector<float> sim_cache;
bool single_quote = s.begins_with("'");
+ Vector<String> completion_options_casei;
for (int i = 0; i < completion_strings.size(); i++) {
if (single_quote && completion_strings[i].is_quoted()) {
@@ -5766,9 +5767,13 @@ void TextEdit::_update_completion_candidates() {
if (completion_strings[i].begins_with(s)) {
completion_options.push_back(completion_strings[i]);
+ } else if (completion_strings[i].to_lower().begins_with(s.to_lower())) {
+ completion_options_casei.push_back(completion_strings[i]);
}
}
+ completion_options.append_array(completion_options_casei);
+
if (completion_options.size() == 0) {
for (int i = 0; i < completion_strings.size(); i++) {
if (s.is_subsequence_of(completion_strings[i])) {
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 8545efb966..a98ae01c17 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -189,7 +189,7 @@ Viewport::GUI::GUI() {
dragging = false;
mouse_focus = NULL;
mouse_click_grabber = NULL;
- mouse_focus_button = -1;
+ mouse_focus_mask = 0;
key_focus = NULL;
mouse_over = NULL;
@@ -671,15 +671,7 @@ void Viewport::_notification(int p_what) {
case SceneTree::NOTIFICATION_WM_FOCUS_OUT: {
if (gui.mouse_focus) {
//if mouse is being pressed, send a release event
- Ref<InputEventMouseButton> mb;
- mb.instance();
- mb->set_position(gui.mouse_focus->get_local_mouse_position());
- mb->set_global_position(gui.mouse_focus->get_local_mouse_position());
- mb->set_button_index(gui.mouse_focus_button);
- mb->set_pressed(false);
- Control *c = gui.mouse_focus;
- gui.mouse_focus = NULL;
- c->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb);
+ _drop_mouse_focus();
}
} break;
}
@@ -1686,10 +1678,10 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (mb->is_pressed()) {
Size2 pos = mpos;
- if (gui.mouse_focus && mb->get_button_index() != gui.mouse_focus_button) {
-
- //do not steal mouse focus and stuff
+ if (gui.mouse_focus_mask) {
+ //do not steal mouse focus and stuff while a focus mask exists
+ gui.mouse_focus_mask |= 1 << (mb->get_button_index() - 1); //add the button to the mask
} else {
bool is_handled = false;
@@ -1734,7 +1726,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
*/
gui.mouse_focus = _gui_find_control(pos);
- gui.mouse_focus_button = mb->get_button_index();
+ gui.mouse_focus_mask = 1 << (mb->get_button_index() - 1);
if (!gui.mouse_focus) {
return;
@@ -1837,6 +1829,8 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
//change mouse accordingly
}
+ gui.mouse_focus_mask &= ~(1 << (mb->get_button_index() - 1)); //remove from mask
+
if (!gui.mouse_focus) {
//release event is only sent if a mouse focus (previously pressed button) exists
return;
@@ -1852,9 +1846,8 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Control *mouse_focus = gui.mouse_focus;
//disable mouse focus if needed before calling input, this makes popups on mouse press event work better, as the release will never be received otherwise
- if (mb->get_button_index() == gui.mouse_focus_button) {
+ if (gui.mouse_focus_mask == 0) {
gui.mouse_focus = NULL;
- gui.mouse_focus_button = -1;
}
if (mouse_focus->can_process()) {
@@ -1900,6 +1893,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (gui.drag_data.get_type() != Variant::NIL) {
gui.mouse_focus = NULL;
+ gui.mouse_focus_mask = 0;
break;
} else {
if (gui.drag_preview != NULL) {
@@ -2412,7 +2406,7 @@ void Viewport::_gui_unfocus_control(Control *p_control) {
void Viewport::_gui_hid_control(Control *p_control) {
if (gui.mouse_focus == p_control) {
- gui.mouse_focus = NULL;
+ _drop_mouse_focus();
}
/* ???
@@ -2439,8 +2433,10 @@ void Viewport::_gui_hid_control(Control *p_control) {
void Viewport::_gui_remove_control(Control *p_control) {
- if (gui.mouse_focus == p_control)
+ if (gui.mouse_focus == p_control) {
gui.mouse_focus = NULL;
+ gui.mouse_focus_mask = 0;
+ }
if (gui.key_focus == p_control)
gui.key_focus = NULL;
if (gui.mouse_over == p_control)
@@ -2489,6 +2485,27 @@ void Viewport::_gui_accept_event() {
set_input_as_handled();
}
+void Viewport::_drop_mouse_focus() {
+
+ Control *c = gui.mouse_focus;
+ int mask = gui.mouse_focus_mask;
+ gui.mouse_focus = NULL;
+ gui.mouse_focus_mask = 0;
+
+ for (int i = 0; i < 3; i++) {
+
+ if (mask & (1 << i)) {
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+ mb->set_position(c->get_local_mouse_position());
+ mb->set_global_position(gui.mouse_focus->get_local_mouse_position());
+ mb->set_button_index(i + 1);
+ mb->set_pressed(false);
+ c->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb);
+ }
+ }
+}
+
List<Control *>::Element *Viewport::_gui_show_modal(Control *p_control) {
gui.modal_stack.push_back(p_control);
@@ -2498,15 +2515,8 @@ List<Control *>::Element *Viewport::_gui_show_modal(Control *p_control) {
p_control->_modal_set_prev_focus_owner(0);
if (gui.mouse_focus && !p_control->is_a_parent_of(gui.mouse_focus) && !gui.mouse_click_grabber) {
- Ref<InputEventMouseButton> mb;
- mb.instance();
- mb->set_position(gui.mouse_focus->get_local_mouse_position());
- mb->set_global_position(gui.mouse_focus->get_local_mouse_position());
- mb->set_button_index(gui.mouse_focus_button);
- mb->set_pressed(false);
- Control *c = gui.mouse_focus;
- gui.mouse_focus = NULL;
- c->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb);
+
+ _drop_mouse_focus();
}
return gui.modal_stack.back();
@@ -2536,24 +2546,45 @@ void Viewport::_post_gui_grab_click_focus() {
if (gui.mouse_focus == focus_grabber)
return;
- Ref<InputEventMouseButton> mb;
- mb.instance();
-
- //send unclic
+ int mask = gui.mouse_focus_mask;
Point2 click = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos);
- mb->set_position(click);
- mb->set_button_index(gui.mouse_focus_button);
- mb->set_pressed(false);
- gui.mouse_focus->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb);
+
+ for (int i = 0; i < 3; i++) {
+
+ if (mask & (1 << i)) {
+
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+
+ //send unclic
+
+ mb->set_position(click);
+ mb->set_button_index(i + 1);
+ mb->set_pressed(false);
+ gui.mouse_focus->call_multilevel(SceneStringNames::get_singleton()->_gui_input, mb);
+ }
+ }
gui.mouse_focus = focus_grabber;
gui.focus_inv_xform = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse();
click = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos);
- mb->set_position(click);
- mb->set_button_index(gui.mouse_focus_button);
- mb->set_pressed(true);
- gui.mouse_focus->call_deferred(SceneStringNames::get_singleton()->_gui_input, mb);
+
+ for (int i = 0; i < 3; i++) {
+
+ if (mask & (1 << i)) {
+
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+
+ //send clic
+
+ mb->set_position(click);
+ mb->set_button_index(i + 1);
+ mb->set_pressed(true);
+ gui.mouse_focus->call_deferred(SceneStringNames::get_singleton()->_gui_input, mb);
+ }
+ }
}
}
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 44fb322ae2..278350b1c9 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -272,7 +272,7 @@ private:
bool key_event_accepted;
Control *mouse_focus;
Control *mouse_click_grabber;
- int mouse_focus_button;
+ int mouse_focus_mask;
Control *key_focus;
Control *mouse_over;
Control *tooltip;
@@ -379,6 +379,8 @@ private:
void _canvas_layer_add(CanvasLayer *p_canvas_layer);
void _canvas_layer_remove(CanvasLayer *p_canvas_layer);
+ void _drop_mouse_focus();
+
protected:
void _notification(int p_what);
static void _bind_methods();