Chromium Code Reviews| Index: services/ui/ws/event_dispatcher.cc |
| diff --git a/services/ui/ws/event_dispatcher.cc b/services/ui/ws/event_dispatcher.cc |
| index 3890db7bb4bc43bd2fa893296d11ec19d1e64634..9e166c19af2de2a91615d8bda8829aff94838669 100644 |
| --- a/services/ui/ws/event_dispatcher.cc |
| +++ b/services/ui/ws/event_dispatcher.cc |
| @@ -9,6 +9,8 @@ |
| #include "base/time/time.h" |
| #include "services/ui/ws/accelerator.h" |
| #include "services/ui/ws/display.h" |
| +#include "services/ui/ws/drag_controller.h" |
| +#include "services/ui/ws/drag_source.h" |
| #include "services/ui/ws/event_dispatcher_delegate.h" |
| #include "services/ui/ws/server_window.h" |
| #include "services/ui/ws/server_window_delegate.h" |
| @@ -123,35 +125,17 @@ bool EventDispatcher::SetCaptureWindow(ServerWindow* window, |
| if (window && modal_window_controller_.IsWindowBlocked(window)) |
| return false; |
| + // If we're currently performing a drag and drop, reject setting the capture |
| + // window. |
| + if (drag_controller_) |
| + return false; |
| + |
| if (capture_window_) { |
| // Stop observing old capture window. |pointer_targets_| are cleared on |
| // initial setting of a capture window. |
| UnobserveWindow(capture_window_); |
| } else { |
| - // Cancel implicit capture to all other windows. |
| - for (const auto& pair : pointer_targets_) { |
| - ServerWindow* target = pair.second.window; |
| - if (!target) |
| - continue; |
| - UnobserveWindow(target); |
| - if (target == window) |
| - continue; |
| - |
| - ui::EventType event_type = pair.second.is_mouse_event |
| - ? ui::ET_POINTER_EXITED |
| - : ui::ET_POINTER_CANCELLED; |
| - ui::EventPointerType pointer_type = |
| - pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE |
| - : ui::EventPointerType::POINTER_TYPE_TOUCH; |
| - // TODO(jonross): Track previous location in PointerTarget for sending |
| - // cancels. |
| - ui::PointerEvent event( |
| - event_type, gfx::Point(), gfx::Point(), ui::EF_NONE, pair.first, |
| - 0 /* changed_button_flags */, ui::PointerDetails(pointer_type), |
| - ui::EventTimeForNow()); |
| - DispatchToPointerTarget(pair.second, event); |
| - } |
| - pointer_targets_.clear(); |
| + CancelImplicitCaptureExcept(window); |
| } |
| // Set the capture before changing native capture; otherwise, the callback |
| @@ -179,6 +163,29 @@ bool EventDispatcher::SetCaptureWindow(ServerWindow* window, |
| return true; |
| } |
| +void EventDispatcher::SetDragDropSourceWindow( |
| + DragSource* drag_source, |
| + ServerWindow* window, |
| + DragTargetConnection* source_connection, |
| + int32_t drag_pointer, |
| + mojo::Map<mojo::String, mojo::Array<uint8_t>> mime_data, |
| + uint32_t drag_operations) { |
| + CancelImplicitCaptureExcept(nullptr); |
| + drag_controller_ = base::MakeUnique<DragController>( |
| + drag_source, window, source_connection, drag_pointer, |
| + std::move(mime_data), drag_operations); |
| +} |
| + |
| +void EventDispatcher::EndDragDrop() { |
| + drag_controller_.reset(); |
| +} |
| + |
| +void EventDispatcher::OnWillDestroyDragTargetConnection( |
| + DragTargetConnection* connection) { |
| + if (drag_controller_) |
| + drag_controller_->OnWillDestroyDragTargetConnection(connection); |
| +} |
| + |
| void EventDispatcher::AddSystemModalWindow(ServerWindow* window) { |
| modal_window_controller_.AddSystemModalWindow(window); |
| } |
| @@ -287,6 +294,11 @@ void EventDispatcher::ProcessKeyEvent(const ui::KeyEvent& event, |
| AcceleratorMatchPhase match_phase) { |
| Accelerator* post_target = |
| FindAccelerator(event, ui::mojom::AcceleratorPhase::POST_TARGET); |
| + if (drag_controller_ && event.type() == ui::ET_KEY_PRESSED && |
| + event.key_code() == ui::VKEY_ESCAPE) { |
| + drag_controller_->Cancel(); |
| + return; |
| + } |
| ServerWindow* focused_window = |
| delegate_->GetFocusedWindowForEventDispatcher(); |
| if (focused_window) { |
| @@ -328,6 +340,12 @@ void EventDispatcher::ProcessPointerEvent(const ui::PointerEvent& event) { |
| mouse_button_down_ = false; |
| } |
| + if (drag_controller_) { |
| + const PointerTarget target = PointerTargetForEvent(event); |
| + if (drag_controller_->DispatchPointerEvent(event, target.window)) |
| + return; |
| + } |
| + |
| if (capture_window_) { |
| mouse_cursor_source_window_ = capture_window_; |
| DispatchToClient(capture_window_, capture_window_client_id_, event); |
| @@ -535,6 +553,32 @@ ServerWindow* EventDispatcher::FindDeepestVisibleWindowForEvents( |
| return ui::ws::FindDeepestVisibleWindowForEvents(root, location); |
| } |
| +void EventDispatcher::CancelImplicitCaptureExcept(ServerWindow* window) { |
| + for (const auto& pair : pointer_targets_) { |
| + ServerWindow* target = pair.second.window; |
| + if (!target) |
| + continue; |
| + UnobserveWindow(target); |
| + if (window && target == window) |
|
sky
2016/09/13 18:15:32
I don't think you need the 'window' conditional.
Elliot Glaysher
2016/09/14 22:19:16
|window| can be null (called at line 173).
sky
2016/09/14 22:52:02
Sure, but the !target on line 559 means you know t
Elliot Glaysher
2016/09/15 17:12:40
Done.
|
| + continue; |
| + |
| + ui::EventType event_type = pair.second.is_mouse_event |
| + ? ui::ET_POINTER_EXITED |
| + : ui::ET_POINTER_CANCELLED; |
| + ui::EventPointerType pointer_type = |
| + pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE |
| + : ui::EventPointerType::POINTER_TYPE_TOUCH; |
| + // TODO(jonross): Track previous location in PointerTarget for sending |
| + // cancels. |
| + ui::PointerEvent event(event_type, gfx::Point(), gfx::Point(), ui::EF_NONE, |
| + pair.first, 0 /* changed_button_flags */, |
| + ui::PointerDetails(pointer_type), |
| + ui::EventTimeForNow()); |
| + DispatchToPointerTarget(pair.second, event); |
| + } |
| + pointer_targets_.clear(); |
| +} |
| + |
| void EventDispatcher::OnWillChangeWindowHierarchy(ServerWindow* window, |
| ServerWindow* new_parent, |
| ServerWindow* old_parent) { |