diff --git a/shell/platform/tizen/BUILD.gn b/shell/platform/tizen/BUILD.gn index 44ecd83653f7a..ddd3dd6809cd1 100644 --- a/shell/platform/tizen/BUILD.gn +++ b/shell/platform/tizen/BUILD.gn @@ -169,6 +169,7 @@ template("embedder") { "capi-base-common", "capi-system-info", "capi-system-system-settings", + "capi-ui-efl-util", "dlog", "feedback", "tbm", @@ -201,7 +202,10 @@ template("embedder") { "tizen_vsync_waiter.cc", ] - libs += [ "ecore_wl2" ] + libs += [ + "ecore_wl2", + "tizen-extension-client", + ] } public_deps = [ ":flutter_engine" ] diff --git a/shell/platform/tizen/flutter_tizen.cc b/shell/platform/tizen/flutter_tizen.cc index 50c609bcbfd3a..ddfd81698c374 100644 --- a/shell/platform/tizen/flutter_tizen.cc +++ b/shell/platform/tizen/flutter_tizen.cc @@ -38,7 +38,7 @@ FlutterDesktopEngineRef FlutterDesktopRunEngine( engine->InitializeRenderer( window_properties.x, window_properties.y, window_properties.width, window_properties.height, window_properties.transparent, - window_properties.focusable); + window_properties.focusable, window_properties.top_level); } if (!engine->RunEngine(engine_properties.entrypoint)) { FT_LOG(Error) << "Failed to start the Flutter engine."; diff --git a/shell/platform/tizen/flutter_tizen_engine.cc b/shell/platform/tizen/flutter_tizen_engine.cc index 4727fafd5273d..43ecf846ffe15 100644 --- a/shell/platform/tizen/flutter_tizen_engine.cc +++ b/shell/platform/tizen/flutter_tizen_engine.cc @@ -88,12 +88,13 @@ void FlutterTizenEngine::InitializeRenderer(int32_t x, int32_t width, int32_t height, bool transparent, - bool focusable) { + bool focusable, + bool top_level) { TizenRenderer::WindowGeometry geometry = {x, y, width, height}; #ifdef TIZEN_RENDERER_EVAS_GL - renderer_ = std::make_unique(geometry, transparent, - focusable, *this); + renderer_ = std::make_unique( + geometry, transparent, focusable, top_level, *this); render_loop_ = std::make_unique( std::this_thread::get_id(), // main thread @@ -105,8 +106,8 @@ void FlutterTizenEngine::InitializeRenderer(int32_t x, }, renderer_.get()); #else - renderer_ = std::make_unique(geometry, transparent, - focusable, *this); + renderer_ = std::make_unique( + geometry, transparent, focusable, top_level, *this); tizen_vsync_waiter_ = std::make_unique(this); #endif diff --git a/shell/platform/tizen/flutter_tizen_engine.h b/shell/platform/tizen/flutter_tizen_engine.h index f9b03864d00c5..51bd0f9b3a6e6 100644 --- a/shell/platform/tizen/flutter_tizen_engine.h +++ b/shell/platform/tizen/flutter_tizen_engine.h @@ -67,7 +67,8 @@ class FlutterTizenEngine : public TizenRenderer::Delegate { int32_t width, int32_t height, bool transparent, - bool focusable); + bool focusable, + bool top_level); // Starts running the engine with the given entrypoint. If null, defaults to // main(). diff --git a/shell/platform/tizen/flutter_tizen_engine_unittest.cc b/shell/platform/tizen/flutter_tizen_engine_unittest.cc index 6dabbbb07db9a..8a9f09cff8d1a 100644 --- a/shell/platform/tizen/flutter_tizen_engine_unittest.cc +++ b/shell/platform/tizen/flutter_tizen_engine_unittest.cc @@ -44,7 +44,7 @@ class FlutterTizenEngineTestHeaded : public FlutterTizenEngineTest { protected: void SetUp() { FlutterTizenEngineTest::SetUp(); - engine_->InitializeRenderer(0, 0, 800, 600, false, true); + engine_->InitializeRenderer(0, 0, 800, 600, false, true, false); } }; diff --git a/shell/platform/tizen/public/flutter_tizen.h b/shell/platform/tizen/public/flutter_tizen.h index f7e1f90024765..0f14c8914b91b 100644 --- a/shell/platform/tizen/public/flutter_tizen.h +++ b/shell/platform/tizen/public/flutter_tizen.h @@ -38,6 +38,8 @@ typedef struct { bool transparent; // Whether the window should be focusable or not. bool focusable; + // Whether the window should be on top layer or not. + bool top_level; } FlutterDesktopWindowProperties; // Properties for configuring a Flutter engine instance. diff --git a/shell/platform/tizen/tizen_renderer.cc b/shell/platform/tizen/tizen_renderer.cc index 5bd94fd6e6bda..e04082634fb84 100644 --- a/shell/platform/tizen/tizen_renderer.cc +++ b/shell/platform/tizen/tizen_renderer.cc @@ -9,10 +9,12 @@ namespace flutter { TizenRenderer::TizenRenderer(WindowGeometry geometry, bool transparent, bool focusable, + bool top_level, Delegate& delegate) : initial_geometry_(geometry), transparent_(transparent), focusable_(focusable), + top_level_(top_level), delegate_(delegate) {} TizenRenderer::~TizenRenderer() = default; diff --git a/shell/platform/tizen/tizen_renderer.h b/shell/platform/tizen/tizen_renderer.h index 06358041be9eb..c8dc232cb9d37 100644 --- a/shell/platform/tizen/tizen_renderer.h +++ b/shell/platform/tizen/tizen_renderer.h @@ -50,11 +50,13 @@ class TizenRenderer { explicit TizenRenderer(WindowGeometry geometry, bool transparent, bool focusable, + bool top_level, Delegate& delegate); WindowGeometry initial_geometry_; bool transparent_; bool focusable_; + bool top_level_; Delegate& delegate_; bool is_valid_ = false; diff --git a/shell/platform/tizen/tizen_renderer_ecore_wl2.cc b/shell/platform/tizen/tizen_renderer_ecore_wl2.cc index eb9d0b1d109a1..75c91dd1cf295 100644 --- a/shell/platform/tizen/tizen_renderer_ecore_wl2.cc +++ b/shell/platform/tizen/tizen_renderer_ecore_wl2.cc @@ -14,8 +14,9 @@ namespace flutter { TizenRendererEcoreWl2::TizenRendererEcoreWl2(WindowGeometry geometry, bool transparent, bool focusable, + bool top_level, Delegate& delegate) - : TizenRenderer(geometry, transparent, focusable, delegate) { + : TizenRenderer(geometry, transparent, focusable, top_level, delegate) { InitializeRenderer(); } @@ -296,7 +297,18 @@ bool TizenRendererEcoreWl2::SetupEcoreWlWindow(int32_t width, int32_t height) { ecore_wl2_window_ = ecore_wl2_window_new(ecore_wl2_display_, nullptr, x, y, width, height); - ecore_wl2_window_type_set(ecore_wl2_window_, ECORE_WL2_WINDOW_TYPE_TOPLEVEL); + + // Change the window type to use the tizen policy for notification window + // according to top_level_. + // Note: ECORE_WL2_WINDOW_TYPE_TOPLEVEL is similar to "ELM_WIN_BASIC" and it + // does not mean that the window always will be overlaid on other apps :( + ecore_wl2_window_type_set(ecore_wl2_window_, + top_level_ ? ECORE_WL2_WINDOW_TYPE_NOTIFICATION + : ECORE_WL2_WINDOW_TYPE_TOPLEVEL); + if (top_level_) { + SetTizenPolicyNotificationLevel(TIZEN_POLICY_LEVEL_TOP); + } + ecore_wl2_window_position_set(ecore_wl2_window_, x, y); ecore_wl2_window_aux_hint_add(ecore_wl2_window_, 0, "wm.policy.win.user.geometry", "1"); @@ -564,4 +576,34 @@ bool TizenRendererEcoreWl2::IsSupportedExtention(const char* name) { return false; } +void TizenRendererEcoreWl2::SetTizenPolicyNotificationLevel(int level) { + Eina_Iterator* iter = ecore_wl2_display_globals_get(ecore_wl2_display_); + struct wl_registry* registry = + ecore_wl2_display_registry_get(ecore_wl2_display_); + + if (iter && registry) { + Ecore_Wl2_Global* global = nullptr; + + // Retrieve global objects to bind tizen policy + EINA_ITERATOR_FOREACH(iter, global) { + if (strcmp(global->interface, tizen_policy_interface.name) == 0) { + tizen_policy_ = static_cast( + wl_registry_bind(registry, global->id, &tizen_policy_interface, 1)); + break; + } + } + } + eina_iterator_free(iter); + + if (tizen_policy_ == nullptr) { + FT_LOG(Error) + << "Failed to initialize the tizen policy handle, the top_level " + "attribute is ignored."; + return; + } + + tizen_policy_set_notification_level( + tizen_policy_, ecore_wl2_window_surface_get(ecore_wl2_window_), level); +} + } // namespace flutter diff --git a/shell/platform/tizen/tizen_renderer_ecore_wl2.h b/shell/platform/tizen/tizen_renderer_ecore_wl2.h index 7924995bcf2d2..df4b0c35f83c5 100644 --- a/shell/platform/tizen/tizen_renderer_ecore_wl2.h +++ b/shell/platform/tizen/tizen_renderer_ecore_wl2.h @@ -8,6 +8,8 @@ #define EFL_BETA_API_SUPPORT #include #include +#include + #include #include "flutter/shell/platform/tizen/tizen_renderer.h" @@ -19,6 +21,7 @@ class TizenRendererEcoreWl2 : public TizenRenderer { explicit TizenRendererEcoreWl2(WindowGeometry geometry, bool transparent, bool focusable, + bool top_level, Delegate& delegate); virtual ~TizenRendererEcoreWl2(); @@ -61,6 +64,7 @@ class TizenRendererEcoreWl2 : public TizenRenderer { bool ChooseEGLConfiguration(); void PrintEGLError(); void DestroyEglSurface(); + void SetTizenPolicyNotificationLevel(int level); static Eina_Bool RotationEventCb(void* data, int type, void* event); void SendRotationChangeDone(); @@ -77,6 +81,8 @@ class TizenRendererEcoreWl2 : public TizenRenderer { EGLSurface egl_resource_surface_ = EGL_NO_SURFACE; std::string egl_extention_str_; + + tizen_policy* tizen_policy_ = nullptr; }; } // namespace flutter diff --git a/shell/platform/tizen/tizen_renderer_evas_gl.cc b/shell/platform/tizen/tizen_renderer_evas_gl.cc index ad8175184ea52..0c71a98ff6753 100644 --- a/shell/platform/tizen/tizen_renderer_evas_gl.cc +++ b/shell/platform/tizen/tizen_renderer_evas_gl.cc @@ -10,13 +10,18 @@ EVAS_GL_GLOBAL_GLES3_DEFINE(); #include "flutter/shell/platform/tizen/logger.h" +#ifndef __X64_SHELL__ +#include +#endif + namespace flutter { TizenRendererEvasGL::TizenRendererEvasGL(WindowGeometry geometry, bool transparent, bool focusable, + bool top_level, Delegate& delegate) - : TizenRenderer(geometry, transparent, focusable, delegate) { + : TizenRenderer(geometry, transparent, focusable, top_level, delegate) { InitializeRenderer(); // Clear once to remove noise. @@ -639,10 +644,17 @@ Evas_Object* TizenRendererEvasGL::SetupEvasWindow(int32_t* width, int32_t* height) { elm_config_accel_preference_set("hw:opengl"); - evas_window_ = elm_win_add(NULL, NULL, ELM_WIN_BASIC); + evas_window_ = elm_win_add(NULL, NULL, + top_level_ ? ELM_WIN_NOTIFICATION : ELM_WIN_BASIC); if (!evas_window_) { return nullptr; } +#ifndef __X64_SHELL__ + if (top_level_) { + efl_util_set_notification_window_level(evas_window_, + EFL_UTIL_NOTIFICATION_LEVEL_TOP); + } +#endif auto* ecore_evas = ecore_evas_ecore_evas_get(evas_object_evas_get(evas_window_)); diff --git a/shell/platform/tizen/tizen_renderer_evas_gl.h b/shell/platform/tizen/tizen_renderer_evas_gl.h index af0f7bb0ec2fc..07a6e28b00f01 100644 --- a/shell/platform/tizen/tizen_renderer_evas_gl.h +++ b/shell/platform/tizen/tizen_renderer_evas_gl.h @@ -19,6 +19,7 @@ class TizenRendererEvasGL : public TizenRenderer { explicit TizenRendererEvasGL(WindowGeometry geometry, bool transparent, bool focusable, + bool top_level, Delegate& delegate); virtual ~TizenRendererEvasGL();