Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qohosnativeaxiseventhandler.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <render/qohosnativeaxiseventhandler.h>
5
6#include <qarkui/input.h>
7#include <qarkui/qarkuiutils.h>
8#include <render/qohosnativegestureshandler.h>
9
11
12namespace {
13
14class QOhosAxisEventHandler final : public std::enable_shared_from_this<QOhosAxisEventHandler>
15{
16public:
18 QtOhos::QThreadSafeRef<QWindow> qWindowRef,
19 QtOhos::QThreadSafeRef<QOhosInputMethodEventHandler> imEventHandlerRef);
20
21 void handleUiAxisEvent(ArkUI_UIInputEvent *event);
22 void handleUiCoastingAxisEvent(::ArkUI_UIInputEvent *event);
23
24private:
25 QtOhos::QThreadSafeRef<QWindow> m_qWindowRef;
26 QtOhos::QThreadSafeRef<QOhosInputMethodEventHandler> m_imEventHandlerRef;
27
28 QOhosOptional<QPointF> m_localPosition;
29 QOhosOptional<QPointF> m_globalPosition;
30 QOhosOptional<std::int32_t> m_wheelScrollLines;
31
32 QOhosConsumer<const QOhosNativeGestureEvent &> m_nativeGesturesHandler;
33};
34
35QOhosOptional<Qt::NativeGestureType> getQtGestureType(::InputEvent_AxisAction ohAxisActionType)
36{
37 switch (ohAxisActionType) {
38 case ::AXIS_ACTION_BEGIN:
39 return makeQOhosOptional(Qt::BeginNativeGesture);
40 case ::AXIS_ACTION_END :
41 case ::AXIS_ACTION_CANCEL:
42 return makeQOhosOptional(Qt::EndNativeGesture);
43 case ::AXIS_ACTION_UPDATE:
44 return makeQOhosOptional(Qt::ZoomNativeGesture);
45 }
47}
48
50{
51 switch (arkUiAxisEventAction) {
52 case UI_AXIS_EVENT_ACTION_NONE:
53 return Qt::NoScrollPhase;
54 case UI_AXIS_EVENT_ACTION_BEGIN:
55 return Qt::ScrollBegin;
56 case UI_AXIS_EVENT_ACTION_UPDATE:
57 return Qt::ScrollUpdate;
58 case UI_AXIS_EVENT_ACTION_END:
59 return Qt::ScrollEnd;
60 case UI_AXIS_EVENT_ACTION_CANCEL:
61 return Qt::ScrollEnd;
62 }
63
64 qOhosReportFatalErrorAndAbort(
65 "Received unsupported UI_AXIS_EVENT_ACTION: %d", arkUiAxisEventAction);
66}
67
69{
70 switch (phase) {
71 case ::ARKUI_COASTING_AXIS_EVENT_PHASE_NONE:
72 return Qt::NoScrollPhase;
73 case ::ARKUI_COASTING_AXIS_EVENT_PHASE_BEGIN:
74 return Qt::ScrollBegin;
75 case ::ARKUI_COASTING_AXIS_EVENT_PHASE_UPDATE:
76 return Qt::ScrollMomentum;
77 case ::ARKUI_COASTING_AXIS_EVENT_PHASE_END:
78 return Qt::ScrollEnd;
79 }
80
81 qOhosReportFatalErrorAndAbort("Received unsupported ArkUI_CoastingAxisEventPhase: %d", phase);
82};
83
84QOhosAxisEventHandler::QOhosAxisEventHandler(
85 QtOhos::QThreadSafeRef<QWindow> qWindowRef,
86 QtOhos::QThreadSafeRef<QOhosInputMethodEventHandler> imEventHandlerRef)
93 const auto totalScale =
95 ? 1.0
96 : event.value;
97 const auto scaleFactor =
103 }))
104{
105}
106
107void QOhosAxisEventHandler::handleUiAxisEvent(ArkUI_UIInputEvent *event)
108{
109 const auto now = std::chrono::steady_clock::now();
110
111 auto eventTimestamp = OH_ArkUI_UIInputEvent_GetEventTime(event);
112 auto localPosition = QArkUi::getPointerEventLocalPosition(event);
113 auto globalPosition = QArkUi::getPointerEventGlobalPosition(event);
114 double horizontalAxisValue = OH_ArkUI_AxisEvent_GetHorizontalAxisValue(event);
115 double verticalAxisValue = OH_ArkUI_AxisEvent_GetVerticalAxisValue(event);
116 auto eventToolType = OH_ArkUI_UIInputEvent_GetToolType(event);
117 auto eventAxisAction = OH_ArkUI_AxisEvent_GetAxisAction(event);
118 std::int32_t wheelScrollLines;
119 wheelScrollLines = OH_ArkUI_AxisEvent_GetScrollStep(event);
120
121 m_localPosition = makeQOhosOptional(localPosition);
122 m_globalPosition = makeQOhosOptional(globalPosition);
123 m_wheelScrollLines = makeQOhosOptional(wheelScrollLines);
124
125 QOhosWheelEvent ohosWheelEvent = {
126 .timestamp = eventTimestamp,
127 .localPoint = localPosition,
128 .globalPoint = globalPosition,
129 .horizontalValue = horizontalAxisValue,
130 .verticalValue = verticalAxisValue,
131 .eventToolType = eventToolType,
132 .scrollPhase = convertArkUiAxisEventActionToQtScrollPhase(eventAxisAction),
133 .wheelScrollLines = wheelScrollLines,
134 .modifiers = readKeyModifiersFromOhosUiInputEvent(event),
135 };
136
137 auto weakSelf = QtOhos::makeWeakPtr(shared_from_this());
138 m_imEventHandlerRef.visitInQtThreadIfAlive(
139 [weakSelf, ohosWheelEvent, qWindowRef = m_qWindowRef](auto &eventHandler) {
140 auto sharedSelf = weakSelf.lock();
141 if (!sharedSelf) {
142 return;
143 };
144 eventHandler.onMouseWheelEvent(ohosWheelEvent, qWindowRef.data());
145 });
146
147 const auto totalScale = OH_ArkUI_AxisEvent_GetPinchAxisScaleValue(event);
148
149 if (qFuzzyIsNull(horizontalAxisValue) && qFuzzyIsNull(verticalAxisValue) && !qFuzzyIsNull(totalScale)) {
150 const auto deviceType = QArkUi::getTouchDeviceType(event);
151 const auto gestureType = getQtGestureType(
152 static_cast<InputEvent_AxisAction>(eventAxisAction)).value_or(Qt::ZoomNativeGesture);
153
154 QOhosNativeGestureEvent newEvent {
155 .timestamp = now,
156 .gestureTimestamp = eventTimestamp,
157 .value = totalScale,
158 .localPosition = localPosition,
159 .globalPosition = globalPosition,
160 .gestureType = gestureType,
161 .deviceType = deviceType,
162 };
163
164 m_nativeGesturesHandler(newEvent);
165 }
166}
167
168void QOhosAxisEventHandler::handleUiCoastingAxisEvent(::ArkUI_UIInputEvent *event)
169{
170 if (!m_localPosition.has_value() || !m_globalPosition.has_value() || !m_wheelScrollLines.has_value()) {
171 qOhosPrintfWarning(
172 "%s: Cannot create wheel event - incomplete data, ignoring coasting event.", Q_FUNC_INFO);
173 return;
174 }
175
176 auto *coastingAxisEvent = QArkUi::callArkUi(
177 Q_OHOS_NAMED_FUNC(::OH_ArkUI_UIInputEvent_GetCoastingAxisEvent), event);
178 auto eventTime = QArkUi::callArkUi(
179 Q_OHOS_NAMED_FUNC(::OH_ArkUI_CoastingAxisEvent_GetEventTime), coastingAxisEvent);
180 auto phase = QArkUi::callArkUi(
181 Q_OHOS_NAMED_FUNC(::OH_ArkUI_CoastingAxisEvent_GetPhase), coastingAxisEvent);
182 auto delta = QPointF(
183 QArkUi::callArkUi(Q_OHOS_NAMED_FUNC(::OH_ArkUI_CoastingAxisEvent_GetDeltaX), coastingAxisEvent),
184 QArkUi::callArkUi(Q_OHOS_NAMED_FUNC(::OH_ArkUI_CoastingAxisEvent_GetDeltaY), coastingAxisEvent));
185
186 const QFlags<OhosKeyboardModifier> coastingAxisEventModifiersFallback = {};
187
188 QOhosWheelEvent ohosWheelEvent = {
189 .timestamp = eventTime,
190 .localPoint = m_localPosition.value(),
191 .globalPoint = m_globalPosition.value(),
192 .horizontalValue = delta.x(),
193 .verticalValue = delta.y(),
194 .eventToolType = ::UI_INPUT_EVENT_TOOL_TYPE_TOUCHPAD,
195 .scrollPhase = convertArkUiCoastingAxisEventActionToQtScrollPhase(phase),
196 .wheelScrollLines = m_wheelScrollLines.value(),
197 .modifiers = coastingAxisEventModifiersFallback,
198 };
199
200 auto weakSelf = QtOhos::makeWeakPtr(shared_from_this());
201 m_imEventHandlerRef.visitInQtThreadIfAlive(
202 [weakSelf, ohosWheelEvent, qWindowRef = m_qWindowRef](auto &eventHandler) {
203 auto sharedSelf = weakSelf.lock();
204 QWindow *qWindow = qWindowRef.data();
205 if (!sharedSelf || qWindow == nullptr)
206 return;
207
208 eventHandler.onMouseWheelEvent(ohosWheelEvent, qWindow);
209 });
210}
211
212}
213
215 QtOhos::QThreadSafeRef<QWindow> qWindowRef,
216 QtOhos::QThreadSafeRef<QOhosInputMethodEventHandler> imEventHandlerRef)
217{
218 auto handler = std::make_shared<QOhosAxisEventHandler>(qWindowRef, imEventHandlerRef);
219 return [handler](QOhosAxisEventType eventType, ::ArkUI_UIInputEvent *inputEvent) {
220 switch (eventType) {
221 case QOhosAxisEventType::AxisEvent:
222 handler->handleUiAxisEvent(inputEvent);
223 break;
224 case QOhosAxisEventType::CoastingAxisEvent:
225 handler->handleUiCoastingAxisEvent(inputEvent);
226 break;
227 }
228 };
229}
230
231QT_END_NAMESPACE
QOhosAxisEventHandler(QtOhos::QThreadSafeRef< QWindow > qWindowRef, QtOhos::QThreadSafeRef< QOhosInputMethodEventHandler > imEventHandlerRef)
void handleUiCoastingAxisEvent(::ArkUI_UIInputEvent *event)
Combined button and popup list for selecting options.
QOhosOptional< Qt::NativeGestureType > getQtGestureType(::InputEvent_AxisAction ohAxisActionType)
Qt::ScrollPhase convertArkUiCoastingAxisEventActionToQtScrollPhase(::ArkUI_CoastingAxisEventPhase phase)
Qt::ScrollPhase convertArkUiAxisEventActionToQtScrollPhase(std::int32_t arkUiAxisEventAction)
QOhosConsumer< QOhosAxisEventType, ::ArkUI_UIInputEvent * > makeQOhosNativeAxisEventHandler(QtOhos::QThreadSafeRef< QWindow > qWindowRef, QtOhos::QThreadSafeRef< QOhosInputMethodEventHandler > imEventHandlerRef)
std::nullopt_t makeEmptyQOhosOptional()