1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ui/views/widget/unique_widget_ptr.h"
6 
7 #include <utility>
8 
9 #include "base/scoped_observer.h"
10 #include "ui/views/view.h"
11 #include "ui/views/widget/widget.h"
12 #include "ui/views/widget/widget_observer.h"
13 
14 namespace views {
15 
16 namespace {
17 
18 struct WidgetAutoCloser {
operator ()views::__anon0c9e62850111::WidgetAutoCloser19   void operator()(Widget* widget) {
20     widget->CloseWithReason(Widget::ClosedReason::kUnspecified);
21   }
22 };
23 
24 using WidgetAutoClosePtr = std::unique_ptr<Widget, WidgetAutoCloser>;
25 
26 }  // namespace
27 
28 class UniqueWidgetPtr::UniqueWidgetPtrImpl : public WidgetObserver {
29  public:
30   UniqueWidgetPtrImpl() = default;
31   // This class acts like unique_ptr<Widget>, so this constructor is
32   // deliberately implicit.
UniqueWidgetPtrImpl(std::unique_ptr<Widget> widget)33   UniqueWidgetPtrImpl(std::unique_ptr<Widget> widget)  // NOLINT
34       : widget_closer_(widget.release()) {
35     widget_observer_.Add(widget_closer_.get());
36   }
37 
38   UniqueWidgetPtrImpl(const UniqueWidgetPtrImpl&) = delete;
39 
40   UniqueWidgetPtrImpl& operator=(const UniqueWidgetPtrImpl&) = delete;
41 
42   ~UniqueWidgetPtrImpl() override = default;
43 
Get() const44   Widget* Get() const { return widget_closer_.get(); }
45 
Reset()46   void Reset() {
47     if (!widget_closer_)
48       return;
49     widget_observer_.RemoveAll();
50     widget_closer_.reset();
51   }
52 
53   // WidgetObserver overrides.
OnWidgetDestroying(Widget * widget)54   void OnWidgetDestroying(Widget* widget) override {
55     DCHECK_EQ(widget, widget_closer_.get());
56     widget_observer_.RemoveAll();
57     widget_closer_.release();
58   }
59 
60  private:
61   ScopedObserver<Widget, WidgetObserver> widget_observer_{this};
62   WidgetAutoClosePtr widget_closer_;
63 };
64 
65 UniqueWidgetPtr::UniqueWidgetPtr() = default;
66 
UniqueWidgetPtr(std::unique_ptr<Widget> widget)67 UniqueWidgetPtr::UniqueWidgetPtr(std::unique_ptr<Widget> widget)
68     : unique_widget_ptr_impl_(
69           std::make_unique<UniqueWidgetPtrImpl>(std::move(widget))) {}
70 
71 UniqueWidgetPtr::UniqueWidgetPtr(UniqueWidgetPtr&& other) = default;
72 
73 UniqueWidgetPtr& UniqueWidgetPtr::operator=(UniqueWidgetPtr&& other) = default;
74 
75 UniqueWidgetPtr::~UniqueWidgetPtr() = default;
76 
operator bool() const77 UniqueWidgetPtr::operator bool() const {
78   return !!get();
79 }
80 
operator *() const81 Widget& UniqueWidgetPtr::operator*() const {
82   return *get();
83 }
84 
operator ->() const85 Widget* UniqueWidgetPtr::operator->() const {
86   return get();
87 }
88 
reset()89 void UniqueWidgetPtr::reset() {
90   unique_widget_ptr_impl_.reset();
91 }
92 
get() const93 Widget* UniqueWidgetPtr::get() const {
94   return unique_widget_ptr_impl_ ? unique_widget_ptr_impl_->Get() : nullptr;
95 }
96 
97 }  // namespace views
98