Enable event handling for Ozone EFL 89/285489/5
authorGajendra N <gajendra.n@samsung.com>
Tue, 13 Dec 2022 09:45:16 +0000 (15:15 +0530)
committerGajendra N <gajendra.n@samsung.com>
Thu, 15 Dec 2022 11:49:32 +0000 (17:19 +0530)
Functionalities:
1) Bringup mouse, touch and HW-KB key input event capturing and forwarding.
2) Enable focus handling and keep browser and engine's focus in sync.
3) Unification of event handling code for both onscreen and offscreen.
4) ubrowser white screen and EWA window size issues are also fixed.

Reference base patch : https://review.tizen.org/gerrit/269026
(Also includes many other fixups and patch changes partially)

Change-Id: Id97fbdc94df8a77f659d7176d6dd4c15c40de43b
Signed-off-by: Gajendra N <gajendra.n@samsung.com>
19 files changed:
content/browser/renderer_host/render_widget_host_view_aura.cc
tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.cc
tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_offscreen_helper_efl.h
tizen_src/chromium_impl/ui/ozone/platform/efl/BUILD.gn
tizen_src/chromium_impl/ui/ozone/platform/efl/efl_event_handler.cc [new file with mode: 0644]
tizen_src/chromium_impl/ui/ozone/platform/efl/efl_event_handler.h [new file with mode: 0644]
tizen_src/chromium_impl/ui/ozone/platform/efl/efl_keycode_map.h [new file with mode: 0644]
tizen_src/chromium_impl/ui/ozone/platform/efl/efl_platform_event_source.cc [new file with mode: 0644]
tizen_src/chromium_impl/ui/ozone/platform/efl/efl_platform_event_source.h [new file with mode: 0644]
tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window.cc
tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window.h
tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window_manager.h [new file with mode: 0644]
tizen_src/chromium_impl/ui/ozone/platform/efl/ozone_platform_efl.cc
tizen_src/ewk/efl_integration/eweb_view.cc
tizen_src/ewk/efl_integration/eweb_view.h
tizen_src/ewk/ubrowser/window.cc
ui/aura/window.cc
ui/aura/window.h
ui/platform_window/platform_window.h

