Commit 3e2f9479 authored by Dominik Laskowski's avatar Dominik Laskowski Committed by Commit Bot

exo: Dispatch touch input to root surface for ARC

This CL enforces that the target surface for touch events is always the
root surface for ClientControlledShellSurface.

ARC currently disables input for all sub-surfaces such that the target
surface is always the root surface. Newer clients will use a surface
hierarchy consistent with upstream Wayland, so focus will move between
different surfaces. This CL prevents touch events from being discarded
when capture changes during dragging/resizing, as a stopgap until
server-driven dragging/resizing is implemented.

Bug: b:67384524
Test: Input still works in ARC.
Change-Id: I3b419ec14cc04432b5b92618ed45df441da0d8eb
Reviewed-on: https://chromium-review.googlesource.com/812980
Commit-Queue: Dominik Laskowski <domlaskowski@chromium.org>
Reviewed-by: default avatarDavid Reveman <reveman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#524259}
parent 025cd13d
...@@ -363,6 +363,17 @@ void ClientControlledShellSurface::OnSurfaceCommit() { ...@@ -363,6 +363,17 @@ void ClientControlledShellSurface::OnSurfaceCommit() {
orientation_compositor_lock_.reset(); orientation_compositor_lock_.reset();
} }
bool ClientControlledShellSurface::IsTouchEnabled(Surface* surface) const {
// The target for input events is selected by recursively hit-testing surfaces
// in the surface tree. During client-driven dragging/resizing, capture is set
// on the root surface. When capture is reset to a different target, mouse
// events are redirected from the old to the new target, but touch/gesture
// events are cancelled. To avoid prematurely ending the drag/resize, ensure
// that the target and capture windows are the same by disabling touch input
// for all but the root surface.
return surface == root_surface();
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// aura::WindowObserver overrides: // aura::WindowObserver overrides:
void ClientControlledShellSurface::OnWindowBoundsChanged( void ClientControlledShellSurface::OnWindowBoundsChanged(
...@@ -533,6 +544,8 @@ float ClientControlledShellSurface::GetScale() const { ...@@ -533,6 +544,8 @@ float ClientControlledShellSurface::GetScale() const {
} }
aura::Window* ClientControlledShellSurface::GetDragWindow() { aura::Window* ClientControlledShellSurface::GetDragWindow() {
// Set capture on the root surface rather than the focus surface, because
// the client may destroy the latter during dragging/resizing.
return root_surface() ? root_surface()->window() : nullptr; return root_surface() ? root_surface()->window() : nullptr;
} }
......
...@@ -101,6 +101,7 @@ class ClientControlledShellSurface ...@@ -101,6 +101,7 @@ class ClientControlledShellSurface
// Overridden from SurfaceDelegate: // Overridden from SurfaceDelegate:
void OnSurfaceCommit() override; void OnSurfaceCommit() override;
bool IsTouchEnabled(Surface* surface) const override;
// Overridden from views::WidgetDelegate: // Overridden from views::WidgetDelegate:
bool CanResize() const override; bool CanResize() const override;
......
...@@ -608,6 +608,10 @@ void ShellSurfaceBase::OnSurfaceCommit() { ...@@ -608,6 +608,10 @@ void ShellSurfaceBase::OnSurfaceCommit() {
} }
} }
bool ShellSurfaceBase::IsTouchEnabled(Surface*) const {
return true;
}
void ShellSurfaceBase::OnSetFrame(SurfaceFrameType type) { void ShellSurfaceBase::OnSetFrame(SurfaceFrameType type) {
// TODO(reveman): Allow frame to change after surface has been enabled. // TODO(reveman): Allow frame to change after surface has been enabled.
switch (type) { switch (type) {
......
...@@ -157,6 +157,7 @@ class ShellSurfaceBase : public SurfaceTreeHost, ...@@ -157,6 +157,7 @@ class ShellSurfaceBase : public SurfaceTreeHost,
// Overridden from SurfaceDelegate: // Overridden from SurfaceDelegate:
void OnSurfaceCommit() override; void OnSurfaceCommit() override;
bool IsTouchEnabled(Surface* surface) const override;
void OnSetFrame(SurfaceFrameType type) override; void OnSetFrame(SurfaceFrameType type) override;
void OnSetParent(Surface* parent, const gfx::Point& position) override; void OnSetParent(Surface* parent, const gfx::Point& position) override;
......
...@@ -106,7 +106,11 @@ bool SubSurface::IsSurfaceSynchronized() const { ...@@ -106,7 +106,11 @@ bool SubSurface::IsSurfaceSynchronized() const {
if (is_synchronized_) if (is_synchronized_)
return true; return true;
return parent_ ? parent_->IsSynchronized() : false; return parent_ && parent_->IsSynchronized();
}
bool SubSurface::IsTouchEnabled(Surface* surface) const {
return !parent_ || parent_->IsTouchEnabled(surface);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
......
...@@ -51,6 +51,7 @@ class SubSurface : public SurfaceDelegate, public SurfaceObserver { ...@@ -51,6 +51,7 @@ class SubSurface : public SurfaceDelegate, public SurfaceObserver {
// Overridden from SurfaceDelegate: // Overridden from SurfaceDelegate:
void OnSurfaceCommit() override; void OnSurfaceCommit() override;
bool IsSurfaceSynchronized() const override; bool IsSurfaceSynchronized() const override;
bool IsTouchEnabled(Surface* surface) const override;
void OnSetFrame(SurfaceFrameType type) override {} void OnSetFrame(SurfaceFrameType type) override {}
void OnSetParent(Surface* parent, const gfx::Point& position) override {} void OnSetParent(Surface* parent, const gfx::Point& position) override {}
......
...@@ -166,6 +166,9 @@ class CustomWindowTargeter : public aura::WindowTargeter { ...@@ -166,6 +166,9 @@ class CustomWindowTargeter : public aura::WindowTargeter {
if (!surface) if (!surface)
return false; return false;
if (event.IsTouchEvent() && !surface->IsTouchEnabled(surface))
return false;
gfx::Point local_point = event.location(); gfx::Point local_point = event.location();
if (window->parent()) if (window->parent())
aura::Window::ConvertPointToTarget(window->parent(), window, aura::Window::ConvertPointToTarget(window->parent(), window,
...@@ -606,7 +609,11 @@ void Surface::AppendSurfaceHierarchyContentsToFrame( ...@@ -606,7 +609,11 @@ void Surface::AppendSurfaceHierarchyContentsToFrame(
} }
bool Surface::IsSynchronized() const { bool Surface::IsSynchronized() const {
return delegate_ ? delegate_->IsSurfaceSynchronized() : false; return delegate_ && delegate_->IsSurfaceSynchronized();
}
bool Surface::IsTouchEnabled(Surface* surface) const {
return !delegate_ || delegate_->IsTouchEnabled(surface);
} }
bool Surface::HasHitTestRegion() const { bool Surface::HasHitTestRegion() const {
......
...@@ -174,6 +174,9 @@ class Surface final : public ui::PropertyHandler { ...@@ -174,6 +174,9 @@ class Surface final : public ui::PropertyHandler {
// Returns true if surface is in synchronized mode. // Returns true if surface is in synchronized mode.
bool IsSynchronized() const; bool IsSynchronized() const;
// Returns true if surface should receive touch events.
bool IsTouchEnabled(Surface* surface) const;
// Returns false if the hit test region is empty. // Returns false if the hit test region is empty.
bool HasHitTestRegion() const; bool HasHitTestRegion() const;
......
...@@ -23,6 +23,11 @@ class SurfaceDelegate { ...@@ -23,6 +23,11 @@ class SurfaceDelegate {
// double-buffered state should be synchronized with parent surface. // double-buffered state should be synchronized with parent surface.
virtual bool IsSurfaceSynchronized() const = 0; virtual bool IsSurfaceSynchronized() const = 0;
// Returns true if surface should receive touch events.
// TODO(domlaskowski): Remove once client-driven dragging/resizing is removed
// in crbug.com/795119.
virtual bool IsTouchEnabled(Surface* surface) const = 0;
// Called when surface was requested to use a specific frame type. // Called when surface was requested to use a specific frame type.
virtual void OnSetFrame(SurfaceFrameType type) = 0; virtual void OnSetFrame(SurfaceFrameType type) = 0;
......
...@@ -217,6 +217,10 @@ bool SurfaceTreeHost::IsSurfaceSynchronized() const { ...@@ -217,6 +217,10 @@ bool SurfaceTreeHost::IsSurfaceSynchronized() const {
return false; return false;
} }
bool SurfaceTreeHost::IsTouchEnabled(Surface*) const {
return true;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cc::BeginFrameObserverBase overrides: // cc::BeginFrameObserverBase overrides:
......
...@@ -90,6 +90,7 @@ class SurfaceTreeHost : public SurfaceDelegate, ...@@ -90,6 +90,7 @@ class SurfaceTreeHost : public SurfaceDelegate,
// Overridden from SurfaceDelegate: // Overridden from SurfaceDelegate:
void OnSurfaceCommit() override; void OnSurfaceCommit() override;
bool IsSurfaceSynchronized() const override; bool IsSurfaceSynchronized() const override;
bool IsTouchEnabled(Surface* surface) const override;
void OnSetFrame(SurfaceFrameType type) override {} void OnSetFrame(SurfaceFrameType type) override {}
void OnSetParent(Surface* parent, const gfx::Point& position) override {} void OnSetParent(Surface* parent, const gfx::Point& position) override {}
......
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