9#include <QtCore/private/qohoslogger_p.h>
10#include <QtCore/qmap.h>
11#include <QtGui/private/qguiapplication_p.h>
12#include <QtGui/private/qhighdpiscaling_p.h>
15#include <arkui/ui_input_event.h>
17#include <render/qohosview.h>
20using namespace Qt::Literals::StringLiterals;
22namespace ch =
std::chrono;
33 qOhosDebug(QtForOhos) <<
"Creating touchDevice!";
35 std::make_unique<QPointingDevice>(
"OHOS touch device"_L1, 1,
36 deviceType, QPointingDevice::PointerType::Finger,
37 QInputDevice::Capability::Position
38 | QInputDevice::Capability::Area
39 | QInputDevice::Capability::Pressure
40 | QInputDevice::Capability::NormalizedPosition,
43 auto *touchDeviceRaw = touchDevice.get();
44 QWindowSystemInterface::registerInputDevice(touchDevice.release());
45 return touchDeviceRaw;
49 QObject *object, QObject *context,
std::function<
void()> signalHandler)
51 auto objDestroyedConnection = QObject::connect(object, &QObject::destroyed, context, std::move(signalHandler));
52 return QtOhos::makeDestroyNotifier(
53 [objDestroyedConnection = std::move(objDestroyedConnection)] ()
mutable {
54 QObject::disconnect(objDestroyedConnection);
61 case OH_NATIVEXCOMPONENT_DOWN:
62 return makeQOhosOptional(QEventPoint::State::Pressed);
63 case OH_NATIVEXCOMPONENT_UP:
64 return makeQOhosOptional(QEventPoint::State::Released);
65 case OH_NATIVEXCOMPONENT_MOVE:
66 return makeQOhosOptional(QEventPoint::State::Updated);
67 case OH_NATIVEXCOMPONENT_CANCEL:
68 case OH_NATIVEXCOMPONENT_UNKNOWN:
76 auto *platformScreen =
static_cast<
QOhosPlatformScreen *>(targetWindow->screen()->handle());
78 QSize screenSize = platformScreen->geometry().size();
80 QPointF clickPointNormalized(
81 clickPoint.x() / screenSize.width(),
82 clickPoint.y() / screenSize.height());
84 return clickPointNormalized;
98 auto *screen = qWindow !=
nullptr
100 : QGuiApplication::primaryScreen();
102 return screen !=
nullptr
103 ? screen->handle()->geometry().topLeft()
109 auto *platformWindow = QOhosPlatformWindow::fromQWindowOrNull(qWindow);
110 auto platformWindowGeometry = platformWindow !=
nullptr
111 ? platformWindow->geometry()
112 : QHighDpi::toNativePixels(qWindow->geometry(), qWindow);
114 return globalPosition - platformWindowGeometry.topLeft();
120 const std::set<QInputDevice::DeviceType> &deviceTypes)
122 for (
const auto &deviceType : deviceTypes)
123 m_touchDevices.emplace(deviceType, createTouchDevice(deviceType));
129 QWindow *targetWindow, ch::nanoseconds timeStamp,
130 const std::vector<QOhosTouchEventTouchPointData> &touchPoints,
131 QInputDevice::DeviceType deviceType, QFlags<OhosKeyboardModifier> modifiers)
133 auto *touchDevice = getTouchDeviceOrCreateIfNeeded(deviceType);
135 QList<QWindowSystemInterface::TouchPoint> wsiTouchPoints;
137 auto timeStampMs = ch::duration_cast<ch::milliseconds>(timeStamp);
139 std::vector<QPoint> activeTouchPointDisplayPositions;
141 auto displayOffset = targetWindow !=
nullptr
142 ? determineScreenGlobalDisplayOffset(targetWindow)
145 for (
const auto &touchPointData : touchPoints) {
146 const auto &touchPoint = touchPointData.touchPoint;
147 QPointF clickPoint = touchPointData.displayPosition;
149 switch (touchPointData.toolType) {
150 case ::OH_NATIVEXCOMPONENT_TOOL_TYPE_FINGER: {
151 QEventPoint::State state =
152 tryMapXComponentTouchEventTypeToQt(touchPoint.type)
153 .value_or(QEventPoint::State::Stationary);
155 if (state != QEventPoint::State::Released)
156 activeTouchPointDisplayPositions.push_back(touchPointData.displayPosition.toPoint());
158 QWindowSystemInterface::TouchPoint qwsiTouchPoint;
159 qwsiTouchPoint.id = touchPoint.id;
160 qwsiTouchPoint.pressure = touchPoint.force;
161 qwsiTouchPoint.normalPosition =
162 calculateTouchPointNormalPosition(targetWindow, clickPoint);
163 qwsiTouchPoint.state = state;
164 qwsiTouchPoint.area = calculateTouchPointArea(clickPoint + displayOffset);
165 wsiTouchPoints.push_back(qwsiTouchPoint);
168 case ::OH_NATIVEXCOMPONENT_TOOL_TYPE_PEN: {
169 Qt::MouseButtons buttons = Qt::NoButton;
170 switch (touchPoint.type) {
171 case OH_NATIVEXCOMPONENT_DOWN:
172 case OH_NATIVEXCOMPONENT_MOVE:
173 buttons = Qt::LeftButton;
175 case OH_NATIVEXCOMPONENT_UP:
176 case OH_NATIVEXCOMPONENT_CANCEL:
177 case OH_NATIVEXCOMPONENT_UNKNOWN:
178 buttons = Qt::NoButton;
181 constexpr float tiltDegreesMin = -60.0f;
182 constexpr float tiltDegreesMax = 60.0f;
183 const int xTilt = qRound(qBound(tiltDegreesMin, touchPointData.tiltX, tiltDegreesMax));
184 const int yTilt = qRound(qBound(tiltDegreesMin, touchPointData.tiltY, tiltDegreesMax));
185 constexpr qreal tangentialPressure = 0;
186 constexpr qreal rotation = 0;
188 QWindowSystemInterface::handleTabletEvent(
189 targetWindow, timeStampMs.count(), {touchPoint.x, touchPoint.y},
191 static_cast<
int>(QInputDevice::DeviceType::Stylus),
192 static_cast<
int>(QPointingDevice::PointerType::Pen),
193 buttons, touchPoint.force, xTilt, yTilt, tangentialPressure, rotation,
194 z, touchPoint.id, convertOhosToQtKeyboardModifiers(modifiers));
197 case ::OH_NATIVEXCOMPONENT_TOOL_TYPE_RUBBER:
198 case ::OH_NATIVEXCOMPONENT_TOOL_TYPE_BRUSH:
199 case ::OH_NATIVEXCOMPONENT_TOOL_TYPE_PENCIL:
200 case ::OH_NATIVEXCOMPONENT_TOOL_TYPE_AIRBRUSH:
201 case ::OH_NATIVEXCOMPONENT_TOOL_TYPE_LENS:
202 case ::OH_NATIVEXCOMPONENT_TOOL_TYPE_UNKNOWN:
203 qOhosWarning(QtForOhos) <<
"Skipping unsupported tool type =" << touchPointData.toolType;
205 case ::OH_NATIVEXCOMPONENT_TOOL_TYPE_MOUSE:
206 qOhosWarning(QtForOhos) <<
"Skipping mouse tool type in touch event.";
211 if (!wsiTouchPoints.isEmpty()) {
212 auto singleActiveTouchEventGlobalPosition = activeTouchPointDisplayPositions.size() == 1
213 ? makeQOhosOptional(displayOffset + activeTouchPointDisplayPositions.front())
216 QWindowSystemInterfaceTouchEvent touchEvent = {
217 .targetWindow = targetWindow,
218 .touchPoints = wsiTouchPoints,
219 .touchDevice = touchDevice,
220 .timestampMs = timeStampMs,
221 .modifiers = modifiers,
222 .singleTouchPointEventGlobalPosition = singleActiveTouchEventGlobalPosition,
225 handleTouchEvent(touchEvent);
231 auto *touchDevice = getTouchDeviceOrCreateIfNeeded(gestureEvent.deviceType);
232 auto *window = gestureEvent.targetWindow.data();
237 auto scaledLocalPosition = QHighDpi::fromNativeLocalPosition(gestureEvent.localPosition, window);
238 auto scaledGlobalPosition = QHighDpi::fromNativePixels(gestureEvent.globalPosition, window);
240 QWindowSystemInterface::handleGestureEventWithRealValue(
241 gestureEvent.targetWindow,
242 gestureEvent.timestamp,
243 static_cast<
const QPointingDevice *>(touchDevice),
244 gestureEvent.gestureType,
247 scaledGlobalPosition);
252 const auto optQOhosQtKeyEvent = keyEvent.tryConvertToQOhosQtKeyEvent();
253 if (!optQOhosQtKeyEvent.has_value())
255 const auto qOhosQtKeyEvent = optQOhosQtKeyEvent.value();
257 constexpr quint32 nativeScanCode = 0;
258 constexpr quint32 nativeModifiers = 0;
261 if (ohosInputContext !=
nullptr)
262 ohosInputContext->setLastInputTypeToTriggerSoftKeyboard(QOhosInputContext::RequestKeyboardReason::NONE);
264 if (qOhosQtKeyEvent.keyAction == QEvent::KeyPress) {
265 if (m_autoRepeatCountMap[qOhosQtKeyEvent.keyCode] < std::numeric_limits<ushort>::max()) {
266 ++m_autoRepeatCountMap[qOhosQtKeyEvent.keyCode];
269 m_autoRepeatCountMap.remove(qOhosQtKeyEvent.keyCode);
271 const auto count = m_autoRepeatCountMap.value(qOhosQtKeyEvent.keyCode, 1);
273 QWindowSystemInterface::handleExtendedKeyEvent(
274 !m_currentKeyboardGrabbingWindow.isNull()
275 ? m_currentKeyboardGrabbingWindow.data()
277 qOhosQtKeyEvent.keyAction, qOhosQtKeyEvent.keyCode,
278 qOhosQtKeyEvent.guiApplicationKeyboardModifiers, nativeScanCode,
279 qOhosQtKeyEvent.nativeKeyCode, nativeModifiers, qOhosQtKeyEvent.keyText, count > 1, count);
284 Qt::MouseButton button = Qt::NoButton;
286 if (mouseEvent.eventType == QEvent::MouseButtonPress || mouseEvent.eventType == QEvent::MouseButtonRelease) {
287 button = mouseEvent.button;
296 registerOnWindowCloseToResetMouseButtonsState(mouseEvent.targetWindow);
300 .targetWindow = mouseEvent.targetWindow,
301 .timestampMs = mouseEvent.timestampMs,
302 .localPosition = mouseEvent.localPosition,
303 .globalPosition = mouseEvent.globalPosition,
305 .eventType = mouseEvent.eventType,
306 .modifiers = mouseEvent.modifiers,
309 handleMouseEvent(wsiEvent);
315 auto local = hoverEvent.localPosition;
316 auto global = hoverEvent.globalPosition;
317 QWindow *window = hoverEvent.targetWindow;
318 if (!m_currentMouseGrabbingWindow.isNull() && m_currentMouseGrabbingWindow != window)
322 QWindowSystemInterface::handleEnterEvent(window, local, global);
324 QWindowSystemInterface::handleLeaveEvent(window);
329 constexpr int angleXMin = -120;
330 constexpr int angleXMax = 120;
331 constexpr int xAxisValueMultiplier = -10;
333 constexpr int angleYMin = angleXMin;
334 constexpr int angleYMax = angleXMax;
335 constexpr int yAxisValueMultiplier = xAxisValueMultiplier;
337 constexpr double wheelStepDegree = 15.0;
338 constexpr double wheelStepPixel = 21.0;
340 constexpr double angleBaseValue = 8.0;
341 constexpr double directionMultiplier = -1.0;
346 static_cast<QOhosPlatformTheme *>(QGuiApplicationPrivate::platformTheme())->setWheelScrollLines(
347 static_cast<
int>(event.wheelScrollLines));
351 if (event.eventToolType == UI_INPUT_EVENT_TOOL_TYPE_MOUSE) {
352 angleDelta.setX(qBound(angleXMin,
static_cast<
int>(event
.horizontalValue * xAxisValueMultiplier), angleXMax));
353 angleDelta.setY(qBound(angleYMin,
static_cast<
int>(event
.verticalValue * yAxisValueMultiplier), angleYMax));
355 auto mousePixelDeltaMultiplier = wheelStepPixel / wheelStepDegree / angleBaseValue;
357 qRound(qFabs(angleDelta.x() * mousePixelDeltaMultiplier) * platformScreen->pixelScalingCoefficient()));
359 qRound(qFabs(angleDelta.y() * mousePixelDeltaMultiplier) * platformScreen->pixelScalingCoefficient()));
360 }
else if (event.eventToolType == UI_INPUT_EVENT_TOOL_TYPE_TOUCHPAD) {
361 auto touchpadAngleDeltaMultiplier =
362 wheelStepDegree / wheelStepPixel / platformScreen->pixelScalingCoefficient() * angleBaseValue * directionMultiplier / event
.wheelScrollLines;
363 angleDelta.setX(qRound(event
.horizontalValue * touchpadAngleDeltaMultiplier));
364 angleDelta.setY(qRound(event
.verticalValue * touchpadAngleDeltaMultiplier));
369 qOhosWarning(QtForOhos)
371 <<
"Received unsupported input event tool type =" << event.eventToolType <<
"skipping...";
375 Qt::MouseEventSource source = event.eventToolType == ::UI_INPUT_EVENT_TOOL_TYPE_TOUCHPAD
376 ? Qt::MouseEventSynthesizedBySystem
377 : Qt::MouseEventNotSynthesized;
378 bool inverted =
false;
380 QWindowSystemInterface::handleWheelEvent(
387 convertOhosToQtKeyboardModifiers(event.modifiers),
394 QWindow *targetWindow, std::vector<QOhosWindowProxy::NonClientAreaMouseEvent> eventBatch)
399 QtOhos::removeMatchingWithLookahead(
400 eventBatch.begin(), eventBatch.end(),
401 [](
const NonClientAreaMouseEvent &event,
const NonClientAreaMouseEvent &nextEvent) {
402 return event.action == QEvent::NonClientAreaMouseMove
403 && nextEvent.action == QEvent::NonClientAreaMouseMove;
407 for (
const auto &mouseEvent : eventBatch) {
408 QOhosMouseEvent qtMouseEvent = {
409 .targetWindow = targetWindow,
410 .timestampMs = mouseEvent.timestamp,
411 .localPosition = mouseEvent.localPosition,
412 .globalPosition = mouseEvent.displayPosition,
413 .button = mouseEvent.button,
414 .eventType = mouseEvent.action,
424 if (mouseEvent.action == QEvent::NonClientAreaMouseButtonPress)
425 registerOnWindowCloseToResetMouseButtonsState(targetWindow);
427 handleMouseEvent(qtMouseEvent);
432 QWindow *targetWindow, std::vector<QOhosWindowProxy::NonClientAreaTouchEvent> eventBatch)
437 QtOhos::removeMatchingWithLookahead(
438 eventBatch.begin(), eventBatch.end(),
439 [](
const NonClientAreaTouchEvent &event,
const NonClientAreaTouchEvent &nextEvent) {
441 event.state == QEventPoint::State::Updated
442 && nextEvent.state == QEventPoint::State::Updated;
446 for (
const auto &touchEvent : eventBatch) {
447 QPointF clickPoint = touchEvent.displayPosition;
449 QWindowSystemInterface::TouchPoint qwsiTouchPoint;
450 qwsiTouchPoint.id = touchEvent.id;
451 qwsiTouchPoint.pressure = 1.0;
452 qwsiTouchPoint.normalPosition = calculateTouchPointNormalPosition(targetWindow, clickPoint);
453 qwsiTouchPoint.state = touchEvent.state;
454 qwsiTouchPoint.area = calculateTouchPointArea(clickPoint);
456 QWindowSystemInterfaceTouchEvent qwsiTouchEvent = {
457 .targetWindow = targetWindow,
458 .touchPoints = {qwsiTouchPoint},
459 .touchDevice = getTouchDeviceOrCreateIfNeeded(QInputDevice::DeviceType::TouchScreen),
460 .timestampMs = touchEvent.timestamp,
463 handleTouchEvent(qwsiTouchEvent);
469 auto lastTouchedPair = getLastTouchedWindowWithSeqNoIfPresent();
470 return lastTouchedPair.has_value()
471 ? lastTouchedPair.value().first
477 auto touchDeviceIter = m_touchDevices.find(deviceType);
478 if (touchDeviceIter == m_touchDevices.end()) {
479 qOhosWarning(QtForOhos) <<
"Trying to get touch device but it isn't registered. Creating and registering one now.";
480 std::tie(touchDeviceIter, std::ignore) = m_touchDevices.emplace(
481 deviceType, createTouchDevice(deviceType));
483 return touchDeviceIter->second;
488 auto maxSeqNoEntryIter =
std::max_element(
489 m_windowsUnderTouchPoints.begin(), m_windowsUnderTouchPoints.end(),
490 [](
const auto &a,
const auto &b) {
491 return a.second.second < b.second.second;
494 return maxSeqNoEntryIter != m_windowsUnderTouchPoints.end()
496 std::make_pair(maxSeqNoEntryIter->first, maxSeqNoEntryIter->second.second))
497 : makeEmptyQOhosOptional();
502 qCDebug(QtForOhos) << Q_FUNC_INFO <<
"window:" << window;
503 m_currentMouseGrabbingWindow = window;
508 qCDebug(QtForOhos) << Q_FUNC_INFO <<
"window:" << window;
509 m_currentKeyboardGrabbingWindow = window;
514 if (!m_currentMouseGrabbingWindow.isNull() && m_lastWsiMouseEvent.has_value()) {
515 auto lastWsiMouseEventValue = m_lastWsiMouseEvent.value();
516 auto *previousCaptureWindow = m_currentMouseGrabbingWindow.data();
517 auto *optLastWindowUnderCursor = lastWsiMouseEventValue.targetWindow.data();
518 auto *optCurrentWindowUnderCursor = qGuiApp->topLevelAt(
519 QHighDpi::fromNativePixels(
520 lastWsiMouseEventValue.globalPosition.toPoint(),
521 lastWsiMouseEventValue.targetWindow.data()));
523 if (optLastWindowUnderCursor !=
nullptr
524 && optCurrentWindowUnderCursor !=
nullptr
525 && optLastWindowUnderCursor != previousCaptureWindow) {
526 QWindowSystemInterface::handleEnterEvent(
527 optLastWindowUnderCursor, lastWsiMouseEventValue.localPosition,
528 lastWsiMouseEventValue.globalPosition);
531 m_currentMouseGrabbingWindow.clear();
536 if (m_lastWsiMouseEvent.has_value())
537 return m_lastWsiMouseEvent.value().globalPosition.toPoint();
539 auto optLastTouchPosition = qAndThen(
541 [](
const QWindowSystemInterfaceTouchEvent &touchEvent) {
542 return touchEvent.singleTouchPointEventGlobalPosition;
544 if (optLastTouchPosition.has_value())
545 return optLastTouchPosition.value();
547 auto lastScaledPositionFromApp = QGuiApplicationPrivate::lastCursorPosition.toPoint();
548 auto *screen = qGuiApp->screenAt(lastScaledPositionFromApp);
549 return QHighDpi::toNativePixels(
550 lastScaledPositionFromApp,
553 : QGuiApplication::primaryScreen());
558 m_currentKeyboardGrabbingWindow.clear();
563 static const QSet<QEvent::Type> mouseButtonPressEventTypes = {
564 QEvent::MouseButtonPress,
565 QEvent::NonClientAreaMouseButtonPress,
567 static const QSet<QEvent::Type> mouseButtonReleaseEventTypes = {
568 QEvent::MouseButtonRelease,
569 QEvent::NonClientAreaMouseButtonRelease,
572 bool eventTypeIsPress = mouseButtonPressEventTypes.contains(wsiEvent.eventType);
573 bool eventTypeIsRelease = mouseButtonReleaseEventTypes.contains(wsiEvent.eventType);
575 if (eventTypeIsPress || eventTypeIsRelease) {
576 m_mouseButtonsState.setFlag(wsiEvent.button, eventTypeIsPress);
578 if (ohosInputContext !=
nullptr)
579 ohosInputContext->setLastInputTypeToTriggerSoftKeyboard(QOhosInputContext::RequestKeyboardReason::MOUSE);
582 QEvent::Type targetEventType;
583 QWindow *targetWindow;
584 QPointF localPosition;
585 if (!m_currentMouseGrabbingWindow.isNull()) {
586 targetWindow = m_currentMouseGrabbingWindow;
587 localPosition = makeWindowLocalPosition(wsiEvent.globalPosition.toPoint(), targetWindow);
588 switch (wsiEvent.eventType) {
589 case QEvent::NonClientAreaMouseButtonRelease:
590 targetEventType = QEvent::MouseButtonRelease;
592 case QEvent::NonClientAreaMouseButtonPress:
593 targetEventType = QEvent::MouseButtonPress;
595 case QEvent::NonClientAreaMouseMove:
596 targetEventType = QEvent::MouseMove;
599 targetEventType = wsiEvent.eventType;
603 targetWindow = wsiEvent.targetWindow;
604 localPosition = wsiEvent.localPosition;
605 targetEventType = wsiEvent.eventType;
608 m_lastWsiMouseEvent = wsiEvent;
610 if (targetEventType == QEvent::None) {
611 qOhosPrintfDebug(
"%s: targetEventType is QEvent::None!", Q_FUNC_INFO);
615 QWindowSystemInterface::handleMouseEvent(
617 wsiEvent.timestampMs.count(),
619 wsiEvent.globalPosition,
623 convertOhosToQtKeyboardModifiers(wsiEvent.modifiers));
628 if (touchEvent.touchPoints.isEmpty()) {
629 qOhosCritical(QtForOhos) <<
"TouchPoints list is empty, nothing to do";
633 m_lastWsiMouseEvent.reset();
635 bool anyEventPressedOrReleased =
637 touchEvent.touchPoints.begin(),
638 touchEvent.touchPoints.end(),
639 [](
const QWindowSystemInterface::TouchPoint &touchPoint) {
640 return touchPoint.state == QEventPoint::State::Pressed || touchPoint.state == QEventPoint::State::Released;
642 if (anyEventPressedOrReleased) {
644 if (ohosInputContext !=
nullptr)
645 ohosInputContext->setLastInputTypeToTriggerSoftKeyboard(QOhosInputContext::RequestKeyboardReason::TOUCH);
648 updateWindowsUnderTouchPoints(touchEvent);
650 m_lastWsiTouchEvent = touchEvent;
651 QWindowSystemInterface::handleTouchEvent(
652 touchEvent.targetWindow, touchEvent.timestampMs.count(),
653 static_cast<
const QPointingDevice *>(touchEvent.touchDevice), touchEvent.touchPoints,
654 convertOhosToQtKeyboardModifiers(touchEvent.modifiers));
659 const auto &touchPoints = touchEvent.touchPoints;
660 auto *targetWindow = touchEvent.targetWindow;
662 const bool allTouchPointsUp =
std::all_of(
663 touchPoints.begin(), touchPoints.end(),
664 [](
const auto &touchPointData) {
665 return touchPointData.state == QEventPoint::State::Released;
668 const bool anyTouchPointDown =
std::any_of(
669 touchPoints.begin(), touchPoints.end(),
670 [](
const auto &touchPointData) {
671 return touchPointData.state == QEventPoint::State::Pressed;
674 if (allTouchPointsUp) {
675 std::ignore = m_windowsUnderTouchPoints.erase(targetWindow);
676 }
else if (anyTouchPointDown) {
677 auto lastTouchedPair = getLastTouchedWindowWithSeqNoIfPresent();
678 auto nextSeqNo = lastTouchedPair.has_value()
679 ? lastTouchedPair.value().second + 1
681 m_windowsUnderTouchPoints[targetWindow] = std::make_pair(
682 registerObjectDestroyedSignalHandler(
684 [
this, targetWindow]() {
685 std::ignore = m_windowsUnderTouchPoints.erase(targetWindow);
693 auto *eventView = QOhosPlatformWindow::fromQWindow(window)->ownedViewOrNull();
694 if (eventView !=
nullptr) {
695 m_lastMouseEventViewLifetimeTrackerHandle = registerObjectDestroyedSignalHandler(
698 m_mouseButtonsState = Qt::NoButton;
QRectF calculateTouchPointArea(const QPointF &clickPoint)
QPoint determineScreenGlobalDisplayOffset(QWindow *qWindow)
QPoint makeWindowLocalPosition(const QPoint &globalPosition, QWindow *qWindow)
QPointF calculateTouchPointNormalPosition(QWindow *targetWindow, const QPointF &clickPoint)
QInputDevice * createTouchDevice(QInputDevice::DeviceType deviceType)
constexpr double fingerAreaWidth
std::shared_ptr< void > registerObjectDestroyedSignalHandler(QObject *object, QObject *context, std::function< void()> signalHandler)
QOhosOptional< QEventPoint::State > tryMapXComponentTouchEventTypeToQt(::OH_NativeXComponent_TouchEventType eventType)
constexpr double fingerAreaHeight
std::nullopt_t makeEmptyQOhosOptional()