Commit 467bd6d1 authored by Jun Mukai's avatar Jun Mukai Committed by Commit Bot

Enable tab-dragging with touch on Mash

This is the final phase of tab-dragging with touch on Mash.
This makes several changes to use the result of the previous
phases and achieve tab-dragging with touch on Mash.

BUG=867074
TEST=manually

Change-Id: I53239efbdf567754d3e9322b334d0a4e6751fa52
Reviewed-on: https://chromium-review.googlesource.com/c/1247034
Commit-Queue: Jun Mukai <mukai@chromium.org>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#599820}
parent d08edc74
......@@ -771,9 +771,17 @@ TabDragController::DragBrowserToNewTabStrip(TabStrip* target_tabstrip,
#if defined(USE_AURA)
// Only Aura windows are gesture consumers.
gfx::NativeView attached_native_view =
GetAttachedBrowserWidget()->GetNativeView();
#if defined(OS_CHROMEOS)
// When using WindowService, the touch events for the window move have
// happened on the root window, so the transfer should happen from the root of
// the currently attached window to the target.
if (features::IsUsingWindowService())
attached_native_view = attached_native_view->GetRootWindow();
#endif
GetAttachedBrowserWidget()->GetGestureRecognizer()->TransferEventsTo(
GetAttachedBrowserWidget()->GetNativeView(),
target_tabstrip->GetWidget()->GetNativeView(),
attached_native_view, target_tabstrip->GetWidget()->GetNativeView(),
ui::TransferTouchesBehavior::kDontCancel);
#endif
......@@ -1249,9 +1257,10 @@ void TabDragController::DetachIntoNewBrowserAndRunMoveLoop(
#if defined(USE_AURA)
// Only Aura windows are gesture consumers.
views::Widget* attached_widget = attached_tabstrip_->GetWidget();
gfx::NativeView attached_native_view = attached_widget->GetNativeView();
// Unlike DragBrowserToNewTabStrip, this does not have to special-handle
// IsUsingWindowServices(), since DesktopWIndowTreeHostMus takes care of it.
attached_widget->GetGestureRecognizer()->TransferEventsTo(
attached_native_view, dragged_widget->GetNativeView(),
attached_widget->GetNativeView(), dragged_widget->GetNativeView(),
ui::TransferTouchesBehavior::kDontCancel);
#endif
......@@ -2044,11 +2053,7 @@ Browser* TabDragController::CreateBrowserForDrag(
gfx::Point TabDragController::GetCursorScreenPoint() {
#if defined(OS_CHROMEOS)
// TODO(erg): Temporarily disable getting location from the gesture
// recognizer in mash until the mus side/window manager side RunMoveLoop() is
// fixed to understand routing touch events. https://crbug.com/867074
if (!features::IsUsingWindowService() &&
event_source_ == EVENT_SOURCE_TOUCH && env_->is_touch_down()) {
if (event_source_ == EVENT_SOURCE_TOUCH && env_->is_touch_down()) {
views::Widget* widget = GetAttachedBrowserWidget();
DCHECK(widget);
aura::Window* widget_window = widget->GetNativeWindow();
......
......@@ -47,6 +47,7 @@ jumbo_component("aura") {
"mus/focus_synchronizer.h",
"mus/focus_synchronizer_delegate.h",
"mus/focus_synchronizer_observer.h",
"mus/gesture_recognizer_impl_mus.h",
"mus/gesture_synchronizer.h",
"mus/in_flight_change.h",
"mus/input_method_mus.h",
......@@ -119,6 +120,7 @@ jumbo_component("aura") {
"mus/drag_drop_controller_mus.cc",
"mus/embed_root.cc",
"mus/focus_synchronizer.cc",
"mus/gesture_recognizer_impl_mus.cc",
"mus/gesture_synchronizer.cc",
"mus/in_flight_change.cc",
"mus/input_method_mus.cc",
......
......@@ -215,6 +215,11 @@ mojo::ScopedSharedBufferHandle Env::GetLastMouseLocationMemory() {
return mouse_location_manager_->GetMouseLocationMemory();
}
void Env::SetGestureRecognizer(
std::unique_ptr<ui::GestureRecognizer> gesture_recognizer) {
gesture_recognizer_ = std::move(gesture_recognizer);
}
void Env::SetWindowTreeClient(WindowTreeClient* window_tree_client) {
// The WindowTreeClient should only be set once. Test code may need to change
// the value after the fact, to do that use EnvTestHelper.
......
......@@ -184,6 +184,9 @@ class AURA_EXPORT Env : public ui::EventTarget,
return gesture_recognizer_.get();
}
void SetGestureRecognizer(
std::unique_ptr<ui::GestureRecognizer> gesture_recognizer);
// See CreateInstance() for description.
void SetWindowTreeClient(WindowTreeClient* window_tree_client);
bool HasWindowTreeClient() const { return window_tree_client_ != nullptr; }
......
// Copyright 2018 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 "ui/aura/mus/gesture_recognizer_impl_mus.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/env.h"
#include "ui/aura/mus/window_tree_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
namespace aura {
GestureRecognizerImplMus::GestureRecognizerImplMus(
aura::WindowTreeClient* client)
: client_(client) {
client->AddObserver(this);
}
GestureRecognizerImplMus::~GestureRecognizerImplMus() {
OnWindowMoveEnded(false);
if (client_)
client_->RemoveObserver(this);
}
void GestureRecognizerImplMus::OnWillDestroyClient(
aura::WindowTreeClient* client) {
DCHECK_EQ(client_, client);
OnWindowMoveEnded(false);
client_->RemoveObserver(this);
client_ = nullptr;
}
void GestureRecognizerImplMus::OnWindowMoveStarted(
aura::Window* window,
const gfx::Point& cursor_location,
ws::mojom::MoveLoopSource source) {
DCHECK(!moving_window_);
if (source != ws::mojom::MoveLoopSource::TOUCH)
return;
moving_window_ = window;
last_location_in_screen_ = cursor_location;
Env* env = Env::GetInstance();
std::set<ui::EventType> types = {
ui::ET_TOUCH_RELEASED, ui::ET_TOUCH_PRESSED, ui::ET_TOUCH_MOVED,
ui::ET_TOUCH_CANCELLED,
};
env->AddEventObserver(this, env, types);
}
void GestureRecognizerImplMus::OnWindowMoveEnded(bool success) {
if (!moving_window_)
return;
Env::GetInstance()->RemoveEventObserver(this);
moving_window_ = nullptr;
}
bool GestureRecognizerImplMus::GetLastTouchPointForTarget(
ui::GestureConsumer* consumer,
gfx::PointF* point) {
// When a window is moving, the touch events are handled completely within the
// shell and do not come to the client and so the default
// GetLastTouchPointForTarget won't work. Instead, this reports the last
// location through PointerWatcher. See also
// https://docs.google.com/document/d/1AKeK8IuF-j2TJ-2sPsewORXdjnr6oAzy5nnR1zwrsfc/edit#
aura::Window* target_window = static_cast<aura::Window*>(consumer);
if (moving_window_ && moving_window_->Contains(target_window)) {
aura::client::ScreenPositionClient* client =
aura::client::GetScreenPositionClient(target_window->GetRootWindow());
if (client) {
gfx::Point location_in_window = last_location_in_screen_;
client->ConvertPointFromScreen(target_window, &location_in_window);
point->set_x(location_in_window.x());
point->set_y(location_in_window.y());
return true;
}
}
return GestureRecognizerImpl::GetLastTouchPointForTarget(consumer, point);
}
void GestureRecognizerImplMus::OnEvent(const ui::Event& event) {
DCHECK(moving_window_);
last_location_in_screen_ = event.AsLocatedEvent()->location();
display::Display display;
if (display::Screen::GetScreen()->GetDisplayWithDisplayId(
moving_window_->GetHost()->GetDisplayId(), &display)) {
last_location_in_screen_ += display.bounds().OffsetFromOrigin();
}
}
} // namespace aura
// Copyright 2018 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 UI_AURA_MUS_GESTURE_RECOGNIZER_IMPL_MUS_H_
#define UI_AURA_MUS_GESTURE_RECOGNIZER_IMPL_MUS_H_
#include "base/macros.h"
#include "ui/aura/mus/window_tree_client_observer.h"
#include "ui/events/event_observer.h"
#include "ui/events/gestures/gesture_recognizer_impl.h"
namespace ui {
class PointF;
}
namespace aura {
class Window;
class WindowTreeClient;
// GestureRecognizer implementation for Mus. This is mostly identical to
// GestureRecognizerImpl, but it handles keeping GetLastTouchPointForTarget in
// sync with the server when the touch events are handled within the server.
class GestureRecognizerImplMus : public ui::GestureRecognizerImpl,
public aura::WindowTreeClientObserver,
public ui::EventObserver {
public:
explicit GestureRecognizerImplMus(aura::WindowTreeClient* client);
~GestureRecognizerImplMus() override;
private:
// ui::GestureRecognizerImpl:
bool GetLastTouchPointForTarget(ui::GestureConsumer* consumer,
gfx::PointF* point) override;
// aura::WindowTreeClientObserver:
void OnWillDestroyClient(aura::WindowTreeClient* client) override;
void OnWindowMoveStarted(aura::Window* window,
const gfx::Point& cursor_location,
ws::mojom::MoveLoopSource source) override;
void OnWindowMoveEnded(bool success) override;
// ui::EventObserver:
void OnEvent(const ui::Event& event) override;
aura::WindowTreeClient* client_;
aura::Window* moving_window_ = nullptr;
gfx::Point last_location_in_screen_;
DISALLOW_COPY_AND_ASSIGN(GestureRecognizerImplMus);
};
} // namespace aura
#endif // UI_AURA_MUS_GESTURE_RECOGNIZER_IMPL_MUS_H_
......@@ -38,6 +38,7 @@
#include "ui/aura/mus/embed_root.h"
#include "ui/aura/mus/embed_root_delegate.h"
#include "ui/aura/mus/focus_synchronizer.h"
#include "ui/aura/mus/gesture_recognizer_impl_mus.h"
#include "ui/aura/mus/gesture_synchronizer.h"
#include "ui/aura/mus/in_flight_change.h"
#include "ui/aura/mus/input_method_mus.h"
......@@ -538,6 +539,8 @@ void WindowTreeClient::WindowTreeConnectionEstablished(
drag_drop_controller_ = std::make_unique<DragDropControllerMus>(this, tree_);
capture_synchronizer_ = std::make_unique<CaptureSynchronizer>(this, tree_);
focus_synchronizer_ = std::make_unique<FocusSynchronizer>(this, tree_);
Env::GetInstance()->SetGestureRecognizer(
std::make_unique<GestureRecognizerImplMus>(this));
gesture_synchronizer_ = std::make_unique<GestureSynchronizer>(tree_);
}
......@@ -1441,6 +1444,8 @@ void WindowTreeClient::OnChangeCompleted(uint32_t change_id, bool success) {
current_move_loop_change_ = 0;
on_current_move_finished_.Run(success);
on_current_move_finished_.Reset();
for (auto& observer : observers_)
observer.OnWindowMoveEnded(success);
}
if (!change)
......@@ -1558,6 +1563,10 @@ void WindowTreeClient::OnWindowTreeHostPerformWindowMove(
// Tell the window manager to take over moving us.
tree_->PerformWindowMove(current_move_loop_change_, window_mus->server_id(),
source, cursor_location);
for (auto& observer : observers_) {
observer.OnWindowMoveStarted(window_tree_host->window(), cursor_location,
source);
}
}
void WindowTreeClient::OnWindowTreeHostCancelWindowMove(
......
......@@ -5,10 +5,12 @@
#ifndef UI_AURA_MUS_WINDOW_TREE_CLIENT_OBSERVER_H_
#define UI_AURA_MUS_WINDOW_TREE_CLIENT_OBSERVER_H_
#include "services/ws/public/mojom/window_tree_constants.mojom.h"
#include "ui/aura/aura_export.h"
namespace aura {
class Window;
class WindowTreeClient;
class AURA_EXPORT WindowTreeClientObserver {
......@@ -16,6 +18,14 @@ class AURA_EXPORT WindowTreeClientObserver {
// Called early on in the destructor of WindowTreeClient.
virtual void OnWillDestroyClient(WindowTreeClient* client) {}
// Called when a WindowMove started on |window| from |source| event.
virtual void OnWindowMoveStarted(Window* window,
const gfx::Point& cursor_location,
ws::mojom::MoveLoopSource source) {}
// Called when the WindowMove ended.
virtual void OnWindowMoveEnded(bool success) {}
protected:
virtual ~WindowTreeClientObserver() {}
};
......
......@@ -12,6 +12,7 @@
#include "ui/aura/client/drag_drop_client.h"
#include "ui/aura/client/focus_client.h"
#include "ui/aura/client/transient_window_client.h"
#include "ui/aura/env.h"
#include "ui/aura/mus/focus_synchronizer.h"
#include "ui/aura/mus/window_port_mus.h"
#include "ui/aura/mus/window_tree_client.h"
......@@ -20,7 +21,9 @@
#include "ui/aura/window.h"
#include "ui/base/hit_test.h"
#include "ui/display/screen.h"
#include "ui/events/gestures/gesture_recognizer.h"
#include "ui/gfx/geometry/dip_util.h"
#include "ui/gfx/geometry/vector2d_conversions.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/corewm/tooltip_aura.h"
#include "ui/views/mus/mus_client.h"
......@@ -730,6 +733,13 @@ Widget::MoveLoopResult DesktopWindowTreeHostMus::RunMoveLoop(
const gfx::Vector2d& drag_offset,
Widget::MoveLoopSource source,
Widget::MoveLoopEscapeBehavior escape_behavior) {
// When using WindowService, the touch events for the window move will
// happen on the root window, so the events need to be transferred from
// widget to its root before starting move loop.
window()->env()->gesture_recognizer()->TransferEventsTo(
desktop_native_widget_aura_->content_window(), window(),
ui::TransferTouchesBehavior::kDontCancel);
static_cast<internal::NativeWidgetPrivate*>(
desktop_native_widget_aura_)->ReleaseCapture();
......@@ -741,8 +751,11 @@ Widget::MoveLoopResult DesktopWindowTreeHostMus::RunMoveLoop(
: ws::mojom::MoveLoopSource::TOUCH;
bool success = false;
gfx::Point cursor_location =
display::Screen::GetScreen()->GetCursorScreenPoint();
// Don't use display::Screen::GetCursorScreenPoint() -- that's incorrect for
// touch events. Rather the cursor location can be computed from window's
// location with drag_offset.
gfx::Point cursor_location = window()->GetBoundsInScreen().origin() +
gfx::ToFlooredVector2d(drag_offset);
WindowTreeHostMus::PerformWindowMove(
mus_source, cursor_location,
base::Bind(OnMoveLoopEnd, &success, run_loop.QuitClosure()));
......
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