1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "core/common/event_manager.h"
17
18 #include "base/geometry/ng/point_t.h"
19 #include "base/log/ace_trace.h"
20 #include "base/memory/ace_type.h"
21 #include "base/thread/frame_trace_adapter.h"
22 #include "base/utils/utils.h"
23 #include "core/common/container.h"
24 #include "core/components_ng/base/frame_node.h"
25 #include "core/components_ng/manager/select_overlay/select_overlay_manager.h"
26 #include "core/event/ace_events.h"
27 #include "core/event/key_event.h"
28 #include "core/event/touch_event.h"
29 #include "core/gestures/gesture_referee.h"
30 #include "core/pipeline/base/element.h"
31 #include "core/pipeline/base/render_node.h"
32
33 namespace OHOS::Ace {
34 constexpr uint8_t KEYS_MAX_VALUE = 3;
35 const std::string SHORT_CUT_VALUE_X = "X";
36 const std::string SHORT_CUT_VALUE_Y = "Y";
37 const std::string SHORT_CUT_VALUE_Z = "Z";
38 const std::string SHORT_CUT_VALUE_A = "A";
39 const std::string SHORT_CUT_VALUE_C = "C";
40 const std::string SHORT_CUT_VALUE_V = "V";
41 enum class CtrlKeysBit {
42 CTRL = 1,
43 SHIFT = 2,
44 ALT = 4,
45 };
46
TouchTest(const TouchEvent & touchPoint,const RefPtr<RenderNode> & renderNode,const TouchRestrict & touchRestrict,const Offset & offset,float viewScale,bool needAppend)47 void EventManager::TouchTest(const TouchEvent& touchPoint, const RefPtr<RenderNode>& renderNode,
48 const TouchRestrict& touchRestrict, const Offset& offset, float viewScale, bool needAppend)
49 {
50 ContainerScope scope(instanceId_);
51
52 ACE_FUNCTION_TRACE();
53 CHECK_NULL_VOID(renderNode);
54 // first clean.
55 referee_->CleanGestureScope(touchPoint.id);
56 // collect
57 TouchTestResult hitTestResult;
58 const Point point { touchPoint.x, touchPoint.y, touchPoint.sourceType };
59 // For root node, the parent local point is the same as global point.
60 renderNode->TouchTest(point, point, touchRestrict, hitTestResult);
61 if (needAppend) {
62 #ifdef OHOS_STANDARD_SYSTEM
63 for (auto entry = hitTestResult.begin(); entry != hitTestResult.end(); ++entry) {
64 if ((*entry)) {
65 (*entry)->SetSubPipelineGlobalOffset(offset, viewScale);
66 }
67 }
68 #endif
69 TouchTestResult prevHitTestResult = touchTestResults_[touchPoint.id];
70 hitTestResult.splice(hitTestResult.end(), prevHitTestResult);
71 }
72 touchTestResults_[touchPoint.id] = std::move(hitTestResult);
73 }
74
TouchTest(const TouchEvent & touchPoint,const RefPtr<NG::FrameNode> & frameNode,const TouchRestrict & touchRestrict,const Offset & offset,float viewScale,bool needAppend)75 void EventManager::TouchTest(const TouchEvent& touchPoint, const RefPtr<NG::FrameNode>& frameNode,
76 const TouchRestrict& touchRestrict, const Offset& offset, float viewScale, bool needAppend)
77 {
78 ContainerScope scope(instanceId_);
79
80 ACE_FUNCTION_TRACE();
81 CHECK_NULL_VOID(frameNode);
82 // collect
83 TouchTestResult hitTestResult;
84 const NG::PointF point { touchPoint.x, touchPoint.y };
85 if (refereeNG_->CheckSourceTypeChange(touchPoint.sourceType)) {
86 refereeNG_->CleanAll(true);
87 }
88 if (refereeNG_->QueryAllDone(touchPoint.id)) {
89 refereeNG_->CleanGestureScope(touchPoint.id);
90 }
91 if (frameNode->HaveSecurityComponent()) {
92 std::vector<NG::RectF> rect;
93 frameNode->CheckSecurityComponentStatus(rect);
94 }
95 if (!needAppend) {
96 NG::NGGestureRecognizer::ResetGlobalTransCfg();
97 }
98 // For root node, the parent local point is the same as global point.
99 frameNode->TouchTest(point, point, point, touchRestrict, hitTestResult, touchPoint.id);
100 if (needAppend) {
101 #ifdef OHOS_STANDARD_SYSTEM
102 for (const auto& entry : hitTestResult) {
103 if (entry) {
104 entry->SetSubPipelineGlobalOffset(offset, viewScale);
105 }
106 }
107 #endif
108 TouchTestResult prevHitTestResult = touchTestResults_[touchPoint.id];
109 hitTestResult.splice(hitTestResult.end(), prevHitTestResult);
110 }
111 touchTestResults_[touchPoint.id] = std::move(hitTestResult);
112 }
113
TouchTest(const AxisEvent & event,const RefPtr<NG::FrameNode> & frameNode,const TouchRestrict & touchRestrict)114 void EventManager::TouchTest(
115 const AxisEvent& event, const RefPtr<NG::FrameNode>& frameNode, const TouchRestrict& touchRestrict)
116 {
117 ContainerScope scope(instanceId_);
118
119 if (refereeNG_->CheckSourceTypeChange(event.sourceType, true)) {
120 refereeNG_->CleanAll(true);
121 }
122 ACE_FUNCTION_TRACE();
123 CHECK_NULL_VOID(frameNode);
124 // collect
125 const NG::PointF point { event.x, event.y };
126 if (frameNode->HaveSecurityComponent()) {
127 std::vector<NG::RectF> rect;
128 frameNode->CheckSecurityComponentStatus(rect);
129 }
130 // For root node, the parent local point is the same as global point.
131 TouchTestResult hitTestResult;
132 frameNode->TouchTest(point, point, point, touchRestrict, hitTestResult, event.id);
133 axisTouchTestResults_[event.id] = std::move(hitTestResult);
134 }
135
HandleGlobalEvent(const TouchEvent & touchPoint,const RefPtr<TextOverlayManager> & textOverlayManager)136 void EventManager::HandleGlobalEvent(const TouchEvent& touchPoint, const RefPtr<TextOverlayManager>& textOverlayManager)
137 {
138 if (touchPoint.type != TouchType::DOWN) {
139 return;
140 }
141 auto coordinateOffset = textOverlayManager->GetCoordinateOffset();
142 const Point point { touchPoint.x - coordinateOffset.GetX(), touchPoint.y - coordinateOffset.GetY(),
143 touchPoint.sourceType };
144 CHECK_NULL_VOID_NOLOG(textOverlayManager);
145 auto textOverlayBase = textOverlayManager->GetTextOverlayBase();
146 CHECK_NULL_VOID_NOLOG(textOverlayBase);
147 auto targetNode = textOverlayManager->GetTargetNode();
148 CHECK_NULL_VOID_NOLOG(targetNode);
149 for (auto& rect : textOverlayManager->GetTextOverlayRect()) {
150 if (rect.IsInRegion(point)) {
151 inSelectedRect_ = true;
152 }
153 }
154 for (auto& rect : textOverlayBase->GetSelectedRect()) {
155 if (rect.IsInRegion(point)) {
156 inSelectedRect_ = true;
157 }
158 }
159 if (!inSelectedRect_) {
160 textOverlayManager->PopTextOverlay();
161 textOverlayBase->ChangeSelection(0, 0);
162 textOverlayBase->MarkIsOverlayShowed(false);
163 targetNode->MarkNeedRender();
164 }
165 inSelectedRect_ = false;
166 }
167
HandleGlobalEventNG(const TouchEvent & touchPoint,const RefPtr<NG::SelectOverlayManager> & selectOverlayManager,const NG::OffsetF & rootOffset)168 void EventManager::HandleGlobalEventNG(const TouchEvent& touchPoint,
169 const RefPtr<NG::SelectOverlayManager>& selectOverlayManager, const NG::OffsetF& rootOffset)
170 {
171 CHECK_NULL_VOID_NOLOG(selectOverlayManager);
172 if (touchPoint.type == TouchType::DOWN &&
173 touchTestResults_.find(touchPoint.id) != touchTestResults_.end()) {
174 std::vector<std::string> touchTestIds;
175 const auto& resultList = touchTestResults_[touchPoint.id];
176 for (const auto& result : resultList) {
177 auto eventTarget = result->GetEventTarget();
178 if (eventTarget.has_value()) {
179 touchTestIds.emplace_back(eventTarget.value().id);
180 }
181 }
182 selectOverlayManager->SetOnTouchTestResults(touchTestIds);
183 }
184 selectOverlayManager->HandleGlobalEvent(touchPoint, rootOffset);
185 }
186
HandleOutOfRectCallback(const Point & point,std::vector<RectCallback> & rectCallbackList)187 void EventManager::HandleOutOfRectCallback(const Point& point, std::vector<RectCallback>& rectCallbackList)
188 {
189 for (auto iter = rectCallbackList.begin(); iter != rectCallbackList.end();) {
190 auto rectCallback = *iter;
191 auto rectGetCallback = rectCallback.rectGetCallback;
192 if (!rectGetCallback) {
193 ++iter;
194 continue;
195 }
196 std::vector<Rect> rectList;
197 rectGetCallback(rectList);
198 if (std::any_of(
199 rectList.begin(), rectList.end(), [point](const Rect& rect) { return rect.IsInRegion(point); })) {
200 ++iter;
201 continue;
202 }
203 for (const auto& rect : rectList) {
204 LOGI("Point(%{public}f, %{public}f) out of Rect-[%{public}f, %{public}f, %{public}f, %{public}f]",
205 point.GetX(), point.GetY(), rect.Left(), rect.Right(), rect.Top(), rect.Bottom());
206 }
207 if (point.GetSourceType() == SourceType::TOUCH) {
208 if (!rectCallback.touchCallback) {
209 ++iter;
210 continue;
211 }
212 rectCallback.touchCallback();
213 } else if (point.GetSourceType() == SourceType::MOUSE) {
214 if (!rectCallback.mouseCallback) {
215 ++iter;
216 continue;
217 }
218 rectCallback.mouseCallback();
219 }
220 iter = rectCallbackList.erase(iter);
221 }
222 }
223
TouchTest(const AxisEvent & event,const RefPtr<RenderNode> & renderNode,const TouchRestrict & touchRestrict)224 void EventManager::TouchTest(
225 const AxisEvent& event, const RefPtr<RenderNode>& renderNode, const TouchRestrict& touchRestrict)
226 {
227 ContainerScope scope(instanceId_);
228
229 ACE_FUNCTION_TRACE();
230 CHECK_NULL_VOID(renderNode);
231 // collect
232 const Point point { event.x, event.y, event.sourceType };
233 // For root node, the parent local point is the same as global point.
234 TouchTestResult hitTestResult;
235 renderNode->TouchTest(point, point, touchRestrict, hitTestResult);
236 axisTouchTestResults_[event.id] = std::move(hitTestResult);
237 }
238
FlushTouchEventsBegin(const std::list<TouchEvent> & touchEvents)239 void EventManager::FlushTouchEventsBegin(const std::list<TouchEvent>& touchEvents)
240 {
241 for (auto iter = touchEvents.begin(); iter != touchEvents.end(); ++iter) {
242 const auto result = touchTestResults_.find((*iter).id);
243 if (result != touchTestResults_.end()) {
244 for (auto entry = result->second.rbegin(); entry != result->second.rend(); ++entry) {
245 (*entry)->OnFlushTouchEventsBegin();
246 }
247 }
248 }
249 }
250
FlushTouchEventsEnd(const std::list<TouchEvent> & touchEvents)251 void EventManager::FlushTouchEventsEnd(const std::list<TouchEvent>& touchEvents)
252 {
253 for (auto iter = touchEvents.begin(); iter != touchEvents.end(); ++iter) {
254 const auto result = touchTestResults_.find((*iter).id);
255 if (result != touchTestResults_.end()) {
256 for (auto entry = result->second.rbegin(); entry != result->second.rend(); ++entry) {
257 (*entry)->OnFlushTouchEventsEnd();
258 }
259 }
260 }
261 }
262
DispatchTouchEvent(const TouchEvent & event)263 bool EventManager::DispatchTouchEvent(const TouchEvent& event)
264 {
265 ContainerScope scope(instanceId_);
266 TouchEvent point = event;
267 #ifdef ENABLE_DRAG_FRAMEWORK
268 if (isDragging_ && point.type == TouchType::PULL_MOVE) {
269 isDragging_ = false;
270 point.type = TouchType::CANCEL;
271 }
272 if (point.type == TouchType::PULL_UP || point.type == TouchType::UP) {
273 isDragging_ = false;
274 point.type = TouchType::UP;
275 }
276 #endif // ENABLE_DRAG_FRAMEWORK
277 ACE_FUNCTION_TRACE();
278 const auto iter = touchTestResults_.find(point.id);
279 if (iter == touchTestResults_.end()) {
280 LOGI("the %{public}d touch test result does not exist!", point.id);
281 return false;
282 }
283
284 if (point.type == TouchType::DOWN) {
285 // first collect gesture into gesture referee.
286 if (Container::IsCurrentUseNewPipeline()) {
287 refereeNG_->AddGestureToScope(point.id, iter->second);
288 }
289 }
290
291 bool dispatchSuccess = true;
292 for (auto entry = iter->second.rbegin(); entry != iter->second.rend(); ++entry) {
293 if (!(*entry)->DispatchMultiContainerEvent(point)) {
294 dispatchSuccess = false;
295 break;
296 }
297 }
298 // If one gesture recognizer has already been won, other gesture recognizers will still be affected by
299 // the event, each recognizer needs to filter the extra events by itself.
300 if (dispatchSuccess) {
301 if (Container::IsCurrentUseNewPipeline()) {
302 // Need update here: onTouch/Recognizer need update
303 bool isStopTouchEvent = false;
304 for (const auto& entry : iter->second) {
305 auto recognizer = AceType::DynamicCast<NG::NGGestureRecognizer>(entry);
306 if (recognizer) {
307 entry->HandleMultiContainerEvent(point);
308 }
309 if (!recognizer && !isStopTouchEvent) {
310 isStopTouchEvent = !entry->HandleMultiContainerEvent(point);
311 }
312 }
313 } else {
314 for (const auto& entry : iter->second) {
315 if (!entry->HandleMultiContainerEvent(point)) {
316 break;
317 }
318 }
319 }
320 }
321
322 if (point.type == TouchType::UP || point.type == TouchType::CANCEL) {
323 FrameTraceAdapter* ft = FrameTraceAdapter::GetInstance();
324 if (ft != nullptr) {
325 ft->SetFrameTraceLimit();
326 }
327 refereeNG_->CleanGestureScope(point.id);
328 referee_->CleanGestureScope(point.id);
329 touchTestResults_.erase(point.id);
330 }
331
332 return true;
333 }
334
DispatchTouchEvent(const AxisEvent & event)335 bool EventManager::DispatchTouchEvent(const AxisEvent& event)
336 {
337 ContainerScope scope(instanceId_);
338
339 const auto curResultIter = axisTouchTestResults_.find(event.id);
340 if (curResultIter == axisTouchTestResults_.end()) {
341 LOGI("the %{public}d axis test result does not exist!", event.id);
342 return false;
343 }
344 if (event.action == AxisAction::BEGIN) {
345 // first collect gesture into gesture referee.
346 if (Container::IsCurrentUseNewPipeline()) {
347 if (refereeNG_) {
348 refereeNG_->AddGestureToScope(event.id, curResultIter->second);
349 }
350 }
351 }
352
353 ACE_FUNCTION_TRACE();
354 for (const auto& entry : curResultIter->second) {
355 if (!entry->HandleEvent(event)) {
356 break;
357 }
358 }
359 if (event.action == AxisAction::END || event.action == AxisAction::NONE || event.action == AxisAction::CANCEL) {
360 if (Container::IsCurrentUseNewPipeline()) {
361 if (refereeNG_) {
362 refereeNG_->CleanGestureScope(event.id);
363 }
364 }
365 axisTouchTestResults_.erase(event.id);
366 }
367 return true;
368 }
369
DispatchTabIndexEvent(const KeyEvent & event,const RefPtr<FocusNode> & focusNode,const RefPtr<FocusGroup> & mainNode)370 bool EventManager::DispatchTabIndexEvent(
371 const KeyEvent& event, const RefPtr<FocusNode>& focusNode, const RefPtr<FocusGroup>& mainNode)
372 {
373 LOGD("The key code is %{public}d, the key action is %{public}d, the repeat time is %{public}d.", event.code,
374 event.action, event.repeatTime);
375 CHECK_NULL_RETURN(focusNode, false);
376 CHECK_NULL_RETURN(mainNode, false);
377 if (focusNode->HandleFocusByTabIndex(event, mainNode)) {
378 LOGI("Tab index focus system handled this event");
379 return true;
380 }
381 return false;
382 }
383
DispatchKeyEvent(const KeyEvent & event,const RefPtr<FocusNode> & focusNode)384 bool EventManager::DispatchKeyEvent(const KeyEvent& event, const RefPtr<FocusNode>& focusNode)
385 {
386 CHECK_NULL_RETURN(focusNode, false);
387 LOGD("The key code is %{public}d, the key action is %{public}d, the repeat time is %{public}d.", event.code,
388 event.action, event.repeatTime);
389 if (focusNode->HandleKeyEvent(event)) {
390 LOGI("Default focus system handled this event");
391 return true;
392 }
393 LOGD("Use platform to handle this event");
394 return false;
395 }
396
DispatchTabIndexEventNG(const KeyEvent & event,const RefPtr<NG::FrameNode> & focusNode,const RefPtr<NG::FrameNode> & mainNode)397 bool EventManager::DispatchTabIndexEventNG(
398 const KeyEvent& event, const RefPtr<NG::FrameNode>& focusNode, const RefPtr<NG::FrameNode>& mainNode)
399 {
400 LOGD("The key code is %{public}d, the key action is %{public}d, the repeat time is %{public}d.", event.code,
401 event.action, event.repeatTime);
402 CHECK_NULL_RETURN(focusNode, false);
403 CHECK_NULL_RETURN(mainNode, false);
404 auto focusNodeHub = focusNode->GetFocusHub();
405 CHECK_NULL_RETURN(focusNodeHub, false);
406 auto mainNodeHub = mainNode->GetFocusHub();
407 CHECK_NULL_RETURN(mainNodeHub, false);
408 if (focusNodeHub->HandleFocusByTabIndex(event, mainNodeHub)) {
409 LOGI("Tab index focus system handled this event");
410 return true;
411 }
412 return false;
413 }
414
DispatchKeyEventNG(const KeyEvent & event,const RefPtr<NG::FrameNode> & focusNode)415 bool EventManager::DispatchKeyEventNG(const KeyEvent& event, const RefPtr<NG::FrameNode>& focusNode)
416 {
417 CHECK_NULL_RETURN(focusNode, false);
418 LOGD("The key code is %{public}d, the key action is %{public}d, the repeat time is %{public}d.", event.code,
419 event.action, event.repeatTime);
420 auto focusNodeHub = focusNode->GetFocusHub();
421 CHECK_NULL_RETURN(focusNodeHub, false);
422 if (focusNodeHub->HandleKeyEvent(event)) {
423 LOGI("Default focus system handled this event");
424 return true;
425 }
426 LOGD("Use platform to handle this event");
427 return false;
428 }
429
MouseTest(const MouseEvent & event,const RefPtr<RenderNode> & renderNode)430 void EventManager::MouseTest(const MouseEvent& event, const RefPtr<RenderNode>& renderNode)
431 {
432 CHECK_NULL_VOID(renderNode);
433 const Point point { event.x, event.y };
434 MouseHoverTestList hitTestResult;
435 WeakPtr<RenderNode> hoverNode = nullptr;
436 renderNode->MouseDetect(point, point, hitTestResult, hoverNode);
437 if (hitTestResult.empty()) {
438 LOGD("mouse hover test result is empty");
439 }
440 if (event.action == MouseAction::WINDOW_LEAVE) {
441 mouseHoverTestResultsPre_ = std::move(mouseHoverTestResults_);
442 mouseHoverTestResults_.clear();
443 } else if (event.action == MouseAction::WINDOW_ENTER) {
444 mouseHoverTestResultsPre_.clear();
445 mouseHoverTestResults_ = std::move(hitTestResult);
446 } else {
447 mouseHoverTestResultsPre_ = std::move(mouseHoverTestResults_);
448 mouseHoverTestResults_ = std::move(hitTestResult);
449 }
450 mouseHoverNodePre_ = mouseHoverNode_;
451 mouseHoverNode_ = hoverNode;
452 LOGI("MouseDetect hit test last/new result size = %{public}zu/%{public}zu", mouseHoverTestResultsPre_.size(),
453 mouseHoverTestResults_.size());
454 }
455
DispatchMouseEvent(const MouseEvent & event)456 bool EventManager::DispatchMouseEvent(const MouseEvent& event)
457 {
458 if (event.action == MouseAction::PRESS || event.action == MouseAction::RELEASE ||
459 event.action == MouseAction::MOVE) {
460 LOGD("RenderBox::HandleMouseEvent, button is %{public}d, action is %{public}d", event.button, event.action);
461 for (const auto& wp : mouseHoverTestResults_) {
462 auto hoverNode = wp.Upgrade();
463 if (hoverNode) {
464 if (hoverNode->HandleMouseEvent(event)) {
465 LOGI("Do HandleMouseEvent. Dispatch node: %{public}s", AceType::TypeName(hoverNode));
466 break;
467 }
468 }
469 }
470 return true;
471 }
472 return false;
473 }
474
DispatchMouseHoverAnimation(const MouseEvent & event)475 void EventManager::DispatchMouseHoverAnimation(const MouseEvent& event)
476 {
477 auto hoverNodeCur = mouseHoverNode_.Upgrade();
478 auto hoverNodePre = mouseHoverNodePre_.Upgrade();
479 if (event.action == MouseAction::PRESS) {
480 if (hoverNodeCur) {
481 hoverNodeCur->AnimateMouseHoverExit();
482 }
483 } else if (event.action == MouseAction::RELEASE) {
484 if (hoverNodeCur) {
485 hoverNodeCur->AnimateMouseHoverEnter();
486 }
487 } else if (event.button == MouseButton::NONE_BUTTON && event.action == MouseAction::MOVE) {
488 if (hoverNodeCur != hoverNodePre) {
489 if (hoverNodeCur) {
490 hoverNodeCur->AnimateMouseHoverEnter();
491 }
492 if (hoverNodePre) {
493 hoverNodePre->AnimateMouseHoverExit();
494 }
495 }
496 } else if (event.action == MouseAction::WINDOW_ENTER) {
497 if (hoverNodeCur) {
498 hoverNodeCur->AnimateMouseHoverEnter();
499 }
500 } else if (event.action == MouseAction::WINDOW_LEAVE) {
501 if (hoverNodeCur) {
502 hoverNodeCur->AnimateMouseHoverExit();
503 }
504 }
505 }
506
DispatchMouseHoverEvent(const MouseEvent & event)507 bool EventManager::DispatchMouseHoverEvent(const MouseEvent& event)
508 {
509 for (const auto& wp : mouseHoverTestResultsPre_) {
510 // get all previous hover nodes while it's not in current hover nodes. Those nodes exit hover
511 auto it = std::find(mouseHoverTestResults_.begin(), mouseHoverTestResults_.end(), wp);
512 if (it == mouseHoverTestResults_.end()) {
513 auto hoverNode = wp.Upgrade();
514 if (hoverNode) {
515 hoverNode->HandleMouseHoverEvent(MouseState::NONE);
516 }
517 }
518 }
519 for (const auto& wp : mouseHoverTestResults_) {
520 // get all current hover nodes while it's not in previous hover nodes. Those nodes are new hover
521 auto it = std::find(mouseHoverTestResultsPre_.begin(), mouseHoverTestResultsPre_.end(), wp);
522 if (it == mouseHoverTestResultsPre_.end()) {
523 auto hoverNode = wp.Upgrade();
524 if (hoverNode) {
525 hoverNode->HandleMouseHoverEvent(MouseState::HOVER);
526 }
527 }
528 }
529 return true;
530 }
531
LogPrintMouseTest()532 void EventManager::LogPrintMouseTest()
533 {
534 #ifdef ACE_DEBUG_LOG
535 if (!SystemProperties::GetDebugEnabled()) {
536 return;
537 }
538 if (currMouseTestResults_.empty()) {
539 LOGD("Mouse test onMouse result is empty.");
540 } else {
541 for (const auto& result : currMouseTestResults_) {
542 LOGD("Mouse test onMouse result: %{public}s/%{public}d.", result->GetNodeName().c_str(),
543 result->GetNodeId());
544 }
545 }
546 if (lastHoverTestResults_.empty()) {
547 LOGD("Mouse test onHover last result is empty.");
548 } else {
549 for (const auto& result : lastHoverTestResults_) {
550 LOGD("Mouse test onHover last result: %{public}s/%{public}d.", result->GetNodeName().c_str(),
551 result->GetNodeId());
552 }
553 }
554 if (currHoverTestResults_.empty()) {
555 LOGD("Mouse test onHover current result is empty.");
556 } else {
557 for (const auto& result : currHoverTestResults_) {
558 LOGD("Mouse test onHover current result: %{public}s/%{public}d.", result->GetNodeName().c_str(),
559 result->GetNodeId());
560 }
561 }
562 auto lastNode = lastHoverNode_.Upgrade();
563 auto currNode = currHoverNode_.Upgrade();
564 LOGD("Mouse test last/current hoverEffect node: %{public}s/%{public}d / %{public}s/%{public}d",
565 lastNode ? lastNode->GetTag().c_str() : "NULL", lastNode ? lastNode->GetId() : -1,
566 currNode ? currNode->GetTag().c_str() : "NULL", currNode ? currNode->GetId() : -1);
567 #endif
568 }
569
MouseTest(const MouseEvent & event,const RefPtr<NG::FrameNode> & frameNode,const TouchRestrict & touchRestrict)570 void EventManager::MouseTest(
571 const MouseEvent& event, const RefPtr<NG::FrameNode>& frameNode, const TouchRestrict& touchRestrict)
572 {
573 LOGD("Mouse test start. Mouse event is (%{public}f,%{public}f), button: %{public}d, action: %{public}d", event.x,
574 event.y, event.button, event.action);
575 CHECK_NULL_VOID(frameNode);
576 const NG::PointF point { event.x, event.y };
577 TouchTestResult testResult;
578 if (frameNode->HaveSecurityComponent()) {
579 std::vector<NG::RectF> rect;
580 frameNode->CheckSecurityComponentStatus(rect);
581 }
582 frameNode->TouchTest(point, point, point, touchRestrict, testResult, event.GetId());
583 if (testResult.empty()) {
584 LOGD("mouse hover test result is empty");
585 }
586 currMouseTestResults_.clear();
587 HoverTestResult hoverTestResult;
588 WeakPtr<NG::FrameNode> hoverNode = nullptr;
589 for (const auto& result : testResult) {
590 auto mouseResult = AceType::DynamicCast<MouseEventTarget>(result);
591 if (mouseResult) {
592 currMouseTestResults_.emplace_back(mouseResult);
593 }
594 auto hoverResult = AceType::DynamicCast<HoverEventTarget>(result);
595 if (hoverResult) {
596 hoverTestResult.emplace_back(hoverResult);
597 }
598 if (!hoverNode.Upgrade()) {
599 auto hoverEffectResult = AceType::DynamicCast<HoverEffectTarget>(result);
600 if (hoverEffectResult) {
601 hoverNode = hoverEffectResult->GetHoverNode();
602 }
603 }
604 }
605 if (event.action == MouseAction::WINDOW_LEAVE) {
606 lastHoverTestResults_ = std::move(currHoverTestResults_);
607 currHoverTestResults_.clear();
608 } else if (event.action == MouseAction::WINDOW_ENTER) {
609 lastHoverTestResults_.clear();
610 currHoverTestResults_ = std::move(hoverTestResult);
611 } else {
612 lastHoverTestResults_ = std::move(currHoverTestResults_);
613 currHoverTestResults_ = std::move(hoverTestResult);
614 }
615 lastHoverNode_ = currHoverNode_;
616 currHoverNode_ = hoverNode;
617 LogPrintMouseTest();
618 LOGD("Mouse test end.");
619 }
620
DispatchMouseEventNG(const MouseEvent & event)621 bool EventManager::DispatchMouseEventNG(const MouseEvent& event)
622 {
623 LOGD("DispatchMouseEventNG: button is %{public}d, action is %{public}d.", event.button, event.action);
624 if (event.action == MouseAction::PRESS || event.action == MouseAction::RELEASE ||
625 event.action == MouseAction::MOVE || event.action == MouseAction::WINDOW_ENTER ||
626 event.action == MouseAction::WINDOW_LEAVE) {
627 MouseTestResult handledResults;
628 handledResults.clear();
629 auto container = Container::Current();
630 CHECK_NULL_RETURN(container, false);
631 if ((event.button == MouseButton::LEFT_BUTTON && !container->IsScenceBoardWindow()) ||
632 (event.button == MouseButton::LEFT_BUTTON && container->IsScenceBoardWindow() &&
633 event.pullAction != MouseAction::PULL_UP && event.pullAction != MouseAction::PULL_MOVE)) {
634 for (const auto& mouseTarget : pressMouseTestResults_) {
635 if (mouseTarget) {
636 handledResults.emplace_back(mouseTarget);
637 if (mouseTarget->HandleMouseEvent(event)) {
638 break;
639 }
640 }
641 }
642 if (event.action == MouseAction::PRESS) {
643 pressMouseTestResults_ = currMouseTestResults_;
644 } else if (event.action == MouseAction::RELEASE) {
645 DoMouseActionRelease();
646 }
647 }
648 if (event.pullAction == MouseAction::PULL_UP) {
649 DoMouseActionRelease();
650 }
651 for (const auto& mouseTarget : currMouseTestResults_) {
652 if (mouseTarget &&
653 std::find(handledResults.begin(), handledResults.end(), mouseTarget) == handledResults.end()) {
654 if (mouseTarget->HandleMouseEvent(event)) {
655 return true;
656 }
657 }
658 }
659 }
660 return false;
661 }
662
DoMouseActionRelease()663 void EventManager::DoMouseActionRelease()
664 {
665 pressMouseTestResults_.clear();
666 }
667
DispatchMouseHoverAnimationNG(const MouseEvent & event)668 void EventManager::DispatchMouseHoverAnimationNG(const MouseEvent& event)
669 {
670 LOGD("DispatchMouseHoverAnimationNG: button is %{public}d, action is %{public}d.", event.button, event.action);
671 auto hoverNodeCur = currHoverNode_.Upgrade();
672 auto hoverNodePre = lastHoverNode_.Upgrade();
673 if (event.action == MouseAction::PRESS) {
674 if (hoverNodeCur) {
675 hoverNodeCur->AnimateHoverEffect(false);
676 }
677 } else if (event.action == MouseAction::RELEASE) {
678 if (hoverNodeCur) {
679 hoverNodeCur->AnimateHoverEffect(true);
680 }
681 } else if (event.button == MouseButton::NONE_BUTTON && event.action == MouseAction::MOVE) {
682 if (hoverNodeCur != hoverNodePre) {
683 if (hoverNodeCur) {
684 hoverNodeCur->AnimateHoverEffect(true);
685 }
686 if (hoverNodePre) {
687 hoverNodePre->AnimateHoverEffect(false);
688 }
689 }
690 } else if (event.action == MouseAction::WINDOW_ENTER) {
691 if (hoverNodeCur) {
692 hoverNodeCur->AnimateHoverEffect(true);
693 }
694 } else if (event.action == MouseAction::WINDOW_LEAVE) {
695 if (hoverNodeCur) {
696 hoverNodeCur->AnimateHoverEffect(false);
697 }
698 }
699 }
700
DispatchMouseHoverEventNG(const MouseEvent & event)701 bool EventManager::DispatchMouseHoverEventNG(const MouseEvent& event)
702 {
703 LOGD("DispatchMouseHoverEventNG: button is %{public}d, action is %{public}d.", event.button, event.action);
704 auto lastHoverEndNode = lastHoverTestResults_.begin();
705 auto currHoverEndNode = currHoverTestResults_.begin();
706 RefPtr<HoverEventTarget> lastHoverEndNodeTarget;
707 uint32_t iterCountLast = 0;
708 uint32_t iterCountCurr = 0;
709 for (const auto& hoverResult : lastHoverTestResults_) {
710 // get valid part of previous hover nodes while it's not in current hover nodes. Those nodes exit hover
711 // there may have some nodes in currHoverTestResults_ but intercepted
712 iterCountLast++;
713 if (lastHoverEndNode != currHoverTestResults_.end()) {
714 lastHoverEndNode++;
715 }
716 if (std::find(currHoverTestResults_.begin(), currHoverTestResults_.end(), hoverResult) ==
717 currHoverTestResults_.end()) {
718 hoverResult->HandleHoverEvent(false, event);
719 }
720 if ((iterCountLast >= lastHoverDispatchLength_) && (lastHoverDispatchLength_ != 0)) {
721 lastHoverEndNodeTarget = hoverResult;
722 break;
723 }
724 }
725 lastHoverDispatchLength_ = 0;
726 for (const auto& hoverResult : currHoverTestResults_) {
727 // get valid part of current hover nodes while it's not in previous hover nodes. Those nodes are new hover
728 // the valid part stops at first interception
729 iterCountCurr++;
730 if (currHoverEndNode != currHoverTestResults_.end()) {
731 currHoverEndNode++;
732 }
733 if (std::find(lastHoverTestResults_.begin(), lastHoverEndNode, hoverResult) == lastHoverEndNode) {
734 if (!hoverResult->HandleHoverEvent(true, event)) {
735 lastHoverDispatchLength_ = iterCountCurr;
736 break;
737 }
738 }
739 if (hoverResult == lastHoverEndNodeTarget) {
740 lastHoverDispatchLength_ = iterCountCurr;
741 break;
742 }
743 }
744 for (auto hoverResultIt = lastHoverTestResults_.begin(); hoverResultIt != lastHoverEndNode; ++hoverResultIt) {
745 // there may have previous hover nodes in the invalid part of current hover nodes. Those nodes exit hover also
746 if (std::find(currHoverEndNode, currHoverTestResults_.end(), *hoverResultIt) != currHoverTestResults_.end()) {
747 (*hoverResultIt)->HandleHoverEvent(false, event);
748 }
749 }
750 return true;
751 }
752
AxisTest(const AxisEvent & event,const RefPtr<RenderNode> & renderNode)753 void EventManager::AxisTest(const AxisEvent& event, const RefPtr<RenderNode>& renderNode)
754 {
755 CHECK_NULL_VOID(renderNode);
756 const Point point { event.x, event.y };
757 WeakPtr<RenderNode> axisNode = nullptr;
758 renderNode->AxisDetect(point, point, axisNode, event.GetDirection());
759 axisNode_ = axisNode;
760 LOGI("Current axis node is %{public}s", AceType::TypeName(axisNode_.Upgrade()));
761 }
762
DispatchAxisEvent(const AxisEvent & event)763 bool EventManager::DispatchAxisEvent(const AxisEvent& event)
764 {
765 auto responseNode = axisNode_.Upgrade();
766 if (responseNode) {
767 responseNode->HandleAxisEvent(event);
768 }
769 return true;
770 }
771
AxisTest(const AxisEvent & event,const RefPtr<NG::FrameNode> & frameNode)772 void EventManager::AxisTest(const AxisEvent& event, const RefPtr<NG::FrameNode>& frameNode)
773 {
774 CHECK_NULL_VOID(frameNode);
775 const NG::PointF point { event.x, event.y };
776 frameNode->AxisTest(point, point, axisTestResults_);
777 }
778
DispatchAxisEventNG(const AxisEvent & event)779 bool EventManager::DispatchAxisEventNG(const AxisEvent& event)
780 {
781 if (event.horizontalAxis == 0 && event.verticalAxis == 0 && event.pinchAxisScale == 0) {
782 return false;
783 }
784 LOGD("DispatchAxisEventNG, action is %{public}d, axis is %{public}f / %{public}f / %{public}f", event.action,
785 event.horizontalAxis, event.verticalAxis, event.pinchAxisScale);
786 for (const auto& axisTarget : axisTestResults_) {
787 if (axisTarget && axisTarget->HandleAxisEvent(event)) {
788 return true;
789 }
790 }
791 return true;
792 }
793
DispatchRotationEvent(const RotationEvent & event,const RefPtr<RenderNode> & renderNode,const RefPtr<RenderNode> & requestFocusNode)794 bool EventManager::DispatchRotationEvent(
795 const RotationEvent& event, const RefPtr<RenderNode>& renderNode, const RefPtr<RenderNode>& requestFocusNode)
796 {
797 CHECK_NULL_RETURN(renderNode, false);
798 if (requestFocusNode && renderNode->RotationMatchTest(requestFocusNode)) {
799 LOGD("RotationMatchTest: dispatch rotation to request node.");
800 return requestFocusNode->RotationTestForward(event);
801 } else {
802 LOGD("RotationMatchTest: dispatch rotation to stack render node.");
803 return renderNode->RotationTest(event);
804 }
805 }
806
AddKeyboardShortcutNode(const WeakPtr<NG::FrameNode> & node)807 void EventManager::AddKeyboardShortcutNode(const WeakPtr<NG::FrameNode>& node)
808 {
809 auto frameNode = node.Upgrade();
810 CHECK_NULL_VOID(frameNode);
811 auto iter = keyboardShortcutNode_.begin();
812 while (iter != keyboardShortcutNode_.end()) {
813 auto keyboardShortcutNode = (*iter).Upgrade();
814 if (!keyboardShortcutNode) {
815 keyboardShortcutNode_.erase(iter++);
816 continue;
817 }
818 if (keyboardShortcutNode->GetId() == frameNode->GetId()) {
819 return;
820 }
821 ++iter;
822 }
823 keyboardShortcutNode_.emplace_back(node);
824 }
825
GetKeyboardShortcutKeys(const std::vector<ModifierKey> & keys)826 uint8_t EventManager::GetKeyboardShortcutKeys(const std::vector<ModifierKey>& keys)
827 {
828 uint8_t keyValue = 0;
829 uint8_t ctrlTimes = 0;
830 uint8_t shiftTimes = 0;
831 uint8_t altTimes = 0;
832 if (keys.size() > KEYS_MAX_VALUE) {
833 return 0;
834 }
835 for (const auto& key : keys) {
836 switch (static_cast<uint8_t>(key)) {
837 case static_cast<uint8_t>(ModifierKey::CTRL): {
838 keyValue |= static_cast<uint8_t>(CtrlKeysBit::CTRL);
839 ++ctrlTimes;
840 break;
841 }
842 case static_cast<uint8_t>(ModifierKey::SHIFT): {
843 keyValue |= static_cast<uint8_t>(CtrlKeysBit::SHIFT);
844 ++shiftTimes;
845 break;
846 }
847 case static_cast<uint8_t>(ModifierKey::ALT): {
848 keyValue |= static_cast<uint8_t>(CtrlKeysBit::ALT);
849 ++altTimes;
850 break;
851 }
852 default:
853 keyValue |= 0;
854 }
855 }
856 if (ctrlTimes > 1 || shiftTimes > 1 || altTimes > 1) {
857 return 0;
858 }
859 return keyValue;
860 }
861
IsSystemKeyboardShortcut(const std::string & value,uint8_t keys)862 bool EventManager::IsSystemKeyboardShortcut(const std::string& value, uint8_t keys)
863 {
864 if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_C) {
865 return true;
866 }
867 if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_A) {
868 return true;
869 }
870 if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_V) {
871 return true;
872 }
873 if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_X) {
874 return true;
875 }
876 if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_Y) {
877 return true;
878 }
879 if (!(keys ^ static_cast<uint8_t>(CtrlKeysBit::CTRL)) && value == SHORT_CUT_VALUE_Z) {
880 return true;
881 }
882 if (!(keys ^ (static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::SHIFT))) &&
883 value == SHORT_CUT_VALUE_Z) {
884 return true;
885 }
886 return false;
887 }
888
IsSameKeyboardShortcutNode(const std::string & value,uint8_t keys)889 bool EventManager::IsSameKeyboardShortcutNode(const std::string& value, uint8_t keys)
890 {
891 if (IsSystemKeyboardShortcut(value, keys)) {
892 return true;
893 }
894 for (auto& weakNode : keyboardShortcutNode_) {
895 auto frameNode = weakNode.Upgrade();
896 if (!frameNode) {
897 continue;
898 }
899 auto eventHub = frameNode->GetEventHub<NG::EventHub>();
900 if (!eventHub) {
901 continue;
902 }
903 auto keyboardShortcuts = eventHub->GetKeyboardShortcut();
904 for (auto& keyboardShortcut : keyboardShortcuts) {
905 LOGI("IsSameKeyboardShortcutNode keys = %{public}d value = %{public}s", keyboardShortcut.keys,
906 keyboardShortcut.value.c_str());
907 if (keyboardShortcut.value.find(value) != std::string::npos && keyboardShortcut.keys == keys) {
908 return true;
909 }
910 }
911 }
912 return false;
913 }
914
AddKeyboardShortcutSingleKey(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)915 void AddKeyboardShortcutSingleKey(
916 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
917 {
918 uint8_t index = 0;
919 std::vector<KeyCode> keyCode1;
920 std::vector<KeyCode> keyCode2;
921 if (keys & static_cast<uint8_t>(CtrlKeysBit::CTRL)) {
922 keyCode1.emplace_back(KeyCode::KEY_CTRL_LEFT);
923 keyCode2.emplace_back(KeyCode::KEY_CTRL_RIGHT);
924 permutation.emplace_back(++index);
925 }
926 if (keys & static_cast<uint8_t>(CtrlKeysBit::SHIFT)) {
927 keyCode1.emplace_back(KeyCode::KEY_SHIFT_LEFT);
928 keyCode2.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
929 permutation.emplace_back(++index);
930 }
931 if (keys & static_cast<uint8_t>(CtrlKeysBit::ALT)) {
932 keyCode1.emplace_back(KeyCode::KEY_ALT_LEFT);
933 keyCode2.emplace_back(KeyCode::KEY_ALT_RIGHT);
934 permutation.emplace_back(++index);
935 }
936 keyCodes.emplace_back(keyCode1);
937 keyCodes.emplace_back(keyCode2);
938 }
939
AddKeyboardShortcutDoubleKeysWithCtrlShift(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)940 void AddKeyboardShortcutDoubleKeysWithCtrlShift(
941 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
942 {
943 uint8_t index = 0;
944 std::vector<KeyCode> keyCode1;
945 std::vector<KeyCode> keyCode2;
946 std::vector<KeyCode> keyCode3;
947 std::vector<KeyCode> keyCode4;
948
949 keyCode1.emplace_back(KeyCode::KEY_CTRL_LEFT);
950 keyCode2.emplace_back(KeyCode::KEY_CTRL_LEFT);
951 keyCode3.emplace_back(KeyCode::KEY_CTRL_RIGHT);
952 keyCode4.emplace_back(KeyCode::KEY_CTRL_RIGHT);
953 permutation.emplace_back(++index);
954
955 keyCode1.emplace_back(KeyCode::KEY_SHIFT_LEFT);
956 keyCode2.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
957 keyCode3.emplace_back(KeyCode::KEY_SHIFT_LEFT);
958 keyCode4.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
959 permutation.emplace_back(++index);
960
961 keyCodes.emplace_back(keyCode1);
962 keyCodes.emplace_back(keyCode2);
963 keyCodes.emplace_back(keyCode3);
964 keyCodes.emplace_back(keyCode4);
965 }
966
AddKeyboardShortcutDoubleKeysWithCtrlAlt(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)967 void AddKeyboardShortcutDoubleKeysWithCtrlAlt(
968 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
969 {
970 uint8_t index = 0;
971 std::vector<KeyCode> keyCode1;
972 std::vector<KeyCode> keyCode2;
973 std::vector<KeyCode> keyCode3;
974 std::vector<KeyCode> keyCode4;
975
976 keyCode1.emplace_back(KeyCode::KEY_CTRL_LEFT);
977 keyCode2.emplace_back(KeyCode::KEY_CTRL_LEFT);
978 keyCode3.emplace_back(KeyCode::KEY_CTRL_RIGHT);
979 keyCode4.emplace_back(KeyCode::KEY_CTRL_RIGHT);
980 permutation.emplace_back(++index);
981
982 keyCode1.emplace_back(KeyCode::KEY_ALT_LEFT);
983 keyCode2.emplace_back(KeyCode::KEY_ALT_RIGHT);
984 keyCode3.emplace_back(KeyCode::KEY_ALT_LEFT);
985 keyCode4.emplace_back(KeyCode::KEY_ALT_RIGHT);
986 permutation.emplace_back(++index);
987
988 keyCodes.emplace_back(keyCode1);
989 keyCodes.emplace_back(keyCode2);
990 keyCodes.emplace_back(keyCode3);
991 keyCodes.emplace_back(keyCode4);
992 }
993
AddKeyboardShortcutDoubleKeysWithShiftAlt(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)994 void AddKeyboardShortcutDoubleKeysWithShiftAlt(
995 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
996 {
997 uint8_t index = 0;
998 std::vector<KeyCode> keyCode1;
999 std::vector<KeyCode> keyCode2;
1000 std::vector<KeyCode> keyCode3;
1001 std::vector<KeyCode> keyCode4;
1002
1003 keyCode1.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1004 keyCode2.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1005 keyCode3.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1006 keyCode4.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1007 permutation.emplace_back(++index);
1008
1009 keyCode1.emplace_back(KeyCode::KEY_ALT_LEFT);
1010 keyCode2.emplace_back(KeyCode::KEY_ALT_RIGHT);
1011 keyCode3.emplace_back(KeyCode::KEY_ALT_LEFT);
1012 keyCode4.emplace_back(KeyCode::KEY_ALT_RIGHT);
1013 permutation.emplace_back(++index);
1014
1015 keyCodes.emplace_back(keyCode1);
1016 keyCodes.emplace_back(keyCode2);
1017 keyCodes.emplace_back(keyCode3);
1018 keyCodes.emplace_back(keyCode4);
1019 }
1020
AddKeyboardShortcutDoubleKeys(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)1021 void AddKeyboardShortcutDoubleKeys(
1022 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
1023 {
1024 if (keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::SHIFT)) {
1025 AddKeyboardShortcutDoubleKeysWithCtrlShift(keys, keyCodes, permutation);
1026 }
1027 if (keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::ALT)) {
1028 AddKeyboardShortcutDoubleKeysWithCtrlAlt(keys, keyCodes, permutation);
1029 }
1030 if (keys == static_cast<uint8_t>(CtrlKeysBit::SHIFT) + static_cast<uint8_t>(CtrlKeysBit::ALT)) {
1031 AddKeyboardShortcutDoubleKeysWithShiftAlt(keys, keyCodes, permutation);
1032 }
1033 }
1034
AddKeyboardShortcutTripleKeys(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)1035 void AddKeyboardShortcutTripleKeys(
1036 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
1037 {
1038 uint8_t index = 0;
1039 std::vector<KeyCode> keyCode1;
1040 std::vector<KeyCode> keyCode2;
1041 std::vector<KeyCode> keyCode3;
1042 std::vector<KeyCode> keyCode4;
1043 std::vector<KeyCode> keyCode5;
1044 std::vector<KeyCode> keyCode6;
1045 std::vector<KeyCode> keyCode7;
1046 std::vector<KeyCode> keyCode8;
1047
1048 keyCode1.emplace_back(KeyCode::KEY_CTRL_LEFT);
1049 keyCode2.emplace_back(KeyCode::KEY_CTRL_LEFT);
1050 keyCode3.emplace_back(KeyCode::KEY_CTRL_LEFT);
1051 keyCode4.emplace_back(KeyCode::KEY_CTRL_LEFT);
1052 keyCode5.emplace_back(KeyCode::KEY_CTRL_RIGHT);
1053 keyCode6.emplace_back(KeyCode::KEY_CTRL_RIGHT);
1054 keyCode7.emplace_back(KeyCode::KEY_CTRL_RIGHT);
1055 keyCode8.emplace_back(KeyCode::KEY_CTRL_RIGHT);
1056 permutation.emplace_back(++index);
1057
1058 keyCode1.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1059 keyCode2.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1060 keyCode3.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1061 keyCode4.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1062 keyCode5.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1063 keyCode6.emplace_back(KeyCode::KEY_SHIFT_LEFT);
1064 keyCode7.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1065 keyCode8.emplace_back(KeyCode::KEY_SHIFT_RIGHT);
1066 permutation.emplace_back(++index);
1067
1068 keyCode1.emplace_back(KeyCode::KEY_ALT_LEFT);
1069 keyCode2.emplace_back(KeyCode::KEY_ALT_RIGHT);
1070 keyCode3.emplace_back(KeyCode::KEY_ALT_LEFT);
1071 keyCode4.emplace_back(KeyCode::KEY_ALT_RIGHT);
1072 keyCode5.emplace_back(KeyCode::KEY_ALT_LEFT);
1073 keyCode6.emplace_back(KeyCode::KEY_ALT_RIGHT);
1074 keyCode7.emplace_back(KeyCode::KEY_ALT_LEFT);
1075 keyCode8.emplace_back(KeyCode::KEY_ALT_RIGHT);
1076 permutation.emplace_back(++index);
1077
1078 keyCodes.emplace_back(keyCode1);
1079 keyCodes.emplace_back(keyCode2);
1080 keyCodes.emplace_back(keyCode3);
1081 keyCodes.emplace_back(keyCode4);
1082 keyCodes.emplace_back(keyCode5);
1083 keyCodes.emplace_back(keyCode6);
1084 keyCodes.emplace_back(keyCode7);
1085 keyCodes.emplace_back(keyCode8);
1086 }
1087
AddKeyboardShortcutKeys(uint8_t keys,std::vector<std::vector<KeyCode>> & keyCodes,std::vector<uint8_t> & permutation)1088 void AddKeyboardShortcutKeys(
1089 uint8_t keys, std::vector<std::vector<KeyCode>>& keyCodes, std::vector<uint8_t>& permutation)
1090 {
1091 // single FunctionKey
1092 if (keys == 0) {
1093 keyCodes.emplace_back(std::vector<KeyCode>());
1094 }
1095 // single key
1096 if (keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) || keys == static_cast<uint8_t>(CtrlKeysBit::SHIFT) ||
1097 keys == static_cast<uint8_t>(CtrlKeysBit::ALT)) {
1098 LOGI("AddKeyboardShortcutKeys single key");
1099 AddKeyboardShortcutSingleKey(keys, keyCodes, permutation);
1100 }
1101 // double keys
1102 if (keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::SHIFT) ||
1103 keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::ALT) ||
1104 keys == static_cast<uint8_t>(CtrlKeysBit::SHIFT) + static_cast<uint8_t>(CtrlKeysBit::ALT)) {
1105 LOGI("AddKeyboardShortcutKeys double keys");
1106 AddKeyboardShortcutDoubleKeys(keys, keyCodes, permutation);
1107 }
1108 // triple keys
1109 if (keys == static_cast<uint8_t>(CtrlKeysBit::CTRL) + static_cast<uint8_t>(CtrlKeysBit::SHIFT) +
1110 static_cast<uint8_t>(CtrlKeysBit::ALT)) {
1111 LOGI("AddKeyboardShortcutKeys triple keys");
1112 AddKeyboardShortcutTripleKeys(keys, keyCodes, permutation);
1113 }
1114 }
1115
TriggerKeyboardShortcut(const KeyEvent & event,const std::vector<NG::KeyboardShortcut> & keyboardShortcuts,const WeakPtr<NG::FrameNode> & node,const RefPtr<NG::EventHub> & eventHub)1116 void TriggerKeyboardShortcut(const KeyEvent& event, const std::vector<NG::KeyboardShortcut>& keyboardShortcuts,
1117 const WeakPtr<NG::FrameNode>& node, const RefPtr<NG::EventHub>& eventHub)
1118 {
1119 CHECK_NULL_VOID(eventHub);
1120 for (auto& keyboardShortcut : keyboardShortcuts) {
1121 if (keyboardShortcut.value.empty()) {
1122 continue;
1123 }
1124
1125 std::vector<std::vector<KeyCode>> keyCodes;
1126 std::vector<uint8_t> permutation;
1127 AddKeyboardShortcutKeys(keyboardShortcut.keys, keyCodes, permutation);
1128 // FunctionKey
1129 if ((event.IsFunctionKey() || event.IsEscapeKey()) &&
1130 event.ConvertInputCodeToString() != keyboardShortcut.value) {
1131 continue;
1132 } else if (event.ConvertInputCodeToString().find(keyboardShortcut.value) == std::string::npos) {
1133 continue;
1134 }
1135 // Handle left and right the keys problem.
1136 std::vector<uint8_t> perm;
1137 for (auto& keyCode : keyCodes) {
1138 perm.assign(permutation.begin(), permutation.end());
1139 // Handle the keys order problem.
1140 do {
1141 keyCode.emplace_back(event.code);
1142 if (!event.IsKey(keyCode)) {
1143 keyCode.pop_back();
1144 std::next_permutation(keyCode.begin(), keyCode.end());
1145 continue;
1146 }
1147
1148 if (keyboardShortcut.onKeyboardShortcutAction) {
1149 keyboardShortcut.onKeyboardShortcutAction();
1150 LOGI("TriggerKeyboardShortcut action done.");
1151 } else {
1152 auto gestureEventHub = eventHub->GetGestureEventHub();
1153 if (gestureEventHub && gestureEventHub->IsClickable()) {
1154 gestureEventHub->KeyBoardShortCutClick(event, node);
1155 LOGI("TriggerKeyboardShortcut click done.");
1156 }
1157 }
1158 keyCode.pop_back();
1159 std::next_permutation(keyCode.begin(), keyCode.end());
1160 } while (std::next_permutation(perm.begin(), perm.end()));
1161 perm.clear();
1162 }
1163 keyCodes.clear();
1164 permutation.clear();
1165 }
1166 }
1167
DispatchKeyboardShortcut(const KeyEvent & event)1168 void EventManager::DispatchKeyboardShortcut(const KeyEvent& event)
1169 {
1170 LOGD("EventManager: The key code is %{public}d, the key action is %{public}d.", event.code, event.action);
1171 if (event.action != KeyAction::DOWN) {
1172 return;
1173 }
1174 for (auto& node : keyboardShortcutNode_) {
1175 auto frameNode = node.Upgrade();
1176 if (!frameNode || !(frameNode->IsActive())) {
1177 continue;
1178 }
1179 auto eventHub = frameNode->GetEventHub<NG::EventHub>();
1180 if (!eventHub || !(eventHub->IsEnabled())) {
1181 continue;
1182 }
1183
1184 auto keyboardShortcuts = eventHub->GetKeyboardShortcut();
1185 TriggerKeyboardShortcut(event, keyboardShortcuts, node, eventHub);
1186 }
1187 }
1188
DelKeyboardShortcutNode(int32_t nodeId)1189 void EventManager::DelKeyboardShortcutNode(int32_t nodeId)
1190 {
1191 auto iter = keyboardShortcutNode_.begin();
1192 while (iter != keyboardShortcutNode_.end()) {
1193 auto frameNode = (*iter).Upgrade();
1194 if (!frameNode) {
1195 keyboardShortcutNode_.erase(iter++);
1196 continue;
1197 }
1198 if (frameNode->GetId() == nodeId) {
1199 keyboardShortcutNode_.erase(iter);
1200 break;
1201 }
1202 ++iter;
1203 }
1204 }
1205
ClearResults()1206 void EventManager::ClearResults()
1207 {
1208 touchTestResults_.clear();
1209 mouseTestResults_.clear();
1210 axisTouchTestResults_.clear();
1211 keyboardShortcutNode_.clear();
1212 }
1213
EventManager()1214 EventManager::EventManager()
1215 {
1216 LOGD("EventManger Constructor.");
1217 refereeNG_ = AceType::MakeRefPtr<NG::GestureReferee>();
1218 referee_ = AceType::MakeRefPtr<GestureReferee>();
1219
1220 auto callback = [weak = WeakClaim(this)](size_t touchId) -> bool {
1221 auto eventManager = weak.Upgrade();
1222 CHECK_NULL_RETURN(eventManager, false);
1223 auto refereeNG = eventManager->refereeNG_;
1224 CHECK_NULL_RETURN(refereeNG, false);
1225 return refereeNG->HasGestureAccepted(touchId);
1226 };
1227 referee_->SetQueryStateFunc(std::move(callback));
1228
1229 auto cleanReferee = [weak = WeakClaim(this)](size_t touchId) -> void {
1230 auto eventManager = weak.Upgrade();
1231 CHECK_NULL_VOID(eventManager);
1232 auto referee = eventManager->referee_;
1233 CHECK_NULL_VOID(referee);
1234 auto gestureScope = referee->GetGestureScope();
1235 const auto iter = gestureScope.find(touchId);
1236 if (iter == gestureScope.end()) {
1237 return;
1238 }
1239
1240 auto highRecognizers = iter->second.GetHighRecognizers();
1241 auto lowRecognizers = iter->second.GetLowRecognizers();
1242 auto parallelRecognizers = iter->second.GetParallelRecognizers();
1243
1244 for (const auto& weak : highRecognizers) {
1245 auto gesture = weak.Upgrade();
1246 if (gesture) {
1247 gesture->OnRejected(touchId);
1248 }
1249 }
1250
1251 for (const auto& weak : lowRecognizers) {
1252 auto gesture = weak.Upgrade();
1253 if (gesture) {
1254 gesture->OnRejected(touchId);
1255 }
1256 }
1257
1258 for (const auto& weak : parallelRecognizers) {
1259 auto gesture = weak.Upgrade();
1260 if (gesture) {
1261 gesture->OnRejected(touchId);
1262 }
1263 }
1264 };
1265 refereeNG_->SetQueryStateFunc(std::move(cleanReferee));
1266 }
1267
1268 } // namespace OHOS::Ace
1269