Merge pull request #18082 from RandomShaper/improve-gui-touch-3.0
Implement universal translation of touch to mouse (3.0)
This commit is contained in:
commit
5917063192
|
@ -118,6 +118,7 @@ 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_mouse_from_touch() const = 0;
|
||||
|
||||
virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2()) = 0;
|
||||
virtual void set_mouse_in_window(bool p_in_window) = 0;
|
||||
|
|
|
@ -249,6 +249,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;
|
||||
|
@ -272,25 +277,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 && !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 && !p_is_emulated && mm->get_button_mask() & 1) {
|
||||
Ref<InputEventScreenDrag> drag_event;
|
||||
drag_event.instance();
|
||||
|
||||
|
@ -302,6 +312,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()) {
|
||||
|
@ -498,6 +560,36 @@ bool InputDefault::is_emulating_touchscreen() const {
|
|||
return emulate_touch;
|
||||
}
|
||||
|
||||
// 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_mouse_from_touch = p_emulate;
|
||||
}
|
||||
|
||||
bool InputDefault::is_emulating_mouse_from_touch() const {
|
||||
|
||||
return emulate_mouse_from_touch;
|
||||
}
|
||||
|
||||
void InputDefault::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
|
||||
if (Engine::get_singleton()->is_editor_hint())
|
||||
return;
|
||||
|
@ -815,6 +907,8 @@ InputDefault::InputDefault() {
|
|||
|
||||
mouse_button_mask = 0;
|
||||
emulate_touch = false;
|
||||
emulate_mouse_from_touch = false;
|
||||
mouse_from_touch_index = -1;
|
||||
main_loop = NULL;
|
||||
|
||||
hat_map_default[HAT_UP].type = TYPE_BUTTON;
|
||||
|
|
|
@ -60,6 +60,9 @@ class InputDefault : public Input {
|
|||
Map<StringName, Action> action_state;
|
||||
|
||||
bool emulate_touch;
|
||||
bool emulate_mouse_from_touch;
|
||||
|
||||
int mouse_from_touch_index;
|
||||
|
||||
struct VibrationInfo {
|
||||
float weak_magnitude;
|
||||
|
@ -175,6 +178,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,6 +230,10 @@ public:
|
|||
|
||||
void set_emulate_touch(bool p_emulate);
|
||||
virtual bool is_emulating_touchscreen() const;
|
||||
void ensure_touch_mouse_raised();
|
||||
|
||||
void set_emulate_mouse_from_touch(bool p_emulate);
|
||||
virtual bool is_emulating_mouse_from_touch() const;
|
||||
|
||||
virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = Input::CURSOR_ARROW, const Vector2 &p_hotspot = Vector2());
|
||||
virtual void set_mouse_in_window(bool p_in_window);
|
||||
|
|
|
@ -1157,13 +1157,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) {
|
||||
//only if no touchscreen ui hint, set emulation
|
||||
InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
|
||||
if (id)
|
||||
InputDefault *id = Object::cast_to<InputDefault>(Input::get_singleton());
|
||||
if (id) {
|
||||
if (bool(GLOBAL_DEF("display/window/handheld/emulate_touchscreen", false)) && !editor) {
|
||||
if (!OS::get_singleton()->has_touchscreen_ui_hint()) {
|
||||
//only if no touchscreen ui hint, set emulation
|
||||
id->set_emulate_touch(true);
|
||||
}
|
||||
}
|
||||
|
||||
id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF("display/window/handheld/emulate_mouse_from_touch", true)));
|
||||
}
|
||||
|
||||
MAIN_PRINT("Main: Load Remaps");
|
||||
|
|
|
@ -332,17 +332,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;
|
||||
|
@ -360,21 +349,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++) {
|
||||
|
||||
|
@ -389,19 +363,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++) {
|
||||
|
@ -434,16 +395,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;
|
||||
|
|
|
@ -93,7 +93,6 @@ public:
|
|||
private:
|
||||
Vector<TouchPos> touch;
|
||||
|
||||
Point2 last_mouse;
|
||||
GFXInitFunc gfx_init_func;
|
||||
void *gfx_init_ud;
|
||||
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -191,7 +191,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;
|
||||
|
@ -203,28 +203,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)) {
|
||||
|
||||
|
@ -235,21 +217,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) {
|
||||
|
@ -263,10 +230,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);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -377,7 +344,7 @@ Point2 OSIPhone::get_mouse_position() const {
|
|||
|
||||
int OSIPhone::get_mouse_button_state() const {
|
||||
|
||||
return mouse_list.pressed[0];
|
||||
return false;
|
||||
};
|
||||
|
||||
void OSIPhone::set_window_title(const String &p_title){};
|
||||
|
|
|
@ -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);
|
||||
|
@ -151,7 +151,6 @@ public:
|
|||
virtual void set_mouse_grab(bool p_grab);
|
||||
virtual bool is_mouse_grab_enabled() const;
|
||||
virtual Point2 get_mouse_position() const;
|
||||
virtual int get_mouse_button_state() const;
|
||||
virtual void set_window_title(const String &p_title);
|
||||
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||
|
|
|
@ -277,23 +277,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;
|
||||
}
|
||||
|
||||
|
@ -319,24 +302,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
||||
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);
|
||||
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)
|
||||
} else {
|
||||
|
||||
// In case the mouse grabbed, MouseMoved will handle this
|
||||
if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED)
|
||||
return;
|
||||
|
||||
}; // fallthrought of sorts
|
||||
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]));
|
||||
|
||||
// In case the mouse grabbed, MouseMoved will handle this
|
||||
if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED)
|
||||
return;
|
||||
last_mouse_pos = pos;
|
||||
|
||||
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;
|
||||
|
||||
os->input_event(mouse_motion);
|
||||
os->input_event(mouse_motion);
|
||||
}
|
||||
}
|
||||
|
||||
void App::OnMouseMoved(MouseDevice ^ mouse_device, MouseEventArgs ^ args) {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -361,6 +361,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
|
||||
|
||||
|
@ -386,18 +394,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();
|
||||
|
@ -467,18 +463,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();
|
||||
|
|
|
@ -1680,6 +1680,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
|
||||
|
@ -1886,6 +1891,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)) {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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: {
|
||||
|
|
Loading…
Reference in New Issue