blob: 7e619673e2d9b3f2488a2cec5a1295fb1fefe6fc [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_VIEWS_WIDGET_UNIQUE_WIDGET_PTR_H_
#define UI_VIEWS_WIDGET_UNIQUE_WIDGET_PTR_H_
#include <memory>
#include "base/scoped_observation.h"
#include "ui/views/views_export.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h"
namespace views {
// A weak owning pointer to a Widget.
// This smart pointer acts like a unique_ptr: it ensures the Widget is
// properly closed when it goes out of scope.
// It also acts like a WeakPtr: the Widget may be deleted by its native
// widget and `get()` becomes nullptr when this happens.
// Caller may check the validity of this pointer before dereferencing it if
// the widget lifetime is in doubt.
class VIEWS_EXPORT UniqueWidgetPtr {
public:
UniqueWidgetPtr();
// This class acts like a std::unique_ptr<Widget>, so this constructor is
// deliberately implicit.
UniqueWidgetPtr(std::unique_ptr<Widget> widget); // NOLINT
// Construct from a subclass instance of Widget. Note that ~Widget() is
// virtual, so the downcasting is safe. This constructor is deliberately
// implicit.
template <class U>
UniqueWidgetPtr(std::unique_ptr<U> widget) { // NOLINT
Init(std::unique_ptr<Widget>(widget.release()));
}
UniqueWidgetPtr(UniqueWidgetPtr&&);
UniqueWidgetPtr& operator=(UniqueWidgetPtr&&);
~UniqueWidgetPtr();
explicit operator bool() const;
Widget& operator*() const;
Widget* operator->() const;
void reset();
Widget* get() const;
private:
class Impl : public WidgetObserver {
public:
Impl();
explicit Impl(std::unique_ptr<Widget> widget);
Impl(const Impl&) = delete;
Impl& operator=(const Impl&) = delete;
~Impl() override;
Widget* Get() const;
// WidgetObserver overrides.
void OnWidgetDestroying(Widget* widget) override;
private:
struct WidgetAutoCloser {
void operator()(Widget* widget);
};
bool received_widget_destruction_signal_ = false;
base::ScopedObservation<Widget, WidgetObserver> widget_observation_{this};
std::unique_ptr<Widget, WidgetAutoCloser> widget_closer_;
};
void Init(std::unique_ptr<Widget> widget);
std::unique_ptr<Impl> unique_widget_ptr_impl_;
};
} // namespace views
#endif // UI_VIEWS_WIDGET_UNIQUE_WIDGET_PTR_H_