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)67UniqueWidgetPtr::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() const77UniqueWidgetPtr::operator bool() const { 78 return !!get(); 79 } 80 operator *() const81Widget& UniqueWidgetPtr::operator*() const { 82 return *get(); 83 } 84 operator ->() const85Widget* UniqueWidgetPtr::operator->() const { 86 return get(); 87 } 88 reset()89void UniqueWidgetPtr::reset() { 90 unique_widget_ptr_impl_.reset(); 91 } 92 get() const93Widget* UniqueWidgetPtr::get() const { 94 return unique_widget_ptr_impl_ ? unique_widget_ptr_impl_->Get() : nullptr; 95 } 96 97 } // namespace views 98