Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(250)

Unified Diff: components/mus/ws/event_dispatcher.cc

Issue 2119963002: Move mus to //services/ui (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/mus/ws/event_dispatcher.h ('k') | components/mus/ws/event_dispatcher_delegate.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/mus/ws/event_dispatcher.cc
diff --git a/components/mus/ws/event_dispatcher.cc b/components/mus/ws/event_dispatcher.cc
deleted file mode 100644
index 23874c3abc406cfdfa651e788b5891cc81a43ff3..0000000000000000000000000000000000000000
--- a/components/mus/ws/event_dispatcher.cc
+++ /dev/null
@@ -1,559 +0,0 @@
-// 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 "components/mus/ws/event_dispatcher.h"
-
-#include <algorithm>
-
-#include "base/time/time.h"
-#include "components/mus/ws/accelerator.h"
-#include "components/mus/ws/display.h"
-#include "components/mus/ws/event_dispatcher_delegate.h"
-#include "components/mus/ws/server_window.h"
-#include "components/mus/ws/server_window_delegate.h"
-#include "components/mus/ws/window_coordinate_conversions.h"
-#include "components/mus/ws/window_finder.h"
-#include "ui/events/event_utils.h"
-#include "ui/gfx/geometry/point.h"
-#include "ui/gfx/geometry/point_conversions.h"
-
-namespace mus {
-namespace ws {
-
-using Entry = std::pair<uint32_t, std::unique_ptr<Accelerator>>;
-
-namespace {
-
-bool IsOnlyOneMouseButtonDown(int flags) {
- const uint32_t button_only_flags =
- flags & (ui::EF_LEFT_MOUSE_BUTTON | ui::EF_MIDDLE_MOUSE_BUTTON |
- ui::EF_RIGHT_MOUSE_BUTTON);
- return button_only_flags == ui::EF_LEFT_MOUSE_BUTTON ||
- button_only_flags == ui::EF_MIDDLE_MOUSE_BUTTON ||
- button_only_flags == ui::EF_RIGHT_MOUSE_BUTTON;
-}
-
-bool IsLocationInNonclientArea(const ServerWindow* target,
- const gfx::Point& location) {
- if (!target->parent())
- return false;
-
- gfx::Rect client_area(target->bounds().size());
- client_area.Inset(target->client_area());
- if (client_area.Contains(location))
- return false;
-
- for (const auto& rect : target->additional_client_areas()) {
- if (rect.Contains(location))
- return false;
- }
-
- return true;
-}
-
-uint32_t PointerId(const ui::LocatedEvent& event) {
- if (event.IsPointerEvent())
- return event.AsPointerEvent()->pointer_id();
- if (event.IsMouseWheelEvent())
- return ui::PointerEvent::kMousePointerId;
-
- NOTREACHED();
- return 0;
-}
-
-} // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-
-EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate)
- : delegate_(delegate),
- capture_window_(nullptr),
- capture_window_client_id_(kInvalidClientId),
- modal_window_controller_(this),
- mouse_button_down_(false),
- mouse_cursor_source_window_(nullptr),
- mouse_cursor_in_non_client_area_(false) {}
-
-EventDispatcher::~EventDispatcher() {
- if (capture_window_) {
- UnobserveWindow(capture_window_);
- capture_window_ = nullptr;
- capture_window_client_id_ = kInvalidClientId;
- }
- for (const auto& pair : pointer_targets_) {
- if (pair.second.window)
- UnobserveWindow(pair.second.window);
- }
- pointer_targets_.clear();
-}
-
-void EventDispatcher::Reset() {
- if (capture_window_) {
- CancelPointerEventsToTarget(capture_window_);
- DCHECK(capture_window_ == nullptr);
- }
-
- while (!pointer_targets_.empty())
- StopTrackingPointer(pointer_targets_.begin()->first);
-
- mouse_button_down_ = false;
-}
-
-void EventDispatcher::SetMousePointerScreenLocation(
- const gfx::Point& screen_location) {
- DCHECK(pointer_targets_.empty());
- mouse_pointer_last_location_ = screen_location;
- UpdateCursorProviderByLastKnownLocation();
- // Write our initial location back to our shared screen coordinate. This
- // shouldn't cause problems because we already read the cursor before we
- // process any events in views during window construction.
- delegate_->OnMouseCursorLocationChanged(screen_location);
-}
-
-bool EventDispatcher::GetCurrentMouseCursor(int32_t* cursor_out) {
- if (!mouse_cursor_source_window_)
- return false;
-
- *cursor_out = mouse_cursor_in_non_client_area_
- ? mouse_cursor_source_window_->non_client_cursor()
- : mouse_cursor_source_window_->cursor();
- return true;
-}
-
-bool EventDispatcher::SetCaptureWindow(ServerWindow* window,
- ClientSpecificId client_id) {
- if (!window)
- client_id = kInvalidClientId;
-
- if (window == capture_window_ && client_id == capture_window_client_id_)
- return true;
-
- // A window that is blocked by a modal window cannot gain capture.
- if (window && modal_window_controller_.IsWindowBlocked(window))
- return false;
-
- if (capture_window_) {
- // Stop observing old capture window. |pointer_targets_| are cleared on
- // initial setting of a capture window.
- delegate_->OnServerWindowCaptureLost(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,
- ui::PointerDetails(pointer_type), ui::EventTimeForNow());
- DispatchToPointerTarget(pair.second, event);
- }
- pointer_targets_.clear();
- }
-
- // Set the capture before changing native capture; otherwise, the callback
- // from native platform might try to set the capture again.
- bool had_capture_window = capture_window_ != nullptr;
- capture_window_ = window;
- capture_window_client_id_ = client_id;
-
- // Begin tracking the capture window if it is not yet being observed.
- if (window) {
- ObserveWindow(window);
- // TODO(sky): this conditional is problematic for the case of capture moving
- // to a different display.
- if (!had_capture_window)
- delegate_->SetNativeCapture(window);
- } else {
- delegate_->ReleaseNativeCapture();
- if (!mouse_button_down_)
- UpdateCursorProviderByLastKnownLocation();
- }
-
- return true;
-}
-
-void EventDispatcher::AddSystemModalWindow(ServerWindow* window) {
- modal_window_controller_.AddSystemModalWindow(window);
-}
-
-void EventDispatcher::ReleaseCaptureBlockedByModalWindow(
- const ServerWindow* modal_window) {
- if (!capture_window_)
- return;
-
- if (modal_window_controller_.IsWindowBlockedBy(capture_window_,
- modal_window)) {
- SetCaptureWindow(nullptr, kInvalidClientId);
- }
-}
-
-void EventDispatcher::ReleaseCaptureBlockedByAnyModalWindow() {
- if (!capture_window_)
- return;
-
- if (modal_window_controller_.IsWindowBlocked(capture_window_))
- SetCaptureWindow(nullptr, kInvalidClientId);
-}
-
-void EventDispatcher::UpdateNonClientAreaForCurrentWindow() {
- if (mouse_cursor_source_window_) {
- gfx::Point location = mouse_pointer_last_location_;
- ServerWindow* target = FindDeepestVisibleWindowForEvents(&location);
- if (target == mouse_cursor_source_window_) {
- mouse_cursor_in_non_client_area_ =
- mouse_cursor_source_window_
- ? IsLocationInNonclientArea(mouse_cursor_source_window_, location)
- : false;
- }
- }
-}
-
-void EventDispatcher::UpdateCursorProviderByLastKnownLocation() {
- if (!mouse_button_down_) {
- gfx::Point location = mouse_pointer_last_location_;
- mouse_cursor_source_window_ = FindDeepestVisibleWindowForEvents(&location);
-
- mouse_cursor_in_non_client_area_ =
- mouse_cursor_source_window_
- ? IsLocationInNonclientArea(mouse_cursor_source_window_, location)
- : false;
- }
-}
-
-bool EventDispatcher::AddAccelerator(uint32_t id,
- mojom::EventMatcherPtr event_matcher) {
- std::unique_ptr<Accelerator> accelerator(new Accelerator(id, *event_matcher));
- // If an accelerator with the same id or matcher already exists, then abort.
- for (const auto& pair : accelerators_) {
- if (pair.first == id || accelerator->EqualEventMatcher(pair.second.get()))
- return false;
- }
- accelerators_.insert(Entry(id, std::move(accelerator)));
- return true;
-}
-
-void EventDispatcher::RemoveAccelerator(uint32_t id) {
- auto it = accelerators_.find(id);
- // Clients may pass bogus ids.
- if (it != accelerators_.end())
- accelerators_.erase(it);
-}
-
-void EventDispatcher::ProcessEvent(const ui::Event& event) {
- if (event.IsKeyEvent()) {
- const ui::KeyEvent* key_event = event.AsKeyEvent();
- if (event.type() == ui::ET_KEY_PRESSED && !key_event->is_char()) {
- Accelerator* pre_target =
- FindAccelerator(*key_event, ui::mojom::AcceleratorPhase::PRE_TARGET);
- if (pre_target) {
- delegate_->OnAccelerator(pre_target->id(), event);
- return;
- }
- }
- ProcessKeyEvent(*key_event);
- return;
- }
-
- if (event.IsPointerEvent() || event.IsMouseWheelEvent()) {
- ProcessLocatedEvent(*event.AsLocatedEvent());
- return;
- }
-
- NOTREACHED();
-}
-
-void EventDispatcher::ProcessKeyEvent(const ui::KeyEvent& event) {
- Accelerator* post_target =
- FindAccelerator(event, ui::mojom::AcceleratorPhase::POST_TARGET);
- ServerWindow* focused_window =
- delegate_->GetFocusedWindowForEventDispatcher();
- if (focused_window) {
- // Assume key events are for the client area.
- const bool in_nonclient_area = false;
- const ClientSpecificId client_id =
- delegate_->GetEventTargetClientId(focused_window, in_nonclient_area);
- delegate_->DispatchInputEventToWindow(focused_window, client_id, event,
- post_target);
- return;
- }
- delegate_->OnEventTargetNotFound(event);
- if (post_target)
- delegate_->OnAccelerator(post_target->id(), event);
-}
-
-void EventDispatcher::ProcessLocatedEvent(const ui::LocatedEvent& event) {
- DCHECK(event.IsPointerEvent() || event.IsMouseWheelEvent());
- const bool is_mouse_event =
- event.IsMousePointerEvent() || event.IsMouseWheelEvent();
-
- if (is_mouse_event) {
- mouse_pointer_last_location_ = event.location();
- delegate_->OnMouseCursorLocationChanged(event.root_location());
- }
-
- // Release capture on pointer up. For mouse we only release if there are
- // no buttons down.
- const bool is_pointer_going_up =
- (event.type() == ui::ET_POINTER_UP ||
- event.type() == ui::ET_POINTER_CANCELLED) &&
- (!is_mouse_event || IsOnlyOneMouseButtonDown(event.flags()));
-
- // Update mouse down state upon events which change it.
- if (is_mouse_event) {
- if (event.type() == ui::ET_POINTER_DOWN)
- mouse_button_down_ = true;
- else if (is_pointer_going_up)
- mouse_button_down_ = false;
- }
-
- if (capture_window_) {
- mouse_cursor_source_window_ = capture_window_;
- DispatchToClient(capture_window_, capture_window_client_id_, event);
- return;
- }
-
- const int32_t pointer_id = PointerId(event);
- if (!IsTrackingPointer(pointer_id) ||
- !pointer_targets_[pointer_id].is_pointer_down) {
- const bool any_pointers_down = AreAnyPointersDown();
- UpdateTargetForPointer(pointer_id, event);
- if (is_mouse_event)
- mouse_cursor_source_window_ = pointer_targets_[pointer_id].window;
-
- PointerTarget& pointer_target = pointer_targets_[pointer_id];
- if (pointer_target.is_pointer_down) {
- if (is_mouse_event)
- mouse_cursor_source_window_ = pointer_target.window;
- if (!any_pointers_down) {
- delegate_->SetFocusedWindowFromEventDispatcher(pointer_target.window);
- delegate_->SetNativeCapture(pointer_target.window);
- }
- }
- }
-
- // When we release the mouse button, we want the cursor to be sourced from
- // the window under the mouse pointer, even though we're sending the button
- // up event to the window that had implicit capture. We have to set this
- // before we perform dispatch because the Delegate is going to read this
- // information from us.
- if (is_pointer_going_up && is_mouse_event)
- UpdateCursorProviderByLastKnownLocation();
-
- DispatchToPointerTarget(pointer_targets_[pointer_id], event);
-
- if (is_pointer_going_up) {
- if (is_mouse_event)
- pointer_targets_[pointer_id].is_pointer_down = false;
- else
- StopTrackingPointer(pointer_id);
- if (!AreAnyPointersDown())
- delegate_->ReleaseNativeCapture();
- }
-}
-
-void EventDispatcher::StartTrackingPointer(
- int32_t pointer_id,
- const PointerTarget& pointer_target) {
- DCHECK(!IsTrackingPointer(pointer_id));
- ObserveWindow(pointer_target.window);
- pointer_targets_[pointer_id] = pointer_target;
-}
-
-void EventDispatcher::StopTrackingPointer(int32_t pointer_id) {
- DCHECK(IsTrackingPointer(pointer_id));
- ServerWindow* window = pointer_targets_[pointer_id].window;
- pointer_targets_.erase(pointer_id);
- if (window)
- UnobserveWindow(window);
-}
-
-void EventDispatcher::UpdateTargetForPointer(int32_t pointer_id,
- const ui::LocatedEvent& event) {
- if (!IsTrackingPointer(pointer_id)) {
- StartTrackingPointer(pointer_id, PointerTargetForEvent(event));
- return;
- }
-
- const PointerTarget pointer_target = PointerTargetForEvent(event);
- if (pointer_target.window == pointer_targets_[pointer_id].window &&
- pointer_target.in_nonclient_area ==
- pointer_targets_[pointer_id].in_nonclient_area) {
- // The targets are the same, only set the down state to true if necessary.
- // Down going to up is handled by ProcessLocatedEvent().
- if (pointer_target.is_pointer_down)
- pointer_targets_[pointer_id].is_pointer_down = true;
- return;
- }
-
- // The targets are changing. Send an exit if appropriate.
- if (event.IsMousePointerEvent()) {
- ui::PointerEvent exit_event(
- ui::ET_POINTER_EXITED, event.location(), event.root_location(),
- event.flags(), ui::PointerEvent::kMousePointerId,
- ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE),
- event.time_stamp());
- DispatchToPointerTarget(pointer_targets_[pointer_id], exit_event);
- }
-
- // Technically we're updating in place, but calling start then stop makes for
- // simpler code.
- StopTrackingPointer(pointer_id);
- StartTrackingPointer(pointer_id, pointer_target);
-}
-
-EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent(
- const ui::LocatedEvent& event) {
- PointerTarget pointer_target;
- gfx::Point location(event.location());
- ServerWindow* target_window = FindDeepestVisibleWindowForEvents(&location);
- pointer_target.window =
- modal_window_controller_.GetTargetForWindow(target_window);
- pointer_target.is_mouse_event = event.IsMousePointerEvent();
- pointer_target.in_nonclient_area =
- target_window != pointer_target.window ||
- IsLocationInNonclientArea(pointer_target.window, location);
- pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN;
- return pointer_target;
-}
-
-bool EventDispatcher::AreAnyPointersDown() const {
- for (const auto& pair : pointer_targets_) {
- if (pair.second.is_pointer_down)
- return true;
- }
- return false;
-}
-
-void EventDispatcher::DispatchToPointerTarget(const PointerTarget& target,
- const ui::LocatedEvent& event) {
- if (!target.window) {
- delegate_->OnEventTargetNotFound(event);
- return;
- }
-
- if (target.is_mouse_event)
- mouse_cursor_in_non_client_area_ = target.in_nonclient_area;
-
- DispatchToClient(target.window, delegate_->GetEventTargetClientId(
- target.window, target.in_nonclient_area),
- event);
-}
-
-void EventDispatcher::DispatchToClient(ServerWindow* window,
- ClientSpecificId client_id,
- const ui::LocatedEvent& event) {
- gfx::Point location(event.location());
- gfx::Transform transform(GetTransformToWindow(window));
- transform.TransformPoint(&location);
- std::unique_ptr<ui::Event> clone = ui::Event::Clone(event);
- clone->AsLocatedEvent()->set_location(location);
- // TODO(jonross): add post-target accelerator support once accelerators
- // support pointer events.
- delegate_->DispatchInputEventToWindow(window, client_id, *clone, nullptr);
-}
-
-void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) {
- if (capture_window_ == window) {
- UnobserveWindow(window);
- capture_window_ = nullptr;
- capture_window_client_id_ = kInvalidClientId;
- mouse_button_down_ = false;
- // A window only cares to be informed that it lost capture if it explicitly
- // requested capture. A window can lose capture if another window gains
- // explicit capture.
- delegate_->OnServerWindowCaptureLost(window);
- delegate_->ReleaseNativeCapture();
- UpdateCursorProviderByLastKnownLocation();
- return;
- }
-
- for (auto& pair : pointer_targets_) {
- if (pair.second.window == window) {
- UnobserveWindow(window);
- pair.second.window = nullptr;
- }
- }
-}
-
-void EventDispatcher::ObserveWindow(ServerWindow* window) {
- auto res = observed_windows_.insert(std::make_pair(window, 0u));
- res.first->second++;
- if (res.second)
- window->AddObserver(this);
-}
-
-void EventDispatcher::UnobserveWindow(ServerWindow* window) {
- auto it = observed_windows_.find(window);
- DCHECK(it != observed_windows_.end());
- DCHECK_LT(0u, it->second);
- it->second--;
- if (!it->second) {
- window->RemoveObserver(this);
- observed_windows_.erase(it);
- }
-}
-
-Accelerator* EventDispatcher::FindAccelerator(
- const ui::KeyEvent& event,
- const ui::mojom::AcceleratorPhase phase) {
- for (const auto& pair : accelerators_) {
- if (pair.second->MatchesEvent(event, phase)) {
- return pair.second.get();
- }
- }
- return nullptr;
-}
-
-ServerWindow* EventDispatcher::FindDeepestVisibleWindowForEvents(
- gfx::Point* location) {
- ServerWindow* root = delegate_->GetRootWindowContaining(*location);
- if (!root)
- return nullptr;
-
- return mus::ws::FindDeepestVisibleWindowForEvents(root, location);
-}
-
-void EventDispatcher::OnWillChangeWindowHierarchy(ServerWindow* window,
- ServerWindow* new_parent,
- ServerWindow* old_parent) {
- // TODO(sky): moving to a different root likely needs to transfer capture.
- // TODO(sky): this isn't quite right, I think the logic should be (assuming
- // moving in same root and still drawn):
- // . if there is capture and window is still in the same root, continue
- // sending to it.
- // . if there isn't capture, then reevaluate each of the pointer targets
- // sending exit as necessary.
- // http://crbug.com/613646 .
- if (!new_parent || !new_parent->IsDrawn() ||
- new_parent->GetRoot() != old_parent->GetRoot()) {
- CancelPointerEventsToTarget(window);
- }
-}
-
-void EventDispatcher::OnWindowVisibilityChanged(ServerWindow* window) {
- CancelPointerEventsToTarget(window);
-}
-
-void EventDispatcher::OnWindowDestroyed(ServerWindow* window) {
- CancelPointerEventsToTarget(window);
-
- if (mouse_cursor_source_window_ == window)
- mouse_cursor_source_window_ = nullptr;
-}
-
-} // namespace ws
-} // namespace mus
« no previous file with comments | « components/mus/ws/event_dispatcher.h ('k') | components/mus/ws/event_dispatcher_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698