index 968980823405ca1b1ac6ab054072b0185ce1480d..a026f35a86d5d3467ce715a7e31f2b63edb9784a 100644 (file)
@@ -327,6 +327,11 @@ void RenderWidgetHostViewAura::InitAsChild(gfx::NativeView parent_view) {
   if (parent_view)
     parent_view->AddChild(GetNativeView());
 
+#if defined(USE_EFL)
+  if (offscreen_helper_)
+    offscreen_helper_->SetAuraParentWindow(parent_view);
+#endif
+
   device_scale_factor_ = GetDeviceScaleFactor();
 
   aura::Window* root = window_->GetRootWindow();
@@ -536,6 +541,11 @@ void RenderWidgetHostViewAura::Focus() {
   aura::client::FocusClient* client = aura::client::GetFocusClient(window_);
   if (client)
     window_->Focus();
+
+#if defined(USE_EFL)
+  if (offscreen_helper_)
+    offscreen_helper_->Focus(true);
+#endif
 }
 
 bool RenderWidgetHostViewAura::HasFocus() {
@@ -2092,6 +2102,8 @@ void RenderWidgetHostViewAura::OnSystemCursorSizeChanged(
 
 void RenderWidgetHostViewAura::OnWindowFocused(aura::Window* gained_focus,
                                                aura::Window* lost_focus) {
+  LOG(INFO) << "OnWindowFocused, Gained : " << gained_focus
+            << ", Lost : " << lost_focus;
   if (window_ == gained_focus) {
     // We need to honor input bypass if the associated tab does not want input.
     // This gives the current focused window a chance to be the text input
@@ -2534,6 +2546,11 @@ void RenderWidgetHostViewAura::UpdateLegacyWin() {
 void RenderWidgetHostViewAura::AddedToRootWindow() {
   DCHECK(delegated_frame_host_) << "Cannot be invoked during destruction.";
 
+#if defined(USE_EFL)
+  if (offscreen_helper_)
+    offscreen_helper_->AuraChildWindowAdded();
+#endif
+
   window_->GetHost()->AddObserver(this);
   UpdateScreenInfo();
 
index e1d77ab0d8d27ec03519ff7de36fe44e9f6e690a..1f7a5e7b21e82d2986f8e9a3df6994b320e73332 100644 (file)
@@ -94,12 +94,20 @@ void RWHVAuraOffscreenHelperEfl::Initialize() {
       display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
 }
 
-void RWHVAuraOffscreenHelperEfl::SetParentNativeView(
-    gfx::NativeView parent_view) {
-  parent_native_view_ = parent_view;
+void RWHVAuraOffscreenHelperEfl::SetAuraParentWindow(
+    gfx::NativeView parent_window) {
+  aura_parent_window_ = parent_window;
 }
 
 void RWHVAuraOffscreenHelperEfl::AuraChildWindowAdded() {
+  aura::WindowTreeHost* window_host = rwhv_aura_->window()->GetHost();
+  if (!window_host)
+    return;
+
+  static_cast<aura::WindowTreeHostPlatform*>(window_host)
+      ->platform_window()
+      ->SetNativeViewOffscreen(content_image_);
+
   // Add FOCUS_{IN,OUT} callbacks only after child aura window is created.
   evas_object_event_callback_add(content_image_, EVAS_CALLBACK_FOCUS_IN,
                                  OnFocusIn, this);
@@ -119,7 +127,7 @@ void RWHVAuraOffscreenHelperEfl::OnParentViewResize(void* data,
   if (window_host)
     window_host->SetBoundsInPixels(new_bounds);
 
-  aura::Window* parent_window = thiz->parent_native_view_;
+  aura::Window* parent_window = thiz->aura_parent_window_;
   if (parent_window)
     parent_window->SetBounds(new_bounds);
 }
index 02bd471a505f5779d3a5983ad02138734447da3f..3eec19a7e5899a8123ed98b9bb90c49af1f9c599 100644 (file)
@@ -38,7 +38,7 @@ class CONTENT_EXPORT RWHVAuraOffscreenHelperEfl {
                              WebContents* web_contents);
   ~RWHVAuraOffscreenHelperEfl();
 
-  void SetParentNativeView(gfx::NativeView parent_view);
+  void SetAuraParentWindow(gfx::NativeView parent_window);
   void AuraChildWindowAdded();
   void NotifySwap(const uint32_t texture_id);
   void Show();
@@ -106,7 +106,7 @@ class CONTENT_EXPORT RWHVAuraOffscreenHelperEfl {
   GLuint texture_id_ = 0;
   GLuint vertex_buffer_obj_;
   GLuint index_buffer_obj_;
-  gfx::NativeView parent_native_view_ = nullptr;
+  gfx::NativeView aura_parent_window_ = nullptr;
 
   int rotation_ = 0;
   float device_scale_factor_ = 1.0f;
index b7af9272c9d32e1c17b2bbb9aba940d52c6dd9a2..30f4eeb50cb7f5b1fce40264d6333bf0c67bf4fc 100644 (file)
@@ -10,12 +10,17 @@ source_set("efl") {
   sources = [
     "client_native_pixmap_factory_efl.cc",
     "client_native_pixmap_factory_efl.h",
+    "efl_event_handler.cc",
+    "efl_event_handler.h",
+    "efl_platform_event_source.cc",
+    "efl_platform_event_source.h",
     "efl_screen.cc",
     "efl_screen.h",
     "efl_surface_factory.cc",
     "efl_surface_factory.h",
     "efl_window.cc",
     "efl_window.h",
+    "efl_window_manager.h",
     "ozone_platform_efl.cc",
     "ozone_platform_efl.h",
   ]
@@ -60,5 +65,9 @@ source_set("efl") {
     ]
   }
 
+  if (tizen_product_tv) {
+    configs += [ "//tizen_src/build:libvd-win-util" ]
+  }
+
   defines = [ "OZONE_IMPLEMENTATION" ]
 }
diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_event_handler.cc b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_event_handler.cc
new file mode 100644 (file)
index 0000000..060ffa0
--- /dev/null
@@ -0,0 +1,639 @@
+// Copyright 2021 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/efl/efl_event_handler.h"
+#include "ui/display/screen.h"
+
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/public/browser/native_web_keyboard_event.h"
+#include "tizen/system_info.h"
+#include "ui/base/ime/linux/linux_input_method_context_factory.h"
+#include "ui/events/base_event_utils.h"
+#include "ui/events/event.h"
+#include "ui/events/types/event_type.h"
+#include "ui/gfx/geometry/point_f.h"
+#include "ui/ozone/platform/efl/efl_keycode_map.h"
+#include "ui/ozone/platform/efl/efl_platform_event_source.h"
+#include "ui/ozone/platform/efl/efl_window.h"
+
+#if defined(OS_TIZEN)
+#include "ui/events/keycodes/dom/dom_code.h"
+#include "ui/events/keycodes/dom/dom_key.h"
+#include "ui/events/keycodes/dom/keycode_converter.h"
+#include "ui/events/keycodes/keyboard_code_conversion.h"
+#endif
+
+namespace ui {
+
+namespace {
+const float kDefaultScrollStep = 20;
+
+inline bool string_ends_with(std::string const& value,
+                             std::string const& match) {
+  if (match.size() > value.size()) {
+    return false;
+  }
+  return std::equal(match.rbegin(), match.rend(), value.rbegin());
+}
+
+inline bool string_starts_with(std::string const& value,
+                               std::string const& match) {
+  if (match.size() > value.size()) {
+    return false;
+  }
+  return std::equal(match.begin(), match.end(), value.begin());
+}
+
+// TV RC device names
+const std::string kDeviceNameSmartView = "SMART_VIEW";
+const std::string kDeviceNamePanelKey = "wt61p807 panel key device";
+const std::string kDeviceNameRemote = "wt61p807 rc device";
+const std::string kDeviceNameSmartRC = "Smart Control";
+// To allow to receive Tomato send key events
+const std::string kDeviceNameAutoModeDevice = "AUTO_MODE_DEVICE";
+const std::string kDeviceNameIME = "ime";
+
+bool IsRCDevice(Evas_Device_Class device_id, const std::string device_name) {
+  if (device_id == EVAS_DEVICE_CLASS_KEYBOARD) {
+    if (!device_name.compare(kDeviceNameRemote) ||
+        !device_name.compare(kDeviceNameSmartView) ||
+        !device_name.compare(kDeviceNamePanelKey) ||
+        !device_name.compare(kDeviceNameAutoModeDevice) ||
+        device_name.find(kDeviceNameSmartRC) != std::string::npos)
+      return true;
+  }
+  return false;
+}
+
+enum { kLeftButton = 1, kMiddleButton = 2, kRightButton = 3 };
+
+EventFlags EvasToUIMouseButton(int button) {
+  if (button == kLeftButton)
+    return EF_LEFT_MOUSE_BUTTON;
+  if (button == kMiddleButton)
+    return EF_MIDDLE_MOUSE_BUTTON;
+  if (button == kRightButton)
+    return EF_RIGHT_MOUSE_BUTTON;
+
+  return EF_NONE;
+}
+
+int GetEventFlagsFromKey(const char* key) {
+  int flags = 0;
+  if (base::StartsWith(key, "Shift", base::CompareCase::SENSITIVE))
+    flags |= EF_SHIFT_DOWN;
+  if (base::StartsWith(key, "Control", base::CompareCase::SENSITIVE))
+    flags |= EF_CONTROL_DOWN;
+  if (base::StartsWith(key, "Alt", base::CompareCase::SENSITIVE))
+    flags |= EF_ALT_DOWN;
+  if (base::StartsWith(key, "Meta", base::CompareCase::SENSITIVE))
+    flags |= EF_COMMAND_DOWN;
+  if (base::StartsWith(key, "Super", base::CompareCase::SENSITIVE))
+    flags |= EF_COMMAND_DOWN;
+
+  return flags;
+}
+
+int EvasModifiersToEventFlags(const Evas_Modifier* modifiers,
+                              bool check_super = true) {
+  int flags = 0;
+  if (evas_key_modifier_is_set(modifiers, "Shift"))
+    flags |= EF_SHIFT_DOWN;
+  if (evas_key_modifier_is_set(modifiers, "Control"))
+    flags |= EF_CONTROL_DOWN;
+  if (evas_key_modifier_is_set(modifiers, "Alt"))
+    flags |= EF_ALT_DOWN;
+  if (evas_key_modifier_is_set(modifiers, "Meta"))
+    flags |= EF_COMMAND_DOWN;
+  if (evas_key_modifier_is_set(modifiers, "Super") && check_super)
+    flags |= EF_COMMAND_DOWN;
+
+  return flags;
+}
+
+static EventType EvasTouchEventTypeToUI(Evas_Touch_Point_State evas_touch) {
+  switch (evas_touch) {
+    case EVAS_TOUCH_POINT_DOWN:
+      return ET_TOUCH_PRESSED;
+    case EVAS_TOUCH_POINT_MOVE:
+      return ET_TOUCH_MOVED;
+    case EVAS_TOUCH_POINT_UP:
+      return ET_TOUCH_RELEASED;
+    case EVAS_TOUCH_POINT_CANCEL:
+      return ET_TOUCH_CANCELLED;
+    case EVAS_TOUCH_POINT_STILL:
+    // Not handled by chromium, should not be passed here.
+    default:
+      NOTREACHED();
+      return ET_UNKNOWN;
+  }
+}
+
+float GetDeviceScaleFactor() {
+  static float device_scale_factor = 0.0f;
+  if (!device_scale_factor) {
+    device_scale_factor =
+        display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
+  }
+  return device_scale_factor;
+}
+
+}  // namespace
+
+EflEventHandler::EflEventHandler(EflWindow* window)
+    : window_(window), native_view_(window->native_view()) {
+  if (IsMobileProfile())
+    touch_events_enabled_ = true;
+
+  RegisterCallbacks();
+
+  evas_object_geometry_get(native_view_, nullptr, &top_controls_height_,
+                           nullptr, nullptr);
+}
+
+EflEventHandler::~EflEventHandler() {
+  evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MOUSE_DOWN,
+                                 OnMouseDown);
+  evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MOUSE_UP,
+                                 OnMouseUp);
+  evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MOUSE_MOVE,
+                                 OnMouseMove);
+  evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MOUSE_IN,
+                                 OnMouseIn);
+  evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MOUSE_OUT,
+                                 OnMouseOut);
+  evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MOUSE_WHEEL,
+                                 OnMouseWheel);
+  if (key_events_enabled_)
+    DeleteKeyCallbacks();
+
+  if (touch_events_enabled_)
+    DeleteTouchCallbacks();
+}
+
+void EflEventHandler::RegisterCallbacks() {
+  evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MOUSE_DOWN,
+                                 OnMouseDown, this);
+  evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MOUSE_UP,
+                                 OnMouseUp, this);
+  evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MOUSE_MOVE,
+                                 OnMouseMove, this);
+  evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MOUSE_IN,
+                                 OnMouseIn, this);
+  evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MOUSE_OUT,
+                                 OnMouseOut, this);
+  evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MOUSE_WHEEL,
+                                 OnMouseWheel, this);
+  if (key_events_enabled_)
+    AddKeyCallbacks();
+
+  evas_object_focus_set(native_view_, EINA_TRUE);
+
+  if (touch_events_enabled_)
+    AddTouchCallbacks();
+}
+
+int EflEventHandler::GetTopControlsHeight() {
+  evas_object_geometry_get(native_view_, nullptr, &top_controls_height_,
+                           nullptr, nullptr);
+  return top_controls_height_;
+}
+
+template <typename EVT>
+bool EflEventHandler::GetTouchEventsEnabled(const EVT* evas_evt) {
+#if defined(OS_TIZEN_TV_PRODUCT)
+  return (touch_events_enabled_ &&
+          evas_device_class_get(evas_evt->dev) == EVAS_DEVICE_CLASS_TOUCH);
+#endif
+  return touch_events_enabled_;
+}
+
+template <class EVT>
+MouseEvent MakeWebMouseEvent(EventType type, const EVT* ev, int delta_y) {
+  gfx::PointF location(ev->canvas.x, ev->canvas.y);
+  location.Offset(0, -delta_y);
+  int button = EvasToUIMouseButton(ev->button);
+  int event_flags = EvasModifiersToEventFlags(ev->modifiers);
+  event_flags |= button;
+  MouseEvent event(type, location, location, base::TimeTicks::Now(),
+                   event_flags, button);
+
+#if defined(OS_TIZEN_TV_PRODUCT)
+  int clickCount = 1;
+  if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)  // dblclick
+    clickCount = 2;
+  if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK)  // triple click
+    clickCount = 3;
+
+  event.SetClickCount(clickCount);
+#endif
+
+  return event;
+}
+
+TouchEvent MakeTouchEvent(Evas_Coord_Point pt,
+                          Evas_Touch_Point_State state,
+                          int id,
+                          unsigned int timestamp,
+                          int delta_y) {
+  base::TimeTicks event_timestamp = base::TimeTicks::FromInternalValue(
+      timestamp * base::Time::kMicrosecondsPerMillisecond);
+
+  if (timestamp == 0)
+    event_timestamp = EventTimeForNow();
+
+  pt.y -= delta_y;
+
+  TouchEvent touch_event(
+      EvasTouchEventTypeToUI(state), gfx::Point(), event_timestamp,
+      PointerDetails(EventPointerType::kTouch, id, 0.0f, 0.0f, 0.0f));
+  gfx::PointF point(pt.x, pt.y);
+  touch_event.set_location_f(point);
+  touch_event.set_root_location_f(point);
+  return touch_event;
+}
+
+template <class EVT>
+KeyEvent MakeWebKeyEvent(bool pressed, const EVT* evt) {
+  EventType type = pressed ? ET_KEY_PRESSED : ET_KEY_RELEASED;
+  int native_key_code = evt->keycode;
+  KeyboardCode windows_key_code = UIKeyCodeFromEflKey(evt->key);
+
+  int flags = 0;
+#if defined(OS_TIZEN_TV_PRODUCT)
+  // On combinate key "shift+Alt+xxx", the "key" of the "Alt" is
+  // "Meta_L/Meta_R", not the "Alt_L/Alt_R", so use the keyname replace the
+  // "key" to get the flag.
+  if (evt->keyname)
+    flags = GetEventFlagsFromKey(evt->keyname);
+  else
+#endif
+    flags = GetEventFlagsFromKey(evt->key);
+
+  int key_modifiers = 0;
+  if (evas_key_lock_is_set(evt->locks, "Caps_Lock"))
+    key_modifiers |= EF_CAPS_LOCK_ON;
+
+  key_modifiers |= EvasModifiersToEventFlags(evt->modifiers);
+
+  // For Modifiers Key, need set the modifier when key press,
+  // no need set the modifier when key release.
+  // refer w3c spec: https://w3c.github.io/uievents/#keys-modifierss
+  if (pressed)
+    key_modifiers |= flags;
+  else
+    key_modifiers &= ~flags;
+
+#if defined(OS_TIZEN)
+  DomCode domCode = KeycodeConverter::NativeKeycodeToDomCode(native_key_code);
+
+  DomKey domKey = KeycodeConverter::KeyStringToDomKey(evt->key);
+  // If the efl key name is not identified, use its domcode to find it in domkey
+  // map
+  if ((domKey == DomKey::NONE) && (domCode != DomCode::NONE)) {
+    int flags = key_modifiers;
+    KeyboardCode windowsKeyCode = VKEY_UNKNOWN;
+    std::ignore =
+        DomCodeToUsLayoutDomKey(domCode, flags, &domKey, &windowsKeyCode);
+  }
+
+  KeyEvent event(type, windows_key_code, domCode, key_modifiers, domKey,
+                 base::TimeTicks::Now(), false);
+#else
+  KeyEvent event(type, windows_key_code, key_modifiers, base::TimeTicks::Now());
+#endif
+
+  return event;
+}
+
+template KeyEvent MakeWebKeyEvent(bool, const Evas_Event_Key_Down*);
+template KeyEvent MakeWebKeyEvent(bool, const Evas_Event_Key_Up*);
+
+void EflEventHandler::SetTouchEventsEnabled(bool enabled) {
+  if (touch_events_enabled_ == enabled)
+    return;
+
+  touch_events_enabled_ = enabled;
+
+  LOG(INFO) << "SetTouchEventsEnabled: " << (enabled ? "enabled" : "disabled");
+  if (enabled)
+    AddTouchCallbacks();
+  else
+    DeleteTouchCallbacks();
+}
+
+void EflEventHandler::SetKeyEventsEnabled(bool enabled) {
+  if (key_events_enabled_ == enabled)
+    return;
+
+  key_events_enabled_ = enabled;
+
+  LOG(INFO) << "SetKeyEventsEnabled: " << (enabled ? "enabled" : "disabled");
+  if (enabled)
+    AddKeyCallbacks();
+  else
+    DeleteKeyCallbacks();
+}
+
+void EflEventHandler::SendKeyEvent(Evas_Object* ewk_view,
+                                   void* event_info,
+                                   bool is_press) {
+  if (is_press) {
+    OnKeyDown(static_cast<void*>(this), nullptr, ewk_view, event_info);
+  } else {
+    OnKeyUp(static_cast<void*>(this), nullptr, ewk_view, event_info);
+  }
+}
+
+static int mouse_pre_x = 0;
+static int mouse_pre_y = 0;
+
+void EflEventHandler::SendMouseDown(int button, int x, int y) {
+  Evas_Event_Mouse_Down ev;
+  ev.button = button;
+  ev.flags = EVAS_BUTTON_NONE;
+  ev.canvas.x = x;
+  ev.canvas.y = y;
+  ev.modifiers = 0;
+  ev.timestamp = ecore_time_get();
+
+  OnMouseDown(static_cast<void*>(this), window_->evas(), native_view_, &ev);
+}
+
+void EflEventHandler::SendMouseUp(int button, int x, int y) {
+  Evas_Event_Mouse_Up ev;
+  ev.button = button;
+  ev.flags = EVAS_BUTTON_NONE;
+  ev.canvas.x = x;
+  ev.canvas.y = y;
+  ev.modifiers = 0;
+  ev.timestamp = ecore_time_get();
+
+  OnMouseUp(static_cast<void*>(this), window_->evas(), native_view_, &ev);
+}
+
+void EflEventHandler::SendMouseMove(int x, int y) {
+  Evas_Event_Mouse_Move ev;
+  ev.buttons = 1;
+  ev.cur.canvas.x = x;
+  ev.cur.canvas.y = y;
+  ev.prev.canvas.x = mouse_pre_x;
+  ev.prev.canvas.y = mouse_pre_y;
+  ev.modifiers = 0;
+  ev.timestamp = ecore_time_get();
+
+  OnMouseMove(static_cast<void*>(this), window_->evas(), native_view_, &ev);
+
+  mouse_pre_x = x;
+  mouse_pre_y = y;
+}
+
+void EflEventHandler::SendMouseWheel(bool y_direction, int step, int x, int y) {
+  Evas_Event_Mouse_Wheel ev;
+  ev.direction = y_direction ? 0 : 1;
+  ev.canvas.x = x;
+  ev.canvas.y = y;
+  ev.z = step;
+  ev.modifiers = 0;
+  ev.timestamp = ecore_time_get();
+
+  OnMouseWheel(static_cast<void*>(this), window_->evas(), native_view_, &ev);
+}
+
+void EflEventHandler::SendMouseOut() {
+  Evas_Event_Mouse_Out ev;
+  ev.buttons = 0;
+  ev.canvas.x = mouse_pre_x;
+  ev.canvas.y = mouse_pre_y;
+  ev.modifiers = 0;
+  ev.timestamp = ecore_time_get();
+
+  OnMouseOut(static_cast<void*>(this), window_->evas(), native_view_, &ev);
+}
+
+void EflEventHandler::AddTouchCallbacks() {
+  evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MULTI_DOWN,
+                                 OnMultiTouchDownEvent, this);
+  evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MULTI_MOVE,
+                                 OnMultiTouchMoveEvent, this);
+  evas_object_event_callback_add(native_view_, EVAS_CALLBACK_MULTI_UP,
+                                 OnMultiTouchUpEvent, this);
+}
+
+void EflEventHandler::DeleteTouchCallbacks() {
+  evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MULTI_DOWN,
+                                 OnMultiTouchDownEvent);
+  evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MULTI_MOVE,
+                                 OnMultiTouchMoveEvent);
+  evas_object_event_callback_del(native_view_, EVAS_CALLBACK_MULTI_UP,
+                                 OnMultiTouchUpEvent);
+}
+
+void EflEventHandler::AddKeyCallbacks() {
+  evas_object_event_callback_add(native_view_, EVAS_CALLBACK_KEY_DOWN,
+                                 OnKeyDown, this);
+  evas_object_event_callback_add(native_view_, EVAS_CALLBACK_KEY_UP, OnKeyUp,
+                                 this);
+}
+
+void EflEventHandler::DeleteKeyCallbacks() {
+  evas_object_event_callback_del(native_view_, EVAS_CALLBACK_KEY_DOWN,
+                                 OnKeyDown);
+  evas_object_event_callback_del(native_view_, EVAS_CALLBACK_KEY_UP, OnKeyUp);
+}
+
+// static
+void EflEventHandler::OnMouseDown(void* data,
+                                  Evas* evas,
+                                  Evas_Object* obj,
+                                  void* event_info) {
+  EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
+  Evas_Event_Mouse_Down* ev = static_cast<Evas_Event_Mouse_Down*>(event_info);
+  LOG(INFO) << "OnMouseDown";
+
+  thiz->window_->UpdateFocus(true);
+
+  if (thiz->GetTouchEventsEnabled(ev)) {
+    thiz->ProcessTouchEvents(ev->timestamp, false);
+  } else {
+    MouseEvent event =
+        MakeWebMouseEvent(ET_MOUSE_PRESSED, ev, thiz->GetTopControlsHeight());
+    EflPlatformEventSource::GetInstance()->DispatchEflEvent(&event);
+  }
+}
+
+// static
+void EflEventHandler::OnMouseUp(void* data,
+                                Evas* evas,
+                                Evas_Object* obj,
+                                void* event_info) {
+  EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
+  Evas_Event_Mouse_Up* ev = static_cast<Evas_Event_Mouse_Up*>(event_info);
+  LOG(INFO) << "OnMouseUp";
+
+  if (thiz->GetTouchEventsEnabled(ev)) {
+    thiz->ProcessTouchEvents(ev->timestamp, false);
+  } else {
+    MouseEvent event =
+        MakeWebMouseEvent(ET_MOUSE_RELEASED, ev, thiz->GetTopControlsHeight());
+    EflPlatformEventSource::GetInstance()->DispatchEflEvent(&event);
+  }
+}
+
+// static
+void EflEventHandler::OnMouseMove(void* data,
+                                  Evas* evas,
+                                  Evas_Object* obj,
+                                  void* event_info) {
+  EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
+
+  Evas_Event_Mouse_Move* ev = static_cast<Evas_Event_Mouse_Move*>(event_info);
+  if (thiz->GetTouchEventsEnabled(ev)) {
+    thiz->ProcessTouchEvents(ev->timestamp, false);
+  } else {
+    gfx::PointF location(ev->cur.canvas.x, ev->cur.canvas.y);
+    location.Offset(0, -thiz->GetTopControlsHeight());
+    int button = EvasToUIMouseButton(ev->buttons);
+    int event_flags = EvasModifiersToEventFlags(ev->modifiers);
+    event_flags |= button;
+    MouseEvent event(ET_MOUSE_MOVED, location, location, base::TimeTicks::Now(),
+                     event_flags, button);
+    const float sf = GetDeviceScaleFactor();
+    ui::MouseEvent::DispatcherApi(&event).set_movement(
+        gfx::Vector2dF((ev->cur.canvas.x / sf - ev->prev.canvas.x / sf),
+                       (ev->cur.canvas.y / sf - ev->prev.canvas.y / sf)));
+    EflPlatformEventSource::GetInstance()->DispatchEflEvent(&event);
+  }
+}
+
+// static
+void EflEventHandler::OnMouseIn(void* data,
+                                Evas* evas,
+                                Evas_Object* obj,
+                                void* event_info) {
+  EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
+  thiz->window_->UpdateFocus(true);
+}
+
+// static
+void EflEventHandler::OnMouseOut(void* data,
+                                 Evas* evas,
+                                 Evas_Object* obj,
+                                 void* event_info) {
+#if !defined(OS_TIZEN_TV_PRODUCT)
+  EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
+  thiz->window_->UpdateFocus(false);
+#endif
+}
+
+// static
+void EflEventHandler::OnMouseWheel(void* data,
+                                   Evas* evas,
+                                   Evas_Object* obj,
+                                   void* event_info) {
+  Evas_Event_Mouse_Wheel* ev = static_cast<Evas_Event_Mouse_Wheel*>(event_info);
+
+  gfx::Vector2d offset;
+  if (ev->direction)
+    offset.set_x(ev->z * kDefaultScrollStep);
+  else
+    offset.set_y(-(ev->z * kDefaultScrollStep));
+
+  gfx::PointF location(ev->canvas.x, ev->canvas.y);
+  int event_flags = EvasModifiersToEventFlags(ev->modifiers);
+  MouseWheelEvent event(offset, location, location, base::TimeTicks::Now(),
+                        event_flags, 0);
+  EflPlatformEventSource::GetInstance()->DispatchEflEvent(&event);
+}
+
+// static
+void EflEventHandler::OnKeyDown(void* data,
+                                Evas* evas,
+                                Evas_Object* obj,
+                                void* event_info) {
+  if (!obj || !event_info || !data)
+    return;
+
+  Evas_Event_Key_Down* key_down = static_cast<Evas_Event_Key_Down*>(event_info);
+  EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
+  LOG(INFO) << "OnKeyDown, key : " << key_down->key;
+  LOG(INFO) << "Before consumed check (Key Name: " << key_down->key
+            << ", Key State: Down)";
+
+  KeyEvent event = MakeWebKeyEvent(true, key_down);
+  EflPlatformEventSource::GetInstance()->DispatchEflEvent(&event);
+}
+
+// static
+void EflEventHandler::OnKeyUp(void* data,
+                              Evas* evas,
+                              Evas_Object* obj,
+                              void* event_info) {
+  if (!obj || !event_info || !data)
+    return;
+
+  Evas_Event_Key_Up* key_up = static_cast<Evas_Event_Key_Up*>(event_info);
+  EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
+  LOG(INFO) << "OnKeyUp, key : " << key_up->key;
+  LOG(INFO) << "Before consumed check (Key Name: " << key_up->key
+            << ", Key State: Up)";
+
+  KeyEvent event = MakeWebKeyEvent(false, key_up);
+  EflPlatformEventSource::GetInstance()->DispatchEflEvent(&event);
+}
+
+void EflEventHandler::OnMultiTouchDownEvent(void* data,
+                                            Evas* evas,
+                                            Evas_Object* obj,
+                                            void* event_info) {
+  EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
+  thiz->ProcessTouchEvents(
+      static_cast<Evas_Event_Multi_Down*>(event_info)->timestamp, true);
+}
+
+void EflEventHandler::OnMultiTouchMoveEvent(void* data,
+                                            Evas* evas,
+                                            Evas_Object* obj,
+                                            void* event_info) {
+  EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
+  thiz->ProcessTouchEvents(
+      static_cast<Evas_Event_Multi_Move*>(event_info)->timestamp, true);
+}
+
+void EflEventHandler::OnMultiTouchUpEvent(void* data,
+                                          Evas* evas,
+                                          Evas_Object* obj,
+                                          void* event_info) {
+  EflEventHandler* thiz = static_cast<EflEventHandler*>(data);
+  thiz->ProcessTouchEvents(
+      static_cast<Evas_Event_Multi_Up*>(event_info)->timestamp, true);
+}
+
+void EflEventHandler::ProcessTouchEvents(unsigned int timestamp,
+                                         bool is_multi_touch) {
+  unsigned count = evas_touch_point_list_count(window_->evas());
+  if (!count)
+    return;
+
+  int id;
+  Evas_Coord_Point pt;
+  Evas_Touch_Point_State state;
+  for (unsigned i = 0; i < count; ++i) {
+    id = evas_touch_point_list_nth_id_get(window_->evas(), i);
+    if ((id == 0 && is_multi_touch) || (id == 1 && !is_multi_touch))
+      continue;
+    evas_touch_point_list_nth_xy_get(window_->evas(), i, &pt.x, &pt.y);
+    state = evas_touch_point_list_nth_state_get(window_->evas(), i);
+    if (state == EVAS_TOUCH_POINT_STILL)
+      continue;
+
+    TouchEvent touch_event =
+        MakeTouchEvent(pt, state, id, timestamp, top_controls_height_);
+    EflPlatformEventSource::GetInstance()->DispatchEflEvent(&touch_event);
+  }
+}
+
+}  // namespace ui
diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_event_handler.h b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_event_handler.h
new file mode 100644 (file)
index 0000000..72e3347
--- /dev/null
@@ -0,0 +1,91 @@
+// Copyright 2021 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_PLATFORM_EFL_EFL_EVENT_HANDLER_H_
+#define UI_OZONE_PLATFORM_EFL_EFL_EVENT_HANDLER_H_
+
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+
+#if defined(OS_TIZEN_TV_PRODUCT)
+#include "base/callback.h"
+#include "ui/gfx/geometry/rect.h"
+#endif
+
+namespace ui {
+
+class EflWindow;
+class EflPlatformEventSource;
+class KeyEvent;
+class TouchEvent;
+
+// Keyboard
+template <class EVT>
+KeyEvent MakeWebKeyEvent(bool pressed, const EVT*);
+
+TouchEvent MakeTouchEvent(Evas_Coord_Point pt,
+                          Evas_Touch_Point_State state,
+                          int id,
+                          unsigned int timestamp,
+                          int delta_y);
+
+class EflEventHandler {
+ public:
+  explicit EflEventHandler(EflWindow* window);
+  ~EflEventHandler();
+
+  EflEventHandler(const EflEventHandler&) = delete;
+  EflEventHandler& operator=(const EflEventHandler&) = delete;
+
+  void SetTouchEventsEnabled(bool enabled);
+  bool TouchEventsEnabled() const { return touch_events_enabled_; }
+  void SetKeyEventsEnabled(bool enabled);
+  bool KeyEventsEnabled() const { return key_events_enabled_; }
+  void SendKeyEvent(Evas_Object* ewk_view, void* event_info, bool is_press);
+  void SendMouseDown(int button, int x, int y);
+  void SendMouseUp(int button, int x, int y);
+  void SendMouseMove(int x, int y);
+  void SendMouseWheel(bool y_direction, int step, int x, int y);
+  void SendMouseOut();
+
+ private:
+  void RegisterCallbacks();
+  void AddTouchCallbacks();
+  void DeleteTouchCallbacks();
+  void AddKeyCallbacks();
+  void DeleteKeyCallbacks();
+
+  static void OnMouseDown(void* data, Evas*, Evas_Object*, void*);
+  static void OnMouseUp(void* data, Evas*, Evas_Object*, void*);
+  static void OnMouseMove(void* data, Evas*, Evas_Object*, void*);
+  static void OnMouseIn(void* data, Evas*, Evas_Object*, void*);
+  static void OnMouseOut(void* data, Evas*, Evas_Object*, void*);
+  static void OnMouseWheel(void* data, Evas*, Evas_Object*, void*);
+  static void OnKeyDown(void*, Evas*, Evas_Object*, void*);
+  static void OnKeyUp(void*, Evas*, Evas_Object*, void*);
+  static void OnMultiTouchDownEvent(void*, Evas*, Evas_Object*, void*);
+  static void OnMultiTouchMoveEvent(void*, Evas*, Evas_Object*, void*);
+  static void OnMultiTouchUpEvent(void*, Evas*, Evas_Object*, void*);
+
+  void ProcessTouchEvents(unsigned int timestamp, bool is_multi_touch);
+  int GetTopControlsHeight();
+  template <typename EVT>
+  bool GetTouchEventsEnabled(const EVT* evas_evt);
+
+  int key_modifiers_ = 0;
+  bool touch_events_enabled_ = false;
+  bool key_events_enabled_ = true;
+  int top_controls_height_ = 0;
+  bool was_keydown_filtered_by_platform_ = false;
+  bool was_return_keydown_filtered_by_platform_ = false;
+  bool was_alt_enter_key_down_ = false;
+  bool was_up_keypress_on_ime_top_ = false;
+
+  EflWindow* window_ = nullptr;
+  Evas_Object* native_view_ = nullptr;
+};
+
+}  // namespace ui
+
+#endif  // UI_OZONE_PLATFORM_EFL_EFL_EVENT_HANDLER_H_
diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_keycode_map.h b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_keycode_map.h
new file mode 100644 (file)
index 0000000..366cb70
--- /dev/null
@@ -0,0 +1,148 @@
+// Copyright 2021 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <unordered_map>
+
+#include "tizen_src/chromium_impl/tizen/system_info.h"
+
+namespace ui {
+
+static ui::KeyboardCode UIKeyCodeFromEflKey(const char* key) {
+  static std::unordered_map<std::string, ui::KeyboardCode> code_from_key_map({
+    {"Shift_L", ui::VKEY_SHIFT}, {"Shift_R", ui::VKEY_SHIFT},
+        {"Control_L", ui::VKEY_CONTROL}, {"Control_R", ui::VKEY_CONTROL},
+        {"Alt_L", ui::VKEY_MENU}, {"Alt_R", ui::VKEY_MENU},
+        {"Meta_L", ui::VKEY_MENU}, {"Meta_R", ui::VKEY_MENU},
+
+        // comes from KeyboardCodeFromXKeysym
+        {"BackSpace", ui::VKEY_BACK}, {"Delete", ui::VKEY_DELETE},
+        {"Tab", ui::VKEY_TAB}, {"Return", ui::VKEY_RETURN},
+        {"KP_Enter", ui::VKEY_RETURN}, {"Clear", ui::VKEY_CLEAR},
+        {"space", ui::VKEY_SPACE}, {"Home", ui::VKEY_HOME},
+        {"KP_Home", ui::VKEY_HOME}, {"End", ui::VKEY_END},
+        {"KP_End", ui::VKEY_END}, {"Prior", ui::VKEY_PRIOR},
+        {"KP_Prior", ui::VKEY_PRIOR}, {"Next", ui::VKEY_NEXT},
+        {"KP_Next", ui::VKEY_NEXT}, {"Left", ui::VKEY_LEFT},
+        {"KP_Left", ui::VKEY_LEFT}, {"Right", ui::VKEY_RIGHT},
+        {"KP_Right", ui::VKEY_RIGHT}, {"Down", ui::VKEY_DOWN},
+        {"KP_Down", ui::VKEY_DOWN}, {"Up", ui::VKEY_UP}, {"KP_Up", ui::VKEY_UP},
+        {"Escape", ui::VKEY_ESCAPE}, {"Kana_Lock", ui::VKEY_KANA},
+        {"Kana_Shift", ui::VKEY_KANA}, {"Hangul", ui::VKEY_HANGUL},
+        {"Hangul_Hanja", ui::VKEY_HANJA}, {"Kanji", ui::VKEY_KANJI},
+        {"Henkan", ui::VKEY_CONVERT}, {"Muhenkan", ui::VKEY_NONCONVERT},
+        {"Zenkaku_Hankaku", ui::VKEY_DBE_DBCSCHAR}, {"KP_0", ui::VKEY_NUMPAD0},
+        {"KP_1", ui::VKEY_NUMPAD1}, {"KP_2", ui::VKEY_NUMPAD2},
+        {"KP_3", ui::VKEY_NUMPAD3}, {"KP_4", ui::VKEY_NUMPAD4},
+        {"KP_5", ui::VKEY_NUMPAD5}, {"KP_6", ui::VKEY_NUMPAD6},
+        {"KP_7", ui::VKEY_NUMPAD7}, {"KP_8", ui::VKEY_NUMPAD8},
+        {"KP_9", ui::VKEY_NUMPAD9}, {"KP_Multiply", ui::VKEY_MULTIPLY},
+        {"KP_Add", ui::VKEY_ADD}, {"KP_Separator", ui::VKEY_SEPARATOR},
+        {"KP_Subtract", ui::VKEY_SUBTRACT}, {"KP_Decimal", ui::VKEY_DECIMAL},
+        {"KP_Divide", ui::VKEY_DIVIDE},
+
+        {"ISO_Level5_Shift", ui::VKEY_OEM_8},
+        {"ISO_Level3_Shift", ui::VKEY_ALTGR}, {"Mode_switch", ui::VKEY_ALTGR},
+        {"Multi_key", ui::VKEY_COMPOSE}, {"Pause", ui::VKEY_PAUSE},
+        {"Caps_Lock", ui::VKEY_CAPITAL}, {"Num_Lock", ui::VKEY_NUMLOCK},
+        {"Scroll_Lock", ui::VKEY_SCROLL}, {"Print", ui::VKEY_PRINT},
+        {"Execute", ui::VKEY_EXECUTE}, {"Insert", ui::VKEY_INSERT},
+        {"KP_Insert", ui::VKEY_INSERT}, {"Help", ui::VKEY_HELP},
+        {"Super_L", ui::VKEY_LWIN}, {"Super_R", ui::VKEY_RWIN},
+        {"Menu", ui::VKEY_APPS}, {"F1", ui::VKEY_F1}, {"KP_F1", ui::VKEY_F1},
+        {"F2", ui::VKEY_F2}, {"KP_F2", ui::VKEY_F2}, {"F3", ui::VKEY_F3},
+        {"KP_F3", ui::VKEY_F3}, {"F4", ui::VKEY_F4}, {"KP_F4", ui::VKEY_F4},
+        {"F5", ui::VKEY_F5}, {"F6", ui::VKEY_F6}, {"F7", ui::VKEY_F7},
+        {"F8", ui::VKEY_F8}, {"F9", ui::VKEY_F9}, {"F10", ui::VKEY_F10},
+        {"F11", ui::VKEY_F11}, {"F12", ui::VKEY_F12}, {"F13", ui::VKEY_F13},
+        {"F14", ui::VKEY_F14}, {"F15", ui::VKEY_F15}, {"F16", ui::VKEY_F16},
+        {"F17", ui::VKEY_F17}, {"F18", ui::VKEY_F18}, {"F19", ui::VKEY_F19},
+        {"F20", ui::VKEY_F20}, {"F21", ui::VKEY_F21}, {"F22", ui::VKEY_F22},
+        {"F23", ui::VKEY_F23}, {"F24", ui::VKEY_F24},
+        {"guillemotleft", ui::VKEY_OEM_102},
+        {"guillemotright", ui::VKEY_OEM_102}, {"degree", ui::VKEY_OEM_102},
+        {"ugrave", ui::VKEY_OEM_102}, {"Ugrave", ui::VKEY_OEM_102},
+        {"brokenbar", ui::VKEY_OEM_102},
+        {"XF86Forward", ui::VKEY_BROWSER_FORWARD},
+        {"XF86Reload", ui::VKEY_BROWSER_REFRESH},
+        {"XF86Stop", ui::VKEY_BROWSER_STOP},
+        {"XF86Favorites", ui::VKEY_BROWSER_FAVORITES},
+        {"XF86HomePage", ui::VKEY_BROWSER_HOME},
+        {"XF86AudioMute", ui::VKEY_VOLUME_MUTE},
+        {"XF86AudioLowerVolume", ui::VKEY_VOLUME_DOWN},
+        {"XF86AudioRaiseVolume", ui::VKEY_VOLUME_UP},
+
+#if !defined(OS_TIZEN_TV_PRODUCT)
+        {"XF86Search", ui::VKEY_BROWSER_SEARCH},
+        {"XF86AudioNext", ui::VKEY_MEDIA_NEXT_TRACK},
+        {"XF86AudioPrev", ui::VKEY_MEDIA_PREV_TRACK},
+        {"XF86AudioStop", ui::VKEY_MEDIA_STOP},
+        {"XF86AudioPlay", ui::VKEY_MEDIA_PLAY_PAUSE},
+        {"Select", ui::VKEY_SELECT}, {"XF86Back", ui::VKEY_BROWSER_BACK},
+#endif
+        {"XF86Mail", ui::VKEY_MEDIA_LAUNCH_MAIL},
+        {"XF86LaunchA", ui::VKEY_MEDIA_LAUNCH_APP1},
+        {"XF86LaunchB", ui::VKEY_MEDIA_LAUNCH_APP2},
+        {"XF86Calculator", ui::VKEY_MEDIA_LAUNCH_APP2},
+        {"XF86WLAN", ui::VKEY_WLAN}, {"XF86PowerOff", ui::VKEY_POWER},
+        {"XF86Sleep", ui::VKEY_SLEEP},
+        {"XF86MonBrightnessDown", ui::VKEY_BRIGHTNESS_DOWN},
+        {"XF86MonBrightnessUp", ui::VKEY_BRIGHTNESS_UP},
+        {"XF86KbdBrightnessDown", ui::VKEY_KBD_BRIGHTNESS_DOWN},
+        {"XF86KbdBrightnessUp", ui::VKEY_KBD_BRIGHTNESS_UP},
+
+        {"0", ui::VKEY_0}, {"1", ui::VKEY_1}, {"2", ui::VKEY_2},
+        {"3", ui::VKEY_3}, {"4", ui::VKEY_4}, {"5", ui::VKEY_5},
+        {"6", ui::VKEY_6}, {"7", ui::VKEY_7}, {"8", ui::VKEY_8},
+        {"9", ui::VKEY_9},
+
+        // XXX: it won't work on all keyboard layouts
+        {"comma", ui::VKEY_OEM_COMMA}, {"less", ui::VKEY_OEM_COMMA},
+        {"minus", ui::VKEY_OEM_MINUS}, {"underscore", ui::VKEY_OEM_MINUS},
+        {"greater", ui::VKEY_OEM_PERIOD}, {"period", ui::VKEY_OEM_PERIOD},
+        {"semicolon", ui::VKEY_OEM_1}, {"colon", ui::VKEY_OEM_1},
+        {"question", ui::VKEY_OEM_2}, {"slash", ui::VKEY_OEM_2},
+        {"asciitilde", ui::VKEY_OEM_3}, {"quoteleft", ui::VKEY_OEM_3},
+        {"bracketleft", ui::VKEY_OEM_4}, {"braceleft", ui::VKEY_OEM_4},
+        {"backslash", ui::VKEY_OEM_5}, {"bar", ui::VKEY_OEM_5},
+        {"bracketright", ui::VKEY_OEM_6}, {"braceright", ui::VKEY_OEM_6},
+        {"quoteright", ui::VKEY_OEM_7}, {"quotedbl", ui::VKEY_OEM_7},
+
+        // support specail keys "!@#$%^&*()+='`"
+        {"exclam", ui::VKEY_1}, {"at", ui::VKEY_2}, {"numbersign", ui::VKEY_3},
+        {"dollar", ui::VKEY_4}, {"percent", ui::VKEY_5},
+        {"asciicircum", ui::VKEY_6}, {"ampersand", ui::VKEY_7},
+        {"asterisk", ui::VKEY_8}, {"parenleft", ui::VKEY_9},
+        {"parenright", ui::VKEY_0}, {"plus", ui::VKEY_OEM_PLUS},
+        {"equal", ui::VKEY_OEM_PLUS}, {"apostrophe", ui::VKEY_OEM_7},
+        {"grave", ui::VKEY_OEM_3},
+
+        // XXX: handle accents and other characters
+        {"a", ui::VKEY_A}, {"A", ui::VKEY_A}, {"b", ui::VKEY_B},
+        {"B", ui::VKEY_B}, {"c", ui::VKEY_C}, {"C", ui::VKEY_C},
+        {"d", ui::VKEY_D}, {"D", ui::VKEY_D}, {"e", ui::VKEY_E},
+        {"E", ui::VKEY_E}, {"f", ui::VKEY_F}, {"F", ui::VKEY_F},
+        {"g", ui::VKEY_G}, {"G", ui::VKEY_G}, {"h", ui::VKEY_H},
+        {"H", ui::VKEY_H}, {"i", ui::VKEY_I}, {"I", ui::VKEY_I},
+        {"j", ui::VKEY_J}, {"J", ui::VKEY_J}, {"k", ui::VKEY_K},
+        {"K", ui::VKEY_K}, {"l", ui::VKEY_L}, {"L", ui::VKEY_L},
+        {"m", ui::VKEY_M}, {"M", ui::VKEY_M}, {"n", ui::VKEY_N},
+        {"N", ui::VKEY_N}, {"o", ui::VKEY_O}, {"O", ui::VKEY_O},
+        {"p", ui::VKEY_P}, {"P", ui::VKEY_P}, {"q", ui::VKEY_Q},
+        {"Q", ui::VKEY_Q}, {"r", ui::VKEY_R}, {"R", ui::VKEY_R},
+        {"s", ui::VKEY_S}, {"S", ui::VKEY_S}, {"t", ui::VKEY_T},
+        {"T", ui::VKEY_T}, {"u", ui::VKEY_U}, {"U", ui::VKEY_U},
+        {"v", ui::VKEY_V}, {"V", ui::VKEY_V}, {"w", ui::VKEY_W},
+        {"W", ui::VKEY_W}, {"x", ui::VKEY_X}, {"X", ui::VKEY_X},
+        {"y", ui::VKEY_Y}, {"Y", ui::VKEY_Y}, {"z", ui::VKEY_Z},
+        {"Z", ui::VKEY_Z},
+  });
+
+  auto uicode = code_from_key_map.find(key);
+  if (uicode == code_from_key_map.end())
+    return ui::VKEY_UNKNOWN;
+
+  return uicode->second;
+}
+
+}  // namespace ui
diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_platform_event_source.cc b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_platform_event_source.cc
new file mode 100644 (file)
index 0000000..23d4153
--- /dev/null
@@ -0,0 +1,23 @@
+// Copyright 2021 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/efl/efl_platform_event_source.h"
+
+namespace ui {
+
+EflPlatformEventSource::EflPlatformEventSource() = default;
+
+EflPlatformEventSource::~EflPlatformEventSource() = default;
+
+// static
+EflPlatformEventSource* EflPlatformEventSource::GetInstance() {
+  return static_cast<EflPlatformEventSource*>(
+      PlatformEventSource::GetInstance());
+}
+
+void EflPlatformEventSource::DispatchEflEvent(PlatformEvent platform_event) {
+  PlatformEventSource::DispatchEvent(platform_event);
+}
+
+}  // namespace ui
diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_platform_event_source.h b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_platform_event_source.h
new file mode 100644 (file)
index 0000000..0429387
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2021 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_PLATFORM_EFL_EFL_PLATFORM_EVENT_SOURCE_H_
+#define UI_OZONE_PLATFORM_EFL_EFL_PLATFORM_EVENT_SOURCE_H_
+
+#include "ui/events/platform/platform_event_source.h"
+
+namespace ui {
+
+// Efl implementation of ui::PlatformEventSource.
+class EflPlatformEventSource : public PlatformEventSource {
+ public:
+  EflPlatformEventSource();
+  ~EflPlatformEventSource() override;
+
+  EflPlatformEventSource(const EflPlatformEventSource&) = delete;
+  EflPlatformEventSource& operator=(const EflPlatformEventSource&) = delete;
+
+  static EflPlatformEventSource* GetInstance();
+  void DispatchEflEvent(PlatformEvent platform_event);
+};
+
+}  // namespace ui
+
+#endif  // UI_OZONE_PLATFORM_EFL_EFL_PLATFORM_EVENT_SOURCE_H_
index c5ffdb357daa17130de08dd19c3d8e3028d08231..4d8784797fae55563124ca767c20e0cb732d4bc8 100644 (file)
@@ -5,21 +5,38 @@
 #include "ui/ozone/platform/efl/efl_window.h"
 
 #include "base/base_switches.h"
