diff --git a/window_scene/common/include/window_session_property.h b/window_scene/common/include/window_session_property.h index 4488ffc5e00037a0bc34c9c749a21b7f9fb9cd40..a9dab6c09457da9997ae391bbd1cdab30bf29ab0 100755 --- a/window_scene/common/include/window_session_property.h +++ b/window_scene/common/include/window_session_property.h @@ -93,6 +93,7 @@ public: void SetTouchHotAreas(const std::vector& rects); void SetNeedKeepKeyboard(bool isNeedKeepKeyboard); void SetIsNeedUpdateWindowMode(bool isNeedUpdateWindowMode); + void SetCallingWindow(uint32_t windowId); bool GetIsNeedUpdateWindowMode() const; const std::string& GetWindowName() const; @@ -132,6 +133,7 @@ public: bool IsFloatingWindowAppType() const; void GetTouchHotAreas(std::vector& rects) const; bool IsNeedKeepKeyboard() const; + uint32_t GetCallingWindow() const; bool MarshallingWindowLimits(Parcel& parcel) const; static void UnmarshallingWindowLimits(Parcel& parcel, WindowSessionProperty* property); @@ -190,6 +192,7 @@ private: bool hideNonSystemFloatingWindows_ = false; bool forceHide_ = false; bool isNeedKeepKeyboard_ = false; + uint32_t callingWindowId_ = INVALID_WINDOW_ID; double textFieldPositionY_ = 0.0; double textFieldHeight_ = 0.0; diff --git a/window_scene/common/src/window_session_property.cpp b/window_scene/common/src/window_session_property.cpp index d068923557832ff08fa91bfeeea811cdd5fb68cf..5dc30503d0354afa43ce4e3971876df64ce5290e 100755 --- a/window_scene/common/src/window_session_property.cpp +++ b/window_scene/common/src/window_session_property.cpp @@ -397,6 +397,16 @@ bool WindowSessionProperty::IsNeedKeepKeyboard() const return isNeedKeepKeyboard_; } +void WindowSessionProperty::SetCallingWindow(uint32_t windowId) +{ + callingWindowId_ = windowId; +} + +uint32_t WindowSessionProperty::GetCallingWindow() const +{ + return callingWindowId_; +} + void WindowSessionProperty::SetIsNeedUpdateWindowMode(bool isNeedUpdateWindowMode) { isNeedUpdateWindowMode_ = isNeedUpdateWindowMode; @@ -517,7 +527,7 @@ bool WindowSessionProperty::Marshalling(Parcel& parcel) const parcel.WriteBool(isFloatingWindowAppType_) && MarshallingTouchHotAreas(parcel) && parcel.WriteBool(isSystemCalling_) && parcel.WriteDouble(textFieldPositionY_) && parcel.WriteDouble(textFieldHeight_) && - parcel.WriteBool(isNeedUpdateWindowMode_); + parcel.WriteBool(isNeedUpdateWindowMode_) && parcel.WriteUint32(callingWindowId_); } WindowSessionProperty* WindowSessionProperty::Unmarshalling(Parcel& parcel) @@ -564,6 +574,7 @@ WindowSessionProperty* WindowSessionProperty::Unmarshalling(Parcel& parcel) property->SetTextFieldPositionY(parcel.ReadDouble()); property->SetTextFieldHeight(parcel.ReadDouble()); property->SetIsNeedUpdateWindowMode(parcel.ReadBool()); + property->SetCallingWindow(parcel.ReadUint32()); return property; } diff --git a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.cpp b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.cpp index 62588480a9385c44710bcdee08bd003a53c80345..f0b2adec0381c6082bb5318162f9ab82588155b8 100644 --- a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.cpp +++ b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.cpp @@ -54,6 +54,7 @@ const std::string OUTSIDE_DOWN_EVENT_CB = "outsideDownEvent"; const std::string ARG_DUMP_HELP = "-h"; const std::string SHIFT_FOCUS_CB = "shiftFocus"; const std::string SHOW_PIP_MAIN_WINDOW_CB = "showPiPMainWindow"; +const std::string CALLING_WINDOW_ID_CHANGE_CB = "callingWindowIdChange"; } // namespace napi_value JsSceneSessionManager::Init(napi_env env, napi_value exportObj) @@ -129,6 +130,7 @@ JsSceneSessionManager::JsSceneSessionManager(napi_env env) : env_(env) { SHOW_PIP_MAIN_WINDOW_CB, &JsSceneSessionManager::ProcessShowPiPMainWindow }, { GESTURE_NAVIGATION_ENABLED_CHANGE_CB, &JsSceneSessionManager::ProcessGestureNavigationEnabledChangeListener }, + { CALLING_WINDOW_ID_CHANGE_CB, &JsSceneSessionManager::ProcessCallingWindowIdChangeRegister}, }; taskScheduler_ = std::make_shared(env); } @@ -255,6 +257,21 @@ void JsSceneSessionManager::OnShowPiPMainWindow(int32_t persistentId) taskScheduler_->PostMainThreadTask(task, "OnShowPiPMainWindow, persistentId:" + std::to_string(persistentId)); } +void JsSceneSessionManager::OnCallingWindowIdChange(const uint32_t windowId) +{ + WLOGFD("[WMSInput][NAPI]OnCallingWindowIdChange"); + auto iter = jsCbMap_.find(CALLING_WINDOW_ID_CHANGE_CB); + if (iter == jsCbMap_.end()) { + return; + } + auto jsCallBack = iter->second; + auto task = [this, windowId, jsCallBack, env = env_]() { + napi_value argv[] = { CreateJsValue(env, windowId) }; + napi_call_function(env, NapiGetUndefined(env), jsCallBack->GetNapiValue(), ArraySize(argv), argv, nullptr); + }; + taskScheduler_->PostMainThreadTask(task, "OnCallingWindowIdChange, windowId:" + std::to_string(windowId)); +} + void JsSceneSessionManager::ProcessCreateSystemSessionRegister() { NotifyCreateSystemSessionFunc func = [this](const sptr& session) { @@ -329,6 +346,15 @@ void JsSceneSessionManager::ProcessShowPiPMainWindow() SceneSessionManager::GetInstance().SetShowPiPMainWindowListener(func); } +void JsSceneSessionManager::ProcessCallingWindowIdChangeRegister() +{ + ProcessCallingWindowIdChangeFunc func = [this](const uint32_t callingWindowId) { + WLOGFD("ProcessCallingWindowIdChangeRegister called, callingWindowId: %{public}d", callingWindowId); + this->OnCallingWindowIdChange(callingWindowId); + }; + SceneSessionManager::GetInstance().SetCallingWindowIdChangeListenser(func); +} + napi_value JsSceneSessionManager::RegisterCallback(napi_env env, napi_callback_info info) { WLOGFD("[NAPI]RegisterCallback"); diff --git a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.h b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.h index e983f71ddb83813225a6ee4febce069aaee85fd2..a0396835e61e6f9960e35be087471024ece46b5a 100644 --- a/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.h +++ b/window_scene/interfaces/kits/napi/scene_session_manager/js_scene_session_manager.h @@ -110,12 +110,14 @@ private: void OnOutsideDownEvent(int32_t x, int32_t y); void OnShiftFocus(int32_t persistentId); void OnShowPiPMainWindow(int32_t persistentId); + void OnCallingWindowIdChange(const uint32_t callingWindowId); void ProcessCreateSystemSessionRegister(); void ProcessStatusBarEnabledChangeListener(); void ProcessGestureNavigationEnabledChangeListener(); void ProcessOutsideDownEvent(); void ProcessShiftFocus(); void ProcessShowPiPMainWindow(); + void ProcessCallingWindowIdChangeRegister(); bool IsCallbackRegistered(napi_env env, const std::string& type, napi_value jsListenerObject); void RegisterDumpRootSceneElementInfoListener(); void RegisterVirtualPixelRatioChangeListener(); diff --git a/window_scene/session_manager/include/scene_session_manager.h b/window_scene/session_manager/include/scene_session_manager.h index 692590628570850094718f28ed8af93af47ec030..7d8a428f37b647d5ea5fdda5113c60f8d690b3a6 100644 --- a/window_scene/session_manager/include/scene_session_manager.h +++ b/window_scene/session_manager/include/scene_session_manager.h @@ -76,6 +76,7 @@ using CmpFunc = std::function>& lhs, std::pair>& rhs)>; using ProcessShowPiPMainWindowFunc = std::function; using NotifySCBAfterUpdateFocusFunc = std::function; +using ProcessCallingWindowIdChangeFunc = std::function; class DisplayChangeListener : public IDisplayChangeListener { public: @@ -122,6 +123,7 @@ public: void SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc& func); void SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc& func); void SetShowPiPMainWindowListener(const ProcessShowPiPMainWindowFunc& func); + void SetCallingWindowIdChangeListenser(const ProcessCallingWindowIdChangeFunc& func); const AppWindowSceneConfig& GetWindowSceneConfig() const; WSError ProcessBackEvent(); WSError BindDialogSessionTarget(uint64_t persistentId, sptr targetToken) override; @@ -397,6 +399,7 @@ private: NotifySCBAfterUpdateFocusFunc notifySCBAfterFocusedFunc_; NotifySCBAfterUpdateFocusFunc notifySCBAfterUnfocusedFunc_; ProcessShowPiPMainWindowFunc showPiPMainWindowFunc_; + ProcessCallingWindowIdChangeFunc callingWindowIdChangeFunc_; AppWindowSceneConfig appWindowSceneConfig_; SystemSessionConfig systemConfig_; float snapshotScale_ = 0.5; diff --git a/window_scene/session_manager/src/scene_session_manager.cpp b/window_scene/session_manager/src/scene_session_manager.cpp index e6ea317b8d9c817a66ef5b95e33d6a50121b32ff..759e9f56a734cea80ce305170e6c34602f1092df 100644 --- a/window_scene/session_manager/src/scene_session_manager.cpp +++ b/window_scene/session_manager/src/scene_session_manager.cpp @@ -1026,10 +1026,20 @@ void SceneSessionManager::OnInputMethodShown(const int32_t& persistentId) WLOGFE("[WMSInput] Input method is null"); return; } - callingSession_ = GetSceneSession(focusedSessionId_); + + uint32_t callingWindowId_ = INVALID_WINDOW_ID; + if (scnSession->GetSessionProperty() != nullptr) { + callingWindowId_ = scnSession->GetSessionProperty()->GetCallingWindow(); + } + WLOGFD("[WMSInput] Calling window id: %{public}d", callingWindowId_); + callingSession_ = GetSceneSession(callingWindowId_); if (callingSession_ == nullptr) { - WLOGFE("[WMSInput] calling session is nullptr"); - return; + WLOGFI("[WMSInput] The calling session obtained through callingWindowId_ is nullptr"); + callingSession_ = GetSceneSession(focusedSessionId_); + if (callingSession_ == nullptr) { + WLOGFE("[WMSInput] The calling session obtained through focusedSessionId_ is nullptr"); + return; + } } callingSession_->SetTextFieldAvoidInfo(scnSession->textFieldPositionY_, scnSession->textFieldHeight_); ResizeSoftInputCallingSessionIfNeed(scnSession); @@ -2201,6 +2211,15 @@ WMError SceneSessionManager::HandleUpdateProperty(const sptrGetSessionProperty() != nullptr) { + sceneSession->GetSessionProperty()->SetCallingWindow(property->GetCallingWindow()); + } + if (callingWindowIdChangeFunc_ != nullptr) { + callingWindowIdChangeFunc_(property->GetCallingWindow()); + } + break; + } case WSPropertyChangeAction::ACTION_UPDATE_DECOR_ENABLE: { if (sceneSession->GetSessionProperty() != nullptr) { sceneSession->GetSessionProperty()->SetDecorEnable(property->IsDecorEnable()); @@ -3162,6 +3181,12 @@ void SceneSessionManager::SetShowPiPMainWindowListener(const ProcessShowPiPMainW showPiPMainWindowFunc_ = func; } +void SceneSessionManager::SetCallingWindowIdChangeListenser(const ProcessCallingWindowIdChangeFunc& func) +{ + WLOGFD("SetCallingWindowIdChangeListenser"); + callingWindowIdChangeFunc_ = func; +} + WSError SceneSessionManager::ShiftFocus(sptr& nextSession) { // unfocus diff --git a/wm/include/window_scene_session_impl.h b/wm/include/window_scene_session_impl.h index 8bac345ab5f606e86374c0d7bba3d1466fa8e255..cb0791d1bb22eb9b2fbba6d15080353cab30bcb9 100644 --- a/wm/include/window_scene_session_impl.h +++ b/wm/include/window_scene_session_impl.h @@ -108,6 +108,7 @@ public: virtual std::shared_ptr Snapshot() override; WMError SetTouchHotAreas(const std::vector& rects) override; virtual WMError SetNeedKeepKeyboard(bool isNeedKeepKeyboard) override; + virtual WMError SetCallingWindow(uint32_t callingWindowId) override; virtual bool IsTransparent() const override; virtual bool IsTurnScreenOn() const override; diff --git a/wm/src/window_scene_session_impl.cpp b/wm/src/window_scene_session_impl.cpp index 7310bfc7813b60fa4b0f1a6da1022fb71e0a0260..f4daa3bed6c3fff965949448e44a4a732cd5790e 100644 --- a/wm/src/window_scene_session_impl.cpp +++ b/wm/src/window_scene_session_impl.cpp @@ -2021,6 +2021,28 @@ WMError WindowSceneSessionImpl::SetNeedKeepKeyboard(bool isNeedKeepKeyboard) return WMError::WM_OK; } +WMError WindowSceneSessionImpl::SetCallingWindow(uint32_t callingWindowId) +{ + if (IsWindowSessionInvalid()) { + WLOGFE("[WMSInput] Set calling window id failed, window session is InValid!"); + return WMError::WM_ERROR_INVALID_WINDOW; + } + + if (property_ == nullptr) { + WLOGFE("[WMSInput] Set calling window id failed, property_ is nullptr!"); + return WMError::WM_ERROR_NULLPTR; + } + uint32_t lastCallingWindowId = property_->GetCallingWindow(); + if (callingWindowId == lastCallingWindowId) { + WLOGFD("[WMSInput] Calling window id does not need to be updated!"); + return WMError::WM_OK; + } + WLOGFI("[WMSInput] Set calling window id: %{public}d", callingWindowId); + property_->SetCallingWindow(callingWindowId); + + return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_CALLING_WINDOW); +} + void WindowSceneSessionImpl::DumpSessionElementInfo(const std::vector& params) { WLOGFD("DumpSessionElementInfo"); diff --git a/wm/src/window_session_impl.cpp b/wm/src/window_session_impl.cpp index ccffbbd590e9368b55d020cbbdaf5255fb011187..1279ce4fa34f02487d861f30ff2d6384dcea5468 100644 --- a/wm/src/window_session_impl.cpp +++ b/wm/src/window_session_impl.cpp @@ -119,6 +119,7 @@ WindowSessionImpl::WindowSessionImpl(const sptr& option) property_->SetKeepScreenOn(option->IsKeepScreenOn()); property_->SetWindowMode(option->GetWindowMode()); property_->SetWindowFlags(option->GetWindowFlags()); + property_->SetCallingWindow(option->GetCallingWindow()); auto isPC = system::GetParameter("const.product.devicetype", "unknown") == "2in1"; if (isPC && WindowHelper::IsSubWindow(option->GetWindowType())) { @@ -1081,11 +1082,42 @@ void WindowSessionImpl::NotifyAfterBackground(bool needNotifyListeners, bool nee VsyncStation::GetInstance().SetFrameRateLinkerEnable(false); } +static void RequestInputMethodCloseKeyboard(bool isNeedKeyboard, bool isNeedKeepKeyboard) +{ + if (!isNeedKeyboard && !isNeedKeepKeyboard) { +#ifdef IMF_ENABLE + WLOGFI("[WMSInput] Notify InputMethod framework close keyboard"); + if (MiscServices::InputMethodController::GetInstance()) { + int32_t ret = MiscServices::InputMethodController::GetInstance()->RequestHideInput(); + if (ret != 0) { // 0 - NO_ERROR + WLOGFE("[WMSInput] InputMethod framework close keyboard failed, ret: %{public}d", ret); + } + } +#endif + } +} + void WindowSessionImpl::NotifyAfterFocused() { auto lifecycleListeners = GetListeners(); CALL_LIFECYCLE_LISTENER(AfterFocused, lifecycleListeners); CALL_UI_CONTENT(Focus); + if (uiContent_ != nullptr) { + auto task = [this]() { + if (uiContent_ != nullptr) { + // isNeedKeyboard is set by arkui and indicates whether the window needs a keyboard or not. + bool isNeedKeyboard = uiContent_->NeedSoftKeyboard(); + /* isNeedKeyboard is set by the system window and the app subwindow, + * which indicates whether the window is set to keep the keyboard. + */ + bool isNeedKeepKeyboard = (property_ != nullptr) ? property_->IsNeedKeepKeyboard() : false; + WLOGFD("[WMSInput] isNeedKeyboard: %{public}d, isNeedKeepKeyboard: %{public}d", + isNeedKeyboard, isNeedKeepKeyboard); + RequestInputMethodCloseKeyboard(isNeedKeyboard, isNeedKeepKeyboard); + } + }; + uiContent_->SetOnWindowFocused(task); + } } void WindowSessionImpl::NotifyAfterUnfocused(bool needNotifyUiContent)