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