[M120 Migration][VD] Support Pointer Lock API for WRT 27/310527/4
authorfang fengrong <fr.fang@samsung.com>
Tue, 30 Apr 2024 09:08:51 +0000 (17:08 +0800)
committerBot Blink <blinkbot@samsung.com>
Mon, 6 May 2024 08:43:32 +0000 (08:43 +0000)
1:The Pointer Lock API is WASM team's requirement for WebApp from tizen 5.5.

  Now We support the Pointer Lock API as below:
  1. Element.requestPointerLock()
  2. Document.exitPointerLock()
  3. Document: pointerlockchange
  4. Document.onpointerlockchange
  5. Document: pointerlockerrors
  6. Document.onpointerlockerror
  7. Document.pointerLockElement
  Refer:https://www.w3.org/TR/pointerlock/

refer:
https://review.tizen.org/gerrit/#/c/293093
https://review.tizen.org/gerrit/#/c/301993/
https://review.tizen.org/gerrit/#/c/302015
https://review.tizen.org/gerrit/#/c/303532

Change-Id: I3a44d90854c895215ba30656d6e613551e207d49
Signed-off-by: fang fengrong <fr.fang@samsung.com>
content/browser/renderer_host/render_widget_host_view_aura.cc
content/browser/renderer_host/render_widget_host_view_aura.h
third_party/blink/renderer/core/dom/document.cc
third_party/blink/renderer/core/dom/element.cc
tizen_src/chromium_impl/content/browser/browser_efl.gni
tizen_src/chromium_impl/content/browser/renderer_host/pointer_lock.cc [new file with mode: 0644]
tizen_src/chromium_impl/content/browser/renderer_host/pointer_lock.h [new file with mode: 0644]
tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.cc
tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.h
tizen_src/chromium_impl/ui/ozone/platform/efl/efl_event_handler.cc
tizen_src/chromium_impl/ui/ozone/platform/efl/efl_event_handler.h

index 1bf0cc6fc210926b8e29c72df5a82c4d6756abfb..b01a99585f2a31cd56621e7ddfd18f0c6378f670 100644 (file)
 #include "ui/display/device_display_info_efl.h"
 #endif
 
+#if BUILDFLAG(IS_TIZEN_TV)
+#include "tizen_src/chromium_impl/content/browser/renderer_host/pointer_lock.h"
+#include "ui/ozone/platform/efl/efl_event_handler.h"
+#endif
+
 using gfx::RectToSkIRect;
 using gfx::SkIRectToRect;
 
