blob: d3f01ea228993bb27a472b92a07dc66a6f7bde37 [file] [log] [blame]
// Copyright 2015 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 "ash/wm/move_event_handler.h"
#include "ash/wm/window_util.h"
#include "ash/wm/workspace/workspace_event_handler_mash.h"
#include "services/ui/public/interfaces/cursor/cursor.mojom.h"
#include "ui/aura/mus/window_manager_delegate.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/class_property.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/hit_test.h"
#include "ui/events/event.h"
DEFINE_UI_CLASS_PROPERTY_TYPE(ash::MoveEventHandler*);
namespace {
// Key used for storing identifier sent to clients for windows.
DEFINE_UI_CLASS_PROPERTY_KEY(ash::MoveEventHandler*,
kWmMoveEventHandler,
nullptr);
} // namespace
namespace ash {
namespace {
ui::CursorType CursorForWindowComponent(int window_component) {
switch (window_component) {
case HTBOTTOM:
return ui::CursorType::kSouthResize;
case HTBOTTOMLEFT:
return ui::CursorType::kSouthWestResize;
case HTBOTTOMRIGHT:
return ui::CursorType::kSouthEastResize;
case HTLEFT:
return ui::CursorType::kWestResize;
case HTRIGHT:
return ui::CursorType::kEastResize;
case HTTOP:
return ui::CursorType::kNorthResize;
case HTTOPLEFT:
return ui::CursorType::kNorthWestResize;
case HTTOPRIGHT:
return ui::CursorType::kNorthEastResize;
default:
return ui::CursorType::kNull;
}
}
void OnMoveLoopCompleted(const base::Callback<void(bool success)>& end_closure,
wm::WmToplevelWindowEventHandler::DragResult result) {
end_closure.Run(result ==
wm::WmToplevelWindowEventHandler::DragResult::SUCCESS);
}
} // namespace
MoveEventHandler::MoveEventHandler(
aura::WindowManagerClient* window_manager_client,
aura::Window* window)
: window_(window), window_manager_client_(window_manager_client) {
window->AddObserver(this);
window->AddPreTargetHandler(this);
window->SetProperty(kWmMoveEventHandler, this);
}
MoveEventHandler::~MoveEventHandler() {
Detach();
}
// static
MoveEventHandler* MoveEventHandler::GetForWindow(aura::Window* window) {
return window->GetProperty(kWmMoveEventHandler);
}
void MoveEventHandler::AttemptToStartDrag(
const gfx::Point& point_in_parent,
int window_component,
::wm::WindowMoveSource source,
const base::Callback<void(bool success)>& end_closure) {
toplevel_window_event_handler_.AttemptToStartDrag(
window_, point_in_parent, window_component, source,
base::Bind(&OnMoveLoopCompleted, end_closure));
}
bool MoveEventHandler::IsDragInProgress() {
return toplevel_window_event_handler_.is_drag_in_progress();
}
void MoveEventHandler::RevertDrag() {
toplevel_window_event_handler_.RevertDrag();
}
void MoveEventHandler::Detach() {
if (!window_)
return;
window_->RemoveObserver(this);
window_->RemovePreTargetHandler(this);
window_->ClearProperty(kWmMoveEventHandler);
window_ = nullptr;
}
WorkspaceEventHandlerMash* MoveEventHandler::GetWorkspaceEventHandlerMash() {
if (!window_->parent())
return nullptr;
return WorkspaceEventHandlerMash::Get(window_->parent());
}
void MoveEventHandler::OnMouseEvent(ui::MouseEvent* event) {
toplevel_window_event_handler_.OnMouseEvent(event, window_);
if (!toplevel_window_event_handler_.is_drag_in_progress() &&
(event->type() == ui::ET_POINTER_MOVED ||
event->type() == ui::ET_MOUSE_MOVED)) {
const int hit_test_location =
wm::GetNonClientComponent(window_, event->location());
window_manager_client_->SetNonClientCursor(
window_, ui::CursorData(CursorForWindowComponent(hit_test_location)));
}
WorkspaceEventHandlerMash* workspace_event_handler =
GetWorkspaceEventHandlerMash();
if (workspace_event_handler)
workspace_event_handler->OnMouseEvent(event, window_);
}
void MoveEventHandler::OnGestureEvent(ui::GestureEvent* event) {
toplevel_window_event_handler_.OnGestureEvent(event, window_);
WorkspaceEventHandlerMash* workspace_event_handler =
GetWorkspaceEventHandlerMash();
if (workspace_event_handler)
workspace_event_handler->OnGestureEvent(event, window_);
}
void MoveEventHandler::OnCancelMode(ui::CancelModeEvent* event) {
toplevel_window_event_handler_.RevertDrag();
}
void MoveEventHandler::OnWindowDestroying(aura::Window* window) {
DCHECK_EQ(window_, window);
Detach();
}
} // namespace ash