1 // Copyright 2016 The Chromium Embedded Framework Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be found 3 // in the LICENSE file. 4 5 #include "libcef/browser/views/layout_util.h" 6 7 #include <utility> 8 9 #include "libcef/browser/views/layout_adapter.h" 10 11 #include "ui/views/view.h" 12 13 namespace layout_util { 14 15 namespace { 16 17 // Manages the association between views::View and CefLayout instances. 18 class UserData : public base::SupportsUserData::Data { 19 public: GetFor(const views::View * view)20 static CefRefPtr<CefLayout> GetFor(const views::View* view) { 21 UserData* data = static_cast<UserData*>(view->GetUserData(UserDataKey())); 22 if (data) 23 return data->layout_; 24 return nullptr; 25 } 26 27 // Assign ownership of the underlying views::LayoutManager to |owner_view|. 28 // The views::View that owns the views::LayoutManager will gain a ref-counted 29 // reference to the CefLayout and the CefLayout will keep an unowned reference 30 // to the views::LayoutManager. Destruction of the views::View will release 31 // the reference to the CefLayout. Assign(CefRefPtr<CefLayout> cef_layout,views::View * owner_view)32 static void Assign(CefRefPtr<CefLayout> cef_layout, views::View* owner_view) { 33 DCHECK(owner_view); 34 DCHECK(cef_layout->IsValid()); 35 36 views::LayoutManager* layout = CefLayoutAdapter::GetFor(cef_layout)->Get(); 37 DCHECK(layout); 38 39 // The CefLayout previously associated with |owner_view|, if any, will be 40 // destroyed by this call. 41 owner_view->SetUserData(UserDataKey(), 42 base::WrapUnique(new UserData(cef_layout))); 43 } 44 45 private: 46 friend std::default_delete<UserData>; 47 UserData(CefRefPtr<CefLayout> cef_layout)48 explicit UserData(CefRefPtr<CefLayout> cef_layout) : layout_(cef_layout) { 49 DCHECK(layout_); 50 } 51 ~UserData()52 ~UserData() override { CefLayoutAdapter::GetFor(layout_)->Detach(); } 53 UserDataKey()54 static void* UserDataKey() { 55 // We just need a unique constant. Use the address of a static that 56 // COMDAT folding won't touch in an optimizing linker. 57 static int data_key = 0; 58 return reinterpret_cast<void*>(&data_key); 59 } 60 61 CefRefPtr<CefLayout> layout_; 62 }; 63 64 } // namespace 65 GetFor(const views::View * view)66CefRefPtr<CefLayout> GetFor(const views::View* view) { 67 return UserData::GetFor(view); 68 } 69 Assign(CefRefPtr<CefLayout> layout,views::View * owner_view)70void Assign(CefRefPtr<CefLayout> layout, views::View* owner_view) { 71 return UserData::Assign(layout, owner_view); 72 } 73 74 } // namespace layout_util 75