Commit 9e387647 authored by erg's avatar erg Committed by Commit bot

aura-mus: wire up drag and drop.

- Drag now works again.
- Ensure the nested run loop gets torn down on errors.
- Adds logs of dvlogs for debugging when needed.
- Moves registration of aura components to //ui/aura/.

BUG=699235,665077

Review-Url: https://codereview.chromium.org/2739213003
Cr-Commit-Position: refs/heads/master@{#456193}
parent 5530deaf
......@@ -75,6 +75,8 @@ void DragController::Cancel() {
bool DragController::DispatchPointerEvent(const ui::PointerEvent& event,
ServerWindow* current_target) {
DVLOG(2) << "DragController dispatching pointer event at "
<< event.location().ToString();
uint32_t event_flags =
event.flags() &
(ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN);
......@@ -83,11 +85,15 @@ bool DragController::DispatchPointerEvent(const ui::PointerEvent& event,
if (waiting_for_final_drop_response_) {
// If we're waiting on a target window to respond to the final drag drop
// call, don't process any more pointer events.
DVLOG(1) << "Ignoring event because we're waiting for final drop response";
return false;
}
if (event.pointer_details().id != drag_pointer_id_)
if (event.pointer_details().id != drag_pointer_id_) {
DVLOG(1) << "Ignoring event from different pointer "
<< event.pointer_details().id;
return false;
}
// If |current_target| doesn't accept drags, walk its hierarchy up until we
// find one that does (or set to nullptr at the top of the tree).
......@@ -119,6 +125,10 @@ bool DragController::DispatchPointerEvent(const ui::PointerEvent& event,
}
SetCurrentTargetWindow(current_target);
} else if (event.type() != ET_POINTER_UP) {
DVLOG(1) << "Performing no action for pointer event at "
<< screen_position.ToString()
<< "! current_target=" << current_target;
}
if (event.type() == ET_POINTER_UP) {
......@@ -143,6 +153,8 @@ void DragController::OnWillDestroyDragTargetConnection(
void DragController::MessageDragCompleted(bool success,
DropEffect action_taken) {
DVLOG(1) << "Drag Completed: success=" << success
<< ", action_taken=" << action_taken;
for (DragTargetConnection* connection : called_on_drag_mime_types_)
connection->PerformOnDragDropDone();
called_on_drag_mime_types_.clear();
......@@ -212,6 +224,8 @@ void DragController::QueueOperation(ServerWindow* window,
OperationType type,
uint32_t event_flags,
const gfx::Point& screen_position) {
DVLOG(2) << "Queueing operation " << ToString(type) << " to " << window;
// If this window doesn't have the mime data, send it.
DragTargetConnection* connection = source_->GetDragTargetForWindow(window);
if (connection != source_connection_ &&
......@@ -329,5 +343,23 @@ void DragController::OnWindowDestroying(ServerWindow* window) {
}
}
// static
std::string DragController::ToString(OperationType type) {
switch (type) {
case OperationType::NONE:
return "NONE";
case OperationType::ENTER:
return "ENTER";
case OperationType::OVER:
return "OVER";
case OperationType::LEAVE:
return "LEAVE";
case OperationType::DROP:
return "DROP";
}
NOTREACHED();
return std::string();
}
} // namespace ws
} // namespace ui
......@@ -111,6 +111,8 @@ class DragController : public ServerWindowObserver {
// ServerWindowObserver:
void OnWindowDestroying(ServerWindow* window) override;
static std::string ToString(OperationType type);
// Our owner.
DragSource* source_;
......
......@@ -1765,7 +1765,8 @@ void WindowTree::PerformDragDrop(
// We need to fail this move loop change, otherwise the client will just be
// waiting for |change_id|.
DVLOG(1) << "PerformDragDrop failed (access denied).";
OnChangeCompleted(change_id, false);
client()->OnPerformDragDropCompleted(change_id, false,
mojom::kDropEffectNone);
return;
}
......@@ -1773,7 +1774,8 @@ void WindowTree::PerformDragDrop(
if (!display_root) {
// The window isn't parented. There's nothing to do.
DVLOG(1) << "PerformDragDrop failed (window unparented).";
OnChangeCompleted(change_id, false);
client()->OnPerformDragDropCompleted(change_id, false,
mojom::kDropEffectNone);
return;
}
......@@ -1781,7 +1783,8 @@ void WindowTree::PerformDragDrop(
// Either the window manager is servicing a window drag or we're servicing
// a drag and drop operation. We can't start a second drag.
DVLOG(1) << "PerformDragDrop failed (already performing a drag).";
OnChangeCompleted(change_id, false);
client()->OnPerformDragDropCompleted(change_id, false,
mojom::kDropEffectNone);
return;
}
......
......@@ -13,6 +13,7 @@
#include "ui/aura/env_observer.h"
#include "ui/aura/input_state_lookup.h"
#include "ui/aura/mus/mus_types.h"
#include "ui/aura/mus/os_exchange_data_provider_mus.h"
#include "ui/aura/mus/window_port_mus.h"
#include "ui/aura/mus/window_tree_client.h"
#include "ui/aura/window.h"
......@@ -75,6 +76,9 @@ class Env::ActiveFocusClientWindowObserver : public WindowObserver {
// Env, public:
Env::~Env() {
if (RunningInsideMus())
ui::OSExchangeDataProviderFactory::SetFactory(nullptr);
for (EnvObserver& observer : observers_)
observer.OnWillDestroyEnv();
DCHECK_EQ(this, lazy_tls_ptr.Pointer()->Get());
......@@ -192,8 +196,11 @@ Env::Env(Mode mode)
}
void Env::Init() {
if (RunningInsideMus())
if (RunningInsideMus()) {
ui::OSExchangeDataProviderFactory::SetFactory(this);
return;
}
#if defined(USE_OZONE)
// The ozone platform can provide its own event source. So initialize the
// platform before creating the default event source. If running inside mus
......@@ -243,4 +250,8 @@ ui::EventTargeter* Env::GetEventTargeter() {
return NULL;
}
std::unique_ptr<ui::OSExchangeData::Provider> Env::BuildProvider() {
return base::MakeUnique<aura::OSExchangeDataProviderMus>();
}
} // namespace aura
......@@ -11,6 +11,7 @@
#include "base/observer_list.h"
#include "base/supports_user_data.h"
#include "ui/aura/aura_export.h"
#include "ui/base/dragdrop/os_exchange_data_provider_factory.h"
#include "ui/events/event_handler.h"
#include "ui/events/event_target.h"
#include "ui/gfx/geometry/point.h"
......@@ -39,7 +40,9 @@ class WindowTreeClient;
class WindowTreeHost;
// A singleton object that tracks general state within Aura.
class AURA_EXPORT Env : public ui::EventTarget, public base::SupportsUserData {
class AURA_EXPORT Env : public ui::EventTarget,
public ui::OSExchangeDataProviderFactory::Factory,
public base::SupportsUserData {
public:
enum class Mode {
// Classic aura.
......@@ -138,6 +141,9 @@ class AURA_EXPORT Env : public ui::EventTarget, public base::SupportsUserData {
std::unique_ptr<ui::EventTargetIterator> GetChildIterator() const override;
ui::EventTargeter* GetEventTargeter() override;
// Overridden from ui::OSExchangeDataProviderFactory::Factory:
std::unique_ptr<ui::OSExchangeData::Provider> BuildProvider() override;
// This is not const for tests, which may share Env across tests and so needs
// to reset the value.
Mode mode_;
......
......@@ -137,23 +137,25 @@ int DragDropControllerMus::StartDragAndDrop(
// we start showing an image representation of the drag under he cursor.
base::RunLoop run_loop;
WindowMus* source_window_mus = WindowMus::Get(source_window);
WindowMus* root_window_mus = WindowMus::Get(root_window);
const uint32_t change_id =
drag_drop_controller_host_->CreateChangeIdForDrag(source_window_mus);
CurrentDragState current_drag_state = {source_window_mus->server_id(),
drag_drop_controller_host_->CreateChangeIdForDrag(root_window_mus);
CurrentDragState current_drag_state = {root_window_mus->server_id(),
change_id, ui::mojom::kDropEffectNone,
data, run_loop.QuitClosure()};
base::AutoReset<CurrentDragState*> resetter(&current_drag_state_,
&current_drag_state);
base::MessageLoop* loop = base::MessageLoop::current();
base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
std::map<std::string, std::vector<uint8_t>> drag_data =
static_cast<const aura::OSExchangeDataProviderMus&>(data.provider())
.GetData();
window_tree_->PerformDragDrop(change_id, source_window_mus->server_id(),
window_tree_->PerformDragDrop(change_id, root_window_mus->server_id(),
mojo::MapToUnorderedMap(drag_data),
drag_operations);
base::MessageLoop* loop = base::MessageLoop::current();
base::MessageLoop::ScopedNestableTaskAllower allow_nested(loop);
run_loop.Run();
return current_drag_state.completed_action;
......
......@@ -71,6 +71,10 @@ void WindowPortMus::SetEventTargetingPolicy(
window_tree_client_->SetEventTargetingPolicy(this, policy);
}
void WindowPortMus::SetCanAcceptDrops(bool can_accept_drops) {
window_tree_client_->SetCanAcceptDrops(this, can_accept_drops);
}
void WindowPortMus::Embed(
ui::mojom::WindowTreeClientPtr client,
uint32_t flags,
......
......@@ -59,6 +59,9 @@ class AURA_EXPORT WindowPortMus : public WindowPort, public WindowMus {
// Sets the EventTargetingPolicy, default is TARGET_AND_DESCENDANTS.
void SetEventTargetingPolicy(ui::mojom::EventTargetingPolicy policy);
// Sets whether this window can accept drops, defaults to false.
void SetCanAcceptDrops(bool can_accept_drops);
// Embeds a new client in this Window. See WindowTreeClient::Embed() for
// details on arguments.
void Embed(ui::mojom::WindowTreeClientPtr client,
......
......@@ -826,9 +826,10 @@ void WindowTreeClient::RemoveTestObserver(
test_observers_.RemoveObserver(observer);
}
void WindowTreeClient::SetCanAcceptDrops(Id window_id, bool can_accept_drops) {
void WindowTreeClient::SetCanAcceptDrops(WindowMus* window,
bool can_accept_drops) {
DCHECK(tree_);
tree_->SetCanAcceptDrops(window_id, can_accept_drops);
tree_->SetCanAcceptDrops(window->server_id(), can_accept_drops);
}
void WindowTreeClient::SetEventTargetingPolicy(
......@@ -1268,10 +1269,9 @@ void WindowTreeClient::OnCompleteDrop(Id window_id,
void WindowTreeClient::OnPerformDragDropCompleted(uint32_t change_id,
bool success,
uint32_t action_taken) {
if (drag_drop_controller_->DoesChangeIdMatchDragChangeId(change_id)) {
OnChangeCompleted(change_id, success);
OnChangeCompleted(change_id, success);
if (drag_drop_controller_->DoesChangeIdMatchDragChangeId(change_id))
drag_drop_controller_->OnPerformDragDropCompleted(action_taken);
}
}
void WindowTreeClient::OnChangeCompleted(uint32_t change_id, bool success) {
......
......@@ -110,7 +110,7 @@ class AURA_EXPORT WindowTreeClient
ClientSpecificId client_id() const { return client_id_; }
void SetCanFocus(Window* window, bool can_focus);
void SetCanAcceptDrops(Id window_id, bool can_accept_drops);
void SetCanAcceptDrops(WindowMus* window, bool can_accept_drops);
void SetEventTargetingPolicy(WindowMus* window,
ui::mojom::EventTargetingPolicy policy);
void SetPredefinedCursor(WindowMus* window,
......
......@@ -307,6 +307,8 @@ void DesktopWindowTreeHostMus::Init(aura::Window* content_window,
if (!params.accept_events) {
aura::WindowPortMus::Get(window())->SetEventTargetingPolicy(
ui::mojom::EventTargetingPolicy::NONE);
} else {
aura::WindowPortMus::Get(content_window)->SetCanAcceptDrops(true);
}
}
......
......@@ -18,7 +18,6 @@
#include "ui/aura/env.h"
#include "ui/aura/mus/capture_synchronizer.h"
#include "ui/aura/mus/mus_context_factory.h"
#include "ui/aura/mus/os_exchange_data_provider_mus.h"
#include "ui/aura/mus/property_converter.h"
#include "ui/aura/mus/window_tree_client.h"
#include "ui/aura/mus/window_tree_host_mus.h"
......@@ -112,8 +111,6 @@ MusClient::MusClient(service_manager::Connector* connector,
clipboard->Init(connector);
ui::Clipboard::SetClipboardForCurrentThread(std::move(clipboard));
ui::OSExchangeDataProviderFactory::SetFactory(this);
ViewsDelegate::GetInstance()->set_native_widget_factory(
base::Bind(&MusClient::CreateNativeWidget, base::Unretained(this)));
}
......@@ -297,8 +294,4 @@ aura::Window* MusClient::GetWindowAtScreenPoint(const gfx::Point& point) {
return nullptr;
}
std::unique_ptr<OSExchangeData::Provider> MusClient::BuildProvider() {
return base::MakeUnique<aura::OSExchangeDataProviderMus>();
}
} // namespace views
......@@ -15,7 +15,6 @@
#include "services/service_manager/public/cpp/identity.h"
#include "ui/aura/client/capture_client.h"
#include "ui/aura/mus/window_tree_client_delegate.h"
#include "ui/base/dragdrop/os_exchange_data_provider_factory.h"
#include "ui/views/mus/mus_export.h"
#include "ui/views/mus/screen_mus_delegate.h"
#include "ui/views/widget/widget.h"
......@@ -61,10 +60,8 @@ class MusClientTestApi;
// MusClient establishes a connection to mus and sets up necessary state so that
// aura and views target mus. This class is useful for typical clients, not the
// WindowManager. Most clients don't create this directly, rather use AuraInit.
class VIEWS_MUS_EXPORT MusClient
: public aura::WindowTreeClientDelegate,
public ScreenMusDelegate,
public ui::OSExchangeDataProviderFactory::Factory {
class VIEWS_MUS_EXPORT MusClient : public aura::WindowTreeClientDelegate,
public ScreenMusDelegate {
public:
// Most clients should use AuraInit, which creates a MusClient.
// |create_wm_state| indicates whether MusClient should create a wm::WMState.
......@@ -135,9 +132,6 @@ class VIEWS_MUS_EXPORT MusClient
void OnWindowManagerFrameValuesChanged() override;
aura::Window* GetWindowAtScreenPoint(const gfx::Point& point) override;
// ui:OSExchangeDataProviderFactory::Factory:
std::unique_ptr<OSExchangeData::Provider> BuildProvider() override;
static MusClient* instance_;
service_manager::Identity identity_;
......
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