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() {
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:
void ClientControlledShellSurface::OnWindowBoundsChanged(
......@@ -533,6 +544,8 @@ float ClientControlledShellSurface::GetScale() const {
}
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;
}
......
......@@ -101,6 +101,7 @@ class ClientControlledShellSurface
// Overridden from SurfaceDelegate:
void OnSurfaceCommit() override;
bool IsTouchEnabled(Surface* surface) const override;
// Overridden from views::WidgetDelegate:
bool CanResize() const override;
......
......@@ -608,6 +608,10 @@ void ShellSurfaceBase::OnSurfaceCommit() {
}
}
bool ShellSurfaceBase::IsTouchEnabled(Surface*) const {
return true;
}
void ShellSurfaceBase::OnSetFrame(SurfaceFrameType type) {
// TODO(reveman): Allow frame to change after surface has been enabled.
switch (type) {
......
......@@ -157,6 +157,7 @@ class ShellSurfaceBase : public SurfaceTreeHost,
// Overridden from SurfaceDelegate:
void OnSurfaceCommit() override;
bool IsTouchEnabled(Surface* surface) const override;
void OnSetFrame(SurfaceFrameType type) override;
void OnSetParent(Surface* parent, const gfx::Point& position) override;
......
......@@ -106,7 +106,11 @@ bool SubSurface::IsSurfaceSynchronized() const {
if (is_synchronized_)
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 {
// Overridden from SurfaceDelegate:
void OnSurfaceCommit() override;
bool IsSurfaceSynchronized() const override;
bool IsTouchEnabled(Surface* surface) const override;
void OnSetFrame(SurfaceFrameType type) override {}
void OnSetParent(Surface* parent, const gfx::Point& position) override {}
......
......@@ -166,6 +166,9 @@ class CustomWindowTargeter : public aura::WindowTargeter {
if (!surface)
return false;
if (event.IsTouchEvent() && !surface->IsTouchEnabled(surface))
return false;
gfx::Point local_point = event.location();
if (window->parent())
aura::Window::ConvertPointToTarget(window->parent(), window,
......@@ -606,7 +609,11 @@ void Surface::AppendSurfaceHierarchyContentsToFrame(
}
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 {
......
......@@ -174,6 +174,9 @@ class Surface final : public ui::PropertyHandler {
// Returns true if surface is in synchronized mode.
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.
bool HasHitTestRegion() const;
......
......@@ -23,6 +23,11 @@ class SurfaceDelegate {
// double-buffered state should be synchronized with parent surface.
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.
virtual void OnSetFrame(SurfaceFrameType type) = 0;
......
......@@ -217,6 +217,10 @@ bool SurfaceTreeHost::IsSurfaceSynchronized() const {
return false;
}
bool SurfaceTreeHost::IsTouchEnabled(Surface*) const {
return true;
}
////////////////////////////////////////////////////////////////////////////////
// cc::BeginFrameObserverBase overrides:
......
......@@ -90,6 +90,7 @@ class SurfaceTreeHost : public SurfaceDelegate,
// Overridden from SurfaceDelegate:
void OnSurfaceCommit() override;
bool IsSurfaceSynchronized() const override;
bool IsTouchEnabled(Surface* surface) const override;
void OnSetFrame(SurfaceFrameType type) 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