4#include <qarkui/window_manager.h>
7#include <qohosdisplayinfo.h>
8#include <multimodalinput/oh_input_manager.h>
9#include <qohosplugincore.h>
10#include <qohosutils.h>
11#include <render/qohosbatchingrequestshandler.h>
12#include <window_manager/oh_display_info.h>
13#include <window_manager/oh_window_comm.h>
14#include <window_manager/oh_window_event_filter.h>
26struct MouseEventFilterRegistryTraits
28 using RawEventType = ::Input_MouseEvent;
31 static constexpr auto registerEventFilterFunc = ::OH_NativeWindowManager_RegisterMouseEventFilter;
32 static constexpr auto unregisterEventFilterFunc = ::OH_NativeWindowManager_UnregisterMouseEventFilter;
34 static JsWindowId extractWindowIdFromEvent(RawEventType *event);
37struct KeyEventFilterRegistryTraits
39 using RawEventType = ::Input_KeyEvent;
42 static constexpr auto registerEventFilterFunc = ::OH_NativeWindowManager_RegisterKeyEventFilter;
43 static constexpr auto unregisterEventFilterFunc = ::OH_NativeWindowManager_UnregisterKeyEventFilter;
45 static JsWindowId extractWindowIdFromEvent(RawEventType *event);
48struct TouchEventFilterRegistryTraits
50 using RawEventType = ::Input_TouchEvent;
53 static constexpr auto registerEventFilterFunc = ::OH_NativeWindowManager_RegisterTouchEventFilter;
54 static constexpr auto unregisterEventFilterFunc = ::OH_NativeWindowManager_UnregisterTouchEventFilter;
56 static JsWindowId extractWindowIdFromEvent(RawEventType *event);
59template<
typename Traits>
60class EventConsumersMap
63 using RawEventType =
typename Traits::RawEventType;
64 using MappedEventType =
typename Traits::MappedEventType;
66 static EventConsumersMap<Traits> &instance();
68 EventConsumersMap(
const EventConsumersMap &) =
delete;
69 EventConsumersMap(EventConsumersMap &&) =
delete;
70 EventConsumersMap &operator=(
const EventConsumersMap &) =
delete;
71 EventConsumersMap &operator=(EventConsumersMap &&) =
delete;
73 std::shared_ptr<
void> registerEventsConsumer(
74 JsWindowId jsWindowId,
75 QOhosConsumer<
const MappedEventType &> eventsConsumer);
78 static bool filterEvent(
typename Traits::RawEventType *event);
79 void consumeEvent(JsWindowId jsWindowId,
typename Traits::MappedEventType mappedEvent);
83 QOhosConsumer<std::tuple<JsWindowId, MappedEventType>> m_mtSafeEventsConsumerProxy;
84 std::map<JsWindowId, std::shared_ptr<QOhosConsumer<
const MappedEventType &>>> m_consumersMap;
87using MouseEventFilterRegistry = EventConsumersMap<MouseEventFilterRegistryTraits>;
88using KeyEventFilterRegistry = EventConsumersMap<KeyEventFilterRegistryTraits>;
89using TouchEventFilterRegistry = EventConsumersMap<TouchEventFilterRegistryTraits>;
91JsWindowId MouseEventFilterRegistryTraits::extractWindowIdFromEvent(::Input_MouseEvent *event)
93 return JsWindowId(::OH_Input_GetMouseEventWindowId(event));
96JsWindowId KeyEventFilterRegistryTraits::extractWindowIdFromEvent(::Input_KeyEvent *event)
98 return JsWindowId(::OH_Input_GetKeyEventWindowId(event));
101JsWindowId TouchEventFilterRegistryTraits::extractWindowIdFromEvent(::Input_TouchEvent *event)
103 return JsWindowId(::OH_Input_GetTouchEventWindowId(event));
106template<
typename Traits>
107EventConsumersMap<Traits> &EventConsumersMap<Traits>::instance()
109 static EventConsumersMap<Traits> eventConsumersMap;
110 return eventConsumersMap;
113template<
typename Traits>
114EventConsumersMap<Traits>::EventConsumersMap()
115 : m_mtSafeEventsConsumerProxy(
116 makeQtOhosSimpleBatchingMTRequestsHandler<std::tuple<JsWindowId, MappedEventType>>(
117 [](std::function<
void()> task) {
118 QtOhos::invokeInJsThread(
119 [task = std::move(task)](QtOhos::JsState &) {
123 [
this](std::vector<std::tuple<JsWindowId, MappedEventType>> eventsBatch) {
124 for (
const auto &event : eventsBatch)
125 consumeEvent(std::get<JsWindowId>(event), std::get<MappedEventType>(event));
130template<
typename Traits>
131std::shared_ptr<
void> EventConsumersMap<Traits>::registerEventsConsumer(
132 JsWindowId jsWindowId,
133 QOhosConsumer<
const MappedEventType &> eventsConsumer)
135 if (m_consumersMap.find(jsWindowId) != m_consumersMap.end()) {
136 qOhosReportFatalErrorAndAbort(
137 "%s: Duplicate event consumer for jsWindowId: %f", Q_FUNC_INFO, jsWindowId.value());
140 auto errorCode = (*Traits::registerEventFilterFunc)(
141 static_cast<
std::int32_t>(jsWindowId.value()), &EventConsumersMap<Traits>::filterEvent);
142 if (errorCode != ::OK) {
143 qOhosReportFatalErrorAndAbort(
144 "%s: failed to register event filter with error: %d",
145 Q_FUNC_INFO, errorCode);
147 auto unregisterHandle = QtOhos::makeDestroyNotifier([jsWindowId]() {
148 qOhosPrintfWarning(
"%s - %f", Q_FUNC_INFO, jsWindowId.value());
149 (*Traits::unregisterEventFilterFunc)(
static_cast<std::int32_t>(jsWindowId.value()));
152 m_consumersMap[jsWindowId] =
153 QtOhos::makeSharedPtrWithAttachedExtraData(
154 QtOhos::moveToSharedPtr(std::move(eventsConsumer)),
155 std::move(unregisterHandle));
157 return QtOhos::makeDestroyNotifier([
this, jsWindowId]() {
158 qOhosPrintfWarning(
"%s: %f", Q_FUNC_INFO, jsWindowId.value());
159 std::ignore = m_consumersMap.erase(jsWindowId);
163template<
typename Traits>
164bool EventConsumersMap<Traits>::filterEvent(
typename Traits::RawEventType *event)
166 auto jsWindowId = Traits::extractWindowIdFromEvent(event);
167 auto optMappedEvent = MappedEventType::createFromNativeEvent(event);
168 if (optMappedEvent.hasValue())
169 instance().m_mtSafeEventsConsumerProxy(
std::make_tuple(jsWindowId, optMappedEvent.value()));
171 qOhosPrintfWarning(
"%s: jsWindowId: %f, Failed to map native event type", Q_FUNC_INFO, jsWindowId.value());
175template<
typename Traits>
176void EventConsumersMap<Traits>::consumeEvent(JsWindowId jsWindowId, MappedEventType mappedEvent)
178 auto consumerIter = m_consumersMap.find(jsWindowId);
179 if (consumerIter == m_consumersMap.end()) {
181 "%s: received event for jsWindowId: %f which does not contain events consumer",
182 Q_FUNC_INFO, jsWindowId.value());
186 auto &eventConsumerFunc = *(consumerIter->second);
187 (eventConsumerFunc)(mappedEvent);
193 JsWindowId jsWindowId,
194 QOhosConsumer<
const MouseEvent &> eventsConsumer)
196 return MouseEventFilterRegistry::instance()
197 .registerEventsConsumer(jsWindowId, std::move(eventsConsumer));
201 JsWindowId jsWindowId,
202 QOhosConsumer<
const KeyEvent &> eventsConsumer)
204 return KeyEventFilterRegistry::instance()
205 .registerEventsConsumer(jsWindowId, std::move(eventsConsumer));
209 JsWindowId jsWindowId,
210 QOhosConsumer<
const TouchEvent &> eventsConsumer)
212 return TouchEventFilterRegistry::instance()
213 .registerEventsConsumer(jsWindowId, std::move(eventsConsumer));
std::shared_ptr< void > registerMouseEventsConsumer(JsWindowId jsWindowId, QOhosConsumer< const MouseEvent & > eventsConsumer)
std::shared_ptr< void > registerKeyEventsConsumer(JsWindowId jsWindowId, QOhosConsumer< const KeyEvent & > eventsConsumer)
std::shared_ptr< void > registerTouchEventsConsumer(JsWindowId jsWindowId, QOhosConsumer< const TouchEvent & > eventsConsumer)
Combined button and popup list for selecting options.