From: tscholb Date: Thu, 20 Jan 2022 12:35:44 +0000 (+0900) Subject: Add SyncKeyEvent for Widget X-Git-Tag: dali_2.1.15~3^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F70%2F271970%2F16;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git Add SyncKeyEvent for Widget In the past, the WidgetApplication used the keyEvent using the screen connector's API. However, this API is not synchronized. So WidgetView cannot get feedback from WidgetApplication. To solve this problem, AppFramework provides a new API to send keyEvent with sync. So we add a new callback to use this API. Plus, Widget Application also needs a new API to send an alarm to the WidgetView when it uses a keyEvent. So we add a new API called SetUsingKeyEvent(). Change-Id: I92c00b57dfe1c72baadb9fc082e253b1a0385d14 --- diff --git a/build/tizen/deps-check.cmake b/build/tizen/deps-check.cmake index 8eecbda..a13dc7d 100755 --- a/build/tizen/deps-check.cmake +++ b/build/tizen/deps-check.cmake @@ -369,6 +369,7 @@ IF( enable_appfw ) ${ECORE_IMF_CFLAGS} ${FRIBIDI_CFLAGS} ${COMPONENT_BASED_CORE_BASE_CFLAGS} + ${SCREENCONNECTORPROVIDER_CFLAGS} ) SET( DALI_LDFLAGS ${DALI_LDFLAGS} @@ -384,6 +385,7 @@ IF( enable_appfw ) ${ECORE_IMF_LDFLAGS} ${FRIBIDI_LDFLAGS} ${COMPONENT_BASED_CORE_BASE_LDFLAGS} + ${SCREENCONNECTORPROVIDER_LDFLAGS} ) ELSE() SET( DALI_CFLAGS ${DALI_CFLAGS} @@ -440,11 +442,9 @@ IF( WEARABLE_PROFILE ) SET( DALI_CFLAGS ${DALI_CFLAGS} ${HAPTIC_CFLAGS} ${EFL_ASSIST_CFLAGS} - ${SCREENCONNECTORPROVIDER_CFLAGS} ${APPCORE_WATCH_CFLAGS} ) SET( DALI_LDFLAGS ${DALI_LDFLAGS} - ${SCREENCONNECTORPROVIDER_LDFLAGS} ${APPCORE_WATCH_LDFLAGS} ) ENDIF() diff --git a/dali/internal/system/common/widget-controller.h b/dali/internal/system/common/widget-controller.h index 99b8995..7353f9b 100644 --- a/dali/internal/system/common/widget-controller.h +++ b/dali/internal/system/common/widget-controller.h @@ -40,6 +40,31 @@ public: * Set content information to widget framework */ virtual void SetContentInfo(const std::string& contentInfo) = 0; + + /** + * Check Widget is using key + */ + virtual bool IsKeyEventUsing() const = 0; + + /** + * Set the flag that widget is using keyEvent + */ + virtual void SetUsingKeyEvent(bool flag) = 0; + + /** + * Set the Information of widget + */ + virtual void SetInformation(Dali::Window window, const std::string& widgetId) = 0; + + /** + * Get the window + */ + virtual Dali::Window GetWindow() const = 0; + + /** + * Get the widget id + */ + virtual std::string GetWidgetId() const = 0; }; } // namespace Adaptor diff --git a/dali/internal/system/tizen-wayland/widget-application-impl-tizen.cpp b/dali/internal/system/tizen-wayland/widget-application-impl-tizen.cpp index 227284a..92c7e6c 100644 --- a/dali/internal/system/tizen-wayland/widget-application-impl-tizen.cpp +++ b/dali/internal/system/tizen-wayland/widget-application-impl-tizen.cpp @@ -24,6 +24,7 @@ #include #include #include +#include // EXTERNAL INCLUDES #include @@ -35,6 +36,43 @@ namespace Internal { namespace { +/** + * This Api is called when widget viewer send keyEvent. + * In this API, widget framework create a new keyEvent, find the proper widget and send this event. + * Finally widget framework receive feedback from widget. + */ +bool OnKeyEventCallback(const char *id, screen_connector_event_type_e eventType, int keyCode, const char *keyName, long long cls, long long subcls, const char* identifier, long long timestamp, void *userData) +{ + Dali::Internal::Adaptor::WidgetApplicationTizen* application = static_cast(userData); + + // Create new key for widget + Dali::KeyEvent::State state = Dali::KeyEvent::DOWN; + if(eventType == SCREEN_CONNECTOR_EVENT_TYPE_KEY_DOWN) + { + state = Dali::KeyEvent::DOWN; + } + else if(eventType == SCREEN_CONNECTOR_EVENT_TYPE_KEY_UP) + { + state = Dali::KeyEvent::UP; + } + + bool consumed = true; + std::string keyEventName = std::string(keyName); + Dali::KeyEvent event = Dali::DevelKeyEvent::New(keyEventName, "", "", keyCode, 0, timestamp, state, "", "", Device::Class::NONE, Device::Subclass::NONE); + + if(application) + { + std::string widgetId = std::string(id); + widget_base_instance_h instanceHandle = application->GetWidgetInstanceFromWidgetId(widgetId); + if(instanceHandle) + { + consumed = application->FeedKeyEvent(instanceHandle, event); + } + } + + return consumed; +} + int OnInstanceInit(widget_base_instance_h instanceHandle, bundle* content, int w, int h, void* classData) { char* id; @@ -79,11 +117,12 @@ int OnInstanceInit(widget_base_instance_h instanceHandle, bundle* content, int w Dali::WidgetApplication::CreateWidgetFunction createFunction = pair.second; Dali::Widget widgetInstance = createFunction(pair.first); - application->AddWidget(instanceHandle, widgetInstance, window); Dali::Internal::Adaptor::Widget::Impl* widgetImpl = new Dali::Internal::Adaptor::WidgetImplTizen(instanceHandle); Internal::Adaptor::GetImplementation(widgetInstance).SetImpl(widgetImpl); + application->AddWidget(instanceHandle, widgetInstance, window, std::string(id)); + std::string encodedContentString = ""; if(bundle_get_count(content)) @@ -98,6 +137,9 @@ int OnInstanceInit(widget_base_instance_h instanceHandle, bundle* content, int w Internal::Adaptor::GetImplementation(widgetInstance).OnCreate(encodedContentString, window); + // connect keyEvent for widget + application->ConnectKeyEvent(window); + return 0; } @@ -172,7 +214,7 @@ int OnInstanceResize(widget_base_instance_h instanceHandle, int w, int h, void* // Get Dali::Widget instance. Dali::Widget widgetInstance = application->GetWidget(instanceHandle); - Dali::Window window = application->GetWindowFromWidget(instanceHandle); + Dali::Window window = application->GetWindowFromWidget(widgetInstance); window.SetSize(Dali::Window::WindowSize(w, h)); Internal::Adaptor::GetImplementation(widgetInstance).OnResize(window); @@ -225,7 +267,9 @@ WidgetApplicationPtr WidgetApplicationTizen::New( } WidgetApplicationTizen::WidgetApplicationTizen(int* argc, char** argv[], const std::string& stylesheet) -: WidgetApplication(argc, argv, stylesheet) +: WidgetApplication(argc, argv, stylesheet), + mConnectedKeyEvent(false), + mReceivedKeyEvent(false) { } @@ -269,10 +313,10 @@ WidgetApplicationTizen::CreateWidgetFunctionPair WidgetApplicationTizen::GetWidg return CreateWidgetFunctionPair("", NULL); } -void WidgetApplicationTizen::AddWidget(widget_base_instance_h widgetBaseInstance, Dali::Widget widget, Dali::Window window) +void WidgetApplicationTizen::AddWidget(widget_base_instance_h widgetBaseInstance, Dali::Widget widget, Dali::Window window, const std::string& widgetId) { mWidgetInstanceContainer.push_back(WidgetInstancePair(widgetBaseInstance, widget)); - mWindowInstanceContainer.push_back(WindowInstancePair(widgetBaseInstance, window)); + Internal::Adaptor::GetImplementation(widget).SetInformation(window, widgetId); } Dali::Widget WidgetApplicationTizen::GetWidget(widget_base_instance_h widgetBaseInstance) const @@ -298,29 +342,29 @@ void WidgetApplicationTizen::DeleteWidget(widget_base_instance_h widgetBaseInsta { mWidgetInstanceContainer.erase(widgetInstance); } +} - // Delete WindowInstance - auto windowInstance = std::find_if(mWindowInstanceContainer.begin(), - mWindowInstanceContainer.end(), - [widgetBaseInstance](WindowInstancePair pair) { return (pair.first == widgetBaseInstance); }); - - if(windowInstance != mWindowInstanceContainer.end()) +Dali::Window WidgetApplicationTizen::GetWindowFromWidget(Dali::Widget widgetInstance) const +{ + if(widgetInstance) { - mWindowInstanceContainer.erase(windowInstance); + return Internal::Adaptor::GetImplementation(widgetInstance).GetWindow(); } + + return Dali::Window(); } -Dali::Window WidgetApplicationTizen::GetWindowFromWidget(widget_base_instance_h widgetBaseInstance) const +widget_base_instance_h WidgetApplicationTizen::GetWidgetInstanceFromWidgetId(std::string& widgetId) const { - for(auto&& iter : mWindowInstanceContainer) + for(auto&& iter : mWidgetInstanceContainer) { - if((iter).first == widgetBaseInstance) + if(widgetId == Internal::Adaptor::GetImplementation((iter).second).GetWidgetId()) { - Dali::Window ret = (iter).second; - return ret; + return (iter).first; } } - return Dali::Window(); + + return nullptr; } int WidgetApplicationTizen::GetWidgetCount() @@ -328,6 +372,49 @@ int WidgetApplicationTizen::GetWidgetCount() return mWidgetInstanceContainer.size(); } +void WidgetApplicationTizen::ConnectKeyEvent(Dali::Window window) +{ + if(!mConnectedKeyEvent) + { + screen_connector_provider_set_key_event_cb(OnKeyEventCallback, this); + mConnectedKeyEvent = true; + } + window.KeyEventSignal().Connect(this, &WidgetApplicationTizen::OnWindowKeyEvent); +} + +void WidgetApplicationTizen::OnWindowKeyEvent(const Dali::KeyEvent& event) +{ + //If Widget Application consume key event, this api is not called. + mReceivedKeyEvent = true; +} + +bool WidgetApplicationTizen::FeedKeyEvent(widget_base_instance_h instanceHandle, const Dali::KeyEvent& keyEvent) +{ + bool consumed = true; + + // Check if application consume key event + Dali::Widget widgetInstance = GetWidget(instanceHandle); + if(widgetInstance) + { + Dali::Window window = GetWindowFromWidget(widgetInstance); + + // Reset the state of key received + mReceivedKeyEvent = false; + + // Feed the keyEvent to widget window + DevelWindow::FeedKeyEvent(window, keyEvent); + + // if the application is not using a key event, verify that the window in the widget has received a key event. + if(Internal::Adaptor::GetImplementation(widgetInstance).IsKeyEventUsing() == false) + { + // if the window has received a key event, widget need to consume its key event + consumed = (mReceivedKeyEvent) ? false : true; + } + } + + return consumed; +} + void WidgetApplicationTizen::OnInit() { WidgetApplication::OnInit(); diff --git a/dali/internal/system/tizen-wayland/widget-application-impl-tizen.h b/dali/internal/system/tizen-wayland/widget-application-impl-tizen.h index f2462bd..80166bd 100644 --- a/dali/internal/system/tizen-wayland/widget-application-impl-tizen.h +++ b/dali/internal/system/tizen-wayland/widget-application-impl-tizen.h @@ -20,6 +20,7 @@ // EXTERNAL INCLUDES #include +#include // INTERNAL INCLUDES #include @@ -40,7 +41,7 @@ typedef IntrusivePtr WidgetApplicationPtr; /** * Implementation of the WidgetApplication class. */ -class WidgetApplicationTizen : public WidgetApplication +class WidgetApplicationTizen : public WidgetApplication, public ConnectionTracker { public: typedef std::pair CreateWidgetFunctionPair; @@ -78,7 +79,7 @@ public: /** * Add widget_base_instance_h - Widget instance pair to container. */ - void AddWidget(widget_base_instance_h widgetBaseInstance, Dali::Widget widget, Dali::Window window); + void AddWidget(widget_base_instance_h widgetBaseInstance, Dali::Widget widget, Dali::Window window, const std::string& widgetId); /** * Find and get Widget instance in container by widget_base_instance_h. @@ -93,13 +94,42 @@ public: /** * Find and get Window instance in container by widget_base_instance_h. */ - Dali::Window GetWindowFromWidget(widget_base_instance_h widgetBaseInstance) const; + Dali::Window GetWindowFromWidget(Dali::Widget widget) const; /** + * Find and get widget_base_instance in container by widget id. + */ + widget_base_instance_h GetWidgetInstanceFromWidgetId(std::string& widgetId) const; + /** * Get the number of created widget. */ int32_t GetWidgetCount(); + /** + * @brief connect the keyEvent for window + * + * @param[in] window window for connecting keyEvent + */ + void ConnectKeyEvent(Dali::Window window); + + /** + * @brief Callback for widget window + * + * If Widget Application consume key event, this api is not called. + * + * @param[in] event The key event. + */ + void OnWindowKeyEvent(const Dali::KeyEvent& event); + + /** + * @brief Feed keyEvent to Widget. + * + * @param[in] instanceHandle the handle of widget instance + * @param[in] keyEvent The key event for widget + * @return True if widget consume keyEvent, false otherwise. + */ + bool FeedKeyEvent(widget_base_instance_h instanceHandle, const Dali::KeyEvent& keyEvent); + protected: /** * Private Constructor @@ -124,9 +154,8 @@ private: CreateWidgetFunctionContainer mCreateWidgetFunctionContainer; WidgetInstanceContainer mWidgetInstanceContainer; - typedef std::pair WindowInstancePair; - typedef std::vector WindowInstanceContainer; - WindowInstanceContainer mWindowInstanceContainer; + bool mConnectedKeyEvent; // Check if keyEvent is connected + bool mReceivedKeyEvent; // Check if application receive keyEvent }; } // namespace Adaptor diff --git a/dali/internal/system/tizen-wayland/widget-controller-tizen.cpp b/dali/internal/system/tizen-wayland/widget-controller-tizen.cpp index d4c4498..efe9f16 100644 --- a/dali/internal/system/tizen-wayland/widget-controller-tizen.cpp +++ b/dali/internal/system/tizen-wayland/widget-controller-tizen.cpp @@ -30,7 +30,10 @@ namespace Adaptor { WidgetImplTizen::WidgetImplTizen(widget_base_instance_h instanceHandle) : Widget::Impl(), - mInstanceHandle(instanceHandle) + mInstanceHandle(instanceHandle), + mWindow(), + mWidgetId(), + mUsingKeyEvent(false) { } @@ -50,6 +53,32 @@ void WidgetImplTizen::SetContentInfo(const std::string& contentInfo) bundle_free(contentBundle); } +bool WidgetImplTizen::IsKeyEventUsing() const +{ + return mUsingKeyEvent; +} + +void WidgetImplTizen::SetUsingKeyEvent(bool flag) +{ + mUsingKeyEvent = flag; +} + +void WidgetImplTizen::SetInformation(Dali::Window window, const std::string& widgetId) +{ + mWindow = window; + mWidgetId = widgetId; +} + +Dali::Window WidgetImplTizen::GetWindow() const +{ + return mWindow; +} + +std::string WidgetImplTizen::GetWidgetId() const +{ + return mWidgetId; +} + } // namespace Adaptor } // namespace Internal diff --git a/dali/internal/system/tizen-wayland/widget-controller-tizen.h b/dali/internal/system/tizen-wayland/widget-controller-tizen.h index de6ae1d..5877f42 100644 --- a/dali/internal/system/tizen-wayland/widget-controller-tizen.h +++ b/dali/internal/system/tizen-wayland/widget-controller-tizen.h @@ -54,8 +54,36 @@ public: */ void SetContentInfo(const std::string& contentInfo) override; + /** + * Check Widget is using key + */ + bool IsKeyEventUsing() const override; + + /** + * Set the flag that widget is using keyEvent + */ + void SetUsingKeyEvent(bool flag) override; + + /** + * Set the Information of widget + */ + void SetInformation(Dali::Window window, const std::string& widgetId) override; + + /** + * Get the window + */ + Dali::Window GetWindow() const override; + + /** + * Get the widget id + */ + std::string GetWidgetId() const override; + private: widget_base_instance_h mInstanceHandle; + Dali::Window mWindow; + std::string mWidgetId; + bool mUsingKeyEvent; }; } // namespace Adaptor diff --git a/dali/internal/system/ubuntu-x11/widget-controller-x.cpp b/dali/internal/system/ubuntu-x11/widget-controller-x.cpp index dc40cdd..b0f9a50 100644 --- a/dali/internal/system/ubuntu-x11/widget-controller-x.cpp +++ b/dali/internal/system/ubuntu-x11/widget-controller-x.cpp @@ -36,6 +36,28 @@ void WidgetImplUbuntu::SetContentInfo(const std::string& contentInfo) { } +bool WidgetImplUbuntu::IsKeyEventUsing() const +{ +} + +void WidgetImplUbuntu::SetUsingKeyEvent(bool flag) +{ +} + +void WidgetImplUbuntu::SetInformation(Dali::Window window, const std::string& widgetId) +{ +} + +Dali::Window WidgetImplUbuntu::GetWindow() const +{ + return Dali::Window(); +} + +std::string WidgetImplUbuntu::GetWidgetId() const +{ + return std::string(); +} + } // namespace Adaptor } // namespace Internal diff --git a/dali/internal/system/ubuntu-x11/widget-controller-x.h b/dali/internal/system/ubuntu-x11/widget-controller-x.h index 685e52a..798e066 100644 --- a/dali/internal/system/ubuntu-x11/widget-controller-x.h +++ b/dali/internal/system/ubuntu-x11/widget-controller-x.h @@ -51,6 +51,31 @@ public: * Set content information to widget framework */ void SetContentInfo(const std::string& contentInfo) override; + + /** + * Check Widget is using key + */ + bool IsKeyEventUsing() const override; + + /** + * Set the flag that widget is using keyEvent + */ + void SetUsingKeyEvent(bool flag) override; + + /** + * Set the Information of widget + */ + void SetInformation(Dali::Window window, const std::string& widgetId) override; + + /** + * Get the window + */ + Dali::Window GetWindow() const override; + + /** + * Get the widget id + */ + std::string GetWidgetId() const override; }; } // namespace Adaptor diff --git a/dali/internal/system/windows/widget-controller-win.cpp b/dali/internal/system/windows/widget-controller-win.cpp index 7dd6686..bb70910 100644 --- a/dali/internal/system/windows/widget-controller-win.cpp +++ b/dali/internal/system/windows/widget-controller-win.cpp @@ -36,6 +36,28 @@ void WidgetImplWin::SetContentInfo(const std::string& contentInfo) { } +bool WidgetImplWin::IsKeyEventUsing() const +{ +} + +void WidgetImplWin::SetUsingKeyEvent(bool flag) +{ +} + +void WidgetImplWin::SetInformation(Dali::Window window, const std::string& widgetId) +{ +} + +Dali::Window WidgetImplWin::GetWindow() const +{ + return Dali::Window(); +} + +std::string WidgetImplWin::GetWidgetId() const +{ + return std::string(); +} + } // namespace Adaptor } // namespace Internal diff --git a/dali/internal/system/windows/widget-controller-win.h b/dali/internal/system/windows/widget-controller-win.h index 63fe4e4..de1e896 100644 --- a/dali/internal/system/windows/widget-controller-win.h +++ b/dali/internal/system/windows/widget-controller-win.h @@ -51,6 +51,31 @@ public: * Set content information to widget framework */ void SetContentInfo(const std::string& contentInfo) override; + + /** + * Check Widget is using key + */ + bool IsKeyEventUsing() const override; + + /** + * Set the flag that widget is using keyEvent + */ + void SetUsingKeyEvent(bool flag) override; + + /** + * Set the Information of widget + */ + void SetInformation(Dali::Window window, const std::string& widgetId) override; + + /** + * Get the window + */ + Dali::Window GetWindow() const override; + + /** + * Get the widget id + */ + std::string GetWidgetId() const override; }; } // namespace Adaptor diff --git a/dali/public-api/adaptor-framework/widget-impl.cpp b/dali/public-api/adaptor-framework/widget-impl.cpp index 6df39a0..8ac4d30 100644 --- a/dali/public-api/adaptor-framework/widget-impl.cpp +++ b/dali/public-api/adaptor-framework/widget-impl.cpp @@ -87,11 +87,59 @@ void Widget::SetContentInfo(const std::string& contentInfo) } } +bool Widget::IsKeyEventUsing() const +{ + if(mImpl != nullptr) + { + return mImpl->IsKeyEventUsing(); + } + + //if mImpl is null, return default value + return false; +} + +void Widget::SetUsingKeyEvent(bool flag) +{ + if(mImpl != nullptr) + { + mImpl->SetUsingKeyEvent(flag); + } +} + void Widget::SetImpl(Impl* impl) { mImpl = impl; } + +void Widget::SetInformation(Dali::Window window, const std::string& widgetId) +{ + if(mImpl != nullptr) + { + mImpl->SetInformation(window, widgetId); + } +} + +Dali::Window Widget::GetWindow() const +{ + if(mImpl != nullptr) + { + return mImpl->GetWindow(); + } + + return Dali::Window(); +} + +std::string Widget::GetWidgetId() const +{ + if(mImpl != nullptr) + { + return mImpl->GetWidgetId(); + } + + return std::string(); +} + Internal::Adaptor::Widget& GetImplementation(Dali::Widget& widget) { DALI_ASSERT_ALWAYS(widget && "widget handle is empty"); diff --git a/dali/public-api/adaptor-framework/widget-impl.h b/dali/public-api/adaptor-framework/widget-impl.h index 3e7e87a..06e990f 100644 --- a/dali/public-api/adaptor-framework/widget-impl.h +++ b/dali/public-api/adaptor-framework/widget-impl.h @@ -131,6 +131,22 @@ public: */ void SetContentInfo(const std::string& contentInfo); + /** + * @brief Check Widget is using key + * + * widget can set flag to SetUsingKeyEvent + * + * @return True if Widget is using key + */ + bool IsKeyEventUsing() const; + + /** + * @brief Set the flag that widget is using keyEvent + * + * @param[in] flag The flag to set. + */ + void SetUsingKeyEvent(bool flag); + protected: /** * @brief WidgetImpl constructor @@ -152,6 +168,28 @@ public: */ void SetImpl(Impl* impl); + /** + * @brief Set the Information of widget + * + * @param window The window to set the information of widget + * @param widgetId The Id of widget + */ + void SetInformation(Dali::Window window, const std::string& widgetId); + + /** + * @brief Get the Window of widget + * + * @return the window of widget + */ + Dali::Window GetWindow() const; + + /** + * @brief Get the id of widget + * + * @return the id of widget + */ + std::string GetWidgetId() const; + private: Impl* mImpl; diff --git a/packaging/dali-adaptor.spec b/packaging/dali-adaptor.spec index e59f8e1..702a44f 100644 --- a/packaging/dali-adaptor.spec +++ b/packaging/dali-adaptor.spec @@ -36,9 +36,9 @@ BuildRequires: pkgconfig(libtzplatform-config) %if "%{?profile}" != "mobile" && "%{?profile}" != "tv" && "%{?profile}" != "ivi" && "%{?profile}" != "common" BuildRequires: pkgconfig(capi-appfw-watch-application) BuildRequires: pkgconfig(appcore-watch) -BuildRequires: pkgconfig(screen_connector_provider) %endif +BuildRequires: pkgconfig(screen_connector_provider) BuildRequires: pkgconfig(gles20) BuildRequires: pkgconfig(glesv2) BuildRequires: pkgconfig(ttrace)