// Copyright 2016 The Chromium Embedded Framework Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be found // in the LICENSE file. #include "libcef/browser/views/layout_util.h" #include #include "libcef/browser/views/layout_adapter.h" #include "ui/views/view.h" namespace layout_util { namespace { // Manages the association between views::View and CefLayout instances. class UserData : public base::SupportsUserData::Data { public: static CefRefPtr GetFor(const views::View* view) { UserData* data = static_cast(view->GetUserData(UserDataKey())); if (data) { return data->layout_; } return nullptr; } // Assign ownership of the underlying views::LayoutManager to |owner_view|. // The views::View that owns the views::LayoutManager will gain a ref-counted // reference to the CefLayout and the CefLayout will keep an unowned reference // to the views::LayoutManager. Destruction of the views::View will release // the reference to the CefLayout. static void Assign(CefRefPtr cef_layout, views::View* owner_view) { DCHECK(owner_view); DCHECK(cef_layout->IsValid()); views::LayoutManager* layout = CefLayoutAdapter::GetFor(cef_layout)->Get(); DCHECK(layout); // The CefLayout previously associated with |owner_view|, if any, will be // destroyed by this call. owner_view->SetUserData(UserDataKey(), base::WrapUnique(new UserData(cef_layout))); } private: friend std::default_delete; explicit UserData(CefRefPtr cef_layout) : layout_(cef_layout) { DCHECK(layout_); } ~UserData() override { CefLayoutAdapter::GetFor(layout_)->Detach(); } static void* UserDataKey() { // We just need a unique constant. Use the address of a static that // COMDAT folding won't touch in an optimizing linker. static int data_key = 0; return reinterpret_cast(&data_key); } CefRefPtr layout_; }; } // namespace CefRefPtr GetFor(const views::View* view) { return UserData::GetFor(view); } void Assign(CefRefPtr layout, views::View* owner_view) { return UserData::Assign(layout, owner_view); } } // namespace layout_util