1 /*
2  * Copyright (c) 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 #include "window_event_process.h"
16 
17 #include "core/components_ng/pattern/window_scene/scene/window_pattern.h"
18 #include "frameworks/core/event/ace_events.h"
19 #include "pointer_event.h"
20 
21 namespace OHOS::Ace::NG {
WindowEventProcess()22 WindowEventProcess::WindowEventProcess() {}
23 
~WindowEventProcess()24 WindowEventProcess::~WindowEventProcess() {}
25 
ProcessEnterLeaveEvent(int32_t nodeId,sptr<Rosen::Session> session,const std::shared_ptr<MMI::PointerEvent> & pointerEvent)26 void WindowEventProcess::ProcessEnterLeaveEvent(int32_t nodeId,
27     sptr<Rosen::Session> session, const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
28 {
29     CHECK_NULL_VOID(session);
30     CHECK_NULL_VOID(pointerEvent);
31     std::shared_ptr<MMI::PointerEvent> enterEvent = std::make_shared<MMI::PointerEvent>(*pointerEvent);
32 
33     int32_t action = pointerEvent->GetPointerAction();
34     if (action == MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW) {
35         lastWindowNodeId_ = nodeId;
36         lastWeakSession_ = session;
37         lastPointEvent_ = enterEvent;
38         return;
39     }
40     auto lastSession = lastWeakSession_.promote();
41     if (lastSession == nullptr) {
42         enterEvent->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW);
43         DispatchPointerEvent(session, enterEvent);
44         lastWindowNodeId_ = nodeId;
45         lastWeakSession_ = session;
46         lastPointEvent_ = enterEvent;
47         return;
48     }
49 
50     if (lastWindowNodeId_ != nodeId) {
51         if (lastPointEvent_ != nullptr) {
52             lastPointEvent_->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
53             lastPointEvent_->SetId(pointerEvent->GetId());
54             DispatchPointerEvent(lastSession, lastPointEvent_);
55 
56             enterEvent->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW);
57             DispatchPointerEvent(session, enterEvent);
58         }
59         lastWindowNodeId_ = nodeId;
60         lastWeakSession_ = session;
61     }
62     lastPointEvent_ = enterEvent;
63 }
64 
ProcessWindowMouseEvent(int32_t nodeId,sptr<Rosen::Session> session,const std::shared_ptr<MMI::PointerEvent> & pointerEvent)65 void WindowEventProcess::ProcessWindowMouseEvent(int32_t nodeId,
66     sptr<Rosen::Session> session, const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
67 {
68     CHECK_NULL_VOID(session);
69     CHECK_NULL_VOID(pointerEvent);
70     if (pointerEvent->GetSourceType() != MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
71         return;
72     }
73     int32_t action = pointerEvent->GetPointerAction();
74     if ((action == MMI::PointerEvent::POINTER_ACTION_MOVE &&
75         pointerEvent->GetButtonId() == MMI::PointerEvent::BUTTON_NONE) ||
76         (action == MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW)) {
77         ProcessEnterLeaveEvent(nodeId, session, pointerEvent);
78     }
79     if (action == MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW) {
80         CleanWindowMouseRecord();
81     }
82 }
83 
ProcessWindowDragEvent(int32_t nodeId,sptr<Rosen::Session> session,const std::shared_ptr<MMI::PointerEvent> & pointerEvent)84 void WindowEventProcess::ProcessWindowDragEvent(int32_t nodeId,
85     sptr<Rosen::Session> session, const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
86 {
87     CHECK_NULL_VOID(session);
88     CHECK_NULL_VOID(pointerEvent);
89     int32_t action = pointerEvent->GetPointerAction();
90     if (action == MMI::PointerEvent::POINTER_ACTION_PULL_UP) {
91         CleanWindowDragEvent();
92         return;
93     }
94     if (action != MMI::PointerEvent::POINTER_ACTION_PULL_MOVE) {
95         return;
96     }
97     std::shared_ptr<MMI::PointerEvent> event = std::make_shared<MMI::PointerEvent>(*pointerEvent);
98     if ((lastDragWindowNodeId_ != -1) && (nodeId != lastDragWindowNodeId_)) {
99         if (lastDragPointEvent_ != nullptr) {
100             lastDragPointEvent_->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW);
101             lastDragPointEvent_->SetId(pointerEvent->GetId());
102             auto lastSession = lastDragSession_.promote();
103             if (lastSession != nullptr) {
104                 DispatchPointerEvent(lastSession, lastDragPointEvent_);
105             }
106             event->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_PULL_IN_WINDOW);
107             DispatchPointerEvent(session, event);
108             if (event->GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
109                 UpdateWindowMouseRecord(nodeId, session, event);
110             }
111         }
112     }
113     lastDragWindowNodeId_ = nodeId;
114     lastDragSession_ = session;
115     lastDragPointEvent_ = event;
116 }
117 
CleanWindowMouseRecord()118 void WindowEventProcess::CleanWindowMouseRecord()
119 {
120     lastWindowNodeId_ = -1;
121     lastWeakSession_ = nullptr;
122     lastPointEvent_ = nullptr;
123 }
124 
CleanWindowDragEvent()125 void WindowEventProcess::CleanWindowDragEvent()
126 {
127     lastDragWindowNodeId_ = -1;
128     lastDragSession_ = nullptr;
129     lastDragPointEvent_ = nullptr;
130 }
131 
UpdateWindowMouseRecord(int32_t nodeId,sptr<Rosen::Session> session,const std::shared_ptr<MMI::PointerEvent> & pointerEvent)132 void WindowEventProcess::UpdateWindowMouseRecord(int32_t nodeId,
133     sptr<Rosen::Session> session, const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
134 {
135     CHECK_NULL_VOID(session);
136     lastWindowNodeId_ = nodeId;
137     lastWeakSession_ = session;
138     lastPointEvent_ = pointerEvent;
139 }
140 
DispatchPointerEvent(sptr<Rosen::Session> session,const std::shared_ptr<MMI::PointerEvent> & pointerEvent)141 void WindowEventProcess::DispatchPointerEvent(sptr<Rosen::Session> session,
142     const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
143 {
144     CHECK_NULL_VOID(session);
145     CHECK_NULL_VOID(pointerEvent);
146     session->TransferPointerEvent(pointerEvent);
147 }
148 } // namespace OHOS::Ace::NG
149