1 // Copyright 2014 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/native/window_delegate_view.h"
6
7 #include <utility>
8
9 #include "content/public/browser/web_contents.h"
10 #include "ui/views/background.h"
11 #include "ui/views/controls/webview/webview.h"
12 #include "ui/views/layout/fill_layout.h"
13 #include "ui/views/widget/widget.h"
14
CefWindowDelegateView(SkColor background_color,bool always_on_top,base::RepeatingClosure on_bounds_changed)15 CefWindowDelegateView::CefWindowDelegateView(
16 SkColor background_color,
17 bool always_on_top,
18 base::RepeatingClosure on_bounds_changed)
19 : background_color_(background_color),
20 web_view_(nullptr),
21 always_on_top_(always_on_top),
22 on_bounds_changed_(on_bounds_changed) {}
23
Init(gfx::AcceleratedWidget parent_widget,content::WebContents * web_contents,const gfx::Rect & bounds)24 void CefWindowDelegateView::Init(gfx::AcceleratedWidget parent_widget,
25 content::WebContents* web_contents,
26 const gfx::Rect& bounds) {
27 DCHECK(!web_view_);
28 web_view_ = new views::WebView(web_contents->GetBrowserContext());
29 web_view_->SetWebContents(web_contents);
30 web_view_->SetPreferredSize(bounds.size());
31
32 SetCanResize(true);
33
34 views::Widget* widget = new views::Widget;
35
36 // See CalculateWindowStylesFromInitParams in
37 // ui/views/widget/widget_hwnd_utils.cc for the conversion of |params| to
38 // Windows style flags.
39 views::Widget::InitParams params;
40 params.parent_widget = parent_widget;
41 params.bounds = bounds;
42 params.delegate = this;
43 // Set the WS_CHILD flag.
44 params.child = true;
45 // Set the WS_VISIBLE flag.
46 params.type = views::Widget::InitParams::TYPE_CONTROL;
47 // Don't set the WS_EX_COMPOSITED flag.
48 params.opacity = views::Widget::InitParams::WindowOpacity::kOpaque;
49 // Tell Aura not to draw the window frame on resize.
50 params.remove_standard_frame = true;
51 // Cause WidgetDelegate::CanActivate to return true. See comments in
52 // AlloyBrowserHostImpl::PlatformSetFocus.
53 params.activatable = views::Widget::InitParams::Activatable::kYes;
54
55 params.z_order = always_on_top_ ? ui::ZOrderLevel::kFloatingWindow
56 : ui::ZOrderLevel::kNormal;
57
58 // Results in a call to InitContent().
59 widget->Init(std::move(params));
60
61 // |widget| should now be associated with |this|.
62 DCHECK_EQ(widget, GetWidget());
63 // |widget| must be top-level for focus handling to work correctly.
64 DCHECK(widget->is_top_level());
65 // |widget| must be activatable for focus handling to work correctly.
66 DCHECK(widget->widget_delegate()->CanActivate());
67 }
68
InitContent()69 void CefWindowDelegateView::InitContent() {
70 SetBackground(views::CreateSolidBackground(background_color_));
71 SetLayoutManager(std::make_unique<views::FillLayout>());
72 AddChildView(web_view_);
73 }
74
ViewHierarchyChanged(const views::ViewHierarchyChangedDetails & details)75 void CefWindowDelegateView::ViewHierarchyChanged(
76 const views::ViewHierarchyChangedDetails& details) {
77 if (details.is_add && details.child == this)
78 InitContent();
79 }
80
OnBoundsChanged(const gfx::Rect & previous_bounds)81 void CefWindowDelegateView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
82 views::WidgetDelegateView::OnBoundsChanged(previous_bounds);
83 if (!on_bounds_changed_.is_null())
84 on_bounds_changed_.Run();
85 }
86