#include "ui/views/test/widget_activation_waiter.h"
#include "base/run_loop.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h"
#if BUILDFLAG(IS_MAC)
#include "base/strings/string_number_conversions.h"
#include "base/test/bind.h"
#include "base/test/scoped_run_loop_timeout.h"
#include "base/test/test_timeouts.h"
#endif
namespace views::test {
namespace {
class WidgetActivationWaiter : public WidgetObserver {
public:
WidgetActivationWaiter(Widget* widget, bool active)
: active_(active), widget_(*widget) {
if (active == widget->native_widget_active()) {
observed_ = true;
return;
}
widget_observation_.Observe(widget);
}
WidgetActivationWaiter(const WidgetActivationWaiter&) = delete;
WidgetActivationWaiter& operator=(const WidgetActivationWaiter&) = delete;
~WidgetActivationWaiter() override = default;
void Wait() {
if (!observed_) {
#if BUILDFLAG(IS_MAC)
const base::test::ScopedRunLoopTimeout increased_run_timeout(
FROM_HERE, TestTimeouts::action_max_timeout(),
base::BindLambdaForTesting([&]() {
return "Requested activation state: " +
base::NumberToString(active_) + ", actual: " +
base::NumberToString(widget_->native_widget_active());
}));
#endif
run_loop_.Run();
}
}
private:
void OnWidgetActivationChanged(Widget* widget, bool active) override {
if (active_ != active) {
return;
}
observed_ = true;
widget_observation_.Reset();
if (run_loop_.running()) {
run_loop_.Quit();
}
}
bool observed_ = false;
bool active_;
const raw_ref<Widget> widget_;
base::RunLoop run_loop_{base::RunLoop::Type::kNestableTasksAllowed};
base::ScopedObservation<Widget, WidgetObserver> widget_observation_{this};
};
}
void WaitForWidgetActive(Widget* widget, bool active) {
WidgetActivationWaiter waiter(widget, active);
waiter.Wait();
}
}