@@ -333,6 +338,10 @@ RenderWidgetHostViewAura::RenderWidgetHostViewAura(
   if (aura_efl_helper())
     aura_efl_helper()->SetOrientation(rotation_);
 #endif
+
+#if BUILDFLAG(IS_TIZEN_TV)
+  pointer_lock_ = std::make_unique<PointerLock>(this, &web_contents);
+#endif
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -977,7 +986,16 @@ void RenderWidgetHostViewAura::WindowTitleChanged() {
 }
 
 bool RenderWidgetHostViewAura::IsMouseLocked() {
+#if BUILDFLAG(IS_TIZEN_TV)
+  ui::EflEventHandler* efl_event_handler =
+      efl_helper_ ? efl_helper_->GetEventHandler() : nullptr;
+  if (!efl_event_handler)
+    return false;
+
+  return efl_event_handler->IsMouseLocked();
+#else
   return event_handler_->mouse_locked();
+#endif
 }
 
 gfx::Size RenderWidgetHostViewAura::GetVisibleViewportSize() {
@@ -1467,7 +1485,17 @@ void RenderWidgetHostViewAura::SetMainFrameAXTreeID(ui::AXTreeID id) {
 
 blink::mojom::PointerLockResult RenderWidgetHostViewAura::LockMouse(
     bool request_unadjusted_movement) {
+#if BUILDFLAG(IS_TIZEN_TV)
+  ui::EflEventHandler* efl_event_handler =
+      efl_helper_ ? efl_helper_->GetEventHandler() : nullptr;
+  if (!efl_event_handler)
+    return blink::mojom::PointerLockResult::kWrongDocument;
+
+  efl_event_handler->SetPointerLock(pointer_lock_.get());
+  return efl_event_handler->LockMouse();
+#else
   return event_handler_->LockMouse(request_unadjusted_movement);
+#endif
 }
 
 blink::mojom::PointerLockResult RenderWidgetHostViewAura::ChangeMouseLock(
@@ -1476,7 +1504,14 @@ blink::mojom::PointerLockResult RenderWidgetHostViewAura::ChangeMouseLock(
 }
 
 void RenderWidgetHostViewAura::UnlockMouse() {
+#if BUILDFLAG(IS_TIZEN_TV)
+  ui::EflEventHandler* efl_event_handler =
+      efl_helper_ ? efl_helper_->GetEventHandler() : nullptr;
+  if (efl_event_handler)
+    efl_event_handler->UnlockMouse();
+#else
   event_handler_->UnlockMouse();
+#endif
 }
 
 bool RenderWidgetHostViewAura::GetIsMouseLockedUnadjustedMovementForTesting() {
index 24d4f1708840bfb2e17ad16acc8ba81530fdbded..075a874a639218347b16660bd53bd3c5667a3570 100644 (file)
@@ -78,6 +78,9 @@ namespace ui {
 enum class DomCode : uint32_t;
 class InputMethod;
 class LocatedEvent;
+#if BUILDFLAG(IS_TIZEN_TV)
+class EflEventHandler;
+#endif
 }
 
 namespace content {
@@ -86,6 +89,10 @@ class LegacyRenderWidgetHostHWND;
 class DirectManipulationBrowserTestBase;
 #endif
 
+#if BUILDFLAG(IS_TIZEN_TV)
+class PointerLock;
+#endif
+
 class CursorManager;
 class DelegatedFrameHost;
 class DelegatedFrameHostClient;
@@ -902,6 +909,10 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
   std::unique_ptr<RWHVAuraCommonHelperEfl> efl_helper_;
 #endif
 
+#if BUILDFLAG(IS_TIZEN_TV)
+  std::unique_ptr<PointerLock> pointer_lock_;
+#endif
+
   bool allocate_local_surface_id_on_next_show_ = false;
 
 #if defined(TIZEN_VIDEO_HOLE)
index d6cdaa688a6e7884de20695ec346c310da3729e7..a1b8541d4797f788529e34062e9647f59b4343ca 100644 (file)
@@ -8163,6 +8163,7 @@ void Document::SetPopoverPointerdownTarget(const HTMLElement* popover) {
 }
 
 void Document::exitPointerLock() {
+  LOG(INFO) << "request exitPointerLock";
   if (!GetPage())
     return;
   if (Element* target = GetPage()->GetPointerLockController().GetElement()) {
index 6f22bbd321908bcf444ba72509be6eac86a8a0c0..0cbb7d423dcbee5a0ee801dd28eb02e6bca70004 100644 (file)
@@ -7903,6 +7903,7 @@ void Element::SetIsInTopLayer(bool in_top_layer) {
 ScriptValue Element::requestPointerLock(ScriptState* script_state,
                                         const PointerLockOptions* options,
                                         ExceptionState& exception_state) {
+  LOG(INFO) << "request PointerLock";
   auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(
       script_state, exception_state.GetContext());
   ScriptPromise promise;
index 914da39924df6a7f8a1ee247ae0602d01aadd903..ae0697e2a9d6fa7bdd0a559331d179060698ebc4 100644 (file)
@@ -167,6 +167,13 @@ if (tizen_multimedia) {
   ]
 }
 
+if (tizen_product_tv) {
+  external_content_browser_efl_sources += [
+    "//tizen_src/chromium_impl/content/browser/renderer_host/pointer_lock.cc",
+    "//tizen_src/chromium_impl/content/browser/renderer_host/pointer_lock.h",
+  ]
+}
+
 if (tizen_pepper_extensions && enable_plugins) {
   external_content_browser_efl_sources += [
     "//tizen_src/chromium_impl/content/browser/renderer_host/pepper/browser_pepper_host_factory_efl.h",
diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/pointer_lock.cc b/tizen_src/chromium_impl/content/browser/renderer_host/pointer_lock.cc
new file mode 100644 (file)
index 0000000..8b1d9dc
--- /dev/null
@@ -0,0 +1,266 @@
+// Copyright 2019 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 "content/browser/renderer_host/pointer_lock.h"
+
+#include "content/browser/renderer_host/render_widget_host_view_aura.h"
+#include "content/browser/renderer_host/rwhv_aura_common_helper_efl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/web_contents_delegate.h"
+#include "ecore_x_wayland_wrapper.h"
+#include "efl/window_factory.h"
+#include "ewk/efl_integration/common/application_type.h"
+#include "ui/events/event.h"
+
+namespace content {
+
+namespace {
+// In mouse lock mode, we need to prevent the (invisible) cursor from hitting
+// the border of the view, in order to get valid movement information. However,
+// forcing the cursor back to the center of the view after each mouse move
+// doesn't work well. It reduces the frequency of useful mouse move messages
+// significantly. Therefore, we move the cursor to the center of the view only
+// if it approaches the border. |kMouseLockBorderPercentage| specifies the width
+// of the border area, in percentage of the corresponding dimension.
+const int kMouseLockBorderPercentage = 15;
+
+}  // namespace
+
+PointerLock::PointerLock(RenderWidgetHostViewAura* rwhva,
+                         content::WebContents* web_contents)
+    : rwhva_(rwhva), web_contents_(web_contents) {
+  evas_ = GetEvas();
+  if (!evas_)
+    LOG(ERROR) << "GetEvas failed!";
+
+  efl_helper_ = rwhva_->aura_efl_helper();
+  if (!efl_helper_)
+    LOG(ERROR) << "efl_helper is null!";
+
+  unlocked_cursor_type_ = WebCursor(ui::mojom::CursorType::kPointer);
+}
+
+PointerLock::~PointerLock() {}
+
+void PointerLock::UpdateUnlockedCursorType(const WebCursor& webcursor) {
+  // In locking process,we no need save the fake cursor type:kTypeTVNone
+  if (!in_locking_process)
+    unlocked_cursor_type_ = webcursor;
+}
+
+void PointerLock::HideCursor() {
+  LOG(INFO) << "HideCursor";
+  if (efl_helper_)
+    efl_helper_->UpdateCursor(WebCursor(ui::mojom::CursorType::kNone));
+}
+
+void PointerLock::ShowCursor() {
+  LOG(INFO) << "ShowCursor";
+  if (efl_helper_)
+    efl_helper_->UpdateCursor(unlocked_cursor_type_);
+}
+
+void PointerLock::LockCursor() {
+  is_mouse_locked_ = true;
+
+  // Record the start lock position
+  LOG(INFO) << "start mouse_position X:" << unlocked_global_mouse_position_.x()
+            << ",Y:" << unlocked_global_mouse_position_.y();
+}
+
+void PointerLock::UnlockCursor() {
+  is_mouse_locked_ = false;
+}
+
+bool PointerLock::IsMouseLocked() {
+  return is_mouse_locked_;
+}
+
+bool PointerLock::IsPointLockEnabled() {
+  // now only support point lock api for WRT
+  if (content::IsTIZENWRT())
+    return true;
+  return false;
+}
+
+void PointerLock::MoveCursorToOriginal() {
+  // Ensure that the global mouse position is updated here to its original
+  // value. If we don't do this then the synthesized mouse move which is posted
+  // after the cursor is moved ends up getting a large movement delta which is
+  // not what sites expect. The delta is computed in the
+  // ModifyEventMovementAndCoords function.
+  Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_);
+  ecore_evas_pointer_warp(ee, unlocked_global_mouse_position_.x(),
+                          unlocked_global_mouse_position_.y());
+  ecore_wl2_sync();
+  LOG(INFO) << "Move Cursor To Original,x:"
+            << unlocked_global_mouse_position_.x()
+            << ",y:" << unlocked_global_mouse_position_.y();
+}
+
+void PointerLock::ModifyEventMovementAndCoords(ui::MouseEvent* event) {
+  const float sf = rwhva_->GetDeviceScaleFactor();
+  float screen_x = evas_coord_world_x_to_screen(evas_, event->x()) / sf;
+  float screen_y = evas_coord_world_x_to_screen(evas_, event->y()) / sf;
+  float client_x = event->x() / sf;
+  float client_y = event->y() / sf;
+
+  // If the mouse has just entered, we must report zero movementX/Y. Hence we
+  // reset any global_mouse_position set previously.
+  if (event->type() == ui::ET_MOUSE_ENTERED ||
+      event->type() == ui::ET_MOUSE_EXITED) {
+    global_mouse_position_.SetPoint(screen_x, screen_y);
+    LOG(INFO) << "mouse_position X:" << global_mouse_position_.x()
+              << ",Y:" << global_mouse_position_.y();
+  }
+
+  // Movement is computed by taking the difference of the new cursor position
+  // and the previous. Under mouse lock the cursor will be warped back to the
+  // center so that we are not limited by clipping boundaries.
+  // We do not measure movement as the delta from cursor to center because
+  // we may receive more mouse movement events before our warp has taken
+  // effect.
+  // TODO(crbug.com/802067): We store event coordinates as pointF but
+  // movement_x/y are integer. In order not to lose fractional part, we need
+  // to keep the movement calculation as "floor(cur_pos) - floor(last_pos)".
+  // Remove the floor here when movement_x/y is changed to double.
+
+  // Because EFL can not update mouse position timely when we set to center
+  // So we don't set the current mouse position to center until we get the
+  // center position.
+  if (pending_center_move_) {
+    gfx::PointF center_in_screen(rwhva_->GetViewBounds().CenterPoint());
+    if (screen_x == center_in_screen.x() && screen_y == center_in_screen.y()) {
+      LOG(INFO) << "current mouse position is center,set "
+                   "global_mouse_position_ to center";
+      global_mouse_position_ = center_in_screen;
+      pending_center_move_ = false;
+    }
+  }
+
+  ui::MouseEvent::DispatcherApi(event).set_movement(gfx::Vector2dF(
+      base::ClampFloor(screen_x) - base::ClampFloor(global_mouse_position_.x()),
+      base::ClampFloor(screen_y) -
+          base::ClampFloor(global_mouse_position_.y())));
+
+  // Record the previous_mouse_position
+  global_mouse_position_.SetPoint(screen_x, screen_y);
+
+  // Under mouse lock, coordinates of mouse are locked to what they were when
+  // mouse lock was entered.
+  if (IsMouseLocked()) {
+    event->set_location_f(unlocked_mouse_position_);
+    event->set_root_location_f(unlocked_global_mouse_position_);
+  } else {
+    unlocked_mouse_position_.SetPoint(client_x, client_y);
+    unlocked_global_mouse_position_.SetPoint(screen_x, screen_y);
+  }
+}
+
+bool PointerLock::ShouldMoveToCenter() {
+  gfx::Rect view_rect = rwhva_->GetViewBounds();
+  float border_x = view_rect.width() * kMouseLockBorderPercentage / 100.0;
+  float border_y = view_rect.height() * kMouseLockBorderPercentage / 100.0;
+
+  return global_mouse_position_.x() < view_rect.x() + border_x ||
+         global_mouse_position_.x() > view_rect.right() - border_x ||
+         global_mouse_position_.y() < view_rect.y() + border_y ||
+         global_mouse_position_.y() > view_rect.bottom() - border_y;
+}
+
+void PointerLock::MoveCursorToCenter() {
+  gfx::PointF center_in_screen(rwhva_->GetViewBounds().CenterPoint());
+
+  // Because EFL can not update mouse position timely when we set to center
+  // So we don't set the current mouse position to center until we get the
+  // center position.
+  LOG(INFO) << "MoveCursorToCenter,center position,X:" << center_in_screen.x()
+            << ",Y:" << center_in_screen.y();
+  pending_center_move_ = true;
+
+  // Move Cursor To Center
+  Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_);
+  ecore_evas_pointer_warp(ee, center_in_screen.x(), center_in_screen.y());
+  ecore_wl2_sync();
+}
+
+void PointerLock::HandleMouseEventForLock(ui::MouseEvent* event) {
+  ModifyEventMovementAndCoords(event);
+
+  // Check if the mouse has reached the border and needs to be centered.
+  if (IsMouseLocked()) {
+    if (ShouldMoveToCenter())
+      MoveCursorToCenter();
+  }
+}
+
+bool PointerLock::LockMouse() {
+  LOG(INFO) << "LockMouse";
+
+  if (!IsPointLockEnabled())
+    return false;
+
+  if (IsMouseLocked())
+    return true;
+
+  in_locking_process = true;
+
+  // HideCursor
+  HideCursor();
+
+  // LockCursor
+  LockCursor();
+
+  // MoveCursor To Center if needed
+  if (ShouldMoveToCenter()) {
+    MoveCursorToCenter();
+  }
+
+  // SetTooltipsEnabled(false)
+
+  in_locking_process = false;
+
+  return true;
+}
+
+void PointerLock::UnlockMouse() {
+  LOG(INFO) << "UnlockMouse";
+
+  if (!IsPointLockEnabled())
+    return;
+
+  if (!IsMouseLocked())
+    return;
+
+  // MoveCursorToOriginal
+  MoveCursorToOriginal();
+
+  // UnlockCursor
+  UnlockCursor();
+
+  // ShowCursor
+  ShowCursor();
+
+  // SetTooltipsEnabled(true)
+
+  // response lost mouse lock
+  if (auto* rwhi = rwhva_->host())
+    rwhi->LostMouseLock();
+}
+
+Evas* PointerLock::GetEvas() {
+  if (!web_contents_)
+    return nullptr;
+
+  WebContentsImpl* wci = static_cast<WebContentsImpl*>(web_contents_);
+  if (!wci)
+    return nullptr;
+
+  Evas_Object* ewk_view = static_cast<Evas_Object*>(wci->ewk_view());
+  if (!ewk_view)
+    return nullptr;
+
+  return evas_object_evas_get(ewk_view);
+}
+}  // namespace content
diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/pointer_lock.h b/tizen_src/chromium_impl/content/browser/renderer_host/pointer_lock.h
new file mode 100644 (file)
index 0000000..8677ead
--- /dev/null
@@ -0,0 +1,114 @@
+// Copyright 2019 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 POINTER_LOCK
+#define POINTER_LOCK
+
+#include <Ecore_Evas.h>
+#include <ui/gfx/geometry/point_f.h>
+#include "content/common/cursors/webcursor.h"
+#include "content/common/cursors/webcursor_efl.h"
+
+namespace ui {
+class MouseEvent;
+}
+
+namespace content {
+
+class RenderWidgetHostViewAura;
+class WebContents;
+class RWHVAuraCommonHelperEfl;
+
+class PointerLock {
+ public:
+  PointerLock(RenderWidgetHostViewAura* rwhva,
+              content::WebContents* web_contents);
+  ~PointerLock();
+
+  // Hides the cursor. Mouse events keep being sent even when the cursor is
+  // invisible.
+  void HideCursor();
+
+  // Shows the cursor. This does not take effect When mouse events are disabled.
+  void ShowCursor();
+
+  // Locks the cursor change. The cursor type, cursor visibility, and mouse
+  // events enable state never change as long as lock is held by anyone.
+  void LockCursor();
+
+  // Unlocks the cursor change. If all the locks are released, the cursor type,
+  // cursor visibility, and mouse events enable state are restored to the ones
+  // set by the lastest call of SetCursor, ShowCursor/HideCursor, and
+  // EnableMouseEvents/DisableMouseEvents.
+  void UnlockCursor();
+
+  // Check pointer is locked or not
+  bool IsMouseLocked();
+
+  // Check pointer lock api enabled or not
+  bool IsPointLockEnabled();
+
+  // Ensure that the global mouse position is updated here to its original
+  // value. If we don't do this then the synthesized mouse move which is posted
+  // after the cursor is moved ends up getting a large movement delta which is
+  // not what sites expect. The delta is computed in the
+  // ModifyEventMovementAndCoords function.
+  void MoveCursorToOriginal();
+
+  // This method computes movementX/Y and keeps track of mouse location for
+  // mouse lock on all mouse move events.
+  // |ui_mouse_event| contains the mouse event received.
+  // |event| contains the WebMouseEvent being modified.
+  void ModifyEventMovementAndCoords(ui::MouseEvent* event);
+
+  // Helper method to determine if, in mouse locked mode, the cursor should be
+  // moved to center.
+  bool ShouldMoveToCenter();
+
+  // This method moves cursor to window center for pointer lock.
+  void MoveCursorToCenter();
+
+  void HandleMouseEventForLock(ui::MouseEvent* event);
+
+  // Record the cursor type when unlocked
+  void UpdateUnlockedCursorType(const WebCursor& webcursor);
+
+  bool LockMouse();
+
+  void UnlockMouse();
+
+  Evas* GetEvas();
+
+ private:
+  RenderWidgetHostViewAura* rwhva_ = nullptr;
+  content::WebContents* web_contents_ = nullptr;
+  RWHVAuraCommonHelperEfl* efl_helper_ = nullptr;
+
+  Evas* evas_ = nullptr;
+
+  // For mouse lock
+  bool is_mouse_locked_ = false;
+
+  // Record the locking process flag
+  bool in_locking_process = false;
+
+  // Record mouse been moved to center by manual
+  bool pending_center_move_ = false;
+
+  // Last cursor position relative to screen. Used to compute movementX/Y.
+  gfx::PointF global_mouse_position_;
+
+  // Used to record the last position of the mouse when lock was entered.
+  // Relative to the upper-left corner of the view.
+  gfx::PointF unlocked_mouse_position_;
+
+  // Relative to the upper-left corner of the screen.
+  gfx::PointF unlocked_global_mouse_position_;
+
+  // Record the cursor type when unlocked
+  WebCursor unlocked_cursor_type_;
+};
+
+}  // namespace content
+#endif
index cd8f9aa11027eddf07a22518ae7e92fadfd29dac..91220d369e9506ca845199fb42a18e9eac850c51 100644 (file)
@@ -41,6 +41,7 @@
 #include "content/common/cursors/webcursor.h"
 #include "ewk/efl_integration/common/application_type.h"
 #include "third_party/skia/include/core/SkBitmap.h"
+#include "tizen_src/chromium_impl/content/browser/renderer_host/pointer_lock.h"
 #include "ui/gfx/geometry/size.h"
 
 #define VD_CURSOR_THEME_NAME "vd-cursors"
@@ -885,6 +886,19 @@ void RWHVAuraCommonHelperEfl::UpdateCursor(const WebCursor& webcursor) {
     return;
   }
 
+  if (auto* efl_event_handler = GetEventHandler()) {
+    if (efl_event_handler->IsMouseLocked()) {
+      LOG(INFO)
+          << "UpdateCursor,MouseLocked,keep on nuncursor style,JUST RETURN";
+      return;
+    }
+
+    // Record the unlocked cursor type for show original cursor when unlocked
+    PointerLock* pointer_lock = efl_event_handler->GetPointerLock();
+    if (pointer_lock && pointer_lock->IsPointLockEnabled())
+      pointer_lock->UpdateUnlockedCursorType(webcursor);
+  }
+
   UpdateCursorName(webcursor);
 #else
   SetCursor(webcursor);
index 849945d419a49d636e145480d2e33c61f03536eb..4c1270c6e46731f73529d753994b462486efb4cd 100644 (file)
@@ -66,6 +66,10 @@ class SelectionControllerEfl;
 class WebContents;
 class WebContentsDelegate;
 
+#if BUILDFLAG(IS_TIZEN_TV)
+class PointerLock;
+#endif
+
 class CONTENT_EXPORT RWHVAuraCommonHelperEfl {
  public:
   RWHVAuraCommonHelperEfl(
@@ -194,6 +198,7 @@ class CONTENT_EXPORT RWHVAuraCommonHelperEfl {
   void TextInputStateChanged(const ui::mojom::TextInputState& params);
   void OnSelectionRectReceived(const gfx::Rect& selection_rect);
   void UpdateTooltipUnderCursor(const std::u16string&);
+  ui::EflEventHandler* GetEventHandler();
 
  protected:
   void SetOffscreenMode() { is_offscreen_mode_ = true; }
@@ -211,8 +216,6 @@ class CONTENT_EXPORT RWHVAuraCommonHelperEfl {
   gfx::Size frame_data_output_size_;
 
  private:
-  ui::EflEventHandler* GetEventHandler();
-
   bool is_focused_node_editable_ = false;
   bool is_scrolling_needed_ = false;
   bool touchstart_consumed_ = false;
index 3760d4401fae16853a1f6a5085124609c20e30a2..91c8d98770e2cd24ab2379861403e9d3f3d17d65 100644 (file)
@@ -31,6 +31,7 @@
 #include "base/base_switches.h"
 #include "base/command_line.h"
 #include "third_party/blink/public/platform/web_application_type.h"
+#include "tizen_src/chromium_impl/content/browser/renderer_host/pointer_lock.h"
 #include "tizen_src/chromium_impl/ui/base/clipboard/clipboard_helper_efl.h"
 #endif
 
@@ -527,6 +528,12 @@ void EflEventHandler::OnMouseDown(void* data,
   } else {
     MouseEvent event =
         MakeWebMouseEvent(ET_MOUSE_PRESSED, ev, thiz->GetTopControlsHeight());
+#if BUILDFLAG(IS_TIZEN_TV)
+    // Handle Mouse Event For Lock
+    if (thiz->pointer_lock_ && thiz->pointer_lock_->IsPointLockEnabled())
+      thiz->pointer_lock_->HandleMouseEventForLock(&event);
+#endif
+
     EflPlatformEventSource::GetInstance()->DispatchEflEvent(&event);
 #if BUILDFLAG(IS_TIZEN_TV)
     if (!thiz->on_mouse_down_callback_.is_null()) {
@@ -558,6 +565,13 @@ void EflEventHandler::OnMouseUp(void* data,
   } else {
     MouseEvent event =
         MakeWebMouseEvent(ET_MOUSE_RELEASED, ev, thiz->GetTopControlsHeight());
+
+#if BUILDFLAG(IS_TIZEN_TV)
+    // Handle Mouse Event For Lock
+    if (thiz->pointer_lock_ && thiz->pointer_lock_->IsPointLockEnabled())
+      thiz->pointer_lock_->HandleMouseEventForLock(&event);
+#endif
+
     EflPlatformEventSource::GetInstance()->DispatchEflEvent(&event);
 #if BUILDFLAG(IS_TIZEN_TV)
     if (!thiz->on_mouse_up_callback_.is_null() &&
@@ -590,10 +604,24 @@ void EflEventHandler::OnMouseMove(void* data,
     event_flags |= button;
     MouseEvent event(ET_MOUSE_MOVED, location, location, base::TimeTicks::Now(),
                      event_flags, button);
+
+#if BUILDFLAG(IS_TIZEN_TV)
+    // Handle Mouse Event For Lock
+    if (thiz->pointer_lock_ && thiz->pointer_lock_->IsPointLockEnabled()) {
+      thiz->pointer_lock_->HandleMouseEventForLock(&event);
+    } else {
+      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)));
+    }
+#else
     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)));
+#endif
+
     EflPlatformEventSource::GetInstance()->DispatchEflEvent(&event);
 #if BUILDFLAG(IS_TIZEN_TV)
     if (!thiz->on_mouse_move_callback_.is_null())
@@ -676,6 +704,14 @@ void EflEventHandler::OnKeyDown(void* data,
             << ", Key State: Down)";
 
 #if BUILDFLAG(IS_TIZEN_TV)
+  // when point lock status,press "ESC" ,exit point lock
+  if (thiz->IsMouseLocked() && !strcmp(key_down->key, "XF86Back")) {
+    LOG(INFO) << "press ESC or Return,exit point lock when point lock status.";
+    thiz->was_keydown_filtered_as_exit_point_lock_ = true;
+    thiz->UnlockMouse();
+    return;
+  }
+
   if (!thiz->key_event_checker_.is_null() &&
       !thiz->key_event_checker_.Run(event_info, true)) {
     return;
@@ -733,6 +769,14 @@ void EflEventHandler::OnKeyUp(void* data,
             << ", Key State: Up)";
 
 #if BUILDFLAG(IS_TIZEN_TV)
+  // when point lock status,press "ESC" ,exit point lock
+  if (!strcmp(key_up->key, "XF86Back") &&
+      thiz->was_keydown_filtered_as_exit_point_lock_) {
+    thiz->was_keydown_filtered_as_exit_point_lock_ = false;
+    LOG(INFO) << "press ESC or Return,exit point lock when point lock status.";
+    return;
+  }
+
   if (!thiz->key_event_checker_.is_null() &&
       !thiz->key_event_checker_.Run(event_info, false)) {
     return;
@@ -943,6 +987,27 @@ bool EflEventHandler::IsMouseOnPopupMenu() const {
 
   return false;
 }
+
+bool EflEventHandler::IsMouseLocked() {
+  if (!pointer_lock_)
+    return false;
+
+  return pointer_lock_->IsMouseLocked();
+}
+
+blink::mojom::PointerLockResult EflEventHandler::LockMouse() {
+  LOG(INFO) << "LockMouse";
+  if (pointer_lock_ && pointer_lock_->LockMouse())
+    return blink::mojom::PointerLockResult::kSuccess;
+  else
+    return blink::mojom::PointerLockResult::kUnsupportedOptions;
+}
+
+void EflEventHandler::UnlockMouse() {
+  LOG(INFO) << "UnlockMouse";
+  if (pointer_lock_)
+    pointer_lock_->UnlockMouse();
+}
 #endif
 
 void EflEventHandler::OnMultiTouchDownEvent(void* data,
index 5242e4a4f2dc2edefac7287b1a95e0811875aedb..cb7c9267b97324203b294812d750289c68bfa5dd 100644 (file)
 
 #if BUILDFLAG(IS_TIZEN_TV)
 #include "base/functional/callback.h"
+#include "third_party/blink/public/mojom/input/pointer_lock_result.mojom.h"
 #include "ui/gfx/geometry/rect.h"
+
+namespace content {
+class PointerLock;
+}  // namespace content
 #endif
 
 namespace ui {
@@ -78,6 +83,13 @@ class EflEventHandler {
    void SetKeyEventChecker(
        const base::RepeatingCallback<bool(void*, bool)>& checker);
    EflWindow* window() { return window_; }
+   void SetPointerLock(content::PointerLock* pointer_lock) {
+     pointer_lock_ = pointer_lock;
+   }
+   content::PointerLock* GetPointerLock() { return pointer_lock_; }
+   bool IsMouseLocked();
+   blink::mojom::PointerLockResult LockMouse();
+   void UnlockMouse();
 #endif
 
  private:
@@ -137,6 +149,8 @@ class EflEventHandler {
   base::RepeatingCallback<void(int, int)> on_mouse_down_callback_;
   base::RepeatingCallback<bool(void)> on_mouse_up_callback_;
   base::RepeatingCallback<void(void)> on_mouse_move_callback_;
+  content::PointerLock* pointer_lock_ = nullptr;
+  bool was_keydown_filtered_as_exit_point_lock_ = false;
   bool popup_visible_ = false;
   gfx::Rect popup_bounds_ = gfx::Rect(0, 0, 0, 0);
 #endif