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();
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() {
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
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();
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);
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);
}
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();
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;
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",
]
]
}
+ if (tizen_product_tv) {
+ configs += [ "//tizen_src/build:libvd-win-util" ]
+ }
+
defines = [ "OZONE_IMPLEMENTATION" ]
}
--- /dev/null
+// 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
--- /dev/null
+// 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_
--- /dev/null
+// 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
--- /dev/null
+// 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
--- /dev/null
+// 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_
#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;
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_);
}
switches::kEnableOffscreenRendering))
return;
+ if (type_ != PlatformWindowType::kWindow)
+ return;
+
+ if (native_view_)
+ evas_object_hide(native_view_);
+
ecore_evas_hide(ee_);
}
}
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(),
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 {
}
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) {
}
ecore_evas_init();
+ evas_init();
#if defined(USE_WAYLAND)
ee_ = ecore_evas_new("wayland_egl", 0, 0, bounds_.width(), bounds_.height(),
#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
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;
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.
// 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
--- /dev/null
+// 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_
#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"
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()
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());
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_;
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(
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;
namespace content {
class RenderFrameHost;
class RenderViewHost;
+class RenderWidgetHostViewAura;
class WebContentsDelegateEfl;
class ContextMenuControllerEfl;
class PopupControllerEfl;
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_; }
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_);
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) {
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;
// 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;
#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;
namespace ui {
class PlatformCursor;
+#if defined(USE_EFL)
+class EflEventHandler;
+#endif
+
// Generic PlatformWindow interface.
class COMPONENT_EXPORT(PLATFORM_WINDOW) PlatformWindow
: public PropertyHandler {
// 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