1 // Copyright 2014 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.
5 #include "apps/ui/views/native_app_window_views.h"
7 #include "apps/app_window.h"
8 #include "base/threading/sequenced_worker_pool.h"
9 #include "content/public/browser/render_view_host.h"
10 #include "content/public/browser/render_widget_host_view.h"
11 #include "content/public/browser/web_contents.h"
12 #include "extensions/common/draggable_region.h"
13 #include "third_party/skia/include/core/SkRegion.h"
14 #include "ui/gfx/path.h"
15 #include "ui/views/controls/webview/webview.h"
16 #include "ui/views/widget/widget.h"
17 #include "ui/views/window/non_client_view.h"
20 #include "ui/aura/window.h"
25 NativeAppWindowViews::NativeAppWindowViews()
30 transparent_background_(false),
33 void NativeAppWindowViews::Init(AppWindow
* app_window
,
34 const AppWindow::CreateParams
& create_params
) {
35 app_window_
= app_window
;
36 frameless_
= create_params
.frame
== AppWindow::FRAME_NONE
;
37 transparent_background_
= create_params
.transparent_background
;
38 resizable_
= create_params
.resizable
;
39 size_constraints_
.set_minimum_size(
40 create_params
.GetContentMinimumSize(gfx::Insets()));
41 size_constraints_
.set_maximum_size(
42 create_params
.GetContentMaximumSize(gfx::Insets()));
43 Observe(app_window_
->web_contents());
45 widget_
= new views::Widget
;
46 InitializeWindow(app_window
, create_params
);
49 widget_
->AddObserver(this);
52 NativeAppWindowViews::~NativeAppWindowViews() {
53 web_view_
->SetWebContents(NULL
);
56 void NativeAppWindowViews::InitializeWindow(
57 AppWindow
* app_window
,
58 const AppWindow::CreateParams
& create_params
) {
59 // Stub implementation. See also ChromeNativeAppWindowViews.
60 views::Widget::InitParams
init_params(views::Widget::InitParams::TYPE_WINDOW
);
61 init_params
.delegate
= this;
62 init_params
.keep_on_top
= create_params
.always_on_top
;
63 widget_
->Init(init_params
);
64 widget_
->CenterWindow(
65 create_params
.GetInitialWindowBounds(gfx::Insets()).size());
68 // ui::BaseWindow implementation.
70 bool NativeAppWindowViews::IsActive() const { return widget_
->IsActive(); }
72 bool NativeAppWindowViews::IsMaximized() const {
73 return widget_
->IsMaximized();
76 bool NativeAppWindowViews::IsMinimized() const {
77 return widget_
->IsMinimized();
80 bool NativeAppWindowViews::IsFullscreen() const {
81 return widget_
->IsFullscreen();
84 gfx::NativeWindow
NativeAppWindowViews::GetNativeWindow() {
85 return widget_
->GetNativeWindow();
88 gfx::Rect
NativeAppWindowViews::GetRestoredBounds() const {
89 return widget_
->GetRestoredBounds();
92 ui::WindowShowState
NativeAppWindowViews::GetRestoredState() const {
93 // Stub implementation. See also ChromeNativeAppWindowViews.
95 return ui::SHOW_STATE_MAXIMIZED
;
97 return ui::SHOW_STATE_FULLSCREEN
;
98 return ui::SHOW_STATE_NORMAL
;
101 gfx::Rect
NativeAppWindowViews::GetBounds() const {
102 return widget_
->GetWindowBoundsInScreen();
105 void NativeAppWindowViews::Show() {
106 if (widget_
->IsVisible()) {
113 void NativeAppWindowViews::ShowInactive() {
114 if (widget_
->IsVisible())
117 widget_
->ShowInactive();
120 void NativeAppWindowViews::Hide() { widget_
->Hide(); }
122 void NativeAppWindowViews::Close() { widget_
->Close(); }
124 void NativeAppWindowViews::Activate() { widget_
->Activate(); }
126 void NativeAppWindowViews::Deactivate() { widget_
->Deactivate(); }
128 void NativeAppWindowViews::Maximize() { widget_
->Maximize(); }
130 void NativeAppWindowViews::Minimize() { widget_
->Minimize(); }
132 void NativeAppWindowViews::Restore() { widget_
->Restore(); }
134 void NativeAppWindowViews::SetBounds(const gfx::Rect
& bounds
) {
135 widget_
->SetBounds(bounds
);
138 void NativeAppWindowViews::FlashFrame(bool flash
) {
139 widget_
->FlashFrame(flash
);
142 bool NativeAppWindowViews::IsAlwaysOnTop() const {
143 // Stub implementation. See also ChromeNativeAppWindowViews.
144 return widget_
->IsAlwaysOnTop();
147 void NativeAppWindowViews::SetAlwaysOnTop(bool always_on_top
) {
148 widget_
->SetAlwaysOnTop(always_on_top
);
151 gfx::NativeView
NativeAppWindowViews::GetHostView() const {
152 return widget_
->GetNativeView();
155 gfx::Point
NativeAppWindowViews::GetDialogPosition(const gfx::Size
& size
) {
156 gfx::Size app_window_size
= widget_
->GetWindowBoundsInScreen().size();
157 return gfx::Point(app_window_size
.width() / 2 - size
.width() / 2,
158 app_window_size
.height() / 2 - size
.height() / 2);
161 gfx::Size
NativeAppWindowViews::GetMaximumDialogSize() {
162 return widget_
->GetWindowBoundsInScreen().size();
165 void NativeAppWindowViews::AddObserver(
166 web_modal::ModalDialogHostObserver
* observer
) {
167 observer_list_
.AddObserver(observer
);
169 void NativeAppWindowViews::RemoveObserver(
170 web_modal::ModalDialogHostObserver
* observer
) {
171 observer_list_
.RemoveObserver(observer
);
174 void NativeAppWindowViews::OnViewWasResized() {
175 FOR_EACH_OBSERVER(web_modal::ModalDialogHostObserver
,
177 OnPositionRequiresUpdate());
180 // WidgetDelegate implementation.
182 void NativeAppWindowViews::OnWidgetMove() {
183 app_window_
->OnNativeWindowChanged();
186 views::View
* NativeAppWindowViews::GetInitiallyFocusedView() {
190 bool NativeAppWindowViews::CanResize() const {
191 return resizable_
&& !size_constraints_
.HasFixedSize();
194 bool NativeAppWindowViews::CanMaximize() const {
195 return resizable_
&& !size_constraints_
.HasMaximumSize() &&
196 !app_window_
->window_type_is_panel();
199 base::string16
NativeAppWindowViews::GetWindowTitle() const {
200 return app_window_
->GetTitle();
203 bool NativeAppWindowViews::ShouldShowWindowTitle() const {
204 return app_window_
->window_type() == AppWindow::WINDOW_TYPE_V1_PANEL
;
207 bool NativeAppWindowViews::ShouldShowWindowIcon() const {
208 return app_window_
->window_type() == AppWindow::WINDOW_TYPE_V1_PANEL
;
211 void NativeAppWindowViews::SaveWindowPlacement(const gfx::Rect
& bounds
,
212 ui::WindowShowState show_state
) {
213 views::WidgetDelegate::SaveWindowPlacement(bounds
, show_state
);
214 app_window_
->OnNativeWindowChanged();
217 void NativeAppWindowViews::DeleteDelegate() {
218 widget_
->RemoveObserver(this);
219 app_window_
->OnNativeClose();
222 views::Widget
* NativeAppWindowViews::GetWidget() { return widget_
; }
224 const views::Widget
* NativeAppWindowViews::GetWidget() const { return widget_
; }
226 views::View
* NativeAppWindowViews::GetContentsView() {
230 bool NativeAppWindowViews::ShouldDescendIntoChildForEventHandling(
231 gfx::NativeView child
,
232 const gfx::Point
& location
) {
233 #if defined(USE_AURA)
234 if (child
->Contains(web_view_
->web_contents()->GetNativeView())) {
235 // App window should claim mouse events that fall within the draggable
237 return !draggable_region_
.get() ||
238 !draggable_region_
->contains(location
.x(), location
.y());
245 // WidgetObserver implementation.
247 void NativeAppWindowViews::OnWidgetVisibilityChanged(views::Widget
* widget
,
249 app_window_
->OnNativeWindowChanged();
252 void NativeAppWindowViews::OnWidgetActivationChanged(views::Widget
* widget
,
254 app_window_
->OnNativeWindowChanged();
256 app_window_
->OnNativeWindowActivated();
259 // WebContentsObserver implementation.
261 void NativeAppWindowViews::RenderViewCreated(
262 content::RenderViewHost
* render_view_host
) {
263 if (transparent_background_
) {
264 content::RenderWidgetHostView
* view
= render_view_host
->GetView();
266 view
->SetBackgroundOpaque(false);
270 void NativeAppWindowViews::RenderViewHostChanged(
271 content::RenderViewHost
* old_host
,
272 content::RenderViewHost
* new_host
) {
276 // views::View implementation.
278 void NativeAppWindowViews::Layout() {
280 web_view_
->SetBounds(0, 0, width(), height());
284 void NativeAppWindowViews::ViewHierarchyChanged(
285 const ViewHierarchyChangedDetails
& details
) {
286 if (details
.is_add
&& details
.child
== this) {
287 web_view_
= new views::WebView(NULL
);
288 AddChildView(web_view_
);
289 web_view_
->SetWebContents(app_window_
->web_contents());
293 gfx::Size
NativeAppWindowViews::GetMinimumSize() const {
294 return size_constraints_
.GetMinimumSize();
297 gfx::Size
NativeAppWindowViews::GetMaximumSize() const {
298 return size_constraints_
.GetMaximumSize();
301 void NativeAppWindowViews::OnFocus() {
302 web_view_
->RequestFocus();
305 // NativeAppWindow implementation.
307 void NativeAppWindowViews::SetFullscreen(int fullscreen_types
) {
308 // Stub implementation. See also ChromeNativeAppWindowViews.
309 widget_
->SetFullscreen(fullscreen_types
!= AppWindow::FULLSCREEN_TYPE_NONE
);
312 bool NativeAppWindowViews::IsFullscreenOrPending() const {
313 // Stub implementation. See also ChromeNativeAppWindowViews.
314 return widget_
->IsFullscreen();
317 bool NativeAppWindowViews::IsDetached() const {
318 // Stub implementation. See also ChromeNativeAppWindowViews.
322 void NativeAppWindowViews::UpdateWindowIcon() { widget_
->UpdateWindowIcon(); }
324 void NativeAppWindowViews::UpdateWindowTitle() { widget_
->UpdateWindowTitle(); }
326 void NativeAppWindowViews::UpdateBadgeIcon() {
327 // Stub implementation. See also ChromeNativeAppWindowViews.
330 void NativeAppWindowViews::UpdateDraggableRegions(
331 const std::vector
<extensions::DraggableRegion
>& regions
) {
332 // Draggable region is not supported for non-frameless window.
336 draggable_region_
.reset(AppWindow::RawDraggableRegionsToSkRegion(regions
));
340 SkRegion
* NativeAppWindowViews::GetDraggableRegion() {
341 return draggable_region_
.get();
344 void NativeAppWindowViews::UpdateShape(scoped_ptr
<SkRegion
> region
) {
345 // Stub implementation. See also ChromeNativeAppWindowViews.
348 void NativeAppWindowViews::HandleKeyboardEvent(
349 const content::NativeWebKeyboardEvent
& event
) {
350 unhandled_keyboard_event_handler_
.HandleKeyboardEvent(event
,
354 bool NativeAppWindowViews::IsFrameless() const { return frameless_
; }
356 bool NativeAppWindowViews::HasFrameColor() const { return false; }
358 SkColor
NativeAppWindowViews::ActiveFrameColor() const {
359 return SK_ColorBLACK
;
362 SkColor
NativeAppWindowViews::InactiveFrameColor() const {
363 return SK_ColorBLACK
;
366 gfx::Insets
NativeAppWindowViews::GetFrameInsets() const {
368 return gfx::Insets();
370 // The pretend client_bounds passed in need to be large enough to ensure that
371 // GetWindowBoundsForClientBounds() doesn't decide that it needs more than
372 // the specified amount of space to fit the window controls in, and return a
373 // number larger than the real frame insets. Most window controls are smaller
374 // than 1000x1000px, so this should be big enough.
375 gfx::Rect client_bounds
= gfx::Rect(1000, 1000);
376 gfx::Rect window_bounds
=
377 widget_
->non_client_view()->GetWindowBoundsForClientBounds(client_bounds
);
378 return window_bounds
.InsetsFrom(client_bounds
);
381 void NativeAppWindowViews::HideWithApp() {}
383 void NativeAppWindowViews::ShowWithApp() {}
385 void NativeAppWindowViews::UpdateShelfMenu() {}
387 gfx::Size
NativeAppWindowViews::GetContentMinimumSize() const {
388 return size_constraints_
.GetMinimumSize();
391 gfx::Size
NativeAppWindowViews::GetContentMaximumSize() const {
392 return size_constraints_
.GetMaximumSize();
395 void NativeAppWindowViews::SetContentSizeConstraints(
396 const gfx::Size
& min_size
, const gfx::Size
& max_size
) {
397 size_constraints_
.set_minimum_size(min_size
);
398 size_constraints_
.set_maximum_size(max_size
);