summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2018-05-02 10:47:49 +0200
committerGitHub <noreply@github.com>2018-05-02 10:47:49 +0200
commit18c28c159d12c9d3227c2199998b271f7c5e5998 (patch)
treeba3591964e6dea9d06daa5aaea399fa53a8c2c8e
parent04a4270a3485bcc4bd1ce8f7095fe9ea36bc5518 (diff)
parentde9d40a9537bafa613dc54f2200b7509ad6fa9e3 (diff)
Merge pull request #17196 from RandomShaper/improve-gui-touch
Implement universal translation of touch to mouse (3.1)
-rw-r--r--core/os/input.h3
-rw-r--r--core/os/os.cpp2
-rw-r--r--editor/editor_node.cpp2
-rw-r--r--main/input_default.cpp118
-rw-r--r--main/input_default.h15
-rw-r--r--main/main.cpp15
-rw-r--r--platform/android/os_android.cpp49
-rw-r--r--platform/android/os_android.h1
-rw-r--r--platform/iphone/gl_view.mm9
-rw-r--r--platform/iphone/os_iphone.cpp45
-rw-r--r--platform/iphone/os_iphone.h6
-rw-r--r--platform/javascript/os_javascript.cpp35
-rw-r--r--platform/uwp/app.cpp83
-rw-r--r--platform/uwp/app.h1
-rw-r--r--platform/windows/os_windows.cpp39
-rw-r--r--platform/x11/os_x11.cpp17
-rw-r--r--platform/x11/os_x11.h1
-rw-r--r--scene/main/scene_tree.cpp8
18 files changed, 223 insertions, 226 deletions
diff --git a/core/os/input.h b/core/os/input.h
index 027147b987..001871c5dc 100644
--- a/core/os/input.h
+++ b/core/os/input.h
@@ -118,7 +118,8 @@ public:
void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
- virtual bool is_emulating_touchscreen() const = 0;
+ virtual bool is_emulating_touch_from_mouse() const = 0;
+ virtual bool is_emulating_mouse_from_touch() const = 0;
virtual CursorShape get_default_cursor_shape() = 0;
virtual void set_default_cursor_shape(CursorShape p_shape) = 0;
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 618a4bbac3..854d554b10 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -411,7 +411,7 @@ Error OS::set_cwd(const String &p_cwd) {
bool OS::has_touchscreen_ui_hint() const {
//return false;
- return Input::get_singleton() && Input::get_singleton()->is_emulating_touchscreen();
+ return Input::get_singleton() && Input::get_singleton()->is_emulating_touch_from_mouse();
}
int OS::get_free_static_memory() const {
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index f68f8380fd..d8c85df83d 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -4886,7 +4886,7 @@ EditorNode::EditorNode() {
if (!OS::get_singleton()->has_touchscreen_ui_hint() && Input::get_singleton()) {
//only if no touchscreen ui hint, set emulation
- id->set_emulate_touch(false); //just disable just in case
+ id->set_emulate_touch_from_mouse(false); //just disable just in case
}
id->set_custom_mouse_cursor(RES());
}
diff --git a/main/input_default.cpp b/main/input_default.cpp
index de7f8ebb4d..29d30110e3 100644
--- a/main/input_default.cpp
+++ b/main/input_default.cpp
@@ -256,6 +256,11 @@ Vector3 InputDefault::get_gyroscope() const {
void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) {
+ _parse_input_event_impl(p_event, false);
+}
+
+void InputDefault::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) {
+
_THREAD_SAFE_METHOD_
Ref<InputEventKey> k = p_event;
@@ -279,25 +284,30 @@ void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) {
mouse_button_mask &= ~(1 << (mb->get_button_index() - 1));
}
- if (main_loop && emulate_touch && mb->get_button_index() == 1) {
+ Point2 pos = mb->get_global_position();
+ if (mouse_pos != pos) {
+ set_mouse_position(pos);
+ }
+
+ if (main_loop && emulate_touch_from_mouse && !p_is_emulated && mb->get_button_index() == 1) {
Ref<InputEventScreenTouch> touch_event;
touch_event.instance();
touch_event->set_pressed(mb->is_pressed());
touch_event->set_position(mb->get_position());
main_loop->input_event(touch_event);
}
-
- Point2 pos = mb->get_global_position();
- if (mouse_pos != pos) {
- set_mouse_position(pos);
- }
}
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
- if (main_loop && emulate_touch && mm->get_button_mask() & 1) {
+ Point2 pos = mm->get_global_position();
+ if (mouse_pos != pos) {
+ set_mouse_position(pos);
+ }
+
+ if (main_loop && emulate_touch_from_mouse && !p_is_emulated && mm->get_button_mask() & 1) {
Ref<InputEventScreenDrag> drag_event;
drag_event.instance();
@@ -309,6 +319,58 @@ void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) {
}
}
+ if (emulate_mouse_from_touch) {
+
+ Ref<InputEventScreenTouch> st = p_event;
+
+ if (st.is_valid()) {
+ bool translate = false;
+ if (st->is_pressed()) {
+ if (mouse_from_touch_index == -1) {
+ translate = true;
+ mouse_from_touch_index = st->get_index();
+ }
+ } else {
+ if (st->get_index() == mouse_from_touch_index) {
+ translate = true;
+ mouse_from_touch_index = -1;
+ }
+ }
+
+ if (translate) {
+ Ref<InputEventMouseButton> button_event;
+ button_event.instance();
+
+ button_event->set_position(st->get_position());
+ button_event->set_global_position(st->get_position());
+ button_event->set_pressed(st->is_pressed());
+ button_event->set_button_index(BUTTON_LEFT);
+ if (st->is_pressed()) {
+ button_event->set_button_mask(mouse_button_mask | (1 << BUTTON_LEFT - 1));
+ } else {
+ button_event->set_button_mask(mouse_button_mask & ~(1 << BUTTON_LEFT - 1));
+ }
+
+ _parse_input_event_impl(button_event, true);
+ }
+ }
+
+ Ref<InputEventScreenDrag> sd = p_event;
+
+ if (sd.is_valid() && sd->get_index() == mouse_from_touch_index) {
+ Ref<InputEventMouseMotion> motion_event;
+ motion_event.instance();
+
+ motion_event->set_position(sd->get_position());
+ motion_event->set_global_position(sd->get_position());
+ motion_event->set_relative(sd->get_relative());
+ motion_event->set_speed(sd->get_speed());
+ motion_event->set_button_mask(mouse_button_mask);
+
+ _parse_input_event_impl(motion_event, true);
+ }
+ }
+
Ref<InputEventJoypadButton> jb = p_event;
if (jb.is_valid()) {
@@ -493,14 +555,44 @@ void InputDefault::action_release(const StringName &p_action) {
action_state[p_action] = action;
}
-void InputDefault::set_emulate_touch(bool p_emulate) {
+void InputDefault::set_emulate_touch_from_mouse(bool p_emulate) {
+
+ emulate_touch_from_mouse = p_emulate;
+}
+
+bool InputDefault::is_emulating_touch_from_mouse() const {
+
+ return emulate_touch_from_mouse;
+}
+
+// Calling this whenever the game window is focused helps unstucking the "touch mouse"
+// if the OS or its abstraction class hasn't properly reported that touch pointers raised
+void InputDefault::ensure_touch_mouse_raised() {
+
+ if (mouse_from_touch_index != -1) {
+ mouse_from_touch_index = -1;
+
+ Ref<InputEventMouseButton> button_event;
+ button_event.instance();
+
+ button_event->set_position(mouse_pos);
+ button_event->set_global_position(mouse_pos);
+ button_event->set_pressed(false);
+ button_event->set_button_index(BUTTON_LEFT);
+ button_event->set_button_mask(mouse_button_mask & ~(1 << BUTTON_LEFT - 1));
+
+ _parse_input_event_impl(button_event, true);
+ }
+}
+
+void InputDefault::set_emulate_mouse_from_touch(bool p_emulate) {
- emulate_touch = p_emulate;
+ emulate_mouse_from_touch = p_emulate;
}
-bool InputDefault::is_emulating_touchscreen() const {
+bool InputDefault::is_emulating_mouse_from_touch() const {
- return emulate_touch;
+ return emulate_mouse_from_touch;
}
Input::CursorShape InputDefault::get_default_cursor_shape() {
@@ -537,7 +629,9 @@ void InputDefault::set_mouse_in_window(bool p_in_window) {
InputDefault::InputDefault() {
mouse_button_mask = 0;
- emulate_touch = false;
+ emulate_touch_from_mouse = false;
+ emulate_mouse_from_touch = false;
+ mouse_from_touch_index = -1;
main_loop = NULL;
hat_map_default[HAT_UP].type = TYPE_BUTTON;
diff --git a/main/input_default.h b/main/input_default.h
index 8a65303df3..2e3cae8520 100644
--- a/main/input_default.h
+++ b/main/input_default.h
@@ -60,7 +60,10 @@ class InputDefault : public Input {
Map<StringName, Action> action_state;
- bool emulate_touch;
+ bool emulate_touch_from_mouse;
+ bool emulate_mouse_from_touch;
+
+ int mouse_from_touch_index;
struct VibrationInfo {
float weak_magnitude;
@@ -176,6 +179,8 @@ private:
void _axis_event(int p_device, int p_axis, float p_value);
float _handle_deadzone(int p_device, int p_axis, float p_value);
+ void _parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated);
+
public:
virtual bool is_key_pressed(int p_scancode) const;
virtual bool is_mouse_button_pressed(int p_button) const;
@@ -225,8 +230,12 @@ public:
void iteration(float p_step);
- void set_emulate_touch(bool p_emulate);
- virtual bool is_emulating_touchscreen() const;
+ void set_emulate_touch_from_mouse(bool p_emulate);
+ virtual bool is_emulating_touch_from_mouse() const;
+ void ensure_touch_mouse_raised();
+
+ void set_emulate_mouse_from_touch(bool p_emulate);
+ virtual bool is_emulating_mouse_from_touch() const;
virtual CursorShape get_default_cursor_shape();
virtual void set_default_cursor_shape(CursorShape p_shape);
diff --git a/main/main.cpp b/main/main.cpp
index 3542133719..ffc02d8823 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1141,13 +1141,16 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
GLOBAL_DEF("application/config/icon", String());
ProjectSettings::get_singleton()->set_custom_property_info("application/config/icon", PropertyInfo(Variant::STRING, "application/config/icon", PROPERTY_HINT_FILE, "*.png,*.webp"));
- if (bool(GLOBAL_DEF("display/window/handheld/emulate_touchscreen", false))) {
- if (!OS::get_singleton()->has_touchscreen_ui_hint() && Input::get_singleton() && !(editor || project_manager)) {
- //only if no touchscreen ui hint, set emulation
- InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
- if (id)
- id->set_emulate_touch(true);
+ InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
+ if (id) {
+ if (bool(GLOBAL_DEF("input/pointing_devices/emulate_touch_from_mouse", false)) && !(editor || project_manager)) {
+ if (!OS::get_singleton()->has_touchscreen_ui_hint()) {
+ //only if no touchscreen ui hint, set emulation
+ id->set_emulate_touch_from_mouse(true);
+ }
}
+
+ id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF("input/pointing_devices/emulate_mouse_from_touch", true)));
}
MAIN_PRINT("Main: Load Remaps");
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 5557c1de44..fc41adeb76 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -330,17 +330,6 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
if (touch.size()) {
//end all if exist
- {
- Ref<InputEventMouseButton> ev;
- ev.instance();
- ev->set_button_index(BUTTON_LEFT);
- ev->set_button_mask(BUTTON_MASK_LEFT);
- ev->set_pressed(false);
- ev->set_position(touch[0].pos);
- ev->set_global_position(touch[0].pos);
- input->parse_input_event(ev);
- }
-
for (int i = 0; i < touch.size(); i++) {
Ref<InputEventScreenTouch> ev;
@@ -358,21 +347,6 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
touch[i].pos = p_points[i].pos;
}
- {
- //send mouse
- Ref<InputEventMouseButton> ev;
- ev.instance();
- // ev.type = Ref<InputEvent>::MOUSE_BUTTON;
- ev->set_button_index(BUTTON_LEFT);
- ev->set_button_mask(BUTTON_MASK_LEFT);
- ev->set_pressed(true);
- ev->set_position(touch[0].pos);
- ev->set_global_position(touch[0].pos);
- input->set_mouse_position(Point2(touch[0].pos.x, touch[0].pos.y));
- last_mouse = touch[0].pos;
- input->parse_input_event(ev);
- }
-
//send touch
for (int i = 0; i < touch.size(); i++) {
@@ -387,19 +361,6 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
} break;
case 1: { //motion
- if (p_points.size()) {
- //send mouse, should look for point 0?
- Ref<InputEventMouseMotion> ev;
- ev.instance();
- ev->set_button_mask(BUTTON_MASK_LEFT);
- ev->set_position(p_points[0].pos);
- input->set_mouse_position(Point2(ev->get_position().x, ev->get_position().y));
- ev->set_speed(input->get_last_mouse_speed());
- ev->set_relative(p_points[0].pos - last_mouse);
- last_mouse = p_points[0].pos;
- input->parse_input_event(ev);
- }
-
ERR_FAIL_COND(touch.size() != p_points.size());
for (int i = 0; i < touch.size(); i++) {
@@ -432,16 +393,6 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
if (touch.size()) {
//end all if exist
- Ref<InputEventMouseButton> ev;
- ev.instance();
- ev->set_button_index(BUTTON_LEFT);
- ev->set_button_mask(BUTTON_MASK_LEFT);
- ev->set_pressed(false);
- ev->set_position(touch[0].pos);
- ev->set_global_position(touch[0].pos);
- input->set_mouse_position(Point2(touch[0].pos.x, touch[0].pos.y));
- input->parse_input_event(ev);
-
for (int i = 0; i < touch.size(); i++) {
Ref<InputEventScreenTouch> ev;
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index 12181b3688..d2457e538d 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -93,7 +93,6 @@ public:
private:
Vector<TouchPos> touch;
- Point2 last_mouse;
GFXInitFunc gfx_init_func;
void *gfx_init_ud;
diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm
index ff95cf6e5f..478a3125af 100644
--- a/platform/iphone/gl_view.mm
+++ b/platform/iphone/gl_view.mm
@@ -497,7 +497,7 @@ static void clear_touches() {
int tid = get_touch_id(touch);
ERR_FAIL_COND(tid == -1);
CGPoint touchPoint = [touch locationInView:self];
- OSIPhone::get_singleton()->mouse_button(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1, tid == 0);
+ OSIPhone::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1);
};
};
}
@@ -514,10 +514,9 @@ static void clear_touches() {
continue;
int tid = get_touch_id(touch);
ERR_FAIL_COND(tid == -1);
- int first = get_first_id(touch);
CGPoint touchPoint = [touch locationInView:self];
CGPoint prev_point = [touch previousLocationInView:self];
- OSIPhone::get_singleton()->mouse_move(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, first == tid);
+ OSIPhone::get_singleton()->touch_drag(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor);
};
};
}
@@ -533,9 +532,9 @@ static void clear_touches() {
continue;
int tid = get_touch_id(touch);
ERR_FAIL_COND(tid == -1);
- int rem = remove_touch(touch);
+ remove_touch(touch);
CGPoint touchPoint = [touch locationInView:self];
- OSIPhone::get_singleton()->mouse_button(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false, rem == 0);
+ OSIPhone::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false);
};
};
}
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index 97ebc19335..f618c80a77 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -190,7 +190,7 @@ void OSIPhone::key(uint32_t p_key, bool p_pressed) {
queue_event(ev);
};
-void OSIPhone::mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_doubleclick, bool p_use_as_mouse) {
+void OSIPhone::touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_doubleclick) {
if (!GLOBAL_DEF("debug/disable_touch", false)) {
Ref<InputEventScreenTouch> ev;
@@ -202,28 +202,10 @@ void OSIPhone::mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_
queue_event(ev);
};
- mouse_list.pressed[p_idx] = p_pressed;
-
- if (p_use_as_mouse) {
-
- Ref<InputEventMouseButton> ev;
- ev.instance();
-
- ev->set_position(Vector2(p_x, p_y));
- ev->set_global_position(Vector2(p_x, p_y));
-
- //mouse_list.pressed[p_idx] = p_pressed;
-
- input->set_mouse_position(ev->get_position());
- ev->set_button_index(BUTTON_LEFT);
- ev->set_doubleclick(p_doubleclick);
- ev->set_pressed(p_pressed);
-
- queue_event(ev);
- };
+ touch_list.pressed[p_idx] = p_pressed;
};
-void OSIPhone::mouse_move(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y, bool p_use_as_mouse) {
+void OSIPhone::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y) {
if (!GLOBAL_DEF("debug/disable_touch", false)) {
@@ -234,21 +216,6 @@ void OSIPhone::mouse_move(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_
ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y));
queue_event(ev);
};
-
- if (p_use_as_mouse) {
- Ref<InputEventMouseMotion> ev;
- ev.instance();
-
- ev->set_position(Vector2(p_x, p_y));
- ev->set_global_position(Vector2(p_x, p_y));
- ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y));
-
- input->set_mouse_position(ev->get_position());
- ev->set_speed(input->get_last_mouse_speed());
- ev->set_button_mask(BUTTON_LEFT); // pressed
-
- queue_event(ev);
- };
};
void OSIPhone::queue_event(const Ref<InputEvent> &p_event) {
@@ -262,10 +229,10 @@ void OSIPhone::touches_cancelled() {
for (int i = 0; i < MAX_MOUSE_COUNT; i++) {
- if (mouse_list.pressed[i]) {
+ if (touch_list.pressed[i]) {
// send a mouse_up outside the screen
- mouse_button(i, -1, -1, false, false, false);
+ touch_press(i, -1, -1, false, false);
};
};
};
@@ -376,7 +343,7 @@ Point2 OSIPhone::get_mouse_position() const {
int OSIPhone::get_mouse_button_state() const {
- return mouse_list.pressed[0];
+ return 0;
};
void OSIPhone::set_window_title(const String &p_title){};
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index 00d9efb01a..7d73a6fe5c 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -106,7 +106,7 @@ private:
};
};
- MouseList mouse_list;
+ MouseList touch_list;
Vector3 last_accel;
@@ -127,8 +127,8 @@ public:
uint8_t get_orientations() const;
- void mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_doubleclick, bool p_use_as_mouse);
- void mouse_move(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y, bool p_use_as_mouse);
+ void touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_doubleclick);
+ void touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y);
void touches_cancelled();
void key(uint32_t p_key, bool p_pressed);
void set_virtual_keyboard_height(int p_height);
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index a275fb7929..1b5463e40d 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -285,23 +285,6 @@ static EM_BOOL _touchpress_callback(int event_type, const EmscriptenTouchEvent *
_input->parse_input_event(ev);
}
-
- if (touch_event->touches[lowest_id_index].isChanged) {
-
- Ref<InputEventMouseButton> ev_mouse;
- ev_mouse.instance();
- ev_mouse->set_button_mask(_input->get_mouse_button_mask());
- dom2godot_mod(touch_event, ev_mouse);
-
- const EmscriptenTouchPoint &first_touch = touch_event->touches[lowest_id_index];
- ev_mouse->set_position(Point2(first_touch.canvasX, first_touch.canvasY));
- ev_mouse->set_global_position(ev_mouse->get_position());
-
- ev_mouse->set_button_index(BUTTON_LEFT);
- ev_mouse->set_pressed(event_type == EMSCRIPTEN_EVENT_TOUCHSTART);
-
- _input->parse_input_event(ev_mouse);
- }
return true;
}
@@ -327,24 +310,6 @@ static EM_BOOL _touchmove_callback(int event_type, const EmscriptenTouchEvent *t
_input->parse_input_event(ev);
}
-
- if (touch_event->touches[lowest_id_index].isChanged) {
-
- Ref<InputEventMouseMotion> ev_mouse;
- ev_mouse.instance();
- dom2godot_mod(touch_event, ev_mouse);
- ev_mouse->set_button_mask(_input->get_mouse_button_mask());
-
- const EmscriptenTouchPoint &first_touch = touch_event->touches[lowest_id_index];
- ev_mouse->set_position(Point2(first_touch.canvasX, first_touch.canvasY));
- ev_mouse->set_global_position(ev_mouse->get_position());
-
- ev_mouse->set_relative(ev_mouse->get_position() - _input->get_mouse_position());
- _input->set_mouse_position(ev_mouse->get_position());
- ev_mouse->set_speed(_input->get_last_mouse_speed());
-
- _input->parse_input_event(ev_mouse);
- }
return true;
}
diff --git a/platform/uwp/app.cpp b/platform/uwp/app.cpp
index 5ff62b38f9..c18aa36402 100644
--- a/platform/uwp/app.cpp
+++ b/platform/uwp/app.cpp
@@ -85,8 +85,7 @@ App::App() :
mWindowHeight(0),
mEglDisplay(EGL_NO_DISPLAY),
mEglContext(EGL_NO_CONTEXT),
- mEglSurface(EGL_NO_SURFACE),
- number_of_contacts(0) {
+ mEglSurface(EGL_NO_SURFACE) {
}
// The first method called when the IFrameworkView is being created.
@@ -271,48 +270,44 @@ void App::pointer_event(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Cor
last_touch_y[screen_touch->get_index()] = pos.Y;
os->input_event(screen_touch);
- if (number_of_contacts > 1)
- return;
+ } else {
- }; // fallthrought of sorts
-
- Ref<InputEventMouseButton> mouse_button;
- mouse_button.instance();
- mouse_button->set_device(0);
- mouse_button->set_pressed(p_pressed);
- mouse_button->set_button_index(but);
- mouse_button->set_position(Vector2(pos.X, pos.Y));
- mouse_button->set_global_position(Vector2(pos.X, pos.Y));
-
- if (p_is_wheel) {
- if (point->Properties->MouseWheelDelta > 0) {
- mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_UP);
- } else if (point->Properties->MouseWheelDelta < 0) {
- mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_LEFT : BUTTON_WHEEL_DOWN);
+ Ref<InputEventMouseButton> mouse_button;
+ mouse_button.instance();
+ mouse_button->set_device(0);
+ mouse_button->set_pressed(p_pressed);
+ mouse_button->set_button_index(but);
+ mouse_button->set_position(Vector2(pos.X, pos.Y));
+ mouse_button->set_global_position(Vector2(pos.X, pos.Y));
+
+ if (p_is_wheel) {
+ if (point->Properties->MouseWheelDelta > 0) {
+ mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_UP);
+ } else if (point->Properties->MouseWheelDelta < 0) {
+ mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_LEFT : BUTTON_WHEEL_DOWN);
+ }
}
- }
- last_touch_x[31] = pos.X;
- last_touch_y[31] = pos.Y;
+ last_touch_x[31] = pos.X;
+ last_touch_y[31] = pos.Y;
- os->input_event(mouse_button);
-
- if (p_is_wheel) {
- // Send release for mouse wheel
- mouse_button->set_pressed(false);
os->input_event(mouse_button);
+
+ if (p_is_wheel) {
+ // Send release for mouse wheel
+ mouse_button->set_pressed(false);
+ os->input_event(mouse_button);
+ }
}
};
void App::OnPointerPressed(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
- number_of_contacts++;
pointer_event(sender, args, true);
};
void App::OnPointerReleased(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
- number_of_contacts--;
pointer_event(sender, args, false);
};
@@ -351,7 +346,7 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co
Windows::UI::Input::PointerPoint ^ point = args->CurrentPoint;
Windows::Foundation::Point pos = _get_pixel_position(window, point->Position, os);
- if (point->IsInContact && _is_touch(point)) {
+ if (_is_touch(point)) {
Ref<InputEventScreenDrag> screen_drag;
screen_drag.instance();
@@ -361,25 +356,23 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co
screen_drag->set_relative(Vector2(screen_drag->get_position().x - last_touch_x[screen_drag->get_index()], screen_drag->get_position().y - last_touch_y[screen_drag->get_index()]));
os->input_event(screen_drag);
- if (number_of_contacts > 1)
- return;
-
- }; // fallthrought of sorts
+ } else {
- // In case the mouse grabbed, MouseMoved will handle this
- if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED)
- return;
+ // In case the mouse grabbed, MouseMoved will handle this
+ if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED)
+ return;
- Ref<InputEventMouseMotion> mouse_motion;
- mouse_motion.instance();
- mouse_motion->set_device(0);
- mouse_motion->set_position(Vector2(pos.X, pos.Y));
- mouse_motion->set_global_position(Vector2(pos.X, pos.Y));
- mouse_motion->set_relative(Vector2(pos.X - last_touch_x[31], pos.Y - last_touch_y[31]));
+ Ref<InputEventMouseMotion> mouse_motion;
+ mouse_motion.instance();
+ mouse_motion->set_device(0);
+ mouse_motion->set_position(Vector2(pos.X, pos.Y));
+ mouse_motion->set_global_position(Vector2(pos.X, pos.Y));
+ mouse_motion->set_relative(Vector2(pos.X - last_touch_x[31], pos.Y - last_touch_y[31]));
- last_mouse_pos = pos;
+ last_mouse_pos = pos;
- os->input_event(mouse_motion);
+ os->input_event(mouse_motion);
+ }
}
void App::OnMouseMoved(MouseDevice ^ mouse_device, MouseEventArgs ^ args) {
diff --git a/platform/uwp/app.h b/platform/uwp/app.h
index c23270b8ba..5f69f2cb0e 100644
--- a/platform/uwp/app.h
+++ b/platform/uwp/app.h
@@ -107,7 +107,6 @@ namespace GodotUWP
int last_touch_x[32]; // 20 fingers, index 31 reserved for the mouse
int last_touch_y[32];
- int number_of_contacts;
Windows::Foundation::Point last_mouse_pos;
};
}
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 9c37b65d77..363f54fc7b 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -342,6 +342,14 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
} break;
case WM_MOUSEMOVE: {
+ if (input->is_emulating_mouse_from_touch()) {
+ // Universal translation enabled; ignore OS translation
+ LPARAM extra = GetMessageExtraInfo();
+ if (IsPenEvent(extra)) {
+ break;
+ }
+ }
+
if (outside) {
//mouse enter
@@ -367,18 +375,6 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
// Don't calculate relative mouse movement if we don't have focus in CAPTURED mode.
if (!window_has_focus && mouse_mode == MOUSE_MODE_CAPTURED)
break;
- /*
- LPARAM extra = GetMessageExtraInfo();
- if (IsPenEvent(extra)) {
-
- int idx = extra & 0x7f;
- _drag_event(idx, uMsg, wParam, lParam);
- if (idx != 0) {
- return 0;
- };
- // fallthrough for mouse event
- };
- */
Ref<InputEventMouseMotion> mm;
mm.instance();
@@ -448,18 +444,13 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
/*case WM_XBUTTONDOWN:
case WM_XBUTTONUP: */ {
- /*
- LPARAM extra = GetMessageExtraInfo();
- if (IsPenEvent(extra)) {
-
- int idx = extra & 0x7f;
- _touch_event(idx, uMsg, wParam, lParam);
- if (idx != 0) {
- return 0;
- };
- // fallthrough for mouse event
- };
- */
+ if (input->is_emulating_mouse_from_touch()) {
+ // Universal translation enabled; ignore OS translation
+ LPARAM extra = GetMessageExtraInfo();
+ if (IsPenEvent(extra)) {
+ break;
+ }
+ }
Ref<InputEventMouseButton> mb;
mb.instance();
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 1928800d8c..336068cb1e 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -1690,6 +1690,11 @@ void OS_X11::process_xevents() {
if (touch.state.has(index)) // Defensive
break;
touch.state[index] = pos;
+ if (touch.state.size() == 1) {
+ // X11 may send a motion event when a touch gesture begins, that would result
+ // in a spurious mouse motion event being sent to Godot; remember it to be able to filter it out
+ touch.mouse_pos_to_filter = pos;
+ }
input->parse_input_event(st);
} else {
if (!touch.state.has(index)) // Defensive
@@ -1896,6 +1901,18 @@ void OS_X11::process_xevents() {
// to be able to send relative motion events.
Point2i pos(event.xmotion.x, event.xmotion.y);
+ // Avoidance of spurious mouse motion (see handling of touch)
+ bool filter = false;
+ // Adding some tolerance to match better Point2i to Vector2
+ if (touch.state.size() && Vector2(pos).distance_squared_to(touch.mouse_pos_to_filter) < 2) {
+ filter = true;
+ }
+ // Invalidate to avoid filtering a possible legitimate similar event coming later
+ touch.mouse_pos_to_filter = Vector2(1e10, 1e10);
+ if (filter) {
+ break;
+ }
+
if (mouse_mode == MOUSE_MODE_CAPTURED) {
if (pos == Point2i(current_videomode.width / 2, current_videomode.height / 2)) {
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index 610dba0716..0a39da77de 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -127,6 +127,7 @@ class OS_X11 : public OS_Unix {
Vector<int> devices;
XIEventMask event_mask;
Map<int, Vector2> state;
+ Vector2 mouse_pos_to_filter;
} touch;
#endif
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 4419dfe70f..727807dbcd 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -33,6 +33,7 @@
#include "editor/editor_node.h"
#include "io/marshalls.h"
#include "io/resource_loader.h"
+#include "main/input_default.h"
#include "message_queue.h"
#include "node.h"
#include "os/keyboard.h"
@@ -620,6 +621,13 @@ void SceneTree::_notification(int p_notification) {
case NOTIFICATION_WM_FOCUS_IN:
case NOTIFICATION_WM_FOCUS_OUT: {
+ if (p_notification == NOTIFICATION_WM_FOCUS_IN) {
+ InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
+ if (id) {
+ id->ensure_touch_mouse_raised();
+ }
+ }
+
get_root()->propagate_notification(p_notification);
} break;
case NOTIFICATION_TRANSLATION_CHANGED: {