123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- // Copyright (c) 2012 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/env.h"
- #include "base/command_line.h"
- #include "base/containers/cxx20_erase.h"
- #include "base/lazy_instance.h"
- #include "base/logging.h"
- #include "base/memory/ptr_util.h"
- #include "base/memory/raw_ptr.h"
- #include "base/observer_list.h"
- #include "base/observer_list_types.h"
- #include "build/build_config.h"
- #include "ui/aura/client/aura_constants.h"
- #include "ui/aura/client/screen_position_client.h"
- #include "ui/aura/env_input_state_controller.h"
- #include "ui/aura/env_observer.h"
- #include "ui/aura/input_state_lookup.h"
- #include "ui/aura/window.h"
- #include "ui/aura/window_event_dispatcher_observer.h"
- #include "ui/aura/window_occlusion_tracker.h"
- #include "ui/display/screen.h"
- #include "ui/events/event_observer.h"
- #include "ui/events/event_target_iterator.h"
- #include "ui/events/gestures/gesture_recognizer_impl.h"
- #include "ui/events/platform/platform_event_source.h"
- #if BUILDFLAG(IS_WIN)
- #include "ui/base/win/win_cursor_factory.h"
- #endif
- #if defined(USE_OZONE)
- #include "ui/ozone/public/ozone_platform.h"
- #endif
- namespace aura {
- namespace {
- // Instance created by all static functions, except
- // CreateLocalInstanceForInProcess(). See GetInstance() for details.
- Env* g_primary_instance = nullptr;
- } // namespace
- // EventObserverAdapter is an aura::Env pre-target handler that forwards
- // read-only events to its observer when they match the requested types.
- class EventObserverAdapter : public ui::EventHandler,
- public base::CheckedObserver {
- public:
- EventObserverAdapter(ui::EventObserver* observer,
- ui::EventTarget* target,
- const std::set<ui::EventType>& types)
- : observer_(observer), target_(target), types_(types) {
- target_->AddPreTargetHandler(this);
- }
- EventObserverAdapter(const EventObserverAdapter&) = delete;
- EventObserverAdapter& operator=(const EventObserverAdapter&) = delete;
- ~EventObserverAdapter() override { target_->RemovePreTargetHandler(this); }
- ui::EventObserver* observer() { return observer_; }
- ui::EventTarget* target() { return target_; }
- const std::set<ui::EventType>& types() const { return types_; }
- // ui::EventHandler:
- void OnEvent(ui::Event* event) override {
- if (types_.count(event->type()) > 0) {
- std::unique_ptr<ui::Event> cloned_event = event->Clone();
- ui::Event::DispatcherApi(cloned_event.get()).set_target(event->target());
- // The root location of located events should be in screen coordinates.
- if (cloned_event->IsLocatedEvent() && cloned_event->target()) {
- ui::LocatedEvent* located_event = cloned_event->AsLocatedEvent();
- auto root = located_event->target()->GetScreenLocationF(*located_event);
- located_event->set_root_location_f(root);
- }
- observer_->OnEvent(*cloned_event);
- }
- }
- private:
- raw_ptr<ui::EventObserver> observer_;
- raw_ptr<ui::EventTarget> target_;
- const std::set<ui::EventType> types_;
- };
- ////////////////////////////////////////////////////////////////////////////////
- // Env, public:
- Env::~Env() {
- for (EnvObserver& observer : observers_)
- observer.OnWillDestroyEnv();
- if (this == g_primary_instance)
- g_primary_instance = nullptr;
- }
- // static
- std::unique_ptr<Env> Env::CreateInstance() {
- DCHECK(!g_primary_instance);
- // No make_unique as constructor is private.
- std::unique_ptr<Env> env(new Env());
- if (!env->Init())
- return {};
- g_primary_instance = env.get();
- return env;
- }
- // static
- Env* Env::GetInstance() {
- Env* env = g_primary_instance;
- DCHECK(env) << "Env::CreateInstance must be called before getting the "
- "instance of Env.";
- return env;
- }
- // static
- bool Env::HasInstance() {
- return !!g_primary_instance;
- }
- void Env::AddObserver(EnvObserver* observer) {
- observers_.AddObserver(observer);
- }
- void Env::RemoveObserver(EnvObserver* observer) {
- observers_.RemoveObserver(observer);
- }
- void Env::AddWindowEventDispatcherObserver(
- WindowEventDispatcherObserver* observer) {
- window_event_dispatcher_observers_.AddObserver(observer);
- }
- void Env::RemoveWindowEventDispatcherObserver(
- WindowEventDispatcherObserver* observer) {
- window_event_dispatcher_observers_.RemoveObserver(observer);
- }
- bool Env::IsMouseButtonDown() const {
- return input_state_lookup_.get() ? input_state_lookup_->IsMouseButtonDown() :
- mouse_button_flags_ != 0;
- }
- void Env::SetLastMouseLocation(const gfx::Point& last_mouse_location) {
- last_mouse_location_ = last_mouse_location;
- }
- void Env::SetGestureRecognizer(
- std::unique_ptr<ui::GestureRecognizer> gesture_recognizer) {
- gesture_recognizer_ = std::move(gesture_recognizer);
- }
- gfx::Point Env::GetLastPointerPoint(ui::mojom::DragEventSource event_source,
- Window* window,
- absl::optional<gfx::Point> fallback) {
- if (event_source == ui::mojom::DragEventSource::kTouch && is_touch_down()) {
- DCHECK(window);
- DCHECK(window->GetRootWindow());
- gfx::PointF touch_point_f;
- bool got_touch_point = gesture_recognizer()->GetLastTouchPointForTarget(
- window, &touch_point_f);
- if (got_touch_point) {
- Window* root = window->GetRootWindow();
- DCHECK(root);
- DCHECK(root->GetRootWindow());
- DCHECK(aura::client::GetScreenPositionClient(root->GetRootWindow()));
- client::GetScreenPositionClient(root->GetRootWindow())
- ->ConvertPointToScreen(root, &touch_point_f);
- return gfx::ToFlooredPoint(touch_point_f);
- }
- // Fallback when touch state is lost. See http://crbug.com/1162541.
- if (fallback)
- return *fallback;
- }
- // TODO(https://crbug.com/1338746): Use last_mouse_location_.
- return display::Screen::GetScreen()->GetCursorScreenPoint();
- }
- WindowOcclusionTracker* Env::GetWindowOcclusionTracker() {
- if (!window_occlusion_tracker_) {
- // Use base::WrapUnique + new because of the constructor is private.
- window_occlusion_tracker_ = base::WrapUnique(new WindowOcclusionTracker());
- }
- return window_occlusion_tracker_.get();
- }
- void Env::PauseWindowOcclusionTracking() {
- GetWindowOcclusionTracker()->Pause();
- }
- void Env::UnpauseWindowOcclusionTracking() {
- GetWindowOcclusionTracker()->Unpause();
- }
- void Env::AddEventObserver(ui::EventObserver* observer,
- ui::EventTarget* target,
- const std::set<ui::EventType>& types) {
- DCHECK(!types.empty()) << "Observers must observe at least one event type";
- auto adapter(std::make_unique<EventObserverAdapter>(observer, target, types));
- event_observer_adapter_list_.AddObserver(adapter.get());
- event_observer_adapters_.insert(std::move(adapter));
- }
- void Env::RemoveEventObserver(ui::EventObserver* observer) {
- for (auto& adapter : event_observer_adapters_) {
- if (adapter->observer() == observer) {
- event_observer_adapter_list_.RemoveObserver(adapter.get());
- event_observer_adapters_.erase(adapter);
- return;
- }
- }
- }
- void Env::NotifyEventObservers(const ui::Event& event) {
- for (auto& adapter : event_observer_adapter_list_) {
- if (adapter.types().count(event.type()) > 0 &&
- (adapter.target() == event.target() || adapter.target() == this)) {
- adapter.observer()->OnEvent(event);
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Env, private:
- // static
- bool Env::initial_throttle_input_on_resize_ = true;
- Env::Env()
- : env_controller_(std::make_unique<EnvInputStateController>(this)),
- gesture_recognizer_(std::make_unique<ui::GestureRecognizerImpl>()),
- input_state_lookup_(InputStateLookup::Create()) {
- #if BUILDFLAG(IS_WIN)
- cursor_factory_ = std::make_unique<ui::WinCursorFactory>();
- #endif
- }
- bool Env::Init() {
- #if defined(USE_OZONE)
- // The ozone platform can provide its own event source. So initialize the
- // platform before creating the default event source
- ui::OzonePlatform::InitParams params;
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- // TODO(kylechar): Pass in single process information to
- // Env::CreateInstance() instead of checking flags here.
- params.single_process = command_line->HasSwitch("single-process") ||
- command_line->HasSwitch("in-process-gpu");
- if (!ui::OzonePlatform::InitializeForUI(params)) {
- LOG(ERROR) << "The platform failed to initialize. Exiting.";
- return false;
- }
- #endif
- if (!ui::PlatformEventSource::GetInstance())
- event_source_ = ui::PlatformEventSource::CreateDefault();
- return true;
- }
- void Env::NotifyWindowInitialized(Window* window) {
- for (EnvObserver& observer : observers_)
- observer.OnWindowInitialized(window);
- }
- void Env::NotifyHostInitialized(WindowTreeHost* host) {
- window_tree_hosts_.push_back(host);
- for (EnvObserver& observer : observers_)
- observer.OnHostInitialized(host);
- }
- void Env::NotifyHostDestroyed(WindowTreeHost* host) {
- base::Erase(window_tree_hosts_, host);
- for (EnvObserver& observer : observers_)
- observer.OnHostDestroyed(host);
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Env, ui::EventTarget implementation:
- bool Env::CanAcceptEvent(const ui::Event& event) {
- return true;
- }
- ui::EventTarget* Env::GetParentTarget() {
- return nullptr;
- }
- std::unique_ptr<ui::EventTargetIterator> Env::GetChildIterator() const {
- return nullptr;
- }
- ui::EventTargeter* Env::GetEventTargeter() {
- NOTREACHED();
- return nullptr;
- }
- } // namespace aura
|