blob: d1607a021602ded40b5d0f742ea728098e683601 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/views/windows_stationarity_monitor_aura.h"
#include <vector>
#include "base/no_destructor.h"
#include "base/ranges/algorithm.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/views/buildflags.h"
#if BUILDFLAG(ENABLE_DESKTOP_AURA)
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
#endif // BUILDFLAG(ENABLE_DESKTOP_AURA)
namespace views {
WindowsStationarityMonitorAura::WindowsStationarityMonitorAura() {
aura::Env::GetInstance()->AddObserver(this);
for (aura::WindowTreeHost* window_tree_host :
aura::Env::GetInstance()->window_tree_hosts()) {
OnHostInitialized(window_tree_host);
}
}
WindowsStationarityMonitorAura::~WindowsStationarityMonitorAura() {
for (aura::Window* window : tracked_windows_) {
window->RemoveObserver(this);
}
aura::Env::GetInstance()->RemoveObserver(this);
tracked_windows_.clear();
}
// static
WindowsStationarityMonitorAura* WindowsStationarityMonitorAura::GetInstance() {
static base::NoDestructor<WindowsStationarityMonitorAura> instance;
return instance.get();
}
void WindowsStationarityMonitorAura::OnHostInitialized(
aura::WindowTreeHost* host) {
auto* window = host->window();
CHECK(window);
#if BUILDFLAG(ENABLE_DESKTOP_AURA)
auto* native_widget = DesktopNativeWidgetAura::ForWindow(window);
// Non client widget, such as tooltip widget, might be destroyed right before
// handling mouse events on other windows, which results in those events being
// ignored.
if (!native_widget ||
!Widget::RequiresNonClientView(native_widget->widget_type())) {
return;
}
#endif
tracked_windows_.push_back(window);
window->AddObserver(this);
}
void WindowsStationarityMonitorAura::OnWindowDestroying(aura::Window* window) {
std::erase(tracked_windows_, window);
NotifyWindowStationaryStateChanged();
}
void WindowsStationarityMonitorAura::OnWindowBoundsChanged(
aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
ui::PropertyChangeReason reason) {
// We will consider from-animation reason the same as not-from-animation
// reason. The main consumer |InputEventActivationProtector| will block input
// event even when the window bounds change due to animation.
NotifyWindowStationaryStateChanged();
}
// static
WindowsStationarityMonitor* WindowsStationarityMonitor::GetInstance() {
return WindowsStationarityMonitorAura::GetInstance();
}
} // namespace views