+#include "base/bind.h"
 #include "base/command_line.h"
 #include "base/logging.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/notreached.h"
 #include "ui/base/cursor/platform_cursor.h"
+#include "ui/events/ozone/events_ozone.h"
+#include "ui/ozone/platform/efl/efl_event_handler.h"
+#include "ui/ozone/platform/efl/efl_platform_event_source.h"
+#include "ui/ozone/platform/efl/efl_screen.h"
+#include "ui/ozone/platform/efl/efl_window_manager.h"
+
+#if defined(OS_TIZEN_TV_PRODUCT)
+#include <cursor_module.h>
+#endif
 
 namespace ui {
 
+#if defined(OS_TIZEN_TV_PRODUCT)
+bool EflWindow::is_cursor_initialized_ = false;
+#endif
+
 EflWindow::EflWindow(PlatformWindowDelegate* delegate,
-                     PlatformWindowInitProperties properties)
-    : delegate_(delegate) {
+                     PlatformWindowInitProperties properties,
+                     EflWindowManager* manager)
+    : delegate_(delegate), window_manager_(manager) {
   Initialize(properties);
 }
 
 EflWindow::~EflWindow() {
+  PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
+
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kEnableOffscreenRendering))
     return;
@@ -39,6 +56,13 @@ void EflWindow::Show(bool inactive) {
           switches::kEnableOffscreenRendering))
     return;
 
