Browse Source

Fix a special case for button masks

In certain situations it is possible that in a `Viewport` the same
mouse button is pressed twice in series without releasing it in
between.
In this case, focus stealing should happen to ensure, that the
mouse button is not sent unintentionally to the previously focused
Control node.
Markus Sauermann 1 year ago
parent
commit
48ea019322
2 changed files with 5 additions and 3 deletions
  1. 4 3
      scene/main/viewport.cpp
  2. 1 0
      tests/scene/test_code_edit.h

+ 4 - 3
scene/main/viewport.cpp

@@ -1705,9 +1705,10 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
 
 		Point2 mpos = mb->get_position();
 		if (mb->is_pressed()) {
-			if (!gui.mouse_focus_mask.is_empty()) {
-				// Do not steal mouse focus and stuff while a focus mask exists.
-				gui.mouse_focus_mask.set_flag(mouse_button_to_mask(mb->get_button_index()));
+			MouseButtonMask button_mask = mouse_button_to_mask(mb->get_button_index());
+			if (!gui.mouse_focus_mask.is_empty() && !gui.mouse_focus_mask.has_flag(button_mask)) {
+				// Do not steal mouse focus and stuff while a focus mask without the current mouse button exists.
+				gui.mouse_focus_mask.set_flag(button_mask);
 			} else {
 				gui.mouse_focus = gui_find_control(mpos);
 				gui.last_mouse_focus = gui.mouse_focus;

+ 1 - 0
tests/scene/test_code_edit.h

@@ -3520,6 +3520,7 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
 			/* Single click selects. */
 			caret_pos.y += code_edit->get_line_height() * 2;
 			SEND_GUI_MOUSE_BUTTON_EVENT(caret_pos, MouseButton::LEFT, MouseButtonMask::LEFT, Key::NONE);
+			SEND_GUI_MOUSE_BUTTON_RELEASED_EVENT(caret_pos, MouseButton::LEFT, MouseButtonMask::NONE, Key::NONE);
 			CHECK(code_edit->get_code_completion_selected_index() == 2);
 
 			/* Double click inserts. */