diff --git a/flutter/shell/platform/tizen/flutter_tizen.cc b/flutter/shell/platform/tizen/flutter_tizen.cc index a89a257..91a2917 100644 --- a/flutter/shell/platform/tizen/flutter_tizen.cc +++ b/flutter/shell/platform/tizen/flutter_tizen.cc @@ -167,15 +167,27 @@ void FlutterDesktopEngineNotifyLowMemoryWarning( } void FlutterDesktopEngineNotifyAppIsInactive(FlutterDesktopEngineRef engine) { - EngineFromHandle(engine)->lifecycle_channel()->AppIsInactive(); + flutter::FlutterTizenEngine* tizen_engine = EngineFromHandle(engine); + tizen_engine->lifecycle_channel()->AppIsInactive(); + if (tizen_engine->view()) { + tizen_engine->view()->OnFocus(kUnfocused); + } } void FlutterDesktopEngineNotifyAppIsResumed(FlutterDesktopEngineRef engine) { - EngineFromHandle(engine)->lifecycle_channel()->AppIsResumed(); + flutter::FlutterTizenEngine* tizen_engine = EngineFromHandle(engine); + tizen_engine->lifecycle_channel()->AppIsResumed(); + if (tizen_engine->view()) { + tizen_engine->view()->OnFocus(kFocused); + } } void FlutterDesktopEngineNotifyAppIsPaused(FlutterDesktopEngineRef engine) { - EngineFromHandle(engine)->lifecycle_channel()->AppIsPaused(); + flutter::FlutterTizenEngine* tizen_engine = EngineFromHandle(engine); + tizen_engine->lifecycle_channel()->AppIsPaused(); + if (tizen_engine->view()) { + tizen_engine->view()->OnFocus(kUnfocused); + } } void FlutterDesktopEngineNotifyAppIsDetached(FlutterDesktopEngineRef engine) { diff --git a/flutter/shell/platform/tizen/flutter_tizen_engine.cc b/flutter/shell/platform/tizen/flutter_tizen_engine.cc index 3c3611e..2de1a11 100644 --- a/flutter/shell/platform/tizen/flutter_tizen_engine.cc +++ b/flutter/shell/platform/tizen/flutter_tizen_engine.cc @@ -195,6 +195,13 @@ bool FlutterTizenEngine::RunEngine() { auto* engine = static_cast(user_data); engine->OnUpdateSemantics(update); }; + args.view_focus_change_request_callback = + [](const FlutterViewFocusChangeRequest* request, void* user_data) { + auto* engine = static_cast(user_data); + if (engine->view()) { + engine->view()->OnFocusChangeRequest(*request); + } + }; if (IsHeaded() && dynamic_cast(renderer_.get())) { vsync_waiter_ = std::make_unique(this); @@ -341,6 +348,13 @@ void FlutterTizenEngine::SendPointerEvent(const FlutterPointerEvent& event) { embedder_api_.SendPointerEvent(engine_, &event, 1); } +void FlutterTizenEngine::SendViewFocusEvent( + const FlutterViewFocusEvent& event) { + if (engine_) { + embedder_api_.SendViewFocusEvent(engine_, &event); + } +} + void FlutterTizenEngine::SendWindowMetrics(int32_t x, int32_t y, int32_t width, diff --git a/flutter/shell/platform/tizen/flutter_tizen_engine.h b/flutter/shell/platform/tizen/flutter_tizen_engine.h index c6cfa34..ffe34d4 100644 --- a/flutter/shell/platform/tizen/flutter_tizen_engine.h +++ b/flutter/shell/platform/tizen/flutter_tizen_engine.h @@ -144,6 +144,9 @@ class FlutterTizenEngine { // Informs the engine of an incoming pointer event. void SendPointerEvent(const FlutterPointerEvent& event); + // Informs the engine of a native view focus change. + void SendViewFocusEvent(const FlutterViewFocusEvent& event); + // Sends a window metrics update to the Flutter engine using current window // dimensions in physical void SendWindowMetrics(int32_t x, diff --git a/flutter/shell/platform/tizen/flutter_tizen_view.cc b/flutter/shell/platform/tizen/flutter_tizen_view.cc index 030e12d..0be61bc 100644 --- a/flutter/shell/platform/tizen/flutter_tizen_view.cc +++ b/flutter/shell/platform/tizen/flutter_tizen_view.cc @@ -151,6 +151,33 @@ void FlutterTizenView::OnRotate(int32_t degree) { SendWindowMetrics(geometry.left, geometry.top, width, height, 0.0); } +void FlutterTizenView::OnFocus(FlutterViewFocusState focus_state) { + if (focus_state == kFocused) { + auto* window = dynamic_cast(tizen_view_.get()); + if (window && !window->focusable()) { + return; + } + } + FlutterViewFocusEvent event = {}; + event.struct_size = sizeof(event); + event.view_id = view_id_; + event.state = focus_state; + event.direction = FlutterViewFocusDirection::kUndefined; + engine_->SendViewFocusEvent(event); +} + +void FlutterTizenView::OnFocusChangeRequest( + const FlutterViewFocusChangeRequest& request) { + if (request.view_id != view_id_ || request.state != kFocused) { + return; + } + if (auto* window = dynamic_cast(tizen_view_.get())) { + if (window->focusable()) { + window->ActivateWindow(); + } + } +} + FlutterTizenView::PointerState* FlutterTizenView::GetOrCreatePointerState( FlutterPointerDeviceKind device_kind, int32_t device_id) { diff --git a/flutter/shell/platform/tizen/flutter_tizen_view.h b/flutter/shell/platform/tizen/flutter_tizen_view.h index 4533acc..362d216 100644 --- a/flutter/shell/platform/tizen/flutter_tizen_view.h +++ b/flutter/shell/platform/tizen/flutter_tizen_view.h @@ -51,6 +51,10 @@ class FlutterTizenView : public TizenViewEventHandlerDelegate { void OnRotate(int32_t degree) override; + void OnFocus(FlutterViewFocusState focus_state); + + void OnFocusChangeRequest(const FlutterViewFocusChangeRequest& request); + void OnPointerMove(double x, double y, size_t timestamp, diff --git a/flutter/shell/platform/tizen/tizen_window.h b/flutter/shell/platform/tizen/tizen_window.h index 90395bd..a77b850 100644 --- a/flutter/shell/platform/tizen/tizen_window.h +++ b/flutter/shell/platform/tizen/tizen_window.h @@ -36,6 +36,8 @@ class TizenWindow : public TizenViewBase { virtual void LowerWindow() = 0; + bool focusable() { return focusable_; } + protected: explicit TizenWindow(TizenGeometry geometry, bool transparent,