From ac546fffc554d8ab95ac0e67017921d764a281ae Mon Sep 17 00:00:00 2001 From: Jaehyun Cho Date: Wed, 13 Jul 2022 18:53:09 +0900 Subject: [PATCH] Add InsetsChangedSignal to WindowBaseEcoreWl2 Window insets are the inner size between window content and window edge. Window insets are required when status bar, virtual keyboard, or clipboard appears on window to avoid window content obsecured by them. To notify the window insets changes, InsetsChangedSignal is added to WindowBaseEcoreWl2. To notice the window insets changes, ECORE_WL2_EVENT_CONFORMANT_CHANGE is used. Change-Id: Iaff1b2c121ee5e07769eac9d9950b74b500e192b --- dali/devel-api/adaptor-framework/window-devel.cpp | 5 + dali/devel-api/adaptor-framework/window-devel.h | 9 + dali/internal/window-system/common/window-base.cpp | 8 +- dali/internal/window-system/common/window-base.h | 7 + dali/internal/window-system/common/window-impl.cpp | 8 + dali/internal/window-system/common/window-impl.h | 20 ++ .../ecore-wl2/window-base-ecore-wl2.cpp | 213 +++++++++++++++++++++ .../ecore-wl2/window-base-ecore-wl2.h | 10 + .../adaptor-framework/window-enumerations.h | 19 ++ 9 files changed, 298 insertions(+), 1 deletion(-) diff --git a/dali/devel-api/adaptor-framework/window-devel.cpp b/dali/devel-api/adaptor-framework/window-devel.cpp index 519aaad..3fab555 100644 --- a/dali/devel-api/adaptor-framework/window-devel.cpp +++ b/dali/devel-api/adaptor-framework/window-devel.cpp @@ -309,6 +309,11 @@ MouseInOutEventSignalType& MouseInOutEventSignal(Window window) return GetImplementation(window).MouseInOutEventSignal(); } +InsetsChangedSignalType& InsetsChangedSignal(Window window) +{ + return GetImplementation(window).InsetsChangedSignal(); +} + } // namespace DevelWindow } // namespace Dali diff --git a/dali/devel-api/adaptor-framework/window-devel.h b/dali/devel-api/adaptor-framework/window-devel.h index 46f380d..287005a 100644 --- a/dali/devel-api/adaptor-framework/window-devel.h +++ b/dali/devel-api/adaptor-framework/window-devel.h @@ -52,6 +52,7 @@ typedef Signal typedef Signal MouseInOutEventSignalType; ///< MouseInOutEvent signal type typedef Signal MoveCompletedSignalType; ///< Window Moved by Server signal type typedef Signal ResizeCompletedSignalType; ///< Window Resized by Server signal type +typedef Signal InsetsChangedSignalType; ///< InsetsChanged signal type /** * @brief Creates an initialized handle to a new Window. @@ -625,6 +626,14 @@ DALI_ADAPTOR_API MoveCompletedSignalType& MoveCompletedSignal(Window window); */ DALI_ADAPTOR_API ResizeCompletedSignalType& ResizeCompletedSignal(Window window); +/** + * @brief This signal is emitted when window insets are changed by appearing or disappearing indicator, virtual keyboard, or clipboard. + * + * @param[in] window The window instance + * @return The signal to connect to + */ +DALI_ADAPTOR_API InsetsChangedSignalType& InsetsChangedSignal(Window window); + } // namespace DevelWindow } // namespace Dali diff --git a/dali/internal/window-system/common/window-base.cpp b/dali/internal/window-system/common/window-base.cpp index a0a89dc..19417d2 100644 --- a/dali/internal/window-system/common/window-base.cpp +++ b/dali/internal/window-system/common/window-base.cpp @@ -44,7 +44,8 @@ WindowBase::WindowBase() mAuxiliaryMessageSignal(), mMouseInOutEventSignal(), mMoveCompletedSignal(), - mResizeCompletedSignal() + mResizeCompletedSignal(), + mInsetsChangedSignal() { } @@ -157,6 +158,11 @@ WindowBase::ResizeCompletedSignalType& WindowBase::ResizeCompletedSignal() return mResizeCompletedSignal; } +WindowBase::InsetsChangedSignalType& WindowBase::InsetsChangedSignal() +{ + return mInsetsChangedSignal; +} + } // namespace Adaptor } // namespace Internal diff --git a/dali/internal/window-system/common/window-base.h b/dali/internal/window-system/common/window-base.h index 699461a..d014379 100644 --- a/dali/internal/window-system/common/window-base.h +++ b/dali/internal/window-system/common/window-base.h @@ -79,6 +79,7 @@ public: typedef Signal MouseInOutEventSignalType; typedef Signal MoveCompletedSignalType; typedef Signal ResizeCompletedSignalType; + typedef Signal InsetsChangedSignalType; // Input events typedef Signal TouchEventSignalType; @@ -577,6 +578,11 @@ public: */ ResizeCompletedSignalType& ResizeCompletedSignal(); + /** + * @brief This signal is emitted when window insets are changed by appearing or disappearing indicator, virtual keyboard, or clipboard. + */ + InsetsChangedSignalType& InsetsChangedSignal(); + protected: // Undefined WindowBase(const WindowBase&) = delete; @@ -606,6 +612,7 @@ protected: MouseInOutEventSignalType mMouseInOutEventSignal; MoveCompletedSignalType mMoveCompletedSignal; ResizeCompletedSignalType mResizeCompletedSignal; + InsetsChangedSignalType mInsetsChangedSignal; }; } // namespace Adaptor diff --git a/dali/internal/window-system/common/window-impl.cpp b/dali/internal/window-system/common/window-impl.cpp index bf94b81..3048d9e 100644 --- a/dali/internal/window-system/common/window-impl.cpp +++ b/dali/internal/window-system/common/window-impl.cpp @@ -94,6 +94,7 @@ Window::Window() mMouseInOutEventSignal(), mMoveCompletedSignal(), mResizeCompletedSignal(), + mInsetsChangedSignal(), mLastKeyEvent(), mLastTouchEvent(), mIsTransparent(false), @@ -168,6 +169,8 @@ void Window::Initialize(Any surface, const PositionSize& positionSize, const std mWindowSurface->OutputTransformedSignal().Connect(this, &Window::OnOutputTransformed); mWindowSurface->RotationFinishedSignal().Connect(this, &Window::OnRotationFinished); + mWindowBase->InsetsChangedSignal().Connect(this, &Window::OnInsetsChanged); + SetClass(name, className); mOrientation = Orientation::New(this); @@ -1132,6 +1135,11 @@ void Window::OnAuxiliaryMessage(const std::string& key, const std::string& value mAuxiliaryMessageSignal.Emit(key, value, options); } +void Window::OnInsetsChanged(WindowInsetsPartType partType, WindowInsetsPartState partState, const Extents& insets) +{ + mInsetsChangedSignal.Emit(partType, partState, insets); +} + void Window::OnAccessibilityEnabled() { auto bridge = Accessibility::Bridge::GetCurrentBridge(); diff --git a/dali/internal/window-system/common/window-impl.h b/dali/internal/window-system/common/window-impl.h index c5d6665..8d15f61 100644 --- a/dali/internal/window-system/common/window-impl.h +++ b/dali/internal/window-system/common/window-impl.h @@ -72,6 +72,7 @@ public: typedef Dali::DevelWindow::MouseInOutEventSignalType MouseInOutEventSignalType; typedef Dali::DevelWindow::MoveCompletedSignalType MoveCompletedSignalType; typedef Dali::DevelWindow::ResizeCompletedSignalType ResizeCompletedSignalType; + typedef Dali::DevelWindow::InsetsChangedSignalType InsetsChangedSignalType; typedef Signal SignalType; /** @@ -663,6 +664,16 @@ private: */ void SetUserGeometryPolicy(); + /** + * @brief Called when window insets are changed by appearing or disappearing indicator, virtual keyboard, or clipboard. + * + * @param[in] partType the type of the part that occurs the window insets change. + * @param[in] partState the state of the part that occurs the window insets change. + * @param[in] insets the extents value of window insets. + */ + void OnInsetsChanged(WindowInsetsPartType partType, WindowInsetsPartState partState, const Extents& insets); + + private: // Dali::Internal::Adaptor::SceneHolder /** * @copydoc Dali::Internal::Adaptor::SceneHolder::OnAdaptorSet @@ -823,6 +834,14 @@ public: // Signals return mResizeCompletedSignal; } + /** + * @copydoc Dali::DevelWindow::InsetsChangedSignal() + */ + InsetsChangedSignalType& InsetsChangedSignal() + { + return mInsetsChangedSignal; + } + private: WindowRenderSurface* mWindowSurface; ///< The window rendering surface WindowBase* mWindowBase; @@ -856,6 +875,7 @@ private: MouseInOutEventSignalType mMouseInOutEventSignal; MoveCompletedSignalType mMoveCompletedSignal; ResizeCompletedSignalType mResizeCompletedSignal; + InsetsChangedSignalType mInsetsChangedSignal; Dali::KeyEvent mLastKeyEvent; Dali::TouchEvent mLastTouchEvent; diff --git a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp index 1e64164..7dd0015 100644 --- a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp +++ b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.cpp @@ -739,6 +739,19 @@ static Eina_Bool EcoreEventWindowResizeCompleted(void* data, int type, void* eve return ECORE_CALLBACK_RENEW; } +///////////////////////////////////////////////////////////////////////////////////////////////// +// Conformant Change Callback +///////////////////////////////////////////////////////////////////////////////////////////////// +static Eina_Bool EcoreEventConformantChange(void* data, int type, void* event) +{ + WindowBaseEcoreWl2* windowBase = static_cast(data); + if(windowBase) + { + windowBase->OnEcoreEventConformantChange(event); + } + return ECORE_CALLBACK_RENEW; +} + static void RegistryGlobalCallback(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version) { WindowBaseEcoreWl2* windowBase = static_cast(data); @@ -763,6 +776,11 @@ static void TizenPolicyConformant(void* data, struct tizen_policy* tizenPolicy, static void TizenPolicyConformantArea(void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, uint32_t conformantPart, uint32_t state, int32_t x, int32_t y, int32_t w, int32_t h) { + WindowBaseEcoreWl2* windowBase = static_cast(data); + if(windowBase) + { + windowBase->TizenPolicyConformantArea(data, tizenPolicy, surface, conformantPart, state, x, y, w, h); + } } static void TizenPolicyNotificationChangeDone(void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, int32_t level, uint32_t state) @@ -979,6 +997,9 @@ void WindowBaseEcoreWl2::Initialize(PositionSize positionSize, Any surface, bool // Register Window auxiliary event mEcoreEventHandler.PushBack(ecore_event_handler_add(ECORE_WL2_EVENT_AUX_MESSAGE, EcoreEventWindowAuxiliaryMessage, this)); + // Register Conformant change event + mEcoreEventHandler.PushBack(ecore_event_handler_add(ECORE_WL2_EVENT_CONFORMANT_CHANGE, EcoreEventConformantChange, this)); + #if defined(VCONF_ENABLED) // Register Vconf notify - font name and size vconf_notify_key_changed_for_ui_thread(DALI_VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, VconfNotifyFontNameChanged, this); @@ -1004,6 +1025,9 @@ void WindowBaseEcoreWl2::Initialize(PositionSize positionSize, Any surface, bool wl_registry* registry = wl_display_get_registry(displayWrapper); wl_registry_add_listener(registry, ®istryListener, this); + + // To support ECORE_WL2_EVENT_CONFORMANT_CHANGE event handler + ecore_wl2_window_conformant_set(mEcoreWindow, true); } wl_proxy_wrapper_destroy(displayWrapper); @@ -1567,6 +1591,106 @@ void WindowBaseEcoreWl2::OnEcoreEventWindowAuxiliaryMessage(void* event) } } +void WindowBaseEcoreWl2::OnEcoreEventConformantChange(void* event) +{ + Ecore_Wl2_Event_Conformant_Change* ev = static_cast(event); + if(ev && ev->win == static_cast(ecore_wl2_window_id_get(mEcoreWindow))) + { + WindowInsetsPartType partType = WindowInsetsPartType::STATUS_BAR; + + int x = 0; + int y = 0; + int w = 0; + int h = 0; + + switch (ev->part_type) + { + case ECORE_WL2_INDICATOR_PART: + { + partType = WindowInsetsPartType::STATUS_BAR; + ecore_wl2_window_indicator_geometry_get(mEcoreWindow, &x, &y, &w, &h); + break; + } + case ECORE_WL2_KEYBOARD_PART: + { + partType = WindowInsetsPartType::KEYBOARD; + ecore_wl2_window_keyboard_geometry_get(mEcoreWindow, &x, &y, &w, &h); + break; + } + case ECORE_WL2_CLIPBOARD_PART: + { + partType = WindowInsetsPartType::CLIPBOARD; + ecore_wl2_window_clipboard_geometry_get(mEcoreWindow, &x, &y, &w, &h); + break; + } + default: + { + break; + } + } + + WindowInsetsPartState partState = WindowInsetsPartState::INVISIBLE; + + int left = 0; + int right = 0; + int top = 0; + int bottom = 0; + + // Insets are applied only if system UI(e.g. virtual keyboard) satisfies the following 2 conditions. + // 1. System UI fits to the window width or height. + // 2. System UI begins or ends from the edge of window. + // Otherwise, we should not resize window content because there would be empty space around system UI. + bool applyInsets = false; + + // Zero insets are applied if state is invisible + if(!ev->state) + { + applyInsets = true; + } + else + { + partState = WindowInsetsPartState::VISIBLE; + + int winX = mWindowPositionSize.x; + int winY = mWindowPositionSize.y; + int winW = mWindowPositionSize.width; + int winH = mWindowPositionSize.height; + + if((x <= winX) && (x + w >= winX + winW)) + { + if((y <= winY) && (y + h >= winY) && (y + h <= winY + winH)) + { + top = y + h - winY; + applyInsets = true; + } + else if((y + h >= winY + winH) && (y >= winY) && (y <= winY + winH)) + { + bottom = winY + winH - y; + applyInsets = true; + } + } + else if((y <= winY) && (y + h >= winY + winH)) + { + if((x <= winX) && (x + w >= winX) && (x + w <= winX + winW)) + { + left = x + w - winX; + applyInsets = true; + } + else if((x + w >= winX + winW) && (x >= winX) && (x <= winX + winW)) + { + right = winX + winW - x; + applyInsets = true; + } + } + } + + if(applyInsets) + { + mInsetsChangedSignal.Emit(partType, partState, Extents(left, right, top, bottom)); + } + } +} + void WindowBaseEcoreWl2::KeymapChanged(void* data, int type, void* event) { Ecore_Wl2_Event_Seat_Keymap_Changed* changed = static_cast(event); @@ -1642,6 +1766,95 @@ void WindowBaseEcoreWl2::RegistryGlobalCallbackRemove(void* data, struct wl_regi mTizenDisplayPolicy = NULL; } +void WindowBaseEcoreWl2::TizenPolicyConformantArea(void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, uint32_t conformantPart, uint32_t state, int32_t x, int32_t y, int32_t w, int32_t h) +{ + int originalX, originalY, originalWidth, originalHeight; + bool changed = false; + + if(!surface) + { + DALI_LOG_ERROR("Failed to get wayland surface in WindowBaseEcoreWl2::TizenPolicyConformantArea()\n"); + return; + } + + if(conformantPart == TIZEN_POLICY_CONFORMANT_PART_INDICATOR) + { + ecore_wl2_window_indicator_geometry_get(mEcoreWindow, &originalX, &originalY, &originalWidth, &originalHeight); + if((originalX != x) || (originalY != y) || (originalWidth != w) || (originalHeight != h)) + { + ecore_wl2_window_indicator_geometry_set(mEcoreWindow, x, y, w, h); + changed = true; + } + + /** + * The given state is based on the visibility value of indicator. + * Thus we need to add 1 to it before comparing with indicator state. + */ + Ecore_Wl2_Indicator_State indState = ecore_wl2_window_indicator_state_get(mEcoreWindow); + if((state + 1) != indState) + { + ecore_wl2_window_indicator_state_set(mEcoreWindow, static_cast(state + 1)); + changed = true; + } + } + else if(conformantPart == TIZEN_POLICY_CONFORMANT_PART_KEYBOARD) + { + ecore_wl2_window_keyboard_geometry_get(mEcoreWindow, &originalX, &originalY, &originalWidth, &originalHeight); + if((originalX != x) || (originalY != y) || (originalWidth != w) || (originalHeight != h)) + { + ecore_wl2_window_keyboard_geometry_set(mEcoreWindow, x, y, w, h); + changed = true; + } + + /** + * The given state is based on the visibility value of virtual keyboard window. + * Thus we need to add 1 to it before comparing with keyboard state. + */ + Ecore_Wl2_Virtual_Keyboard_State kbdState = ecore_wl2_window_keyboard_state_get(mEcoreWindow); + if((state + 1) != (kbdState)) + { + ecore_wl2_window_keyboard_state_set(mEcoreWindow, static_cast(state + 1)); + changed = true; + } + } + else if(conformantPart == TIZEN_POLICY_CONFORMANT_PART_CLIPBOARD) + { + ecore_wl2_window_clipboard_geometry_get(mEcoreWindow, &originalX, &originalY, &originalWidth, &originalHeight); + if((originalX != x) || (originalY != y) || (originalWidth != w) || (originalHeight != h)) + { + ecore_wl2_window_clipboard_geometry_set(mEcoreWindow, x, y, w, h); + changed = true; + } + + /** + * The given state is based on the visibility value of clipboard window. + * Thus we need to add 1 to it before comparing with clipboard state. + */ + Ecore_Wl2_Clipboard_State clipState = ecore_wl2_window_clipboard_state_get(mEcoreWindow); + if((state + 1) != clipState) + { + ecore_wl2_window_clipboard_state_set(mEcoreWindow, static_cast(state + 1)); + changed = true; + } + } + + if(changed) + { + Ecore_Wl2_Event_Conformant_Change *ev = static_cast(calloc(1, sizeof(Ecore_Wl2_Event_Conformant_Change))); + + if(!ev) + { + return; + } + ev->win = GetNativeWindowId(); + ev->part_type = static_cast(conformantPart); + ev->state = state; + ecore_event_add(ECORE_WL2_EVENT_CONFORMANT_CHANGE, ev, NULL, NULL); + } + + DALI_LOG_INFO(gWindowBaseLogFilter, Debug::General, "WindowBaseEcoreWl2::TizenPolicyConformantArea: conformantPart = %u, state = %u, position = (%d, %d), size = (%d, %d)\n", conformantPart, state, x, y, w, h); +} + void WindowBaseEcoreWl2::TizenPolicyNotificationChangeDone(void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, int32_t level, uint32_t state) { mNotificationLevel = level; diff --git a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.h b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.h index b70afbc..13b1271 100644 --- a/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.h +++ b/dali/internal/window-system/tizen-wayland/ecore-wl2/window-base-ecore-wl2.h @@ -171,6 +171,11 @@ public: void OnEcoreEventWindowRedrawRequest(); /** + * @brief Called when a conformant is changed. + */ + void OnEcoreEventConformantChange(void* event); + + /** * @brief Called when window's auxiliary is changed then display server send the changed message. * * @param[in] auxiliary's message data. It has key, value and integer list data. @@ -211,6 +216,11 @@ public: void RegistryGlobalCallbackRemove(void* data, struct wl_registry* registry, uint32_t id); /** + * @brief TizenPolicyConformantArea + */ + void TizenPolicyConformantArea(void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, uint32_t conformantPart, uint32_t state, int32_t x, int32_t y, int32_t w, int32_t h); + + /** * @brief TizenPolicyNotificationChangeDone */ void TizenPolicyNotificationChangeDone(void* data, struct tizen_policy* tizenPolicy, struct wl_surface* surface, int32_t level, uint32_t state); diff --git a/dali/public-api/adaptor-framework/window-enumerations.h b/dali/public-api/adaptor-framework/window-enumerations.h index b33132d..cf81add 100644 --- a/dali/public-api/adaptor-framework/window-enumerations.h +++ b/dali/public-api/adaptor-framework/window-enumerations.h @@ -129,6 +129,25 @@ enum class WindowResizeDirection BOTTOM_RIGHT = 8 ///< Start resizing window to the bottom-right edge. }; +/** + * @brief Enumeration of window insets part type. + */ +enum class WindowInsetsPartType +{ + STATUS_BAR = 0, ///< Status bar + KEYBOARD, ///< Keyboard + CLIPBOARD, ///< Clipboard +}; + +/** + * @brief Enumeration of window insets part state. + */ +enum class WindowInsetsPartState +{ + INVISIBLE = 0, ///< Invisible + VISIBLE, ///< Visible +}; + } // namespace Dali #endif // DALI_WINDOW_ENUMERATIONS_H -- 2.7.4