Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: chrome/browser/ui/views/apps/chrome_native_app_window_views.cc

Issue 947343003: Split out Ash/Aura parts of ChromeNativeAppWindowViews. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/apps/chrome_native_app_window_views.h" 5 #include "chrome/browser/ui/views/apps/chrome_native_app_window_views.h"
6 6
7 #include "apps/ui/views/app_window_frame_view.h" 7 #include "apps/ui/views/app_window_frame_view.h"
8 #include "base/command_line.h"
9 #include "chrome/app/chrome_command_ids.h" 8 #include "chrome/app/chrome_command_ids.h"
10 #include "chrome/browser/app_mode/app_mode_utils.h" 9 #include "chrome/browser/app_mode/app_mode_utils.h"
11 #include "chrome/browser/favicon/favicon_tab_helper.h" 10 #include "chrome/browser/favicon/favicon_tab_helper.h"
12 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ui/host_desktop.h"
14 #include "chrome/browser/ui/views/apps/desktop_keyboard_capture.h" 12 #include "chrome/browser/ui/views/apps/desktop_keyboard_capture.h"
15 #include "chrome/browser/ui/views/apps/shaped_app_window_targeter.h"
16 #include "chrome/browser/ui/views/extensions/extension_keybinding_registry_views .h" 13 #include "chrome/browser/ui/views/extensions/extension_keybinding_registry_views .h"
17 #include "chrome/browser/ui/views/frame/taskbar_decorator.h" 14 #include "chrome/browser/ui/views/frame/taskbar_decorator.h"
18 #include "chrome/browser/web_applications/web_app.h"
19 #include "chrome/common/chrome_switches.h"
20 #include "components/ui/zoom/page_zoom.h" 15 #include "components/ui/zoom/page_zoom.h"
21 #include "components/ui/zoom/zoom_controller.h" 16 #include "components/ui/zoom/zoom_controller.h"
22 #include "extensions/common/extension.h"
23 #include "ui/aura/window.h"
24 #include "ui/base/hit_test.h"
25 #include "ui/base/models/simple_menu_model.h"
26 #include "ui/gfx/image/image_skia.h"
27 #include "ui/views/controls/menu/menu_runner.h"
28 #include "ui/views/controls/webview/webview.h" 17 #include "ui/views/controls/webview/webview.h"
29 #include "ui/views/widget/widget.h" 18 #include "ui/views/widget/widget.h"
30 #include "ui/wm/core/easy_resize_window_targeter.h"
31
32 #if defined(OS_LINUX)
33 #include "chrome/browser/shell_integration_linux.h"
34 #endif
35
36 #if defined(USE_ASH)
37 #include "ash/ash_constants.h"
38 #include "ash/ash_switches.h"
39 #include "ash/frame/custom_frame_view_ash.h"
40 #include "ash/screen_util.h"
41 #include "ash/shell.h"
42 #include "ash/wm/immersive_fullscreen_controller.h"
43 #include "ash/wm/panels/panel_frame_view.h"
44 #include "ash/wm/window_properties.h"
45 #include "ash/wm/window_state.h"
46 #include "ash/wm/window_state_delegate.h"
47 #include "ash/wm/window_state_observer.h"
48 #include "chrome/browser/ui/ash/ash_util.h"
49 #include "chrome/browser/ui/ash/multi_user/multi_user_context_menu.h"
50 #include "ui/aura/client/aura_constants.h"
51 #include "ui/aura/client/window_tree_client.h"
52 #include "ui/aura/window_observer.h"
53 #endif
54
55 #if defined(OS_CHROMEOS)
56 #include "ash/shell_window_ids.h"
57 #endif
58 19
59 using extensions::AppWindow; 20 using extensions::AppWindow;
60 21
61 namespace { 22 namespace {
62 23
63 const int kMinPanelWidth = 100; 24 const int kMinPanelWidth = 100;
64 const int kMinPanelHeight = 100; 25 const int kMinPanelHeight = 100;
65 const int kDefaultPanelWidth = 200; 26 const int kDefaultPanelWidth = 200;
66 const int kDefaultPanelHeight = 300; 27 const int kDefaultPanelHeight = 300;
67 28
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 if (chrome::IsRunningInForcedAppMode()) { 76 if (chrome::IsRunningInForcedAppMode()) {
116 AddAcceleratorsFromMapping( 77 AddAcceleratorsFromMapping(
117 kAppWindowKioskAppModeAcceleratorMap, 78 kAppWindowKioskAppModeAcceleratorMap,
118 arraysize(kAppWindowKioskAppModeAcceleratorMap), 79 arraysize(kAppWindowKioskAppModeAcceleratorMap),
119 &accelerators); 80 &accelerators);
120 } 81 }
121 } 82 }
122 return accelerators; 83 return accelerators;
123 } 84 }
124 85
125 #if defined(USE_ASH)
126 // This class handles a user's fullscreen request (Shift+F4/F4).
127 class NativeAppWindowStateDelegate : public ash::wm::WindowStateDelegate,
128 public ash::wm::WindowStateObserver,
129 public aura::WindowObserver {
130 public:
131 NativeAppWindowStateDelegate(AppWindow* app_window,
132 extensions::NativeAppWindow* native_app_window)
133 : app_window_(app_window),
134 window_state_(
135 ash::wm::GetWindowState(native_app_window->GetNativeWindow())) {
136 // Add a window state observer to exit fullscreen properly in case
137 // fullscreen is exited without going through AppWindow::Restore(). This
138 // is the case when exiting immersive fullscreen via the "Restore" window
139 // control.
140 // TODO(pkotwicz): This is a hack. Remove ASAP. http://crbug.com/319048
141 window_state_->AddObserver(this);
142 window_state_->window()->AddObserver(this);
143 }
144 ~NativeAppWindowStateDelegate() override {
145 if (window_state_) {
146 window_state_->RemoveObserver(this);
147 window_state_->window()->RemoveObserver(this);
148 }
149 }
150
151 private:
152 // Overridden from ash::wm::WindowStateDelegate.
153 bool ToggleFullscreen(ash::wm::WindowState* window_state) override {
154 // Windows which cannot be maximized should not be fullscreened.
155 DCHECK(window_state->IsFullscreen() || window_state->CanMaximize());
156 if (window_state->IsFullscreen())
157 app_window_->Restore();
158 else if (window_state->CanMaximize())
159 app_window_->OSFullscreen();
160 return true;
161 }
162
163 // Overridden from ash::wm::WindowStateObserver:
164 void OnPostWindowStateTypeChange(ash::wm::WindowState* window_state,
165 ash::wm::WindowStateType old_type) override {
166 // Since the window state might get set by a window manager, it is possible
167 // to come here before the application set its |BaseWindow|.
168 if (!window_state->IsFullscreen() && !window_state->IsMinimized() &&
169 app_window_->GetBaseWindow() &&
170 app_window_->GetBaseWindow()->IsFullscreenOrPending()) {
171 app_window_->Restore();
172 // Usually OnNativeWindowChanged() is called when the window bounds are
173 // changed as a result of a state type change. Because the change in state
174 // type has already occurred, we need to call OnNativeWindowChanged()
175 // explicitly.
176 app_window_->OnNativeWindowChanged();
177 }
178 }
179
180 // Overridden from aura::WindowObserver:
181 void OnWindowDestroying(aura::Window* window) override {
182 window_state_->RemoveObserver(this);
183 window_state_->window()->RemoveObserver(this);
184 window_state_ = NULL;
185 }
186
187 // Not owned.
188 AppWindow* app_window_;
189 ash::wm::WindowState* window_state_;
190
191 DISALLOW_COPY_AND_ASSIGN(NativeAppWindowStateDelegate);
192 };
193 #endif // USE_ASH
194
195 } // namespace 86 } // namespace
196 87
197 ChromeNativeAppWindowViews::ChromeNativeAppWindowViews() 88 ChromeNativeAppWindowViews::ChromeNativeAppWindowViews()
198 : is_fullscreen_(false), 89 : is_fullscreen_(false),
199 has_frame_color_(false), 90 has_frame_color_(false),
200 active_frame_color_(SK_ColorBLACK), 91 active_frame_color_(SK_ColorBLACK),
201 inactive_frame_color_(SK_ColorBLACK) { 92 inactive_frame_color_(SK_ColorBLACK) {
202 } 93 }
203 94
204 ChromeNativeAppWindowViews::~ChromeNativeAppWindowViews() {} 95 ChromeNativeAppWindowViews::~ChromeNativeAppWindowViews() {}
205 96
206 void ChromeNativeAppWindowViews::OnBeforeWidgetInit( 97 void ChromeNativeAppWindowViews::OnBeforeWidgetInit(
98 const AppWindow::CreateParams& create_params,
207 views::Widget::InitParams* init_params, 99 views::Widget::InitParams* init_params,
208 views::Widget* widget) {} 100 views::Widget* widget) {
101 }
102
103 void ChromeNativeAppWindowViews::OnBeforePanelWidgetInit(
104 views::Widget::InitParams* init_params,
105 views::Widget* widget) {
106 }
209 107
210 void ChromeNativeAppWindowViews::InitializeDefaultWindow( 108 void ChromeNativeAppWindowViews::InitializeDefaultWindow(
211 const AppWindow::CreateParams& create_params) { 109 const AppWindow::CreateParams& create_params) {
212 std::string app_name = web_app::GenerateApplicationNameFromExtensionId(
213 app_window()->extension_id());
214
215 views::Widget::InitParams init_params(views::Widget::InitParams::TYPE_WINDOW); 110 views::Widget::InitParams init_params(views::Widget::InitParams::TYPE_WINDOW);
216 init_params.delegate = this; 111 init_params.delegate = this;
217 init_params.remove_standard_frame = IsFrameless() || has_frame_color_; 112 init_params.remove_standard_frame = IsFrameless() || has_frame_color_;
218 init_params.use_system_default_icon = true; 113 init_params.use_system_default_icon = true;
219 if (create_params.alpha_enabled) { 114 if (create_params.alpha_enabled) {
220 init_params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 115 init_params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
221 116
222 // The given window is most likely not rectangular since it uses 117 // The given window is most likely not rectangular since it uses
223 // transparency and has no standard frame, don't show a shadow for it. 118 // transparency and has no standard frame, don't show a shadow for it.
224 // TODO(skuhne): If we run into an application which should have a shadow 119 // TODO(skuhne): If we run into an application which should have a shadow
225 // but does not have, a new attribute has to be added. 120 // but does not have, a new attribute has to be added.
226 if (IsFrameless()) 121 if (IsFrameless())
227 init_params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE; 122 init_params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE;
228 } 123 }
229 init_params.keep_on_top = create_params.always_on_top; 124 init_params.keep_on_top = create_params.always_on_top;
230 init_params.visible_on_all_workspaces = 125 init_params.visible_on_all_workspaces =
231 create_params.visible_on_all_workspaces; 126 create_params.visible_on_all_workspaces;
232 127
233 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 128 OnBeforeWidgetInit(create_params, &init_params, widget());
234 // Set up a custom WM_CLASS for app windows. This allows task switchers in
235 // X11 environments to distinguish them from main browser windows.
236 init_params.wm_class_name = web_app::GetWMClassFromAppName(app_name);
237 init_params.wm_class_class = shell_integration_linux::GetProgramClassName();
238 const char kX11WindowRoleApp[] = "app";
239 init_params.wm_role_name = std::string(kX11WindowRoleApp);
240 #endif
241
242 OnBeforeWidgetInit(&init_params, widget());
243 #if defined(OS_CHROMEOS)
244 if (create_params.is_ime_window) {
245 // Puts ime windows into ime window container.
246 init_params.parent =
247 ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(),
248 ash::kShellWindowId_ImeWindowParentContainer);
249 }
250 #endif
251 widget()->Init(init_params); 129 widget()->Init(init_params);
252 130
253 // The frame insets are required to resolve the bounds specifications 131 // The frame insets are required to resolve the bounds specifications
254 // correctly. So we set the window bounds and constraints now. 132 // correctly. So we set the window bounds and constraints now.
255 gfx::Insets frame_insets = GetFrameInsets(); 133 gfx::Insets frame_insets = GetFrameInsets();
256 gfx::Rect window_bounds = create_params.GetInitialWindowBounds(frame_insets); 134 gfx::Rect window_bounds = create_params.GetInitialWindowBounds(frame_insets);
257 SetContentSizeConstraints(create_params.GetContentMinimumSize(frame_insets), 135 SetContentSizeConstraints(create_params.GetContentMinimumSize(frame_insets),
258 create_params.GetContentMaximumSize(frame_insets)); 136 create_params.GetContentMaximumSize(frame_insets));
259 if (!window_bounds.IsEmpty()) { 137 if (!window_bounds.IsEmpty()) {
260 typedef AppWindow::BoundsSpecification BoundsSpecification; 138 typedef AppWindow::BoundsSpecification BoundsSpecification;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 initial_window_bounds.height()); 194 initial_window_bounds.height());
317 if (preferred_size_.width() == 0) 195 if (preferred_size_.width() == 0)
318 preferred_size_.set_width(kDefaultPanelWidth); 196 preferred_size_.set_width(kDefaultPanelWidth);
319 else if (preferred_size_.width() < kMinPanelWidth) 197 else if (preferred_size_.width() < kMinPanelWidth)
320 preferred_size_.set_width(kMinPanelWidth); 198 preferred_size_.set_width(kMinPanelWidth);
321 199
322 if (preferred_size_.height() == 0) 200 if (preferred_size_.height() == 0)
323 preferred_size_.set_height(kDefaultPanelHeight); 201 preferred_size_.set_height(kDefaultPanelHeight);
324 else if (preferred_size_.height() < kMinPanelHeight) 202 else if (preferred_size_.height() < kMinPanelHeight)
325 preferred_size_.set_height(kMinPanelHeight); 203 preferred_size_.set_height(kMinPanelHeight);
326 #if defined(USE_ASH) 204
327 if (ash::Shell::HasInstance()) {
328 // Open a new panel on the target root.
329 aura::Window* target = ash::Shell::GetTargetRootWindow();
330 params.bounds = ash::ScreenUtil::ConvertRectToScreen(
331 target, gfx::Rect(preferred_size_));
332 } else {
333 params.bounds = gfx::Rect(preferred_size_);
334 }
335 #else
336 params.bounds = gfx::Rect(preferred_size_); 205 params.bounds = gfx::Rect(preferred_size_);
337 #endif 206 OnBeforePanelWidgetInit(&params, widget());
338 widget()->Init(params); 207 widget()->Init(params);
339 widget()->set_focus_on_creation(create_params.focused); 208 widget()->set_focus_on_creation(create_params.focused);
340 } 209 }
341 210
342 views::NonClientFrameView* 211 views::NonClientFrameView*
343 ChromeNativeAppWindowViews::CreateStandardDesktopAppFrame() { 212 ChromeNativeAppWindowViews::CreateStandardDesktopAppFrame() {
344 return views::WidgetDelegateView::CreateNonClientFrameView(widget()); 213 return views::WidgetDelegateView::CreateNonClientFrameView(widget());
345 } 214 }
346 215
216 apps::AppWindowFrameView*
217 ChromeNativeAppWindowViews::CreateNonStandardAppFrame() {
218 apps::AppWindowFrameView* frame =
219 new apps::AppWindowFrameView(widget(), this, has_frame_color_,
220 active_frame_color_, inactive_frame_color_);
221 frame->Init();
222 return frame;
223 }
224
347 // ui::BaseWindow implementation. 225 // ui::BaseWindow implementation.
348 226
349 gfx::Rect ChromeNativeAppWindowViews::GetRestoredBounds() const { 227 gfx::Rect ChromeNativeAppWindowViews::GetRestoredBounds() const {
350 #if defined(USE_ASH)
351 gfx::Rect* bounds = widget()->GetNativeWindow()->GetProperty(
352 ash::kRestoreBoundsOverrideKey);
353 if (bounds && !bounds->IsEmpty())
354 return *bounds;
355 #endif
356 return widget()->GetRestoredBounds(); 228 return widget()->GetRestoredBounds();
357 } 229 }
358 230
359 ui::WindowShowState ChromeNativeAppWindowViews::GetRestoredState() const { 231 ui::WindowShowState ChromeNativeAppWindowViews::GetRestoredState() const {
360 #if !defined(USE_ASH)
361 if (IsMaximized()) 232 if (IsMaximized())
362 return ui::SHOW_STATE_MAXIMIZED; 233 return ui::SHOW_STATE_MAXIMIZED;
363 if (IsFullscreen()) 234 if (IsFullscreen())
364 return ui::SHOW_STATE_FULLSCREEN; 235 return ui::SHOW_STATE_FULLSCREEN;
365 #else
366 // Use kRestoreShowStateKey in case a window is minimized/hidden.
367 ui::WindowShowState restore_state = widget()->GetNativeWindow()->GetProperty(
368 aura::client::kRestoreShowStateKey);
369 if (widget()->GetNativeWindow()->GetProperty(
370 ash::kRestoreBoundsOverrideKey)) {
371 // If an override is given, we use that restore state (after filtering).
372 restore_state = widget()->GetNativeWindow()->GetProperty(
373 ash::kRestoreShowStateOverrideKey);
374 } else {
375 // Otherwise first normal states are checked.
376 if (IsMaximized())
377 return ui::SHOW_STATE_MAXIMIZED;
378 if (IsFullscreen()) {
379 if (immersive_fullscreen_controller_.get() &&
380 immersive_fullscreen_controller_->IsEnabled()) {
381 // Restore windows which were previously in immersive fullscreen to
382 // maximized. Restoring the window to a different fullscreen type
383 // makes for a bad experience.
384 return ui::SHOW_STATE_MAXIMIZED;
385 }
386 return ui::SHOW_STATE_FULLSCREEN;
387 }
388 }
389 // Whitelist states to return so that invalid and transient states
390 // are not saved and used to restore windows when they are recreated.
391 switch (restore_state) {
392 case ui::SHOW_STATE_NORMAL:
393 case ui::SHOW_STATE_MAXIMIZED:
394 case ui::SHOW_STATE_FULLSCREEN:
395 return restore_state;
396 236
397 case ui::SHOW_STATE_DEFAULT:
398 case ui::SHOW_STATE_MINIMIZED:
399 case ui::SHOW_STATE_INACTIVE:
400 case ui::SHOW_STATE_END:
401 return ui::SHOW_STATE_NORMAL;
402 }
403 #endif // !defined(USE_ASH)
404 return ui::SHOW_STATE_NORMAL; 237 return ui::SHOW_STATE_NORMAL;
405 } 238 }
406 239
407 bool ChromeNativeAppWindowViews::IsAlwaysOnTop() const { 240 bool ChromeNativeAppWindowViews::IsAlwaysOnTop() const {
408 if (app_window()->window_type_is_panel()) { 241 // TODO(jackhou): On Mac, only docked panels are always-on-top.
409 #if defined(USE_ASH) 242 return app_window()->window_type_is_panel() || widget()->IsAlwaysOnTop();
410 return ash::wm::GetWindowState(widget()->GetNativeWindow())
411 ->panel_attached();
412 #else
413 return true;
414 #endif
415 } else {
416 return widget()->IsAlwaysOnTop();
417 }
418 }
419
420 // views::ContextMenuController implementation.
421
422 void ChromeNativeAppWindowViews::ShowContextMenuForView(
423 views::View* source,
424 const gfx::Point& p,
425 ui::MenuSourceType source_type) {
426 #if defined(USE_ASH) && defined(OS_CHROMEOS)
427 scoped_ptr<ui::MenuModel> model =
428 CreateMultiUserContextMenu(app_window()->GetNativeWindow());
429 if (!model.get())
430 return;
431
432 // Only show context menu if point is in caption.
433 gfx::Point point_in_view_coords(p);
434 views::View::ConvertPointFromScreen(widget()->non_client_view(),
435 &point_in_view_coords);
436 int hit_test =
437 widget()->non_client_view()->NonClientHitTest(point_in_view_coords);
438 if (hit_test == HTCAPTION) {
439 menu_runner_.reset(new views::MenuRunner(
440 model.get(),
441 views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU));
442 if (menu_runner_->RunMenuAt(source->GetWidget(),
443 NULL,
444 gfx::Rect(p, gfx::Size(0, 0)),
445 views::MENU_ANCHOR_TOPLEFT,
446 source_type) ==
447 views::MenuRunner::MENU_DELETED) {
448 return;
449 }
450 }
451 #endif
452 } 243 }
453 244
454 // views::WidgetDelegate implementation. 245 // views::WidgetDelegate implementation.
455 246
456 gfx::ImageSkia ChromeNativeAppWindowViews::GetWindowAppIcon() { 247 gfx::ImageSkia ChromeNativeAppWindowViews::GetWindowAppIcon() {
457 gfx::Image app_icon = app_window()->app_icon(); 248 gfx::Image app_icon = app_window()->app_icon();
458 if (app_icon.IsEmpty()) 249 if (app_icon.IsEmpty())
459 return GetWindowIcon(); 250 return GetWindowIcon();
460 else 251 else
461 return *app_icon.ToImageSkia(); 252 return *app_icon.ToImageSkia();
462 } 253 }
463 254
464 gfx::ImageSkia ChromeNativeAppWindowViews::GetWindowIcon() { 255 gfx::ImageSkia ChromeNativeAppWindowViews::GetWindowIcon() {
465 content::WebContents* web_contents = app_window()->web_contents(); 256 content::WebContents* web_contents = app_window()->web_contents();
466 if (web_contents) { 257 if (web_contents) {
467 FaviconTabHelper* favicon_tab_helper = 258 FaviconTabHelper* favicon_tab_helper =
468 FaviconTabHelper::FromWebContents(web_contents); 259 FaviconTabHelper::FromWebContents(web_contents);
469 gfx::Image app_icon = favicon_tab_helper->GetFavicon(); 260 gfx::Image app_icon = favicon_tab_helper->GetFavicon();
470 if (!app_icon.IsEmpty()) 261 if (!app_icon.IsEmpty())
471 return *app_icon.ToImageSkia(); 262 return *app_icon.ToImageSkia();
472 } 263 }
473 return gfx::ImageSkia(); 264 return gfx::ImageSkia();
474 } 265 }
475 266
476 views::NonClientFrameView* ChromeNativeAppWindowViews::CreateNonClientFrameView( 267 views::NonClientFrameView* ChromeNativeAppWindowViews::CreateNonClientFrameView(
477 views::Widget* widget) { 268 views::Widget* widget) {
478 #if defined(USE_ASH)
479 if (chrome::IsNativeViewInAsh(widget->GetNativeView())) {
480 // Set the delegate now because CustomFrameViewAsh sets the
481 // WindowStateDelegate if one is not already set.
482 ash::wm::GetWindowState(GetNativeWindow())->SetDelegate(
483 scoped_ptr<ash::wm::WindowStateDelegate>(
484 new NativeAppWindowStateDelegate(app_window(), this)).Pass());
485
486 if (IsFrameless())
487 return CreateNonStandardAppFrame();
488
489 if (app_window()->window_type_is_panel()) {
490 views::NonClientFrameView* frame_view =
491 new ash::PanelFrameView(widget, ash::PanelFrameView::FRAME_ASH);
492 frame_view->set_context_menu_controller(this);
493 return frame_view;
494 }
495
496 ash::CustomFrameViewAsh* custom_frame_view =
497 new ash::CustomFrameViewAsh(widget);
498 // Non-frameless app windows can be put into immersive fullscreen.
499 immersive_fullscreen_controller_.reset(
500 new ash::ImmersiveFullscreenController());
501 custom_frame_view->InitImmersiveFullscreenControllerForView(
502 immersive_fullscreen_controller_.get());
503 custom_frame_view->GetHeaderView()->set_context_menu_controller(this);
504
505 if (has_frame_color_) {
506 custom_frame_view->SetFrameColors(active_frame_color_,
507 inactive_frame_color_);
508 }
509
510 return custom_frame_view;
511 }
512 #endif
513 return (IsFrameless() || has_frame_color_) ? 269 return (IsFrameless() || has_frame_color_) ?
514 CreateNonStandardAppFrame() : CreateStandardDesktopAppFrame(); 270 CreateNonStandardAppFrame() : CreateStandardDesktopAppFrame();
515 } 271 }
516 272
517 bool ChromeNativeAppWindowViews::WidgetHasHitTestMask() const { 273 bool ChromeNativeAppWindowViews::WidgetHasHitTestMask() const {
518 return shape_ != NULL; 274 return shape_ != NULL;
519 } 275 }
520 276
521 void ChromeNativeAppWindowViews::GetWidgetHitTestMask(gfx::Path* mask) const { 277 void ChromeNativeAppWindowViews::GetWidgetHitTestMask(gfx::Path* mask) const {
522 shape_->getBoundaryPath(mask); 278 shape_->getBoundaryPath(mask);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 318
563 // NativeAppWindow implementation. 319 // NativeAppWindow implementation.
564 320
565 void ChromeNativeAppWindowViews::SetFullscreen(int fullscreen_types) { 321 void ChromeNativeAppWindowViews::SetFullscreen(int fullscreen_types) {
566 // Fullscreen not supported by panels. 322 // Fullscreen not supported by panels.
567 if (app_window()->window_type_is_panel()) 323 if (app_window()->window_type_is_panel())
568 return; 324 return;
569 is_fullscreen_ = (fullscreen_types != AppWindow::FULLSCREEN_TYPE_NONE); 325 is_fullscreen_ = (fullscreen_types != AppWindow::FULLSCREEN_TYPE_NONE);
570 widget()->SetFullscreen(is_fullscreen_); 326 widget()->SetFullscreen(is_fullscreen_);
571 327
572 #if defined(USE_ASH)
573 if (immersive_fullscreen_controller_.get()) {
574 // |immersive_fullscreen_controller_| should only be set if immersive
575 // fullscreen is the fullscreen type used by the OS.
576 immersive_fullscreen_controller_->SetEnabled(
577 ash::ImmersiveFullscreenController::WINDOW_TYPE_PACKAGED_APP,
578 (fullscreen_types & AppWindow::FULLSCREEN_TYPE_OS) != 0);
579 // Autohide the shelf instead of hiding the shelf completely when only in
580 // OS fullscreen.
581 ash::wm::WindowState* window_state =
582 ash::wm::GetWindowState(widget()->GetNativeWindow());
583 window_state->set_hide_shelf_when_fullscreen(fullscreen_types !=
584 AppWindow::FULLSCREEN_TYPE_OS);
585 DCHECK(ash::Shell::HasInstance());
586 ash::Shell::GetInstance()->UpdateShelfVisibility();
587 }
588 #endif
589
590 // TODO(jeremya) we need to call RenderViewHost::ExitFullscreen() if we 328 // TODO(jeremya) we need to call RenderViewHost::ExitFullscreen() if we
591 // ever drop the window out of fullscreen in response to something that 329 // ever drop the window out of fullscreen in response to something that
592 // wasn't the app calling webkitCancelFullScreen(). 330 // wasn't the app calling webkitCancelFullScreen().
593 } 331 }
594 332
595 bool ChromeNativeAppWindowViews::IsFullscreenOrPending() const { 333 bool ChromeNativeAppWindowViews::IsFullscreenOrPending() const {
596 return is_fullscreen_; 334 return is_fullscreen_;
597 } 335 }
598 336
599 void ChromeNativeAppWindowViews::UpdateBadgeIcon() { 337 void ChromeNativeAppWindowViews::UpdateBadgeIcon() {
600 const gfx::Image* icon = NULL; 338 const gfx::Image* icon = NULL;
601 if (!app_window()->badge_icon().IsEmpty()) { 339 if (!app_window()->badge_icon().IsEmpty()) {
602 icon = &app_window()->badge_icon(); 340 icon = &app_window()->badge_icon();
603 // chrome::DrawTaskbarDecoration can do interesting things with non-square 341 // chrome::DrawTaskbarDecoration can do interesting things with non-square
604 // bitmaps. 342 // bitmaps.
605 // TODO(benwells): Refactor chrome::DrawTaskbarDecoration to not be avatar 343 // TODO(benwells): Refactor chrome::DrawTaskbarDecoration to not be avatar
606 // specific, and lift this restriction. 344 // specific, and lift this restriction.
607 if (icon->Width() != icon->Height()) { 345 if (icon->Width() != icon->Height()) {
608 LOG(ERROR) << "Attempt to set a non-square badge; request ignored."; 346 LOG(ERROR) << "Attempt to set a non-square badge; request ignored.";
609 return; 347 return;
610 } 348 }
611 } 349 }
612 chrome::DrawTaskbarDecoration(GetNativeWindow(), icon); 350 chrome::DrawTaskbarDecoration(GetNativeWindow(), icon);
613 } 351 }
614 352
615 void ChromeNativeAppWindowViews::UpdateShape(scoped_ptr<SkRegion> region) { 353 void ChromeNativeAppWindowViews::UpdateShape(scoped_ptr<SkRegion> region) {
616 bool had_shape = shape_;
617 shape_ = region.Pass(); 354 shape_ = region.Pass();
618 355 widget()->SetShape(shape() ? new SkRegion(*shape()) : nullptr);
619 aura::Window* native_window = widget()->GetNativeWindow();
620 if (shape_) {
621 widget()->SetShape(new SkRegion(*shape_));
622 if (!had_shape) {
623 native_window->SetEventTargeter(scoped_ptr<ui::EventTargeter>(
624 new ShapedAppWindowTargeter(native_window, this)));
625 }
626 } else {
627 widget()->SetShape(NULL);
628 if (had_shape)
629 native_window->SetEventTargeter(scoped_ptr<ui::EventTargeter>());
630 }
631 widget()->OnSizeConstraintsChanged(); 356 widget()->OnSizeConstraintsChanged();
632 } 357 }
633 358
634 bool ChromeNativeAppWindowViews::HasFrameColor() const { 359 bool ChromeNativeAppWindowViews::HasFrameColor() const {
635 return has_frame_color_; 360 return has_frame_color_;
636 } 361 }
637 362
638 SkColor ChromeNativeAppWindowViews::ActiveFrameColor() const { 363 SkColor ChromeNativeAppWindowViews::ActiveFrameColor() const {
639 return active_frame_color_; 364 return active_frame_color_;
640 } 365 }
(...skipping 24 matching lines...) Expand all
665 InitializePanelWindow(create_params); 390 InitializePanelWindow(create_params);
666 } else { 391 } else {
667 InitializeDefaultWindow(create_params); 392 InitializeDefaultWindow(create_params);
668 } 393 }
669 extension_keybinding_registry_.reset(new ExtensionKeybindingRegistryViews( 394 extension_keybinding_registry_.reset(new ExtensionKeybindingRegistryViews(
670 Profile::FromBrowserContext(app_window->browser_context()), 395 Profile::FromBrowserContext(app_window->browser_context()),
671 widget()->GetFocusManager(), 396 widget()->GetFocusManager(),
672 extensions::ExtensionKeybindingRegistry::PLATFORM_APPS_ONLY, 397 extensions::ExtensionKeybindingRegistry::PLATFORM_APPS_ONLY,
673 NULL)); 398 NULL));
674 } 399 }
675
676 apps::AppWindowFrameView*
677 ChromeNativeAppWindowViews::CreateNonStandardAppFrame() {
678 apps::AppWindowFrameView* frame =
679 new apps::AppWindowFrameView(widget(),
680 this,
681 has_frame_color_,
682 active_frame_color_,
683 inactive_frame_color_);
684 frame->Init();
685 #if defined(USE_ASH)
686 // For Aura windows on the Ash desktop the sizes are different and the user
687 // can resize the window from slightly outside the bounds as well.
688 if (chrome::IsNativeWindowInAsh(widget()->GetNativeWindow())) {
689 frame->SetResizeSizes(ash::kResizeInsideBoundsSize,
690 ash::kResizeOutsideBoundsSize,
691 ash::kResizeAreaCornerSize);
692 }
693 #endif
694
695 #if !defined(OS_CHROMEOS)
696 // For non-Ash windows, install an easy resize window targeter, which ensures
697 // that the root window (not the app) receives mouse events on the edges.
698 if (chrome::GetHostDesktopTypeForNativeWindow(widget()->GetNativeWindow()) !=
699 chrome::HOST_DESKTOP_TYPE_ASH) {
700 aura::Window* window = widget()->GetNativeWindow();
701 int resize_inside = frame->resize_inside_bounds_size();
702 gfx::Insets inset(
703 resize_inside, resize_inside, resize_inside, resize_inside);
704 // Add the EasyResizeWindowTargeter on the window, not its root window. The
705 // root window does not have a delegate, which is needed to handle the event
706 // in Linux.
707 window->SetEventTargeter(scoped_ptr<ui::EventTargeter>(
708 new wm::EasyResizeWindowTargeter(window, inset, inset)));
709 }
710 #endif
711
712 return frame;
713 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698