+  // For now, only show kWindow and ignore other types : kMenu, kTootltip etc.
+  if (type_ != PlatformWindowType::kWindow)
+    return;
+
+  if (native_view_)
+    evas_object_show(native_view_);
+
   ecore_evas_show(ee_);
 }
 
@@ -47,6 +71,12 @@ void EflWindow::Hide() {
           switches::kEnableOffscreenRendering))
     return;
 
+  if (type_ != PlatformWindowType::kWindow)
+    return;
+
+  if (native_view_)
+    evas_object_hide(native_view_);
+
   ecore_evas_hide(ee_);
 }
 
@@ -64,6 +94,15 @@ void EflWindow::PrepareForShutdown() {
 }
 
 void EflWindow::SetBoundsInPixels(const gfx::Rect& bounds) {
+  bool origin_changed = bounds_.origin() != bounds.origin();
+  bounds_ = bounds;
+  delegate_->OnBoundsChanged({origin_changed});
+
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableOffscreenRendering)) {
+    return;
+  }
+
 #if defined(USE_WAYLAND)
   if (wl2_egl_window_) {
     ecore_wl2_egl_window_resize_with_rotation(wl2_egl_window_, bounds.x(),
@@ -74,9 +113,6 @@ void EflWindow::SetBoundsInPixels(const gfx::Rect& bounds) {
   if (ee_)
     ecore_evas_resize(ee_, bounds.width(), bounds.height());
 #endif
-  bool origin_changed = bounds_.origin() != bounds.origin();
-  bounds_ = bounds;
-  delegate_->OnBoundsChanged({origin_changed});
 }
 
 gfx::Rect EflWindow::GetBoundsInPixels() const {
@@ -176,13 +212,27 @@ void EflWindow::SizeConstraintsChanged() {
 }
 
 bool EflWindow::CanDispatchEvent(const PlatformEvent& event) {
-  NOTIMPLEMENTED();
-  return false;
+  return has_focus_;
+}
+
+void EflWindow::UpdateFocus(bool focused) {
+  if (has_focus_ == focused)
+    return;
+
+  has_focus_ = focused;
+  if (!focused)
+    return;
+
+  // At any point of time only one window can have focus.
+  // Set set other windows' focus to false.
+  window_manager_->UpdateWindowFocus(this, focused);
 }
 
 uint32_t EflWindow::DispatchEvent(const PlatformEvent& event) {
-  NOTIMPLEMENTED();
-  return POST_DISPATCH_NONE;
+  bool handled = DispatchEventFromNativeUiEvent(
+      event, base::BindOnce(&PlatformWindowDelegate::DispatchEvent,
+                            base::Unretained(delegate_)));
+  return handled ? POST_DISPATCH_STOP_PROPAGATION : POST_DISPATCH_NONE;
 }
 
 void EflWindow::Initialize(const PlatformWindowInitProperties& properties) {
@@ -197,6 +247,7 @@ void EflWindow::Initialize(const PlatformWindowInitProperties& properties) {
   }
 
   ecore_evas_init();
+  evas_init();
 
 #if defined(USE_WAYLAND)
   ee_ = ecore_evas_new("wayland_egl", 0, 0, bounds_.width(), bounds_.height(),
@@ -236,6 +287,90 @@ void EflWindow::Initialize(const PlatformWindowInitProperties& properties) {
 #else
   delegate_->OnAcceleratedWidgetAvailable(ecore_evas_window_get(ee_));
 #endif
+
+  if (type_ != PlatformWindowType::kWindow)
+    return;
+
+  // Initialize efl event handler for main window
+  native_view_ = evas_object_rectangle_add(ecore_evas_get(ee_));
+  evas_object_color_set(native_view_, 0, 0, 0, 255);
+  evas_object_resize(native_view_, bounds_.width(), bounds_.height());
+
+  InitializeEventHandler();
+
+#if defined(OS_TIZEN_TV_PRODUCT)
+  CreateMouseCursor();
+#endif
+}
+
+#if defined(OS_TIZEN_TV_PRODUCT)
+void EflWindow::CreateMouseCursor() {
+  if (is_cursor_initialized_)
+    return;
+
+  Ecore_Wl2_Display* wl2_display = ecore_wl2_connected_display_get(NULL);
+  struct wl_display* display = ecore_wl2_display_get(wl2_display);
+  Eina_Iterator* globals = ecore_wl2_display_globals_get(wl2_display);
+  struct wl_registry* registry = ecore_wl2_display_registry_get(wl2_display);
+  struct wl_seat* seat =
+      ecore_wl2_input_seat_get(ecore_wl2_input_default_input_get(wl2_display));
+
+  const char* t_cursor = "tizen_cursor";
+  Ecore_Wl2_Global* global;
+  EINA_ITERATOR_FOREACH(globals, global) {
+    if (!strncmp(global->interface, t_cursor, strlen(t_cursor)))
+      if (!CursorModule_Initialize(display, registry, seat, global->id))
+        LOG(ERROR) << "CursorModule_Initialize() Failed!";
+  }
+  eina_iterator_free(globals);
+
+  struct wl_surface* const surface =
+      (struct wl_surface*)(ecore_wl2_window_native_surface_get(
+          ecore_evas_wayland2_window_get(ee_)));
+  ecore_wl2_sync();
+
+  if (!Cursor_Set_Config(surface, TIZEN_CURSOR_CONFIG_CURSOR_AVAILABLE, NULL))
+    LOG(ERROR) << "Cursor_Set_Config() Failed!";
+
+  CursorModule_Finalize();
+  is_cursor_initialized_ = true;
+}
+#endif
+
+void EflWindow::InitializeEventHandler() {
+  // Set activation true on window to capture key events.
+  delegate_->OnActivationChanged(true /*active*/);
+
+  // Set focus active for a newly opened window.
+  UpdateFocus(true);
+
+  efl_event_handler_ = std::make_unique<EflEventHandler>(this);
+  PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
+}
+
+void EflWindow::ResetEventHandler() {
+  delegate_->OnActivationChanged(false /*active*/);
+  UpdateFocus(false);
+  efl_event_handler_.reset();
+}
+
+// Offscreen
+void EflWindow::SetNativeViewOffscreen(Evas_Object* native_view) {
+  native_view_ = native_view;
+  evas_ = evas_object_evas_get(native_view_);
+  ee_ = ecore_evas_ecore_evas_get(evas_);
+
+  if (EflWindow* window = window_manager_->GetWindow(native_view_)) {
+    // Sometimes multiple child aura windows will be created for the same RWHVA
+    // which results in multiple EflWindows creation for the same native_view_.
+    // If a native_view_ already had an associated EflWindow, then deregister it
+    // and register the newly created one.
+    window->ResetEventHandler();
+    window_manager_->RemoveWindow(native_view_);
+  }
+  window_manager_->AddWindow(this, native_view_);
+
+  InitializeEventHandler();
 }
 
 }  // namespace ui
index 1aaad68962b7458f16fb8bde94a92fe05737b555..d951668235150d5721a691effa351d46b122ac84 100644 (file)
 
 namespace ui {
 
+class EflEventHandler;
+class EflWindowManager;
+
 class EflWindow : public PlatformWindow, public PlatformEventDispatcher {
  public:
   EflWindow(PlatformWindowDelegate* delegate,
-            PlatformWindowInitProperties properties);
+            PlatformWindowInitProperties properties,
+            EflWindowManager* manager);
 
   EflWindow(const EflWindow&) = delete;
   EflWindow& operator=(const EflWindow&) = delete;
@@ -65,11 +69,32 @@ class EflWindow : public PlatformWindow, public PlatformEventDispatcher {
   bool CanDispatchEvent(const PlatformEvent& event) override;
   uint32_t DispatchEvent(const PlatformEvent& event) override;
 
+  // Called only in case of offscreen rendering
+  void SetNativeViewOffscreen(Evas_Object* native_view) override;
+
+  void UpdateFocus(bool focused);
+  void SetFocus(bool focused) { has_focus_ = focused; }
+
+  Evas* evas() const { return evas_; }
+  Evas_Object* native_view() const { return native_view_; }
+
+  EflEventHandler* GetEventHandler() override {
+    return efl_event_handler_.get();
+  }
+
  private:
   void Initialize(const PlatformWindowInitProperties& properties);
+  void InitializeEventHandler();
+  void ResetEventHandler();
+#if defined(OS_TIZEN_TV_PRODUCT)
+  void CreateMouseCursor();
+  static bool is_cursor_initialized_;
+#endif
 
   PlatformWindowDelegate* delegate_;
 
+  EflWindowManager* window_manager_ = nullptr;
+
   // Current bounds of the platform window.
   gfx::Rect bounds_;
   // The bounds of the platform window before it went maximized or fullscreen.
@@ -81,11 +106,16 @@ class EflWindow : public PlatformWindow, public PlatformEventDispatcher {
   // The type of the current WaylandWindow object.
   ui::PlatformWindowType type_ = ui::PlatformWindowType::kWindow;
 
-  Ecore_Evas* ee_ = nullptr;
+  bool has_focus_ = false;
 
+  Ecore_Evas* ee_ = nullptr;
+  Evas* evas_ = nullptr;
+  Evas_Object* native_view_ = nullptr;
 #if defined(USE_WAYLAND)
   Ecore_Wl2_Egl_Window* wl2_egl_window_ = nullptr;
 #endif
+
+  std::unique_ptr<EflEventHandler> efl_event_handler_;
 };
 
 }  // namespace ui
diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window_manager.h b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_window_manager.h
new file mode 100644 (file)
index 0000000..7de95a1
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright (c) 2021 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_PLATFORM_EFL_EFL_WINDOW_MANAGER_
+#define UI_OZONE_PLATFORM_EFL_EFL_WINDOW_MANAGER_
+
+#include "base/containers/flat_map.h"
+#include "ui/ozone/platform/efl/efl_window.h"
+
+namespace ui {
+
+class EflWindowManager {
+ public:
+  EflWindowManager() {}
+  ~EflWindowManager() {}
+
+  EflWindowManager(const EflWindowManager&) = delete;
+  EflWindowManager& operator=(const EflWindowManager&) = delete;
+
+  void AddWindow(EflWindow* window, Evas_Object* eo) {
+    window_map_[eo] = window;
+  }
+
+  EflWindow* GetWindow(Evas_Object* eo) const {
+    auto it = window_map_.find(eo);
+    return it == window_map_.end() ? nullptr : it->second;
+  }
+
+  void RemoveWindow(Evas_Object* eo) {
+    auto* window = window_map_[eo];
+    DCHECK(window);
+    window_map_.erase(eo);
+  }
+
+  void UpdateWindowFocus(EflWindow* window, bool focused) {
+    for (const auto& item : window_map_) {
+      if (item.second != window)
+        item.second->SetFocus(false);
+    }
+  }
+
+  std::vector<EflWindow*> GetAllOpenWindows() const {
+    std::vector<EflWindow*> all_windows;
+    for (const auto& item : window_map_)
+      all_windows.push_back(item.second);
+    return all_windows;
+  }
+
+ private:
+  base::flat_map<Evas_Object*, EflWindow*> window_map_;
+};
+
+}  // namespace ui
+
+#endif  // UI_OZONE_PLATFORM_EFL_EFL_WINDOW_MANAGER_
index cffb56fa5ce320afca5e2cb0b4ba41e626f9b565..5e5d89539ba9a9621e4a5f67ec89395c16775e81 100644 (file)
 #include "ui/gfx/native_widget_types.h"
 #include "ui/ozone/common/bitmap_cursor_factory.h"
 #include "ui/ozone/common/stub_overlay_manager.h"
+#include "ui/ozone/platform/efl/efl_platform_event_source.h"
 #include "ui/ozone/platform/efl/efl_screen.h"
 #include "ui/ozone/platform/efl/efl_surface_factory.h"
 #include "ui/ozone/platform/efl/efl_window.h"
+#include "ui/ozone/platform/efl/efl_window_manager.h"
 #include "ui/ozone/public/gpu_platform_support_host.h"
 #include "ui/ozone/public/input_controller.h"
 #include "ui/ozone/public/ozone_platform.h"
@@ -75,7 +77,8 @@ class OzonePlatformEfl : public OzonePlatform {
   std::unique_ptr<PlatformWindow> CreatePlatformWindow(
       PlatformWindowDelegate* delegate,
       PlatformWindowInitProperties properties) override {
-    return std::make_unique<EflWindow>(delegate, std::move(properties));
+    return std::make_unique<EflWindow>(delegate, std::move(properties),
+                                       efl_window_manager_.get());
   }
 
   std::unique_ptr<display::NativeDisplayDelegate> CreateNativeDisplayDelegate()
@@ -116,6 +119,8 @@ class OzonePlatformEfl : public OzonePlatform {
       LOG(ERROR) << "Failed to initialize ecore-x.";
 #endif
 
+    platform_event_source_ = std::make_unique<EflPlatformEventSource>();
+    efl_window_manager_ = std::make_unique<EflWindowManager>();
     keyboard_layout_engine_ = std::make_unique<StubKeyboardLayoutEngine>();
     KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(
         keyboard_layout_engine_.get());
@@ -145,6 +150,8 @@ class OzonePlatformEfl : public OzonePlatform {
   void AddInterfaces(mojo::BinderMap* binders) override {}
 
  private:
+  std::unique_ptr<PlatformEventSource> platform_event_source_;
+  std::unique_ptr<EflWindowManager> efl_window_manager_;
   std::unique_ptr<KeyboardLayoutEngine> keyboard_layout_engine_;
   std::unique_ptr<EflSurfaceFactory> surface_factory_;
   std::unique_ptr<CursorFactory> cursor_factory_;
index 3e0d5aa5eac0ea0b651204e0198947cecca1184b..4a4c755421ec76097afc30566ce0d52875f5a2ed 100644 (file)
@@ -301,13 +301,27 @@ void EWebView::ReleasePopupMenuList() {
   popupMenuItems_ = 0;
 }
 
+content::RenderWidgetHostViewAura* EWebView::rwhva() const {
+  return static_cast<content::RenderWidgetHostViewAura*>(
+      web_contents_->GetRenderWidgetHostView());
+}
+
 void EWebView::ResetContextMenuController() {
   return context_menu_.reset();
 }
 
 void EWebView::SetFocus(Eina_Bool focus) {
-  if (HasFocus() != focus)
-    elm_object_focus_set(native_view_, focus);
+  if (!web_contents_ || !rwhva() || (HasFocus() == focus))
+    return;
+
+  rwhva()->offscreen_helper()->Focus(focus);
+}
+
+Eina_Bool EWebView::HasFocus() const {
+  if (!rwhva())
+    return EINA_FALSE;
+
+  return rwhva()->offscreen_helper()->HasFocus() ? EINA_TRUE : EINA_FALSE;
 }
 
 void EWebView::CreateNewWindow(
@@ -376,10 +390,6 @@ Eina_Bool EWebView::CanGoForward() {
   return web_contents_->GetController().CanGoForward();
 }
 
-Eina_Bool EWebView::HasFocus() const {
-  return elm_object_focus_get(native_view_);
-}
-
 Eina_Bool EWebView::GoBack() {
   if (!web_contents_->GetController().CanGoBack())
     return EINA_FALSE;
index c05ad97e3dba138e616506c2530aae75b4f44fc8..36aa94c11328c8e732b726f6adfe877b3d50b99f 100644 (file)
@@ -64,6 +64,7 @@ class WindowParentingClient;
 namespace content {
 class RenderFrameHost;
 class RenderViewHost;
+class RenderWidgetHostViewAura;
 class WebContentsDelegateEfl;
 class ContextMenuControllerEfl;
 class PopupControllerEfl;
@@ -183,6 +184,7 @@ class EWebView {
       content::WebContentsEflDelegate::WebContentsCreateCallback);
   static Evas_Object* GetHostWindowDelegate(const content::WebContents*);
 
+  content::RenderWidgetHostViewAura* rwhva() const;
   Ewk_Context* context() const { return context_.get(); }
   Evas_Object* evas_object() const { return evas_object_; }
   Evas_Object* native_view() const { return native_view_; }
index 254a6a0b13e88b6a1999de5122d3246c61ba5f3d..a7cf4a6059df6dc3fde6980775262413a8c41907 100644 (file)
@@ -94,7 +94,6 @@ Window::Window(Browser& browser, int width, int height, bool incognito)
                                    EVAS_HINT_EXPAND);
   elm_box_pack_end(box, web_view_elm_host_);
   elm_object_focus_allow_set(web_view_elm_host_, EINA_TRUE);
-  elm_object_focus_set(web_view_elm_host_, EINA_TRUE);
   evas_object_show(web_view_elm_host_);
 
   Evas* evas = evas_object_evas_get(window_);
@@ -724,6 +723,9 @@ void Window::OnLoadFinished(void* data, Evas_Object*, void*) {
   log_trace("%s", __PRETTY_FUNCTION__);
   thiz->browser_.OnWindowLoadFinished(thiz->Id());
   thiz->ui_->OnLoadingFinished();
+
+  // Set initial focus on webview host after load is finished.
+  elm_object_focus_set(thiz->web_view_elm_host_, EINA_TRUE);
 }
 
 void Window::OnConsoleMessage(void*, Evas_Object*, void* event_info) {
index c41d5cd63096fad62ede4240bf624da91ebf3e93..7e6028598aa076a7bc6fb90f7801b87854c93259 100644 (file)
@@ -786,6 +786,14 @@ void Window::Focus() {
   client->FocusWindow(this);
 }
 
+#if defined(USE_EFL)
+void Window::LostFocus() {
+  client::FocusClient* client = client::GetFocusClient(this);
+  DCHECK(client);
+  client->FocusWindow(nullptr);
+}
+#endif
+
 bool Window::HasFocus() const {
   client::FocusClient* client = client::GetFocusClient(this);
   return client && client->GetFocusedWindow() == this;
index b01edaf3c43376467f152309e33649180530b5f8..a3304debea08aa2554cee68031eabc8b926420e9 100644 (file)
@@ -421,6 +421,11 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
   // Claims focus.
   void Focus();
 
+#if defined(USE_EFL)
+  // Focus lost.
+  void LostFocus();
+#endif
+
   // Returns true if the Window is currently the focused window.
   bool HasFocus() const;
 
index a7bd3ef17a728fe92b510ae7075c9f01771bdc9b..d7ea97cc31b3382ccca5a98f686cf1a6f670cb51 100644 (file)
 #include "ui/gfx/native_widget_types.h"
 #include "ui/platform_window/platform_window_delegate.h"
 
+#if defined(USE_EFL)
+#include <Evas.h>
+#endif
+
 template <class T>
 class scoped_refptr;
 
@@ -30,6 +34,10 @@ class Transform;
 namespace ui {
 class PlatformCursor;
 
+#if defined(USE_EFL)
+class EflEventHandler;
+#endif
+
 // Generic PlatformWindow interface.
 class COMPONENT_EXPORT(PLATFORM_WINDOW) PlatformWindow
     : public PropertyHandler {
@@ -199,6 +207,13 @@ class COMPONENT_EXPORT(PLATFORM_WINDOW) PlatformWindow
   // Notifies the DE that the app is done loading, so that it can dismiss any
   // loading animations.
   virtual void NotifyStartupComplete(const std::string& startup_id);
+
+#if defined(USE_EFL)
+  // Sets native_view created in RWHVAura for offscreen rendering.
+  virtual void SetNativeViewOffscreen(Evas_Object* native_view) {}
+
+  virtual EflEventHandler* GetEventHandler() { return nullptr; }
+#endif
 };
 
 }  // namespace ui