Commit 4a9d5724 authored by Prabir Pradhan's avatar Prabir Pradhan Committed by Commit Bot

[PointerCapture] Add pointer capture support to exo

This CL creates the creates the relative pointer manager that uses the
wayland extension relative-pointer-unstable-v1. It also adds and
implements the RelativePointerDelegate, which the is used to send
relative motion events through the OnPointerRelativeMotion method.

Whenever pointer capture is requested, we hide the pointer and send
relative movements though the RelativePointerDelegate.

If a RelativePointerDelegate is created, we assume that pointer capture
is enabled, and when it is destroyed, we assume pointer capture is
disabled.

Bug: 121287287
Change-Id: Ie7f662afcc15cb2e538cd22ad56409798d1757c1
Reviewed-on: https://chromium-review.googlesource.com/c/1388298
Commit-Queue: Prabir Pradhan <prabirmsp@chromium.org>
Auto-Submit: Prabir Pradhan <prabirmsp@chromium.org>
Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#634537}
parent 17e7c467
This diff is collapsed.
...@@ -10,12 +10,15 @@ ...@@ -10,12 +10,15 @@
#include "ash/display/window_tree_host_manager.h" #include "ash/display/window_tree_host_manager.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/unguessable_token.h" #include "base/unguessable_token.h"
#include "components/exo/surface_observer.h" #include "components/exo/surface_observer.h"
#include "components/exo/surface_tree_host.h" #include "components/exo/surface_tree_host.h"
#include "components/exo/wm_helper.h" #include "components/exo/wm_helper.h"
#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkBitmap.h"
#include "ui/aura/client/capture_client_observer.h"
#include "ui/aura/client/cursor_client_observer.h" #include "ui/aura/client/cursor_client_observer.h"
#include "ui/aura/client/focus_change_observer.h"
#include "ui/base/cursor/cursor.h" #include "ui/base/cursor/cursor.h"
#include "ui/events/event_constants.h" #include "ui/events/event_constants.h"
#include "ui/events/event_handler.h" #include "ui/events/event_handler.h"
...@@ -35,6 +38,7 @@ class MouseEvent; ...@@ -35,6 +38,7 @@ class MouseEvent;
namespace exo { namespace exo {
class PointerDelegate; class PointerDelegate;
class PointerGesturePinchDelegate; class PointerGesturePinchDelegate;
class RelativePointerDelegate;
class Surface; class Surface;
class SurfaceTreeHost; class SurfaceTreeHost;
...@@ -43,7 +47,9 @@ class SurfaceTreeHost; ...@@ -43,7 +47,9 @@ class SurfaceTreeHost;
class Pointer : public SurfaceTreeHost, class Pointer : public SurfaceTreeHost,
public SurfaceObserver, public SurfaceObserver,
public ui::EventHandler, public ui::EventHandler,
public aura::client::CaptureClientObserver,
public aura::client::CursorClientObserver, public aura::client::CursorClientObserver,
public aura::client::FocusChangeObserver,
public ash::WindowTreeHostManager::Observer { public ash::WindowTreeHostManager::Observer {
public: public:
explicit Pointer(PointerDelegate* delegate); explicit Pointer(PointerDelegate* delegate);
...@@ -68,7 +74,7 @@ class Pointer : public SurfaceTreeHost, ...@@ -68,7 +74,7 @@ class Pointer : public SurfaceTreeHost,
// Overridden from SurfaceDelegate: // Overridden from SurfaceDelegate:
void OnSurfaceCommit() override; void OnSurfaceCommit() override;
// Overriden from SurfaceObserver: // Overridden from SurfaceObserver:
void OnSurfaceDestroying(Surface* surface) override; void OnSurfaceDestroying(Surface* surface) override;
// Overridden from ui::EventHandler: // Overridden from ui::EventHandler:
...@@ -76,13 +82,25 @@ class Pointer : public SurfaceTreeHost, ...@@ -76,13 +82,25 @@ class Pointer : public SurfaceTreeHost,
void OnScrollEvent(ui::ScrollEvent* event) override; void OnScrollEvent(ui::ScrollEvent* event) override;
void OnGestureEvent(ui::GestureEvent* event) override; void OnGestureEvent(ui::GestureEvent* event) override;
// Overridden from ui::client::CursorClientObserver: // Overridden from aura::client::CaptureClientObserver:
void OnCaptureChanged(aura::Window* lost_capture,
aura::Window* gained_capture) override;
// Overridden from aura::client::CursorClientObserver:
void OnCursorSizeChanged(ui::CursorSize cursor_size) override; void OnCursorSizeChanged(ui::CursorSize cursor_size) override;
void OnCursorDisplayChanged(const display::Display& display) override; void OnCursorDisplayChanged(const display::Display& display) override;
// Overridden from aura::client::FocusChangeObserver;
void OnWindowFocused(aura::Window* gained_focus,
aura::Window* lost_focus) override;
// Overridden from ash::WindowTreeHostManager::Observer: // Overridden from ash::WindowTreeHostManager::Observer:
void OnDisplayConfigurationChanged() override; void OnDisplayConfigurationChanged() override;
// Pointer capture toggles:
void EnablePointerCapture(RelativePointerDelegate* delegate);
void DisablePointerCapture();
private: private:
// Returns the effective target for |event|. // Returns the effective target for |event|.
Surface* GetEffectiveTargetForEvent(ui::LocatedEvent* event) const; Surface* GetEffectiveTargetForEvent(ui::LocatedEvent* event) const;
...@@ -107,18 +125,47 @@ class Pointer : public SurfaceTreeHost, ...@@ -107,18 +125,47 @@ class Pointer : public SurfaceTreeHost,
// Update |cursor_| to |cursor_bitmap_| transformed for the current display. // Update |cursor_| to |cursor_bitmap_| transformed for the current display.
void UpdateCursor(); void UpdateCursor();
// Convert the given |location_in_target| to coordinates in the root window.
gfx::PointF GetLocationInRoot(Surface* target,
gfx::PointF location_in_target);
// Called to check if cursor should be moved to the center of the window when
// sending relative movements.
bool ShouldMoveToCenter();
// Moves the cursor to center of the active display.
void MoveCursorToCenterOfActiveDisplay();
// Process the delta for relative pointer motion.
void HandleRelativePointerMotion(base::TimeTicks time_stamp,
gfx::PointF location_in_target);
// The delegate instance that all events are dispatched to. // The delegate instance that all events are dispatched to.
PointerDelegate* const delegate_; PointerDelegate* const delegate_;
// The delegate instance that all pinch related events are dispatched to. // The delegate instance that all pinch related events are dispatched to.
PointerGesturePinchDelegate* pinch_delegate_ = nullptr; PointerGesturePinchDelegate* pinch_delegate_ = nullptr;
// The delegate instance that relative movement events are dispatched to.
// Pointer capture is enabled if and only if this is not nullptr.
RelativePointerDelegate* relative_pointer_delegate_ = nullptr;
// The current focus surface for the pointer. // The current focus surface for the pointer.
Surface* focus_surface_ = nullptr; Surface* focus_surface_ = nullptr;
// The location of the pointer in the current focus surface. // The location of the pointer in the current focus surface.
gfx::PointF location_; gfx::PointF location_;
// The location of the pointer when pointer capture is first enabled.
base::Optional<gfx::Point> location_when_pointer_capture_enabled_;
// If this is not nullptr, a synthetic move was sent and this points to the
// location of a generated move that was sent which should not be forwarded.
base::Optional<gfx::Point> location_synthetic_move_;
// The window with input capture.
aura::Window* capture_window_ = nullptr;
// The position of the pointer surface relative to the pointer location. // The position of the pointer surface relative to the pointer location.
gfx::Point hotspot_; gfx::Point hotspot_;
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_EXO_RELATIVE_POINTER_DELEGATE_H_
#define COMPONENTS_EXO_RELATIVE_POINTER_DELEGATE_H_
#include "base/time/time.h"
namespace exo {
class Pointer;
// Handles sending relative mouse movements.
class RelativePointerDelegate {
public:
// Called at the top of the pointer's destructor, to give observers a
// chance to remove themselves.
virtual void OnPointerDestroying(Pointer* pointer) = 0;
virtual void OnPointerRelativeMotion(base::TimeTicks time_stamp,
const gfx::PointF& relativeMotion) = 0;
protected:
virtual ~RelativePointerDelegate() {}
};
} // namespace exo
#endif // COMPONENTS_EXO_RELATIVE_POINTER_DELEGATE_H_
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "ui/aura/client/capture_client.h" #include "ui/aura/client/capture_client.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/events/event.h" #include "ui/events/event.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/window_util.h" #include "ui/wm/core/window_util.h"
namespace exo { namespace exo {
...@@ -72,8 +73,14 @@ Surface* GetTargetSurfaceForLocatedEvent(ui::LocatedEvent* event) { ...@@ -72,8 +73,14 @@ Surface* GetTargetSurfaceForLocatedEvent(ui::LocatedEvent* event) {
Surface* main_surface = GetShellMainSurface(window); Surface* main_surface = GetShellMainSurface(window);
// Skip if the event is captured by non exo windows. // Skip if the event is captured by non exo windows.
if (!main_surface) if (!main_surface) {
return nullptr; auto* widget = views::Widget::GetTopLevelWidgetForNativeView(window);
if (!widget)
return nullptr;
main_surface = GetShellMainSurface(widget->GetNativeWindow());
if (!main_surface)
return nullptr;
}
while (true) { while (true) {
aura::Window* focused = window->GetEventHandlerForPoint( aura::Window* focused = window->GetEventHandlerForPoint(
......
...@@ -93,6 +93,8 @@ source_set("wayland") { ...@@ -93,6 +93,8 @@ source_set("wayland") {
"zwp_linux_explicit_synchronization.h", "zwp_linux_explicit_synchronization.h",
"zwp_pointer_gestures.cc", "zwp_pointer_gestures.cc",
"zwp_pointer_gestures.h", "zwp_pointer_gestures.h",
"zwp_relative_pointer_manager.cc",
"zwp_relative_pointer_manager.h",
"zwp_text_input_manager.cc", "zwp_text_input_manager.cc",
"zwp_text_input_manager.h", "zwp_text_input_manager.h",
"zxdg_shell.cc", "zxdg_shell.cc",
...@@ -118,6 +120,7 @@ source_set("wayland") { ...@@ -118,6 +120,7 @@ source_set("wayland") {
"//third_party/wayland-protocols:notification_shell_protocol", "//third_party/wayland-protocols:notification_shell_protocol",
"//third_party/wayland-protocols:pointer_gestures_protocol", "//third_party/wayland-protocols:pointer_gestures_protocol",
"//third_party/wayland-protocols:presentation_time_protocol", "//third_party/wayland-protocols:presentation_time_protocol",
"//third_party/wayland-protocols:relative_pointer_protocol",
"//third_party/wayland-protocols:remote_shell_protocol", "//third_party/wayland-protocols:remote_shell_protocol",
"//third_party/wayland-protocols:secure_output_protocol", "//third_party/wayland-protocols:secure_output_protocol",
"//third_party/wayland-protocols:stylus_protocol", "//third_party/wayland-protocols:stylus_protocol",
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <notification-shell-unstable-v1-server-protocol.h> #include <notification-shell-unstable-v1-server-protocol.h>
#include <pointer-gestures-unstable-v1-server-protocol.h> #include <pointer-gestures-unstable-v1-server-protocol.h>
#include <presentation-time-server-protocol.h> #include <presentation-time-server-protocol.h>
#include <relative-pointer-unstable-v1-server-protocol.h>
#include <remote-shell-unstable-v1-server-protocol.h> #include <remote-shell-unstable-v1-server-protocol.h>
#include <secure-output-unstable-v1-server-protocol.h> #include <secure-output-unstable-v1-server-protocol.h>
#include <stddef.h> #include <stddef.h>
...@@ -110,6 +111,7 @@ ...@@ -110,6 +111,7 @@
#include "components/exo/wayland/zwp_input_timestamps_manager.h" #include "components/exo/wayland/zwp_input_timestamps_manager.h"
#include "components/exo/wayland/zwp_linux_explicit_synchronization.h" #include "components/exo/wayland/zwp_linux_explicit_synchronization.h"
#include "components/exo/wayland/zwp_pointer_gestures.h" #include "components/exo/wayland/zwp_pointer_gestures.h"
#include "components/exo/wayland/zwp_relative_pointer_manager.h"
#include "components/exo/wayland/zwp_text_input_manager.h" #include "components/exo/wayland/zwp_text_input_manager.h"
#include "components/exo/wayland/zxdg_shell.h" #include "components/exo/wayland/zxdg_shell.h"
#include "components/exo/wm_helper_chromeos.h" #include "components/exo/wm_helper_chromeos.h"
...@@ -735,6 +737,9 @@ Server::Server(Display* display) ...@@ -735,6 +737,9 @@ Server::Server(Display* display)
bind_input_timestamps_manager); bind_input_timestamps_manager);
wl_global_create(wl_display_.get(), &zwp_pointer_gestures_v1_interface, 1, wl_global_create(wl_display_.get(), &zwp_pointer_gestures_v1_interface, 1,
display_, bind_pointer_gestures); display_, bind_pointer_gestures);
wl_global_create(wl_display_.get(),
&zwp_relative_pointer_manager_v1_interface, 1, display_,
bind_relative_pointer_manager);
wl_global_create(wl_display_.get(), &zwp_text_input_manager_v1_interface, 1, wl_global_create(wl_display_.get(), &zwp_text_input_manager_v1_interface, 1,
display_, bind_text_input_manager); display_, bind_text_input_manager);
wl_global_create(wl_display_.get(), &zxdg_shell_v6_interface, 1, display_, wl_global_create(wl_display_.get(), &zxdg_shell_v6_interface, 1, display_,
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/exo/wayland/zwp_relative_pointer_manager.h"
#include <relative-pointer-unstable-v1-server-protocol.h>
#include <wayland-server-core.h>
#include <wayland-server-protocol-core.h>
#include <memory>
#include "components/exo/pointer.h"
#include "components/exo/relative_pointer_delegate.h"
#include "components/exo/wayland/server_util.h"
namespace exo {
namespace wayland {
namespace {
////////////////////////////////////////////////////////////////////////////////
// relative_pointer_v1 interface:
class WaylandRelativePointerDelegate : public RelativePointerDelegate {
public:
WaylandRelativePointerDelegate(wl_resource* resource, Pointer* pointer)
: resource_(resource), pointer_(pointer) {
pointer_->EnablePointerCapture(this);
}
~WaylandRelativePointerDelegate() override {
if (pointer_)
pointer_->DisablePointerCapture();
}
void OnPointerDestroying(Pointer* pointer) override { pointer_ = nullptr; }
void OnPointerRelativeMotion(base::TimeTicks time_stamp,
const gfx::PointF& relativeMotion) override {
zwp_relative_pointer_v1_send_relative_motion(
resource_, // resource
0, // utime_hi
TimeTicksToMilliseconds(time_stamp), // utime_lo
wl_fixed_from_double(relativeMotion.x()), // dx
wl_fixed_from_double(relativeMotion.y()), // dy
wl_fixed_from_double(relativeMotion.x()), // dx_unaccel
wl_fixed_from_double(relativeMotion.y())); // dy_unaccel
}
private:
wl_resource* const resource_;
Pointer* pointer_;
DISALLOW_COPY_AND_ASSIGN(WaylandRelativePointerDelegate);
};
void relative_pointer_destroy(wl_client* client, wl_resource* resource) {
wl_resource_destroy(resource);
}
const struct zwp_relative_pointer_v1_interface relative_pointer_impl = {
relative_pointer_destroy};
////////////////////////////////////////////////////////////////////////////////
// relative_pointer_manager_v1 interface:
void relative_pointer_manager_destroy(wl_client* client,
wl_resource* resource) {
wl_resource_destroy(resource);
}
void relative_pointer_manager_get_relative_pointer(
wl_client* client,
wl_resource* resource,
uint32_t id,
wl_resource* pointer_resource) {
Pointer* pointer = GetUserDataAs<Pointer>(pointer_resource);
wl_resource* relative_pointer_resource =
wl_resource_create(client, &zwp_relative_pointer_v1_interface, 1, id);
SetImplementation(relative_pointer_resource, &relative_pointer_impl,
std::make_unique<WaylandRelativePointerDelegate>(
relative_pointer_resource, pointer));
}
const struct zwp_relative_pointer_manager_v1_interface
relative_pointer_manager_impl = {
relative_pointer_manager_destroy,
relative_pointer_manager_get_relative_pointer};
} // namespace
void bind_relative_pointer_manager(wl_client* client,
void* data,
uint32_t version,
uint32_t id) {
wl_resource* resource = wl_resource_create(
client, &zwp_relative_pointer_manager_v1_interface, version, id);
wl_resource_set_implementation(resource, &relative_pointer_manager_impl, data,
nullptr);
}
} // namespace wayland
} // namespace exo
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_EXO_WAYLAND_ZWP_RELATIVE_POINTER_MANAGER_H_
#define COMPONENTS_EXO_WAYLAND_ZWP_RELATIVE_POINTER_MANAGER_H_
#include <stdint.h>
struct wl_client;
namespace exo {
namespace wayland {
void bind_relative_pointer_manager(wl_client* client,
void* data,
uint32_t version,
uint32_t id);
} // namespace wayland
} // namespace exo
#endif // COMPONENTS_EXO_WAYLAND_ZWP_RELATIVE_POINTER_MANAGER_H_
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment