diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2018-05-02 10:47:49 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-02 10:47:49 +0200 |
commit | 18c28c159d12c9d3227c2199998b271f7c5e5998 (patch) | |
tree | ba3591964e6dea9d06daa5aaea399fa53a8c2c8e | |
parent | 04a4270a3485bcc4bd1ce8f7095fe9ea36bc5518 (diff) | |
parent | de9d40a9537bafa613dc54f2200b7509ad6fa9e3 (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.h | 3 | ||||
-rw-r--r-- | core/os/os.cpp | 2 | ||||
-rw-r--r-- | editor/editor_node.cpp | 2 | ||||
-rw-r--r-- | main/input_default.cpp | 118 | ||||
-rw-r--r-- | main/input_default.h | 15 | ||||
-rw-r--r-- | main/main.cpp | 15 | ||||
-rw-r--r-- | platform/android/os_android.cpp | 49 | ||||
-rw-r--r-- | platform/android/os_android.h | 1 | ||||
-rw-r--r-- | platform/iphone/gl_view.mm | 9 | ||||
-rw-r--r-- | platform/iphone/os_iphone.cpp | 45 | ||||
-rw-r--r-- | platform/iphone/os_iphone.h | 6 | ||||
-rw-r--r-- | platform/javascript/os_javascript.cpp | 35 | ||||
-rw-r--r-- | platform/uwp/app.cpp | 83 | ||||
-rw-r--r-- | platform/uwp/app.h | 1 | ||||
-rw-r--r-- | platform/windows/os_windows.cpp | 39 | ||||
-rw-r--r-- | platform/x11/os_x11.cpp | 17 | ||||
-rw-r--r-- | platform/x11/os_x11.h | 1 | ||||
-rw-r--r-- | scene/main/scene_tree.cpp | 8 |
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: { |