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
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 std::optional<QPointF> m_localPosition;
29 std::optional<QPointF> m_globalPosition;
30 std::optional<std::int32_t> m_wheelScrollLines;
31};
32
34{
35 switch (arkUiAxisEventAction) {
36 case UI_AXIS_EVENT_ACTION_NONE:
37 return Qt::NoScrollPhase;
38 case UI_AXIS_EVENT_ACTION_BEGIN:
39 return Qt::ScrollBegin;
40 case UI_AXIS_EVENT_ACTION_UPDATE:
41 return Qt::ScrollUpdate;
42 case UI_AXIS_EVENT_ACTION_END:
43 return Qt::ScrollEnd;
44 case UI_AXIS_EVENT_ACTION_CANCEL:
45 return Qt::ScrollEnd;
46 }
47
48 qOhosReportFatalErrorAndAbort(
49 "Received unsupported UI_AXIS_EVENT_ACTION: %d", arkUiAxisEventAction);
50}
51
53{
54 switch (phase) {
55 case ::ARKUI_COASTING_AXIS_EVENT_PHASE_NONE:
56 return Qt::NoScrollPhase;
57 case ::ARKUI_COASTING_AXIS_EVENT_PHASE_BEGIN:
58 return Qt::ScrollBegin;
59 case ::ARKUI_COASTING_AXIS_EVENT_PHASE_UPDATE:
60 return Qt::ScrollMomentum;
61 case ::ARKUI_COASTING_AXIS_EVENT_PHASE_END:
62 return Qt::ScrollEnd;
63 }
64
65 qOhosReportFatalErrorAndAbort("Received unsupported ArkUI_CoastingAxisEventPhase: %d", phase);
66};
67
68QOhosAxisEventHandler::QOhosAxisEventHandler(
69 QtOhos::QThreadSafeRef<QWindow> qWindowRef,
70 QtOhos::QThreadSafeRef<QOhosInputMethodEventHandler> imEventHandlerRef)
73{
74}
75
76void QOhosAxisEventHandler::handleUiAxisEvent(ArkUI_UIInputEvent *event)
77{
78 auto eventTimestamp = OH_ArkUI_UIInputEvent_GetEventTime(event);
79 auto localPosition = QArkUi::getPointerEventLocalPosition(event);
80 auto globalPosition = QArkUi::getPointerEventGlobalPosition(event);
81 double horizontalAxisValue = OH_ArkUI_AxisEvent_GetHorizontalAxisValue(event);
82 double verticalAxisValue = OH_ArkUI_AxisEvent_GetVerticalAxisValue(event);
83 auto eventToolType = OH_ArkUI_UIInputEvent_GetToolType(event);
84 auto eventAxisAction = OH_ArkUI_AxisEvent_GetAxisAction(event);
85 std::int32_t wheelScrollLines;
86 wheelScrollLines = OH_ArkUI_AxisEvent_GetScrollStep(event);
87
88 const auto totalScale = OH_ArkUI_AxisEvent_GetPinchAxisScaleValue(event);
89
90 if (qFuzzyIsNull(horizontalAxisValue) && qFuzzyIsNull(verticalAxisValue) && !qFuzzyIsNull(totalScale))
91 return;
92
93 m_localPosition = localPosition;
94 m_globalPosition = globalPosition;
95 m_wheelScrollLines = wheelScrollLines;
96
97 QOhosWheelEvent ohosWheelEvent = {
98 .timestamp = eventTimestamp,
99 .localPoint = localPosition,
100 .globalPoint = globalPosition,
101 .horizontalValue = horizontalAxisValue,
102 .verticalValue = verticalAxisValue,
103 .eventToolType = eventToolType,
104 .scrollPhase = convertArkUiAxisEventActionToQtScrollPhase(eventAxisAction),
105 .wheelScrollLines = wheelScrollLines,
106 .modifiers = readKeyModifiersFromOhosUiInputEvent(event),
107 };
108
109 auto weakSelf = QtOhos::makeWeakPtr(shared_from_this());
110 m_imEventHandlerRef.visitInQtThreadIfAlive(
111 [weakSelf, ohosWheelEvent, qWindowRef = m_qWindowRef](auto &eventHandler) {
112 auto sharedSelf = weakSelf.lock();
113 if (!sharedSelf) {
114 return;
115 };
116 eventHandler.onMouseWheelEvent(ohosWheelEvent, qWindowRef.data());
117 });
118}
119
120void QOhosAxisEventHandler::handleUiCoastingAxisEvent(::ArkUI_UIInputEvent *event)
121{
122 if (!m_localPosition.has_value() || !m_globalPosition.has_value() || !m_wheelScrollLines.has_value()) {
123 qOhosPrintfWarning(
124 "%s: Cannot create wheel event - incomplete data, ignoring coasting event.", Q_FUNC_INFO);
125 return;
126 }
127
128 auto *coastingAxisEvent = QArkUi::callArkUi(
129 Q_OHOS_NAMED_FUNC(::OH_ArkUI_UIInputEvent_GetCoastingAxisEvent), event);
130 auto eventTime = QArkUi::callArkUi(
131 Q_OHOS_NAMED_FUNC(::OH_ArkUI_CoastingAxisEvent_GetEventTime), coastingAxisEvent);
132 auto phase = QArkUi::callArkUi(
133 Q_OHOS_NAMED_FUNC(::OH_ArkUI_CoastingAxisEvent_GetPhase), coastingAxisEvent);
134 auto delta = QPointF(
135 QArkUi::callArkUi(Q_OHOS_NAMED_FUNC(::OH_ArkUI_CoastingAxisEvent_GetDeltaX), coastingAxisEvent),
136 QArkUi::callArkUi(Q_OHOS_NAMED_FUNC(::OH_ArkUI_CoastingAxisEvent_GetDeltaY), coastingAxisEvent));
137
138 const QFlags<OhosKeyboardModifier> coastingAxisEventModifiersFallback = {};
139
140 QOhosWheelEvent ohosWheelEvent = {
141 .timestamp = eventTime,
142 .localPoint = m_localPosition.value(),
143 .globalPoint = m_globalPosition.value(),
144 .horizontalValue = delta.x(),
145 .verticalValue = delta.y(),
146 .eventToolType = ::UI_INPUT_EVENT_TOOL_TYPE_TOUCHPAD,
147 .scrollPhase = convertArkUiCoastingAxisEventActionToQtScrollPhase(phase),
148 .wheelScrollLines = m_wheelScrollLines.value(),
149 .modifiers = coastingAxisEventModifiersFallback,
150 };
151
152 auto weakSelf = QtOhos::makeWeakPtr(shared_from_this());
153 m_imEventHandlerRef.visitInQtThreadIfAlive(
154 [weakSelf, ohosWheelEvent, qWindowRef = m_qWindowRef](auto &eventHandler) {
155 auto sharedSelf = weakSelf.lock();
156 QWindow *qWindow = qWindowRef.data();
157 if (!sharedSelf || qWindow == nullptr)
158 return;
159
160 eventHandler.onMouseWheelEvent(ohosWheelEvent, qWindow);
161 });
162}
163
164}
165
167 QtOhos::QThreadSafeRef<QWindow> qWindowRef,
168 QtOhos::QThreadSafeRef<QOhosInputMethodEventHandler> imEventHandlerRef)
169{
170 auto handler = std::make_shared<QOhosAxisEventHandler>(qWindowRef, imEventHandlerRef);
171 return [handler](QOhosAxisEventType eventType, ::ArkUI_UIInputEvent *inputEvent) {
172 switch (eventType) {
173 case QOhosAxisEventType::AxisEvent:
174 handler->handleUiAxisEvent(inputEvent);
175 break;
176 case QOhosAxisEventType::CoastingAxisEvent:
177 handler->handleUiCoastingAxisEvent(inputEvent);
178 break;
179 }
180 };
181}
182
183QT_END_NAMESPACE
QOhosAxisEventHandler(QtOhos::QThreadSafeRef< QWindow > qWindowRef, QtOhos::QThreadSafeRef< QOhosInputMethodEventHandler > imEventHandlerRef)
void handleUiCoastingAxisEvent(::ArkUI_UIInputEvent *event)
Combined button and popup list for selecting options.
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)