diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 92eefefe243..f5b5b65f6c6 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -1451,6 +1451,10 @@ void OS_X11::process_xevents() { input_event.ID = ++event_id; input_event.device = 0; + InputEvent mouse_event; + mouse_event.ID = ++event_id; + mouse_event.device = 0; + XIDeviceEvent *event_data = (XIDeviceEvent *)event.xcookie.data; int index = event_data->detail; Point2i pos = Point2i(event_data->event_x, event_data->event_y); @@ -1465,22 +1469,53 @@ void OS_X11::process_xevents() { bool is_begin = event_data->evtype == XI_TouchBegin; + bool translate = false; + if (is_begin) { + ++num_touches; + if (num_touches == 1) { + touch_mouse_index = index; + translate = true; + } + } else { + --num_touches; + if (num_touches == 0) { + translate = true; + } else if (num_touches < 0) { // Defensive + num_touches = 0; + } + touch_mouse_index = -1; + } + input_event.type = InputEvent::SCREEN_TOUCH; input_event.screen_touch.index = index; input_event.screen_touch.x = pos.x; input_event.screen_touch.y = pos.y; input_event.screen_touch.pressed = is_begin; + if (translate) { + mouse_event.type = InputEvent::MOUSE_BUTTON; + mouse_event.mouse_button.x = pos.x; + mouse_event.mouse_button.y = pos.y; + mouse_event.mouse_button.global_x = pos.x; + mouse_event.mouse_button.global_y = pos.y; + input->set_mouse_pos(pos); + mouse_event.mouse_button.button_index = 1; + mouse_event.mouse_button.pressed = is_begin; + last_mouse_pos = pos; + } + if (is_begin) { if (touch.state.has(index)) // Defensive break; touch.state[index] = pos; input->parse_input_event(input_event); + input->parse_input_event(mouse_event); } else { if (!touch.state.has(index)) // Defensive break; touch.state.erase(index); input->parse_input_event(input_event); + input->parse_input_event(mouse_event); } } break; @@ -1500,6 +1535,19 @@ void OS_X11::process_xevents() { input_event.screen_drag.relative_y = pos.y - curr_pos_elem->value().y; input->parse_input_event(input_event); + if (index == touch_mouse_index) { + mouse_event.type = InputEvent::MOUSE_MOTION; + mouse_event.mouse_motion.x = pos.x; + mouse_event.mouse_motion.y = pos.y; + mouse_event.mouse_motion.global_x = pos.x; + mouse_event.mouse_motion.global_y = pos.y; + input->set_mouse_pos(pos); + mouse_event.mouse_motion.relative_x = pos.x - last_mouse_pos.x; + mouse_event.mouse_motion.relative_y = pos.y - last_mouse_pos.y; + last_mouse_pos = pos; + input->parse_input_event(mouse_event); + } + curr_pos_elem->value() = pos; } } break; @@ -1543,10 +1591,13 @@ void OS_X11::process_xevents() { GrabModeAsync, GrabModeAsync, x11_window, None, CurrentTime); } #ifdef TOUCH_ENABLED -// Grab touch devices to avoid OS gesture interference -/*for (int i = 0; i < touch.devices.size(); ++i) { + // Grab touch devices to avoid OS gesture interference + /*for (int i = 0; i < touch.devices.size(); ++i) { XIGrabDevice(x11_display, touch.devices[i], x11_window, CurrentTime, None, XIGrabModeAsync, XIGrabModeAsync, False, &touch.event_mask); }*/ + // Ensure touch mouse is unstuck + touch_mouse_index = -1; + num_touches = 0; #endif break; @@ -2328,6 +2379,10 @@ OS_X11::OS_X11() { minimized = false; xim_style = 0L; mouse_mode = MOUSE_MODE_VISIBLE; +#ifdef TOUCH_ENABLED + num_touches = 0; + touch_mouse_index = -1; +#endif } void OS_X11::disable_crash_handler() { diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index b2c6498a1a4..5584831eb21 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -132,6 +132,9 @@ class OS_X11 : public OS_Unix { XIEventMask event_mask; Map<int, Point2i> state; } touch; + // For touch-to-mouse + int num_touches; + int touch_mouse_index; #endif PhysicsServer *physics_server;