chrome_native_app_window_views.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/ui/views/apps/chrome_native_app_window_views.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "apps/ui/views/app_window_frame_view.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/app/chrome_command_ids.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/app_mode/app_mode_utils.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chrome_page_zoom.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/favicon/favicon_tab_helper.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/ui/host_desktop.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/views/apps/shaped_app_window_targeter.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/views/extensions/extension_keybinding_registry_views.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/views/frame/taskbar_decorator.h" 1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/web_applications/web_app.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_switches.h" 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/base/hit_test.h" 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/base/models/simple_menu_model.h" 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/gfx/image/image_skia.h" 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/views/controls/menu/menu_runner.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/webview/webview.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget.h" 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/easy_resize_window_targeter.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_LINUX) 3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/shell_integration_linux.h" 3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif 3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_ASH) 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/ash_constants.h" 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/ash_switches.h" 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/frame/custom_frame_view_ash.h" 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/screen_util.h" 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shell.h" 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/wm/immersive_fullscreen_controller.h" 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/panels/panel_frame_view.h" 4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_state.h" 421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ash/wm/window_state_delegate.h" 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/wm/window_state_observer.h" 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/ash/ash_util.h" 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/ui/ash/multi_user/multi_user_context_menu.h" 46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "ui/aura/client/aura_constants.h" 471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/aura/client/window_tree_client.h" 481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/aura/window.h" 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/window_observer.h" 501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif 511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(USE_AURA) 53b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "ui/aura/window.h" 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using apps::AppWindow; 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kMinPanelWidth = 100; 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kMinPanelHeight = 100; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kDefaultPanelWidth = 200; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kDefaultPanelHeight = 300; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kResizeInsideBoundsSize = 5; 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const int kResizeAreaCornerSize = 16; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct AcceleratorMapping { 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::KeyboardCode keycode; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int modifiers; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int command_id; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const AcceleratorMapping kAppWindowAcceleratorMap[] = { 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_W, ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW }, 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_CLOSE_WINDOW }, 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { ui::VKEY_F4, ui::EF_ALT_DOWN, IDC_CLOSE_WINDOW }, 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// These accelerators will only be available in kiosk mode. These allow the 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// user to manually zoom app windows. This is only necessary in kiosk mode 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// (in normal mode, the user can zoom via the screen magnifier). 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(xiyuan): Write a test for kiosk accelerators. 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const AcceleratorMapping kAppWindowKioskAppModeAcceleratorMap[] = { 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_OEM_MINUS, ui::EF_CONTROL_DOWN, IDC_ZOOM_MINUS }, 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_OEM_MINUS, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IDC_ZOOM_MINUS }, 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_SUBTRACT, ui::EF_CONTROL_DOWN, IDC_ZOOM_MINUS }, 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_OEM_PLUS, ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS }, 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_OEM_PLUS, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS }, 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_ADD, ui::EF_CONTROL_DOWN, IDC_ZOOM_PLUS }, 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_0, ui::EF_CONTROL_DOWN, IDC_ZOOM_NORMAL }, 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { ui::VKEY_NUMPAD0, ui::EF_CONTROL_DOWN, IDC_ZOOM_NORMAL }, 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AddAcceleratorsFromMapping(const AcceleratorMapping mapping[], 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t mapping_length, 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::map<ui::Accelerator, int>* accelerators) { 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < mapping_length; ++i) { 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::Accelerator accelerator(mapping[i].keycode, mapping[i].modifiers); 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (*accelerators)[accelerator] = mapping[i].command_id; 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const std::map<ui::Accelerator, int>& GetAcceleratorTable() { 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef std::map<ui::Accelerator, int> AcceleratorMap; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CR_DEFINE_STATIC_LOCAL(AcceleratorMap, accelerators, ()); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (accelerators.empty()) { 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddAcceleratorsFromMapping( 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kAppWindowAcceleratorMap, 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) arraysize(kAppWindowAcceleratorMap), 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &accelerators); 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Add accelerators for kiosk mode. 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (chrome::IsRunningInForcedAppMode()) { 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddAcceleratorsFromMapping( 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kAppWindowKioskAppModeAcceleratorMap, 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) arraysize(kAppWindowKioskAppModeAcceleratorMap), 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &accelerators); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return accelerators; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(USE_ASH) 1251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// This class handles a user's fullscreen request (Shift+F4/F4). 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class NativeAppWindowStateDelegate : public ash::wm::WindowStateDelegate, 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public ash::wm::WindowStateObserver, 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public aura::WindowObserver { 1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) public: 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NativeAppWindowStateDelegate(AppWindow* app_window, 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) apps::NativeAppWindow* native_app_window) 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : app_window_(app_window), 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_( 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::GetWindowState(native_app_window->GetNativeWindow())) { 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Add a window state observer to exit fullscreen properly in case 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // fullscreen is exited without going through AppWindow::Restore(). This 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // is the case when exiting immersive fullscreen via the "Restore" window 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // control. 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(pkotwicz): This is a hack. Remove ASAP. http://crbug.com/319048 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_->AddObserver(this); 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_->window()->AddObserver(this); 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~NativeAppWindowStateDelegate(){ 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (window_state_) { 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_->RemoveObserver(this); 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_->window()->RemoveObserver(this); 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private: 1511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Overridden from ash::wm::WindowStateDelegate. 1521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual bool ToggleFullscreen(ash::wm::WindowState* window_state) OVERRIDE { 1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Windows which cannot be maximized should not be fullscreened. 1541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(window_state->IsFullscreen() || window_state->CanMaximize()); 1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (window_state->IsFullscreen()) 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_window_->Restore(); 1571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) else if (window_state->CanMaximize()) 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_window_->OSFullscreen(); 1591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return true; 1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Overridden from ash::wm::WindowStateObserver: 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnPostWindowStateTypeChange( 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::WindowState* window_state, 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::wm::WindowStateType old_type) OVERRIDE { 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!window_state->IsFullscreen() && !window_state->IsMinimized() && 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_window_->GetBaseWindow()->IsFullscreenOrPending()) { 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_window_->Restore(); 169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Usually OnNativeWindowChanged() is called when the window bounds are 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // changed as a result of a state type change. Because the change in state 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // type has already occurred, we need to call OnNativeWindowChanged() 172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // explicitly. 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_window_->OnNativeWindowChanged(); 174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Overridden from aura::WindowObserver: 178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void OnWindowDestroying(aura::Window* window) OVERRIDE { 179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_->RemoveObserver(this); 180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_->window()->RemoveObserver(this); 181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state_ = NULL; 182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Not owned. 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppWindow* app_window_; 186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::WindowState* window_state_; 1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(NativeAppWindowStateDelegate); 1891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}; 1901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif // USE_ASH 1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ChromeNativeAppWindowViews::ChromeNativeAppWindowViews() 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : is_fullscreen_(false), 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_frame_color_(false), 197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) frame_color_(SK_ColorBLACK) {} 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ChromeNativeAppWindowViews::~ChromeNativeAppWindowViews() {} 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::OnBeforeWidgetInit( 202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::Widget::InitParams* init_params, 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::Widget* widget) {} 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::InitializeDefaultWindow( 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const AppWindow::CreateParams& create_params) { 20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string app_name = 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) web_app::GenerateApplicationNameFromExtensionId( 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) app_window()->extension()->id()); 21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::Widget::InitParams init_params(views::Widget::InitParams::TYPE_WINDOW); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) init_params.delegate = this; 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) init_params.remove_standard_frame = !ShouldUseNativeFrame(); 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_LINUX) && !defined(OS_CHROMEOS) 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // On Linux, remove the standard frame. Instead, we will use CustomFrameView 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to draw a native-like frame. 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(mgiuca): Remove this during fix for http://crbug.com/322256. 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) init_params.remove_standard_frame = true; 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) init_params.use_system_default_icon = true; 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(erg): Conceptually, these are toplevel windows, but we theoretically 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // could plumb context through to here in some cases. 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) init_params.top_level = true; 224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (create_params.transparent_background) 225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) init_params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) init_params.keep_on_top = create_params.always_on_top; 22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(OS_LINUX) && !defined(OS_CHROMEOS) 22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Set up a custom WM_CLASS for app windows. This allows task switchers in 23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // X11 environments to distinguish them from main browser windows. 23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) init_params.wm_class_name = web_app::GetWMClassFromAppName(app_name); 23258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) init_params.wm_class_class = ShellIntegrationLinux::GetProgramClassName(); 233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char kX11WindowRoleApp[] = "app"; 234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) init_params.wm_role_name = std::string(kX11WindowRoleApp); 23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif 23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OnBeforeWidgetInit(&init_params, window()); 238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window()->Init(init_params); 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The frame insets are required to resolve the bounds specifications 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // correctly. So we set the window bounds and constraints now. 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Insets frame_insets = GetFrameInsets(); 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect window_bounds = create_params.GetInitialWindowBounds(frame_insets); 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SetContentSizeConstraints(create_params.GetContentMinimumSize(frame_insets), 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) create_params.GetContentMaximumSize(frame_insets)); 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!window_bounds.IsEmpty()) { 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) typedef apps::AppWindow::BoundsSpecification BoundsSpecification; 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool position_specified = 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_bounds.x() != BoundsSpecification::kUnspecifiedPosition && 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_bounds.y() != BoundsSpecification::kUnspecifiedPosition; 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!position_specified) 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window()->CenterWindow(window_bounds.size()); 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) else 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window()->SetBounds(window_bounds); 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Register accelarators supported by app windows. 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(jeremya/stevenjb): should these be registered for panels too? 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::FocusManager* focus_manager = GetFocusManager(); 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::map<ui::Accelerator, int>& accelerator_table = 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetAcceleratorTable(); 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const bool is_kiosk_app_mode = chrome::IsRunningInForcedAppMode(); 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Ensures that kiosk mode accelerators are enabled when in kiosk mode (to be 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // future proof). This is needed because GetAcceleratorTable() uses a static 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to store data and only checks kiosk mode once. If a platform app is 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // launched before kiosk mode starts, the kiosk accelerators will not be 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // registered. This DCHECK catches the case. 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!is_kiosk_app_mode || 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) accelerator_table.size() == 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) arraysize(kAppWindowAcceleratorMap) + 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) arraysize(kAppWindowKioskAppModeAcceleratorMap)); 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::map<ui::Accelerator, int>::const_iterator iter = 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) accelerator_table.begin(); 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != accelerator_table.end(); ++iter) { 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (is_kiosk_app_mode && !chrome::IsCommandAllowedInAppMode(iter->second)) 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) focus_manager->RegisterAccelerator( 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter->first, ui::AcceleratorManager::kNormalPriority, this); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::InitializePanelWindow( 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const AppWindow::CreateParams& create_params) { 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::Widget::InitParams params(views::Widget::InitParams::TYPE_PANEL); 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.delegate = this; 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect initial_window_bounds = 291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) create_params.GetInitialWindowBounds(gfx::Insets()); 292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) preferred_size_ = gfx::Size(initial_window_bounds.width(), 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) initial_window_bounds.height()); 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (preferred_size_.width() == 0) 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preferred_size_.set_width(kDefaultPanelWidth); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (preferred_size_.width() < kMinPanelWidth) 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preferred_size_.set_width(kMinPanelWidth); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (preferred_size_.height() == 0) 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preferred_size_.set_height(kDefaultPanelHeight); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (preferred_size_.height() < kMinPanelHeight) 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preferred_size_.set_height(kMinPanelHeight); 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_ASH) 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ash::Shell::HasInstance()) { 305d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Open a new panel on the target root. 3061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* target = ash::Shell::GetTargetRootWindow(); 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.bounds = ash::ScreenUtil::ConvertRectToScreen( 308d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) target, gfx::Rect(preferred_size_)); 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.bounds = gfx::Rect(preferred_size_); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.bounds = gfx::Rect(preferred_size_); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(erg): Conceptually, these are toplevel windows, but we theoretically 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // could plumb context through to here in some cases. 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.top_level = true; 318a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window()->Init(params); 319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window()->set_focus_on_creation(create_params.focused); 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 321b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#if defined(USE_ASH) 322b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (create_params.state == ui::SHOW_STATE_DETACHED) { 323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect window_bounds(initial_window_bounds.x(), 324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) initial_window_bounds.y(), 325b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) preferred_size_.width(), 326b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) preferred_size_.height()); 327b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) aura::Window* native_window = GetNativeWindow(); 32868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ash::wm::GetWindowState(native_window)->set_panel_attached(false); 3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::client::ParentWindowWithContext(native_window, 3301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) native_window->GetRootWindow(), 3311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) native_window->GetBoundsInScreen()); 332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window()->SetBounds(window_bounds); 333b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 334b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#else 335b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // TODO(stevenjb): NativeAppWindow panels need to be implemented for other 336b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // platforms. 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 340a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::ShouldUseNativeFrame() const { 341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return !IsFrameless() && !has_frame_color_; 342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::InstallEasyResizeTargeterOnContainer() const { 345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* root_window = window()->GetNativeWindow()->GetRootWindow(); 346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Insets inset(kResizeInsideBoundsSize, kResizeInsideBoundsSize, 347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kResizeInsideBoundsSize, kResizeInsideBoundsSize); 348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) root_window->SetEventTargeter(scoped_ptr<ui::EventTargeter>( 349a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new wm::EasyResizeWindowTargeter(root_window, inset, inset))); 3504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)apps::AppWindowFrameView* 353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ChromeNativeAppWindowViews::CreateAppWindowFrameView() { 3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // By default the user can resize the window from slightly inside the bounds. 3554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int resize_inside_bounds_size = kResizeInsideBoundsSize; 3564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int resize_outside_bounds_size = 0; 3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int resize_outside_scale_for_touch = 1; 3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int resize_area_corner_size = kResizeAreaCornerSize; 3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(USE_ASH) 3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // For Aura windows on the Ash desktop the sizes are different and the user 3614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // can resize the window from slightly outside the bounds as well. 362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (chrome::IsNativeWindowInAsh(window()->GetNativeWindow())) { 3634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) resize_inside_bounds_size = ash::kResizeInsideBoundsSize; 3644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) resize_outside_bounds_size = ash::kResizeOutsideBoundsSize; 3654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) resize_outside_scale_for_touch = ash::kResizeOutsideBoundsScaleForTouch; 3664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) resize_area_corner_size = ash::kResizeAreaCornerSize; 3674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) apps::AppWindowFrameView* frame_view = new apps::AppWindowFrameView(this); 370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) frame_view->Init(window(), 371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) frame_color_, 3724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) resize_inside_bounds_size, 3734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) resize_outside_bounds_size, 3744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) resize_outside_scale_for_touch, 3754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) resize_area_corner_size); 3764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return frame_view; 3774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// ui::BaseWindow implementation. 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ui::WindowShowState ChromeNativeAppWindowViews::GetRestoredState() const { 382b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (IsMaximized()) 383b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return ui::SHOW_STATE_MAXIMIZED; 384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (IsFullscreen()) { 385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(USE_ASH) 386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (immersive_fullscreen_controller_.get() && 387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) immersive_fullscreen_controller_->IsEnabled()) { 388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Restore windows which were previously in immersive fullscreen to 389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // maximized. Restoring the window to a different fullscreen type 390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // makes for a bad experience. 391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ui::SHOW_STATE_MAXIMIZED; 392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 394b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return ui::SHOW_STATE_FULLSCREEN; 395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 39668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(USE_ASH) 397b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Use kRestoreShowStateKey in case a window is minimized/hidden. 398b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ui::WindowShowState restore_state = 399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window()->GetNativeWindow()->GetProperty( 400b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) aura::client::kRestoreShowStateKey); 401ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Whitelist states to return so that invalid and transient states 402ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // are not saved and used to restore windows when they are recreated. 403ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch switch (restore_state) { 404ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_NORMAL: 405ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_MAXIMIZED: 406ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_FULLSCREEN: 407ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_DETACHED: 408ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return restore_state; 409ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 410ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_DEFAULT: 411ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_MINIMIZED: 412ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_INACTIVE: 413ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch case ui::SHOW_STATE_END: 414ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return ui::SHOW_STATE_NORMAL; 415ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 416b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#endif 417b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return ui::SHOW_STATE_NORMAL; 418b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 419b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::IsAlwaysOnTop() const { 421a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (app_window()->window_type_is_panel()) { 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(USE_ASH) 423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return ash::wm::GetWindowState(window()->GetNativeWindow())-> 424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) panel_attached(); 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else 426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 4284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 429a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return window()->IsAlwaysOnTop(); 4304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// views::ContextMenuController implementation. 434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::ShowContextMenuForView( 436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::View* source, 437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const gfx::Point& p, 438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ui::MenuSourceType source_type) { 439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(USE_ASH) && defined(OS_CHROMEOS) 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<ui::MenuModel> model = 441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CreateMultiUserContextMenu(app_window()->GetNativeWindow()); 442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!model.get()) 443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Only show context menu if point is in caption. 446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Point point_in_view_coords(p); 447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) views::View::ConvertPointFromScreen(window()->non_client_view(), 448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &point_in_view_coords); 449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int hit_test = window()->non_client_view()->NonClientHitTest( 450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) point_in_view_coords); 451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (hit_test == HTCAPTION) { 452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) menu_runner_.reset(new views::MenuRunner(model.get())); 453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (menu_runner_->RunMenuAt(source->GetWidget(), NULL, 454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect(p, gfx::Size(0,0)), views::MenuItemView::TOPLEFT, 455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) source_type, 456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU) == 457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::MenuRunner::MENU_DELETED) 458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// views::WidgetDelegate implementation. 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)gfx::ImageSkia ChromeNativeAppWindowViews::GetWindowAppIcon() { 466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Image app_icon = app_window()->app_icon(); 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (app_icon.IsEmpty()) 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetWindowIcon(); 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return *app_icon.ToImageSkia(); 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 473a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)gfx::ImageSkia ChromeNativeAppWindowViews::GetWindowIcon() { 474a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) content::WebContents* web_contents = app_window()->web_contents(); 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (web_contents) { 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconTabHelper* favicon_tab_helper = 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FaviconTabHelper::FromWebContents(web_contents); 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Image app_icon = favicon_tab_helper->GetFavicon(); 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!app_icon.IsEmpty()) 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return *app_icon.ToImageSkia(); 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return gfx::ImageSkia(); 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 485a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)views::NonClientFrameView* ChromeNativeAppWindowViews::CreateNonClientFrameView( 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::Widget* widget) { 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_ASH) 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (chrome::IsNativeViewInAsh(widget->GetNativeView())) { 489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Set the delegate now because CustomFrameViewAsh sets the 490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // WindowStateDelegate if one is not already set. 491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ash::wm::GetWindowState(GetNativeWindow())->SetDelegate( 492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<ash::wm::WindowStateDelegate>( 493a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new NativeAppWindowStateDelegate(app_window(), this)).Pass()); 494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 495a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (app_window()->window_type_is_panel()) { 496a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::PanelFrameView::FrameType frame_type = IsFrameless() ? 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ash::PanelFrameView::FRAME_NONE : ash::PanelFrameView::FRAME_ASH; 498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::NonClientFrameView* frame_view = 499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new ash::PanelFrameView(widget, frame_type); 500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) frame_view->set_context_menu_controller(this); 501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return frame_view; 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 504a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!IsFrameless()) { 505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::CustomFrameViewAsh* custom_frame_view = 506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new ash::CustomFrameViewAsh(widget); 507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_CHROMEOS) 508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Non-frameless app windows can be put into immersive fullscreen. 509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(pkotwicz): Investigate if immersive fullscreen can be enabled for 510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Windows Ash. 511a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) immersive_fullscreen_controller_.reset( 512a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new ash::ImmersiveFullscreenController()); 513a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) custom_frame_view->InitImmersiveFullscreenControllerForView( 514a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) immersive_fullscreen_controller_.get()); 515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) custom_frame_view->GetHeaderView()->set_context_menu_controller(this); 517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return custom_frame_view; 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 521a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!ShouldUseNativeFrame()) 5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return CreateAppWindowFrameView(); 523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return views::WidgetDelegateView::CreateNonClientFrameView(widget); 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 526a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::WidgetHasHitTestMask() const { 527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return shape_ != NULL; 5283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 530a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::GetWidgetHitTestMask(gfx::Path* mask) const { 531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) shape_->getBoundaryPath(mask); 5323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// views::View implementation. 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 536a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)gfx::Size ChromeNativeAppWindowViews::GetPreferredSize() { 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!preferred_size_.IsEmpty()) 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return preferred_size_; 539a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NativeAppWindowViews::GetPreferredSize(); 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::AcceleratorPressed( 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ui::Accelerator& accelerator) { 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::map<ui::Accelerator, int>& accelerator_table = 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetAcceleratorTable(); 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<ui::Accelerator, int>::const_iterator iter = 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) accelerator_table.find(accelerator); 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(iter != accelerator_table.end()); 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int command_id = iter->second; 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (command_id) { 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case IDC_CLOSE_WINDOW: 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Close(); 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case IDC_ZOOM_MINUS: 555a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome_page_zoom::Zoom(web_view()->GetWebContents(), 5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::PAGE_ZOOM_OUT); 5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case IDC_ZOOM_NORMAL: 559a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome_page_zoom::Zoom(web_view()->GetWebContents(), 5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::PAGE_ZOOM_RESET); 5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case IDC_ZOOM_PLUS: 563a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome_page_zoom::Zoom(web_view()->GetWebContents(), 5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::PAGE_ZOOM_IN); 5655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED() << "Unknown accelerator sent to app window."; 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 569a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NativeAppWindowViews::AcceleratorPressed(accelerator); 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// NativeAppWindow implementation. 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 574a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::SetFullscreen(int fullscreen_types) { 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Fullscreen not supported by panels. 576a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (app_window()->window_type_is_panel()) 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) is_fullscreen_ = (fullscreen_types != AppWindow::FULLSCREEN_TYPE_NONE); 579a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window()->SetFullscreen(is_fullscreen_); 580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 581f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(USE_ASH) 582f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (immersive_fullscreen_controller_.get()) { 583f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |immersive_fullscreen_controller_| should only be set if immersive 584f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // fullscreen is the fullscreen type used by the OS. 585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) immersive_fullscreen_controller_->SetEnabled( 5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ash::ImmersiveFullscreenController::WINDOW_TYPE_PACKAGED_APP, 5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (fullscreen_types & AppWindow::FULLSCREEN_TYPE_OS) != 0); 588f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Autohide the shelf instead of hiding the shelf completely when only in 589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // OS fullscreen. 590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::wm::WindowState* window_state = 591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::wm::GetWindowState(window()->GetNativeWindow()); 5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_state->set_hide_shelf_when_fullscreen(fullscreen_types != 5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppWindow::FULLSCREEN_TYPE_OS); 594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(ash::Shell::HasInstance()); 595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ash::Shell::GetInstance()->UpdateShelfVisibility(); 596f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 598f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(jeremya) we need to call RenderViewHost::ExitFullscreen() if we 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ever drop the window out of fullscreen in response to something that 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // wasn't the app calling webkitCancelFullScreen(). 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 604a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::IsFullscreenOrPending() const { 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return is_fullscreen_; 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 608a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::IsDetached() const { 609a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!app_window()->window_type_is_panel()) 610b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return false; 611b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#if defined(USE_ASH) 612a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return !ash::wm::GetWindowState(window()->GetNativeWindow()) 613a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ->panel_attached(); 614b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#else 615b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return false; 616b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#endif 617b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 618b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 619a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::UpdateBadgeIcon() { 6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Image* icon = NULL; 621a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!app_window()->badge_icon().IsEmpty()) { 622a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) icon = &app_window()->badge_icon(); 6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // chrome::DrawTaskbarDecoration can do interesting things with non-square 6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // bitmaps. 6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(benwells): Refactor chrome::DrawTaskbarDecoration to not be avatar 6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // specific, and lift this restriction. 6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (icon->Width() != icon->Height()) { 6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(ERROR) << "Attempt to set a non-square badge; request ignored."; 6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome::DrawTaskbarDecoration(GetNativeWindow(), icon); 6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 635a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::UpdateShape(scoped_ptr<SkRegion> region) { 6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool had_shape = shape_; 637f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) shape_ = region.Pass(); 638f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 639a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* native_window = window()->GetNativeWindow(); 6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (shape_) { 641a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window()->SetShape(new SkRegion(*shape_)); 6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!had_shape) { 6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) native_window->SetEventTargeter(scoped_ptr<ui::EventTargeter>( 6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new ShapedAppWindowTargeter(native_window, this))); 6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 647a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window()->SetShape(NULL); 6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (had_shape) 6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) native_window->SetEventTargeter(scoped_ptr<ui::EventTargeter>()); 6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 6524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 653a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ChromeNativeAppWindowViews::HasFrameColor() const { 654a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return has_frame_color_; 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 657a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SkColor ChromeNativeAppWindowViews::FrameColor() const { return frame_color_; } 6584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 659a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// NativeAppWindowViews implementation. 6604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 661a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ChromeNativeAppWindowViews::InitializeWindow( 662a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AppWindow* app_window, 663a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const AppWindow::CreateParams& create_params) { 664a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(window()); 665a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) has_frame_color_ = create_params.has_frame_color; 666a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) frame_color_ = create_params.frame_color; 667a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (create_params.window_type == AppWindow::WINDOW_TYPE_PANEL || 668a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) create_params.window_type == AppWindow::WINDOW_TYPE_V1_PANEL) { 669a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) InitializePanelWindow(create_params); 670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 671a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) InitializeDefaultWindow(create_params); 672a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 673a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extension_keybinding_registry_.reset(new ExtensionKeybindingRegistryViews( 674a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Profile::FromBrowserContext(app_window->browser_context()), 675a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window()->GetFocusManager(), 676a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extensions::ExtensionKeybindingRegistry::PLATFORM_APPS_ONLY, 677a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NULL)); 678a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 679a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_WIN) 680a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!ShouldUseNativeFrame() && 681a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome::GetHostDesktopTypeForNativeWindow(window()->GetNativeWindow()) != 682a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome::HOST_DESKTOP_TYPE_ASH) { 683a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) InstallEasyResizeTargeterOnContainer(); 684a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 685a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 686a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 687